diff --git a/.mozconfig.mk b/.mozconfig.mk
index cc5b448a..7f871989 100644
--- a/.mozconfig.mk
+++ b/.mozconfig.mk
@@ -1,12 +1,12 @@
# gmake
# This file is automatically generated for client.mk.
-# Do not edit. Edit /c/projects/retrozilla/mozilla/mozconfig instead.
+# Do not edit. Edit /c/projects/moz95/mozilla/mozconfig instead.
# To create a new .mozconfig file, you can visit,
# http://webtools.mozilla.org/build/config.cgi
# PATH=/local/bin:/c/mozilla-build//wget:/c/mozilla-build//7zip:/c/mozilla-build//blat261/full:/c/mozilla-build//python25:/c/mozilla-build//svn-win32-1.4.2/bin:/c/mozilla-build//upx203w:/c/mozilla-build//xemacs/XEmacs-21.4.19/i586-pc-win32:/c/mozilla-build//info-zip:/c/mozilla-build//nsis-2.22:/c/mozilla-build//nsis-2.33u:.:/usr/local/bin:/mingw/bin:/bin:/c/PROGRA~1/MICROS~3/Common/msdev98/BIN:/c/PROGRA~1/MICROS~3/VC98/BIN:/c/PROGRA~1/MICROS~3/Common/TOOLS/WINNT:/c/PROGRA~1/MICROS~3/Common/TOOLS:/c/WINNT/System32:/c/WINNT:/c/WINNT/System32/Wbem:/c/mozilla-build/moztools-180compat/bin
MOZ_MAKE_FLAGS=-j4
-MOZ_OBJDIR=/c/projects/retrozilla/obj-sm95-release
+MOZ_OBJDIR=/c/projects/moz95/obj-sm95-release
# --target=i586-pc-msvc is used by configure (not client.mk)
# --enable-application=suite is used by configure (not client.mk)
# --enable-optimize is used by configure (not client.mk)
diff --git a/.mozconfig.mk-tmp2536 b/.mozconfig.mk-tmp2536
deleted file mode 100644
index d4e358bf..00000000
--- a/.mozconfig.mk-tmp2536
+++ /dev/null
@@ -1,14 +0,0 @@
-# gmake
-# This file is automatically generated for client.mk.
-# Do not edit. Edit /c/projects/moz95/mozilla/mozconfig instead.
-# To create a new .mozconfig file, you can visit,
-# http://webtools.mozilla.org/build/config.cgi
-
-# PATH=/local/bin:/c/mozilla-build//wget:/c/mozilla-build//7zip:/c/mozilla-build//blat261/full:/c/mozilla-build//python25:/c/mozilla-build//svn-win32-1.4.2/bin:/c/mozilla-build//upx203w:/c/mozilla-build//xemacs/XEmacs-21.4.19/i586-pc-win32:/c/mozilla-build//info-zip:/c/mozilla-build//nsis-2.22:/c/mozilla-build//nsis-2.33u:.:/usr/local/bin:/mingw/bin:/bin:/c/PROGRA~1/MICROS~3/Common/msdev98/BIN:/c/PROGRA~1/MICROS~3/VC98/BIN:/c/PROGRA~1/MICROS~3/Common/TOOLS/WINNT:/c/PROGRA~1/MICROS~3/Common/TOOLS:/c/WINNT/System32:/c/WINNT:/c/WINNT/System32/Wbem:/c/mozilla-build/moztools-180compat/bin
-MOZ_MAKE_FLAGS=-j4
-MOZ_OBJDIR=/c/projects/moz95/obj-sm95-release
-# --target=i586-pc-msvc is used by configure (not client.mk)
-# --enable-application=suite is used by configure (not client.mk)
-# --enable-optimize is used by configure (not client.mk)
-# --disable-debug is used by configure (not client.mk)
-# --disable-tests is used by configure (not client.mk)
diff --git a/xpfe/bootstrap/browser-prefs.js b/xpfe/bootstrap/browser-prefs.js
index 6a1e6854..a468f919 100644
--- a/xpfe/bootstrap/browser-prefs.js
+++ b/xpfe/bootstrap/browser-prefs.js
@@ -41,6 +41,29 @@
#expand pref("general.useragent.extra.__MOZ_APP_NAME__", "__MOZ_APP_DISPLAYNAME__/__MOZ_APP_VERSION__ SeaMonkey/1.1.19 Firefox/2.0.20");
pref("rzHome.autofocus", true);
+// RETROZILLA SESSION RESTORE PREFERENCES
+pref("extensions.crashrecovery.interval", 10000);
+pref("extensions.crashrecovery.postdata", -1);
+pref("extensions.crashrecovery.privacy_level", 1);
+pref("extensions.crashrecovery.restore_prompt", true);
+pref("extensions.crashrecovery.restore_prompt_uri", "chrome://global/content/extensions/sessionmanager/restore_prompt.xul"); // change this to new URI
+pref("extensions.crashrecovery.resume_session", false);
+pref("extensions.crashrecovery.resume_session_once", false);
+
+pref("extensions.sessionmanager.backup_session", 1);
+pref("extensions.sessionmanager.max_backup_keep", 1);
+pref("extensions.sessionmanager.max_closed_undo", 10);
+pref("extensions.sessionmanager.max_tabs_undo", 10);
+pref("extensions.sessionmanager.name_format", "%40t-%d");
+pref("extensions.sessionmanager.options_selected_tab", 0);
+pref("extensions.sessionmanager.overwrite", true);
+pref("extensions.sessionmanager.reload", false);
+pref("extensions.sessionmanager.resume_session", "");
+pref("extensions.sessionmanager.save_closed_tabs", 0);
+pref("extensions.sessionmanager.save_window_list", false);
+pref("extensions.sessionmanager.session_list_order", 1);
+pref("extensions.sessionmanager.submenus", false);
+
/* The prefs in this file are specific to the seamonkey browser.
* Generic default prefs that would be useful to embedders belong in
* modules/libpref/src/init/all.js
diff --git a/xpfe/browser/resources/content/navigator.xul b/xpfe/browser/resources/content/navigator.xul
index 1c65bd01..584a0963 100644
--- a/xpfe/browser/resources/content/navigator.xul
+++ b/xpfe/browser/resources/content/navigator.xul
@@ -49,6 +49,8 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xpfe/components/sessionstore/crashrecovery.properties b/xpfe/components/sessionstore/crashrecovery.properties
new file mode 100644
index 00000000..3dab2473
--- /dev/null
+++ b/xpfe/components/sessionstore/crashrecovery.properties
@@ -0,0 +1,4 @@
+extensions.{1280606b-2510-4fe0-97ef-9b5a22eafe6a}.description=Automagically recovers all windows (after a crash).
+
+restore_prompt=All windows from before the last crash will be restored.
+restore_prompt_again=Don't show this dialog again
diff --git a/xpfe/components/sessionstore/locale/en-US/contents.rdf b/xpfe/components/sessionstore/locale/en-US/contents.rdf
new file mode 100644
index 00000000..8854db1f
--- /dev/null
+++ b/xpfe/components/sessionstore/locale/en-US/contents.rdf
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xpfe/components/sessionstore/locale/en-US/crashrecovery.properties b/xpfe/components/sessionstore/locale/en-US/crashrecovery.properties
new file mode 100644
index 00000000..3dab2473
--- /dev/null
+++ b/xpfe/components/sessionstore/locale/en-US/crashrecovery.properties
@@ -0,0 +1,4 @@
+extensions.{1280606b-2510-4fe0-97ef-9b5a22eafe6a}.description=Automagically recovers all windows (after a crash).
+
+restore_prompt=All windows from before the last crash will be restored.
+restore_prompt_again=Don't show this dialog again
diff --git a/xpfe/components/sessionstore/public/Makefile.in b/xpfe/components/sessionstore/public/Makefile.in
new file mode 100644
index 00000000..407aee36
--- /dev/null
+++ b/xpfe/components/sessionstore/public/Makefile.in
@@ -0,0 +1,51 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (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.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = crashrecovery
+XPIDL_MODULE=crashrecovery
+
+XPIDLSRCS = crashrecovery.idl \
+
+include $(topsrcdir)/config/rules.mk
+
diff --git a/xpfe/components/sessionstore/public/crashrecovery.idl b/xpfe/components/sessionstore/public/crashrecovery.idl
new file mode 100644
index 00000000..b7679ab0
--- /dev/null
+++ b/xpfe/components/sessionstore/public/crashrecovery.idl
@@ -0,0 +1,32 @@
+#include "nsISupports.idl"
+
+interface nsIDOMWindow;
+
+/**
+ * nsICrashRecoveryService keeps track of the current browsing state - i.e.
+ * tab history, cookies, scroll state, form data, POSTDATA and window features
+ * - and allows to restore everything into one window.
+ */
+
+[scriptable, uuid(1280606b-2510-4fe0-97ef-9b5a22eafe33)]
+interface nsICrashRecoveryService : nsISupports
+{
+ /**
+ * @return The current browsing state, serialized into a string.
+ */
+ wstring getCurrentState();
+
+ /**
+ * @param aWindow is the window whose state is to be returned.
+ *
+ * @return The current state of one window, serialized into a string.
+ */
+ wstring getWindowState(in nsIDOMWindow aWindow);
+
+ /**
+ * @param aWindow is the window into which the browsing state will be restored.
+ * @param aState is a serialized browsing state as produced by getCurrentState.
+ * @param aOverwriteTabs indicates whether the window's tabs will be overwritten.
+ */
+ void restoreWindow(in nsIDOMWindow aWindow, in wstring aState, in boolean aOverwriteTabs);
+};
diff --git a/xpfe/components/sessionstore/src/Makefile.in b/xpfe/components/sessionstore/src/Makefile.in
new file mode 100644
index 00000000..afd88972
--- /dev/null
+++ b/xpfe/components/sessionstore/src/Makefile.in
@@ -0,0 +1,48 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (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.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org Code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+EXTRA_COMPONENTS = crashrecovery.js
+
+include $(topsrcdir)/config/rules.mk
+
diff --git a/xpfe/components/sessionstore/src/crashrecovery.js b/xpfe/components/sessionstore/src/crashrecovery.js
new file mode 100644
index 00000000..d24f87fe
--- /dev/null
+++ b/xpfe/components/sessionstore/src/crashrecovery.js
@@ -0,0 +1,1940 @@
+/* Crash Recovery 2006-07-30 - Copyleft © 2006 Simon Bünzli */
+
+/* :::::::: Basic Convenience ::::::::::::::: */
+
+/*const*/ var Cc = Components.classes;
+/*const*/ var Ci = Components.interfaces;
+/*const*/ var Cr = Components.results;
+
+/*const*/ var report = Components.utils.reportError;
+
+
+/* :::::::: Constants ::::::::::::::: */
+
+/*const*/ var gIOService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+/*const*/ var gObserverService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
+/*const*/ var gPrefRoot = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch2);
+/*const*/ var gWindowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
+
+/*const*/ var gObserving = ["domwindowopened", "domwindowclosed", "quit-application-requested", "quit-application-granted", "quit-application", "browser:purge-session-history"];
+/*const*/ var gPrefBranch = gPrefRoot.QueryInterface(Ci.nsIPrefService).getBranch("extensions.crashrecovery.").QueryInterface(Ci.nsIPrefBranch2);
+
+/*const*/ var gCapabilities = ["Subframes", "Plugins", "Javascript", "MetaRedirects", "Images"];
+/*const*/ var gWinAttributes = ["width", "height", "screenX", "screenY", "sizemode"];
+/*const*/ var gWinHidable = ["menubar", "toolbar", "locationbar", "personalbar", "statusbar", "scrollbars"];
+/*const*/ var gXulAttributes = ["locked", "protected", "marked"];
+
+/*const*/ var STATE_STOPPED = 0;
+/*const*/ var STATE_RUNNING = 1;
+/*const*/ var STATE_QUITTING = -1;
+
+/*const*/ var POTENTIAL_CRASH_DELAY = 8000;
+
+
+/* :::::::: State Variables ::::::::::::::: */
+
+var gInitialState, gLastSaveTime, gQuitRequest, gSaveTimer;
+
+var gLoadState = STATE_STOPPED;
+var gLastClosedWindow = null;
+var gWindows = {};
+var gDirty = {};
+var gPrefs = {};
+
+
+/* :::::::: Crash Recovery Service ::::::::::::::: */
+
+/*const*/ var CrashRecoveryService = {
+ mCID: Components.ID("{1280606b-2510-4fe0-97ef-9b5a22eafe6b}"),
+ mContractID: "@zeniko/crashrecoveryservice;1",
+ mClassName: "Crash Recovery Service",
+
+/* ........ Global Event Handlers .............. */
+
+ init: function()
+ {
+ gObserving.forEach(function(aTopic) { gObserverService.addObserver(this, aTopic, false); }, this);
+
+ gPrefs.interval = getPref("interval", 10000);
+ gPrefs.postdata = getPref("postdata", -1);
+ gPrefs.privacy_level = getPref("privacy_level", 1);
+ gPrefBranch.addObserver("", this, false);
+
+ try
+ {
+ gInitialState = readFile(getSessionFile());
+ }
+ catch (ex) { report(ex); }
+ if (gInitialState)
+ {
+ try
+ {
+ writeFile(getSessionFile("bak"), gInitialState);
+
+ gInitialState = decodeINI(gInitialState);
+ delete gInitialState.Window[0].hidden;
+ gWinAttributes.forEach(function(aAttr) { delete gInitialState.Window[0][aAttr]; });
+ }
+ catch (ex)
+ {
+ report(ex);
+ gInitialState = null;
+ }
+ }
+ if (gInitialState && gInitialState.CrashRecovery && gInitialState.CrashRecovery.state && gInitialState.CrashRecovery.state != "stopped")
+ {
+ if (gInitialState.CrashRecovery.state == "running")
+ {
+ try
+ {
+ writeFile(getSessionFile(), readFile(getSessionFile()).replace(/^state=running$/m, "state=crashed"));
+ }
+ catch (ex) { report(ex); }
+ }
+ try
+ {
+ restoreCache();
+ }
+ catch (ex) { report(ex); }
+ }
+ },
+
+ uninit: function()
+ {
+ if (doResumeSession())
+ {
+ saveState(true);
+ }
+ else
+ {
+ clearDisk();
+ }
+
+ if (gSaveTimer)
+ {
+ gSaveTimer.cancel();
+ gSaveTimer = null;
+ }
+
+ gObserving.forEach(function(aTopic) { gObserverService.removeObserver(this, aTopic); }, this);
+ gPrefBranch.removeObserver("", this);
+ },
+
+ observe: function(aSubject, aTopic, aData)
+ {
+ switch (aTopic)
+ {
+ case "app-startup":
+ gObserverService.addObserver(this, "profile-after-change", false);
+ break;
+ case "profile-after-change":
+ gObserverService.removeObserver(this, aTopic);
+ this.init();
+ break;
+ case "domwindowopened":
+ aSubject.addEventListener("load", onWindowLoad_window, false);
+ break;
+ case "domwindowclosed":
+ onWindowClose(aSubject, gQuitRequest && gQuitRequest > Date.now() - 3000);
+ break;
+ case "quit-application-requested":
+ forEachBrowserWindow(collectWindowData);
+ gDirty = {};
+ gQuitRequest = Date.now();
+ break;
+ case "quit-application-granted":
+ gLoadState = STATE_QUITTING;
+ break;
+ case "quit-application":
+ if (aData == "restart")
+ {
+ gPrefBranch.setBoolPref("resume_session_once", true);
+ }
+ gLoadState = STATE_QUITTING;
+ this.uninit();
+ break;
+ case "browser:purge-session-history":
+ onPurgeHistory();
+ break;
+ case "nsPref:changed":
+ if (aData in gPrefs)
+ {
+ gPrefs[aData] = getPref(aData);
+ }
+ switch (aData)
+ {
+ case "interval":
+ if (gSaveTimer && gLastSaveTime - Date.now() + gPrefs.interval <= 0)
+ {
+ saveState();
+ }
+ break;
+ case "privacy_level":
+ saveState(true);
+ break;
+ }
+ break;
+ }
+ },
+
+/* ........ Saving Functionality .............. */
+
+ /*API*/ getCurrentState: function()
+ {
+ return encodeINI(getCurrentState());
+ },
+
+ /*API*/ getWindowState: function(aWindow)
+ {
+ return encodeINI(getCurrentState(aWindow));
+ },
+
+/* ........ Restoring Functionality .............. */
+
+ /*API*/ restoreWindow: function(aWindow, aState, aOverwriteTabs)
+ {
+ try
+ {
+ var root = decodeINI(aState);
+ if (!root.Window[0])
+ {
+ return;
+ }
+ }
+ catch (ex)
+ {
+ report(ex);
+ return;
+ }
+
+ restoreWindow(aWindow, root, aOverwriteTabs);
+ },
+
+/* ........ QueryInterface .............. */
+
+ QueryInterface: function(aIID)
+ {
+ if (!aIID.equals(Ci.nsISupports) && !aIID.equals(Ci.nsIObserver) && !aIID.equals(Ci.nsICrashRecoveryService || null))
+ {
+ Components.returnCode = Cr.NS_ERROR_NO_INTERFACE;
+ return null;
+ }
+
+ return this;
+ }
+};
+
+
+/* :::::::: Window Event Handlers ::::::::::::::: */
+
+function onWindowLoad_window()
+{
+ this.removeEventListener("load", onWindowLoad_window, false);
+
+ if (this.document.documentElement.getAttribute("windowtype") != "navigator:browser" || gLoadState == STATE_QUITTING)
+ {
+ return;
+ }
+
+ this.__CRi = "window" + Date.now();
+
+ if (gLoadState == STATE_STOPPED)
+ {
+ gWindows = {};
+ }
+ gWindows[this.__CRi] = { Tab: [], selected: 0 };
+
+ if (gLoadState == STATE_STOPPED)
+ {
+ var lastSessionState = gInitialState && gInitialState.CrashRecovery && gInitialState.CrashRecovery.state && gInitialState.CrashRecovery.state || "stopped";
+
+ if (gInitialState && !((lastSessionState != "stopped")?doRecoverSession(lastSessionState == "crashed"):doResumeSession()))
+ {
+ gInitialState = null;
+ }
+ if (getPref("resume_session_once"))
+ {
+ gPrefBranch.setBoolPref("resume_session_once", false);
+ }
+ gLoadState = STATE_RUNNING;
+ gLastSaveTime = Date.now();
+
+ saveStateDelayed(this, 5000);
+
+ if (gInitialState)
+ {
+ gInitialState._firstTabs = true;
+ gInitialState._crashed = lastSessionState != "stopped";
+ restoreWindow(this, gInitialState, isCmdLineEmpty(this));
+ gInitialState = null;
+ }
+
+ if (lastSessionState != "stopped")
+ {
+ this.setTimeout(retryDownloads, 0, this);
+ }
+ }
+
+ var tabpanels = this.getBrowser().mPanelContainer;
+ Array.forEach(tabpanels.childNodes, function(aPanel) { onTabAdd(this, aPanel, true); }, this);
+ tabpanels.addEventListener("DOMNodeInserted", onTabAdd_panels, false);
+ tabpanels.addEventListener("DOMNodeRemoved", onTabRemove_panels, false);
+ tabpanels.addEventListener("select", onTabSelect_panels, false);
+}
+
+function onWindowClose(aWindow, aIgnoreClosure)
+{
+ if (aWindow.document.documentElement.getAttribute("windowtype") != "navigator:browser" || !aWindow.__CRi)
+ {
+ return;
+ }
+
+ var tabpanels = aWindow.getBrowser().mPanelContainer;
+ Array.forEach(tabpanels.childNodes, function(aPanel) { onTabRemove(this, aPanel, true); }, this);
+ tabpanels.removeEventListener("DOMNodeInserted", onTabAdd_panels, false);
+ tabpanels.removeEventListener("DOMNodeRemoved", onTabRemove_panels, false);
+ tabpanels.removeEventListener("select", onTabSelect_panels, false);
+
+ if (gLoadState == STATE_RUNNING && !aIgnoreClosure)
+ {
+ gLastClosedWindow = getCurrentState(aWindow);
+ delete gWindows[aWindow.__CRi];
+ saveStateDelayed();
+
+ if (gQuitRequest)
+ {
+ var windows = {};
+ forEachBrowserWindow(function(aWindow) { windows[aWindow.__CRi] = true; });
+ for (var ix in gWindows)
+ {
+ if (!windows[ix])
+ {
+ delete gWindows[ix];
+ }
+ }
+ gQuitRequest = null;
+ }
+
+ var notifyClosedWindow = gLastClosedWindow;
+ }
+ if (gLoadState == STATE_RUNNING && !getMostRecentBrowserWindow())
+ {
+ if (!getPref("allow_empty_session"))
+ {
+ gLoadState = STATE_STOPPED;
+ gInitialState = getCurrentState();
+ notifyClosedWindow = null;
+ }
+ else
+ {
+ gLastClosedWindow = null;
+ }
+ }
+ if (notifyClosedWindow)
+ {
+ gObserverService.notifyObservers(aWindow, "crashrecovery:windowclosed", encodeINI(notifyClosedWindow));
+ }
+
+ delete aWindow.__CRi;
+}
+
+function onTabAdd_panels(aEvent)
+{
+ onTabAdd(this.ownerDocument.defaultView, aEvent.target);
+}
+
+function onTabAdd(aWindow, aBrowser, aNoNotification)
+{
+ aBrowser.addEventListener("load", onTabLoad_browser, true);
+ aBrowser.addEventListener("pageshow", onTabLoad_browser, true);
+ aBrowser.addEventListener("input", onTabInput_browser, true);
+ aBrowser.addEventListener("DOMAutoComplete", onTabInput_browser, true);
+
+ if (!aNoNotification)
+ {
+ saveStateDelayed(aWindow);
+ }
+}
+
+function onTabRemove_panels(aEvent)
+{
+ onTabRemove(this.ownerDocument.defaultView, aEvent.target);
+}
+
+function onTabRemove(aWindow, aBrowser, aNoNotification)
+{
+ aBrowser.removeEventListener("load", onTabLoad_browser, true);
+ aBrowser.removeEventListener("pageshow", onTabLoad_browser, true);
+ aBrowser.removeEventListener("input", onTabInput_browser, true);
+ aBrowser.removeEventListener("DOMAutoComplete", onTabInput_browser, true);
+
+ aBrowser = ensureBrowser(aBrowser);
+ delete aBrowser.__CR_data;
+ delete aBrowser.__CR_text;
+
+ if (!aNoNotification)
+ {
+ saveStateDelayed(aWindow);
+ }
+}
+
+function onTabSelect_panels(aEvent)
+{
+ if (gLoadState == STATE_RUNNING)
+ {
+ var window = this.ownerDocument.defaultView;
+
+ gWindows[window.__CRi].selected = this.selectedIndex + 1;
+ saveStateDelayed(window);
+ }
+}
+
+function onTabLoad_browser(aEvent)
+{
+ if (aEvent.type != "load" && !aEvent.persisted)
+ {
+ return;
+ }
+
+ var browser = ensureBrowser(this);
+ var window = this.ownerDocument.defaultView;
+
+ delete browser.__CR_data;
+ delete browser.__CR_text;
+ saveStateDelayed(window);
+}
+
+function onTabInput_browser(aEvent)
+{
+ if (saveTextData(ensureBrowser(this), aEvent.originalTarget))
+ {
+ var window = this.ownerDocument.defaultView;
+
+ saveStateDelayed(window, 3000);
+ }
+}
+
+function onPurgeHistory()
+{
+ forEachBrowserWindow(function(aWindow) {
+ Array.forEach(aWindow.getBrowser().browsers, function(aBrowser) {
+ delete aBrowser.__CR_data;
+ });
+ });
+ clearDisk();
+
+ var window = getMostRecentBrowserWindow();
+ if (window)
+ {
+ window.setTimeout(saveState, 0, true);
+ }
+ else
+ {
+ saveState(true);
+ }
+}
+
+/* :::::::: Saving Functionality ::::::::::::::: */
+
+function getCurrentState(aWindow)
+{
+ if (!aWindow)
+ {
+ var activeWindow = getMostRecentBrowserWindow();
+
+ if (gLoadState == STATE_RUNNING)
+ {
+ forEachBrowserWindow(function(aWindow) {
+ if (gDirty.all || gDirty[aWindow.__CRi] || aWindow == activeWindow)
+ {
+ collectWindowData(aWindow);
+ }
+ else
+ {
+ updateWindowFeatures(aWindow);
+ }
+ });
+ gDirty = {};
+ }
+
+ var winDataList = [], windows = [];
+ for (var ix in gWindows)
+ {
+ winDataList.push(gWindows[ix]);
+ windows.push(ix);
+ }
+ if (windows.length == 0 && gLastClosedWindow)
+ {
+ return gLastClosedWindow;
+ }
+ ix = (activeWindow)?windows.indexOf(activeWindow.__CRi || ""):-1;
+ if (ix > 0)
+ {
+ winDataList.unshift(winDataList.splice(ix, 1)[0]);
+ }
+ }
+ else
+ {
+ if (gLoadState == STATE_RUNNING)
+ {
+ collectWindowData(aWindow);
+ }
+
+ winDataList = [gWindows[aWindow.__CRi]];
+ }
+
+ updateCookies(winDataList);
+
+ return { Window: winDataList };
+}
+
+function collectWindowData(aWindow)
+{
+ saveWindowHistory(aWindow);
+ updateTextAndScrollData(aWindow);
+ updateCookieHosts(aWindow);
+ updateWindowFeatures(aWindow);
+
+ gDirty[aWindow.__CRi] = false;
+}
+
+function saveWindowHistory(aWindow)
+{
+ var tabbrowser = aWindow.getBrowser();
+ var browsers = tabbrowser.browsers;
+ if (!tabbrowser.mTabs) // MultiZilla
+ {
+ tabbrowser.mTabs = tabbrowser.mTabContainer.childNodes;
+ }
+ var tabs = gWindows[aWindow.__CRi].Tab = [];
+ gWindows[aWindow.__CRi].selected = 0;
+
+ for (var i = 0; i < browsers.length; i++)
+ {
+ var tabData = { Entry: [], index: 0 };
+
+ var browser = browsers[i];
+ if (!browser)
+ {
+ tabs.push(tabData);
+ continue;
+ }
+
+ try
+ {
+ var history = browser.sessionHistory;
+ }
+ catch (ex) { report(ex); }
+
+ if (history && browser.__CR_data && browser.__CR_data.Entry[history.index])
+ {
+ tabData = browser.__CR_data;
+ tabData.index = history.index + 1;
+ if (tabData.recent && Date.now() - tabData.recent > POTENTIAL_CRASH_DELAY)
+ {
+ delete tabData.recent;
+ }
+ }
+ else if (history && history.count > 0)
+ {
+ for (var j = 0; j < history.count; j++)
+ {
+ tabData.Entry.push(serializeHistoryEntry(history.getEntryAtIndex(j, false)));
+ }
+ tabData.index = history.index + 1;
+ tabData.recent = Date.now();
+
+ browser.__CR_data = tabData;
+ }
+ else if (browser.currentURI)
+ {
+ tabData.Entry[0] = { uri: browser.currentURI.spec };
+ tabData.index = 1;
+ }
+ tabData.zoom = (((browser.markupDocumentViewer.textZoom - 1) || -1) + 1) || "";
+
+ var disallow = gCapabilities.filter(function(aCapability) {
+ return !browser.docShell["allow" + aCapability];
+ });
+ tabData.disallow = disallow.join(",");
+
+ var xulattr = Array.filter(tabbrowser.mTabs[i].attributes, function(aAttr) {
+ return aAttr.name.substr(0, 3).toUpperCase() == "CR_" || gXulAttributes.indexOf(aAttr.name) > -1;
+ }).map(function(aAttr) {
+ return aAttr.name + "=" + encodeURI(aAttr.value);
+ });
+ tabData.xultab = xulattr.join(" ");
+
+ tabs.push(tabData);
+
+ if (browser == tabbrowser.selectedBrowser)
+ {
+ gWindows[aWindow.__CRi].selected = i + 1;
+ }
+ }
+}
+
+function serializeHistoryEntry(aEntry)
+{
+ var entry = { uri: aEntry.URI.spec, Child: [] };
+
+ if (aEntry.title && aEntry.title != entry.uri)
+ {
+ entry.title = aEntry.title;
+ }
+ if (aEntry.isSubFrame)
+ {
+ entry.subframe = true;
+ }
+ if (!(aEntry instanceof Ci.nsISHEntry))
+ {
+ return entry;
+ }
+
+ var cacheKey = aEntry.cacheKey;
+ if (cacheKey && cacheKey instanceof Ci.nsISupportsPRUint32)
+ {
+ entry.cacheKey = cacheKey.data || "";
+ }
+ entry.ID = aEntry.ID;
+
+ var x = {}, y = {};
+ aEntry.getScrollPosition(x, y);
+ entry.scroll = x.value + "," + y.value;
+
+ try
+ {
+ if (gPrefs.postdata && aEntry.postData && checkPrivacyLevel(entry.uri))
+ {
+ aEntry.postData.QueryInterface(Ci.nsISeekableStream).seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
+ var stream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
+ stream.init(aEntry.postData);
+ var postdata = stream.read(stream.available());
+ if (gPrefs.postdata == -1 || postdata.replace(/^(Content-.*\r\n)+(\r\n)*/, "").length <= gPrefs.postdata)
+ {
+ entry.postdata = postdata;
+ }
+ }
+ }
+ catch (ex) { report(ex); }
+
+ if (!(aEntry instanceof Ci.nsISHContainer))
+ {
+ return entry;
+ }
+
+ for (var i = 0; i < aEntry.childCount; i++)
+ {
+ var child = aEntry.GetChildAt(i);
+ if (child)
+ {
+ entry.Child.push(serializeHistoryEntry(child));
+ }
+ else
+ {
+ entry.Child.push({ uri: "about:blank" });
+ }
+ }
+
+ return entry;
+}
+
+function saveTextData(aBrowser, aTextarea)
+{
+ var wrappedTextarea = XPCNativeWrapper(aTextarea);
+ var id = (wrappedTextarea.id)?"#" + wrappedTextarea.id:wrappedTextarea.name;
+ if (!id || !(wrappedTextarea instanceof Ci.nsIDOMHTMLTextAreaElement || wrappedTextarea instanceof Ci.nsIDOMHTMLInputElement))
+ {
+ return false;
+ }
+
+ if (!aBrowser.__CR_text)
+ {
+ aBrowser.__CR_text = {};
+ }
+ else if (aBrowser.__CR_text[aTextarea] && !aBrowser.__CR_text[aTextarea].cache)
+ {
+ return false;
+ }
+
+ var content = wrappedTextarea.ownerDocument.defaultView;
+ while (content != content.top)
+ {
+ var frames = content.parent.frames;
+ for (var i = frames.length - 1; i >= 0 && frames[i] != content; i--);
+ id = i + "|" + id;
+ content = content.parent;
+ }
+
+ aBrowser.__CR_text[aTextarea] = { id: id, element: wrappedTextarea };
+
+ return true;
+}
+
+function updateTextAndScrollData(aWindow)
+{
+ Array.forEach(aWindow.getBrowser().browsers, function(aBrowser, aIx) {
+ try
+ {
+ var tabData = gWindows[aWindow.__CRi].Tab[aIx];
+
+ var text = [];
+ if (aBrowser.__CR_text && checkPrivacyLevel(aBrowser.currentURI.spec))
+ {
+ for (var key in aBrowser.__CR_text)
+ {
+ var data = aBrowser.__CR_text[key];
+ if (!data.cache)
+ {
+ data.cache = encodeURI(data.element.value);
+ }
+ text.push(data.id + "=" + data.cache);
+ }
+ }
+ if (aBrowser.currentURI.spec == "about:config")
+ {
+ text = ["#textbox=" + encodeURI(aBrowser.contentDocument.getElementById("textbox").value)];
+ }
+ tabData.text = text.join(" ");
+
+ updateScrollDataRecursively(aWindow, XPCNativeWrapper(aBrowser.contentWindow), tabData.Entry[tabData.index - 1]);
+ }
+ catch (ex) { report(ex); }
+ });
+}
+
+function updateScrollDataRecursively(aWindow, aContent, aData)
+{
+ for (var i = aContent.frames.length - 1; i >= 0; i--)
+ {
+ if (aData.Child && aData.Child[i])
+ {
+ updateScrollDataRecursively(aWindow, aContent.frames[i], aData.Child[i]);
+ }
+ }
+ if ((aContent.document.designMode || "") == "on" && checkPrivacyLevel((aContent.parent || aContent).document.location.href))
+ {
+ if (aData.innerHTML == undefined)
+ {
+ aContent.addEventListener("keypress", function(aEvent) { saveStateDelayed(aWindow, 3000); }, true);
+ }
+ aData.innerHTML = aContent.document.body.innerHTML;
+ }
+ aData.scroll = aContent.scrollX + "," + aContent.scrollY;
+}
+
+function updateCookieHosts(aWindow)
+{
+ var hosts = gWindows[aWindow.__CRi]._hosts = {};
+
+ function extractHosts(aEntry)
+ {
+ if (/^https?:\/\/(?:[^@\/\s]+@)?([\w.-]+)/.test(aEntry.uri) && !hosts[RegExp.$1] && checkPrivacyLevel(aEntry.uri))
+ {
+ var host = RegExp.$1;
+ for (var ix = host.indexOf(".") + 1; ix; ix = host.indexOf(".", ix) + 1)
+ {
+ hosts[host.substr(ix)] = true;
+ }
+ hosts[host] = true;
+ }
+ if (aEntry.Child)
+ {
+ aEntry.Child.forEach(extractHosts);
+ }
+ }
+
+ gWindows[aWindow.__CRi].Tab.forEach(function(aTabData) { aTabData.Entry.forEach(extractHosts); });
+}
+
+function updateCookies(aWindows)
+{
+ var cookiesEnum = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager).enumerator;
+ var cookieSets = aWindows.map(function() { return { count: 0 }; });
+
+ while (cookiesEnum.hasMoreElements())
+ {
+ var cookie = cookiesEnum.getNext().QueryInterface(Ci.nsICookie2);
+ if (cookie.isSession && cookie.host)
+ {
+ var url = "", value = "";
+ aWindows.forEach(function(aWindow, aIx) {
+ if (aWindow._hosts && aWindow._hosts[cookie.rawHost])
+ {
+ if (!url)
+ {
+ url = "http" + ((cookie.isSecure)?"s":"") + "://" + cookie.host + (cookie.path || "").replace(/^(?!\/)/, "/");
+ if (checkPrivacyLevel(url))
+ {
+ value = (cookie.name || "name") + "=" + (cookie.value || "") + ";";
+ value += (cookie.isDomain)?"domain=" + cookie.rawHost + ";":"";
+ value += (cookie.path)?"path=" + cookie.path + ";":"";
+ value += (cookie.isSecure)?"secure;":"";
+ }
+ }
+ if (value)
+ {
+ var set = cookieSets[aIx];
+ set["domain" + ++set.count] = url;
+ set["value" + set.count] = value;
+ }
+ }
+ });
+ }
+ }
+
+ cookieSets.forEach(function(aSet, aIx) { aWindows[aIx].Cookies = (aSet.count > 0)?aSet:null; });
+}
+
+function updateWindowFeatures(aWindow)
+{
+ var winData = gWindows[aWindow.__CRi];
+
+ gWinAttributes.forEach(function(aAttr) { winData[aAttr] = getWindowDimension(aWindow, aAttr); });
+
+ winData.hidden = gWinHidable.filter(function(aItem) {
+ return aWindow[aItem] && !aWindow[aItem].visible;
+ }).join(",");
+
+ if (aWindow.toggleSidebar) // Firefox
+ {
+ winData.sidebar = aWindow.document.getElementById("sidebar-box").getAttribute("sidebarcommand");
+ }
+ else if (aWindow.sidebar_is_hidden) // SeaMonkey
+ {
+ winData.sidebar = !aWindow.sidebar_is_hidden();
+ }
+}
+
+
+/* :::::::: Restoring Functionality ::::::::::::::: */
+
+function restoreWindow(aWindow, aRootObj, aOverwriteTabs)
+{
+ for (var w = aRootObj.Window.length - 1; w >= 1; w--)
+ {
+ var winObj = aRootObj.Window[w];
+ if (winObj.Tab && winObj.Tab.length > 0)
+ {
+ openWindowWithState({ Window: [winObj], opener: aWindow, _crashed: aRootObj._crashed || false });
+ }
+ }
+
+ var winData = aRootObj.Window[0];
+ if (!winData.Tab)
+ {
+ winData.Tab = [];
+ }
+ var tabbrowser = aWindow.getBrowser();
+ if (!tabbrowser.mTabs) // MultiZilla
+ {
+ tabbrowser.mTabs = tabbrowser.mTabContainer.childNodes;
+ tabbrowser.moveTabTo = tabbrowser.moveTabTo || tabbrowser.moveTab;
+ }
+ var openTabCount = (aOverwriteTabs)?tabbrowser.browsers.length:-1;
+ var newTabCount = winData.Tab.length;
+
+ for (var t = 0; t < newTabCount; t++)
+ {
+ winData.Tab[t]._tab = (t < openTabCount)?tabbrowser.mTabs[t]:tabbrowser.addTab();
+ if (!aOverwriteTabs && aRootObj._firstTabs)
+ {
+ tabbrowser.moveTabTo(winData.Tab[t]._tab, t);
+ }
+ }
+ for (t = openTabCount - 1; t >= newTabCount; t--)
+ {
+ tabbrowser.removeTab(tabbrowser.mTabs[t]);
+ }
+
+ if (aOverwriteTabs)
+ {
+ restoreWindowFeatures(aWindow, winData, aRootObj.opener || null);
+ }
+ if (winData.Cookies)
+ {
+ restoreCookies(winData.Cookies);
+ }
+
+ aWindow.setTimeout(restoreHistory_window, 0, winData.Tab, (aOverwriteTabs)?parseInt(winData.selected) || 1:0, (aRootObj._crashed)?getPref("crash_warning_uri"):null, 0, 0);
+}
+
+function restoreHistory_window(aTabs, aSelectTab, aWarningURL, aIx, aCount)
+{
+ var tabbrowser = this.getBrowser();
+
+ for (var t = aIx; t < aTabs.length; t++)
+ {
+ try
+ {
+ if (!tabbrowser.getBrowserForTab(aTabs[t]._tab).webNavigation.sessionHistory)
+ {
+ throw new Error();
+ }
+ }
+ catch (ex)
+ {
+ if (++aCount < 10)
+ {
+ this.setTimeout(restoreHistory_window, 100, aTabs, aSelectTab, aWarningURL, t, aCount);
+ return;
+ }
+ }
+ }
+
+ try
+ {
+ var tabLoading = getStringBundle("chrome://global/locale/tabbrowser.properties").GetStringFromName("tabs.loading");
+ for (t = 0; t < aTabs.length; t++)
+ {
+ var tab = aTabs[t]._tab;
+ tab.setAttribute("busy", "true");
+ tab.removeAttribute("image");
+ tab.label = tabLoading;
+ }
+ }
+ catch (ex) { }
+
+ if (aSelectTab-- && aTabs[aSelectTab])
+ {
+ aTabs.unshift(aTabs.splice(aSelectTab, 1)[0]);
+ tabbrowser.selectedTab = aTabs[0]._tab;
+ }
+
+ this.setTimeout(restoreHistory, 0, this, aTabs, aWarningURL, null);
+}
+
+function restoreHistory(aWindow, aTabs, aWarningURL, aIdMap)
+{
+ while (aTabs.length > 0 && (!aTabs[0]._tab || !aTabs[0]._tab.parentNode))
+ {
+ aTabs.shift();
+ }
+ if (aTabs.length == 0)
+ {
+ return;
+ }
+
+ var tabData = aTabs.shift();
+ var idMap = aIdMap || { used: {} };
+
+ var tab = tabData._tab;
+ var browser = aWindow.getBrowser().getBrowserForTab(tab);
+ var history = browser.webNavigation.sessionHistory;
+
+ if (history.count > 0)
+ {
+ history.PurgeHistory(history.count);
+ }
+ history.QueryInterface(Ci.nsISHistoryInternal);
+
+ if (!tabData.Entry)
+ {
+ tabData.Entry = [];
+ }
+
+ browser.markupDocumentViewer.textZoom = parseFloat(tabData.zoom || 1);
+
+ if (tabData.recent && !tabData.text && aWarningURL)
+ {
+ var warnEntry = { uri: aWarningURL };
+ if (tabData.index < tabData.Entry.length)
+ {
+ warnEntry.uri += "#" + tabData.index;
+ }
+ tabData.Entry.push(warnEntry);
+ tabData.index = tabData.Entry.length;
+ }
+ for (var i = 0; i < tabData.Entry.length; i++)
+ {
+ history.addEntry(deserializeHistoryEntry(tabData.Entry[i], idMap), true);
+ }
+
+ var disallow = (tabData.disallow)?tabData.disallow.split(","):[];
+ gCapabilities.forEach(function(aCapability) {
+ browser.docShell["allow" + aCapability] = disallow.indexOf(aCapability) == -1;
+ });
+ Array.filter(tab.attributes, function(aAttr) {
+ return aAttr.name.substr(0, 3).toUpperCase() == "CR_" || gXulAttributes.indexOf(aAttr.name) > -1;
+ }).forEach(tab.removeAttribute, tab);
+ if (tabData.xultab)
+ {
+ tabData.xultab.split(" ").forEach(function(aAttr) {
+ if (/^([^\s=]+)=(.*)/.test(aAttr))
+ {
+ tab.setAttribute(RegExp.$1, decodeURI(RegExp.$2));
+ }
+ });
+ }
+
+ var event = aWindow.document.createEvent("Events");
+ event.initEvent("CRTabRestoring", true, false);
+ tab.dispatchEvent(event);
+
+ var activeIndex = (tabData.index || tabData.Entry.length) - 1;
+ try
+ {
+ browser.webNavigation.gotoIndex(activeIndex);
+ }
+ catch (ex) { report(ex); }
+
+ browser.__CR_restore_data = tabData.Entry[activeIndex] || {};
+ browser.__CR_restore_text = tabData.text || "";
+ browser.__CR_restore_tab = tab;
+ browser.__CR_restore = restoreDocument_browser;
+ browser.addEventListener("load", browser.__CR_restore, true);
+
+ aWindow.setTimeout(restoreHistory, 0, aWindow, aTabs, aWarningURL, idMap);
+}
+
+function deserializeHistoryEntry(aEntry, aIdMap)
+{
+ var shEntry = Cc["@mozilla.org/browser/session-history-entry;1"].createInstance(Ci.nsISHEntry);
+
+ shEntry.setURI(gIOService.newURI(aEntry.uri, null, null));
+ shEntry.setTitle(aEntry.title || aEntry.uri);
+ shEntry.setIsSubFrame(aEntry.subframe || false);
+ shEntry.loadType = Ci.nsIDocShellLoadInfo.loadHistory;
+
+ if (aEntry.cacheKey)
+ {
+ var cacheKey = Cc["@mozilla.org/supports-PRUint32;1"].createInstance(Ci.nsISupportsPRUint32);
+ cacheKey.data = aEntry.cacheKey;
+ shEntry.cacheKey = cacheKey;
+ }
+ if (aEntry.ID)
+ {
+ var id = aIdMap[aEntry.ID] || 0;
+ if (!id)
+ {
+ for (id = Date.now(); aIdMap.used[id]; id++);
+ aIdMap[aEntry.ID] = id;
+ aIdMap.used[id] = true;
+ }
+ shEntry.ID = id;
+ }
+
+ var scrollPos = (aEntry.scroll || "0,0").split(",");
+ scrollPos = [parseInt(scrollPos[0]) || 0, parseInt(scrollPos[1]) || 0];
+ shEntry.setScrollPosition(scrollPos[0], scrollPos[1]);
+
+ if (aEntry.postdata)
+ {
+ var stream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);
+ stream.setData(aEntry.postdata, -1);
+ shEntry.postData = stream;
+ }
+
+ if (aEntry.Child && shEntry instanceof Ci.nsISHContainer)
+ {
+ for (var i = 0; i < aEntry.Child.length; i++)
+ {
+ shEntry.AddChild(deserializeHistoryEntry(aEntry.Child[i], aIdMap), i);
+ }
+ }
+
+ return shEntry;
+}
+
+function restoreDocument_browser(aEvent)
+{
+ if (!aEvent || !aEvent.originalTarget || !aEvent.originalTarget.defaultView || aEvent.originalTarget.defaultView != aEvent.originalTarget.defaultView.top)
+ {
+ return;
+ }
+
+ var content = XPCNativeWrapper(aEvent.originalTarget).defaultView;
+ if (this.currentURI.spec == "about:config")
+ {
+ content = aEvent.originalTarget.defaultView;
+ }
+ var textArray = (this.__CR_restore_text)?this.__CR_restore_text.split(" "):[];
+ restoreTextDataAndScrolling(content, this.__CR_restore_data, "", textArray);
+
+ var event = this.ownerDocument.createEvent("Events");
+ event.initEvent("CRTabRestored", true, false);
+ this.__CR_restore_tab.dispatchEvent(event);
+
+ this.removeEventListener("load", this.__CR_restore, true);
+ delete this.__CR_restore_data;
+ delete this.__CR_restore_text;
+ delete this.__CR_restore_tab;
+ delete this.__CR_restore;
+}
+
+function restoreTextData(aContent, aPrefix, aTextArray)
+{
+ aTextArray.forEach(function(aEntry) {
+ if (/^((?:\d+\|)*)(#?)([^\s=]+)=(.*)$/.test(aEntry) && (!RegExp.$1 || RegExp.$1 == aPrefix))
+ {
+ var document = aContent.document;
+ var node = (RegExp.$2)?document.getElementById(RegExp.$3):document.getElementsByName(RegExp.$3)[0] || null;
+ if (node && "value" in node)
+ {
+ node.value = decodeURI(RegExp.$4);
+
+ var event = document.createEvent("UIEvents");
+ event.initUIEvent("input", true, true, aContent, 0);
+ node.dispatchEvent(event);
+ }
+ }
+ });
+}
+
+function restoreTextDataAndScrolling(aContent, aData, aPrefix, aTextArray)
+{
+ restoreTextData(aContent, aPrefix, aTextArray);
+ if (aData.innerHTML)
+ {
+ aContent.setTimeout(function(aHTML) { if (this.document.designMode == "on") { this.document.body.innerHTML = aHTML; } }, 0, aData.innerHTML);
+ }
+ if (aData.scroll && /(\d+),(\d+)/.test(aData.scroll))
+ {
+ aContent.scrollTo(RegExp.$1, RegExp.$2);
+ }
+ for (var i = 0; i < aContent.frames.length; i++)
+ {
+ if (aData.Child && aData.Child[i])
+ {
+ restoreTextDataAndScrolling(aContent.frames[i], aData.Child[i], i + "|" + aPrefix, aTextArray);
+ }
+ }
+}
+
+function restoreWindowFeatures(aWindow, aWinData, aOpener)
+{
+ var hidden = (aWinData.hidden)?aWinData.hidden.split(","):[];
+ gWinHidable.forEach(function(aItem) {
+ aWindow[aItem].visible = hidden.indexOf(aItem) == -1;
+ });
+
+ aWindow.setTimeout(restoreDimensions, 0, aWindow, aOpener, aWinData.width || 0, aWinData.height || 0, ("screenX" in aWinData)?aWinData.screenX:NaN, ("screenY" in aWinData)?aWinData.screenY:NaN, aWinData.sizemode || "", aWinData.sidebar || "");
+}
+
+function restoreDimensions(aWindow, aOpener, aWidth, aHeight, aLeft, aTop, aSizeMode, aSidebar)
+{
+ function win_(aName) { return getWindowDimension(aWindow, aName); }
+
+ if (aWidth && aHeight && (aWidth != win_("width") || aHeight != win_("height")))
+ {
+ aWindow.resizeTo(aWidth, aHeight);
+ }
+ if (!isNaN(aLeft) && !isNaN(aTop) && (aLeft != win_("screenX") || aTop != win_("screenY")))
+ {
+ aWindow.moveTo(aLeft, aTop);
+ }
+ if (aSizeMode == "maximized" && win_("sizemode") != "maximized")
+ {
+ aWindow.maximize();
+ }
+ else if (aSizeMode && aSizeMode != "maximized" && win_("sizemode") != "normal")
+ {
+ aWindow.restore();
+ }
+ var sidebar = aWindow.document.getElementById("sidebar-box");
+ if (aWindow.toggleSidebar && sidebar.getAttribute("sidebarcommand") != aSidebar)
+ {
+ aWindow.toggleSidebar(aSidebar);
+ }
+ else if (aWindow.sidebar_is_hidden && aWindow.sidebar_is_hidden() != !aSidebar)
+ {
+ aWindow.SidebarShowHide();
+ }
+ if (aOpener)
+ {
+ aOpener.focus();
+ }
+}
+
+function restoreCookies(aCookies)
+{
+ var cookieService = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService);
+
+ for (var i = 1; i <= aCookies.count; i++)
+ {
+ try
+ {
+ cookieService.setCookieString(gIOService.newURI(aCookies["domain" + i], null, null), null, aCookies["value" + i] + "expires=0;", null);
+ }
+ catch (ex) { report(ex); }
+ }
+}
+
+// code adapted from Danil Ivanov's "Cache Fixer" extension
+function restoreCache()
+{
+ var cache = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties).get("ProfLD", Ci.nsILocalFile);
+ cache.append("Cache");
+ cache.append("_CACHE_MAP_");
+ if (!cache.exists())
+ {
+ return;
+ }
+
+ var stream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
+ stream.init(cache, 0x01, 0, 0); // PR_RDONLY
+ var input = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream);
+ input.setInputStream(stream);
+ var content = input.readByteArray(input.available());
+ input.close();
+
+ if (content[15] != 1)
+ {
+ return;
+ }
+ content[15] = 0;
+
+ stream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
+ stream.init(cache, 0x02 | 0x20, 0600, 0); // PR_WRONLY | PR_TRUNCATE
+ var output = Cc["@mozilla.org/binaryoutputstream;1"].createInstance(Ci.nsIBinaryOutputStream);
+ output.setOutputStream(stream);
+ output.writeByteArray(content, content.length);
+ output.flush();
+ output.close();
+}
+
+function retryDownloads(aWindow)
+{
+ var downloadManager = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager);
+ var rdfService = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
+ var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+
+ var rdfContainer = Cc["@mozilla.org/rdf/container;1"].createInstance(Ci.nsIRDFContainer);
+ var datasource = downloadManager.datasource;
+
+ try
+ {
+ rdfContainer.Init(datasource, rdfService.GetResource("NC:DownloadsRoot"));
+ }
+ catch (ex)
+ {
+ // SeaMonkey doesn't support saveURL without user interaction, so we stop here
+ // (it doesn't support downloadManager.datasource, either)
+ return;
+ }
+
+ var downloads = rdfContainer.GetElements();
+
+ while (downloads.hasMoreElements())
+ {
+ var download = downloads.getNext().QueryInterface(Ci.nsIRDFResource);
+
+ var node = datasource.GetTarget(rdfService.GetResource(download.Value), rdfService.GetResource("http://home.netscape.com/NC-rdf#DownloadState"), true);
+ if (!node || node.QueryInterface(Ci.nsIRDFInt).Value != Ci.nsIDownloadManager.DOWNLOAD_DOWNLOADING)
+ {
+ continue;
+ }
+
+ node = datasource.GetTarget(rdfService.GetResource(download.Value), rdfService.GetResource("http://home.netscape.com/NC-rdf#URL"), true).QueryInterface(Ci.nsIRDFResource);
+
+ var url = node.Value;
+
+ node = datasource.GetTarget(rdfService.GetResource(download.Value), rdfService.GetResource("http://home.netscape.com/NC-rdf#File"), true).QueryInterface(Ci.nsIRDFResource);
+
+ var linkChecker = Cc["@mozilla.org/network/urichecker;1"].createInstance(Ci.nsIURIChecker);
+
+ linkChecker.init(ioService.newURI(url, null, null));
+ linkChecker.loadFlags = Ci.nsIRequest.LOAD_BACKGROUND;
+ linkChecker.asyncCheck(new AutoDownloader(url, node.Value, aWindow), null);
+ }
+}
+
+/* ........ Asynchronous File Downloader .............. */
+
+function AutoDownloader(aURL, aFilename, aWindow)
+{
+ this.mURL = aURL;
+ this.mFilename = aFilename;
+ this.mWindow = aWindow;
+}
+
+AutoDownloader.prototype = {
+ onStartRequest: function(aRequest, aContext) { },
+
+ onStopRequest: function(aRequest, aContext, aStatus)
+ {
+ if (Components.isSuccessCode(aStatus))
+ {
+ var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+ file.initWithPath(this.mFilename);
+ if (file.exists())
+ {
+ file.remove(false);
+ }
+
+ this.mWindow.saveURL(this.mURL, this.mFilename, null, true, true, null);
+ }
+ }
+};
+
+
+/* :::::::: Timed Session Saving Functionality ::::::::::::::: */
+
+function saveStateDelayed(aWindow, aDelay)
+{
+ if (aWindow)
+ {
+ gDirty[aWindow.__CRi] = true;
+ }
+ if (!gSaveTimer)
+ {
+ aDelay = Math.max(gLastSaveTime - Date.now() + gPrefs.interval, aDelay || Math.min(gPrefs.interval, 2000));
+ if (aDelay > 0)
+ {
+ gSaveTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ gSaveTimer.init(gSaveStateDelayedObserver, aDelay, Ci.nsITimer.TYPE_ONE_SHOT);
+ }
+ else
+ {
+ saveState();
+ }
+ }
+}
+
+/*const*/ var gSaveStateDelayedObserver = {
+ observe: function(aSubject, aTopic, aData)
+ {
+ gSaveTimer = null;
+ saveState();
+ }
+};
+
+function saveState(aUpdateAll)
+{
+ if (!gLastSaveTime)
+ {
+ return;
+ }
+ if (gSaveTimer)
+ {
+ gSaveTimer.cancel();
+ gSaveTimer = null;
+ }
+
+ gDirty.all = aUpdateAll;
+ gThreadedSaver.saveCurrentState(aUpdateAll);
+ gLastSaveTime = Date.now();
+}
+
+function clearDisk()
+{
+ delFile(getSessionFile());
+ delFile(getSessionFile("bak"));
+ delFile(getSessionFile("dat.tmp", true));
+}
+
+function getSessionFile(aExt, aLocal)
+{
+ var dirs = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
+ try
+ {
+ var file = dirs.get((!aLocal)?"ProfD":"ProfLD", Ci.nsILocalFile);
+ }
+ catch (ex)
+ {
+ file = dirs.get("ProfD", Ci.nsILocalFile);
+ }
+ file.append("crashrecovery." + (aExt || "dat"));
+
+ return file;
+}
+
+/* ........ Threaded State Saver .............. */
+
+/*const*/ var gThreadedSaver = {
+ saveCurrentState: function(aMainThread)
+ {
+ if (this.mThread)
+ {
+ try
+ {
+ if (Ci.nsIThreadManager)
+ {
+ this.mThread.shutdown();
+ }
+ else
+ {
+ this.mThread.join();
+ }
+ }
+ catch (ex) { report(ex); }
+ this.mThread = null;
+ }
+
+ this.mState = getCurrentState();
+ if (aMainThread)
+ {
+ this.run();
+ }
+ else if (Ci.nsIThreadManager)
+ {
+ this.mThread = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager).newThread(0);
+ this.mThread.QueryInterface(Ci.nsIEventTarget).dispatch(this, Ci.nsIEventTarget.DISPATCH_NORMAL)
+ }
+ else
+ {
+ this.mThread = Cc["@mozilla.org/thread;1"].createInstance(Ci.nsIThread);
+ this.mThread.init(this, 128 * 1024, Ci.nsIThread.PRIORITY_NORMAL, Ci.nsIThread.SCOPE_GLOBAL, Ci.nsIThread.STATE_JOINABLE);
+ }
+ },
+
+ run: function()
+ {
+ var tmpFile = getSessionFile("dat.tmp", true);
+ writeFile(tmpFile, [
+ "; This file will be periodically overwritten by Crash Recovery",
+ "; Do not edit while the state indicated below is 'running'",
+ "; The file encoding is UTF-8",
+ "[CrashRecovery]",
+ "state=" + ((gLoadState == STATE_RUNNING)?"running":"stopped"),
+ "date=" + (new Date()).toString(),
+ encodeINI(this.mState),
+ ""
+ ].join("\n").replace(/\n\[/g, "\n$&"));
+
+ var sessionFile = getSessionFile();
+ tmpFile.moveTo(sessionFile.parent, sessionFile.leafName);
+ }
+};
+
+
+/* :::::::: Auxiliary Functions ::::::::::::::: */
+
+function forEachBrowserWindow(aFunc)
+{
+ var windowsEnum = gWindowMediator.getEnumerator("navigator:browser");
+ while (windowsEnum.hasMoreElements())
+ {
+ var window = windowsEnum.getNext();
+ if (window.__CRi)
+ {
+ aFunc(window);
+ }
+ }
+}
+
+function getMostRecentBrowserWindow()
+{
+ return gWindowMediator.getMostRecentWindow("navigator:browser");
+}
+
+function openWindowWithState(aState)
+{
+ var argString = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
+ argString.data = "";
+
+ var window = Cc["@mozilla.org/embedcomp/window-watcher;1"].getService(Ci.nsIWindowWatcher).openWindow(null, getPref("browser.chromeURL", null, true), "_blank", "chrome,all,dialog=no", argString);
+
+ window.__CR_state = aState;
+ window.addEventListener("load", openWindowWithState_onLoad_window, true);
+}
+
+function openWindowWithState_onLoad_window()
+{
+ this.removeEventListener("load", openWindowWithState_onLoad_window, true);
+ restoreWindow(this, this.__CR_state, true);
+ delete this.__CR_state;
+}
+
+function doResumeSession()
+{
+ return getPref("resume_session") || getPref("resume_session_once") || getPref("browser.startup.page", 1, true) == 3 || getPref("browser.startup.page", 1, true) == 2;
+}
+
+function doRecoverSession(aRepeatedCrash)
+{
+ if (!getPref("restore_prompt", true))
+ {
+ return true;
+ }
+
+ var recover = true;
+ var dontPrompt = { value: false };
+ var dialogURI = getPref("restore_prompt_uri");
+
+ try
+ {
+ if (dialogURI)
+ {
+ var params = Cc["@mozilla.org/embedcomp/dialogparam;1"].createInstance(Ci.nsIDialogParamBlock);
+ params.SetInt(0, (aRepeatedCrash)?0:1);
+ params.SetInt(1, 0);
+ Cc["@mozilla.org/embedcomp/window-watcher;1"].getService(Ci.nsIWindowWatcher).openWindow(null, dialogURI, "_blank", "chrome,modal,centerscreen,titlebar,dialog=yes", params);
+ recover = params.GetInt(0) == 0;
+ dontPrompt.value = params.GetInt(1);
+ }
+ else if (aRepeatedCrash)
+ {
+ var strings = getStringBundle("chrome://crashrecovery/locale/crashrecovery.properties");
+ var branding = getStringBundle("chrome://branding/locale/brand.properties");
+
+ recover = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService).confirmCheck(null, "Crash Recovery - " + branding.GetStringFromName("brandFullName"), strings.GetStringFromName("restore_prompt"), strings.GetStringFromName("restore_prompt_again"), dontPrompt);
+ }
+ }
+ catch (ex) { report(ex); }
+
+ if (dontPrompt.value)
+ {
+ gPrefBranch.setBoolPref("restore_prompt", false);
+ }
+
+ return recover;
+}
+
+function isCmdLineEmpty(aWindow)
+{
+ if (!aWindow.arguments || !aWindow.arguments[0])
+ {
+ return true;
+ }
+
+ var homepage = "about:blank";
+ switch (getPref("browser.startup.page", 1, true))
+ {
+ case 1:
+ try
+ {
+ homepage = gPrefRoot.getComplexValue("browser.startup.homepage", Ci.nsIPrefLocalizedString).data;
+ }
+ catch (ex)
+ {
+ homepage = getPref("browser.startup.homepage", "", true);
+ }
+ homepage = homepage.split("\n")[0];
+ break;
+ case 2:
+ homepage = Cc["@mozilla.org/browser/global-history;2"].getService(Ci.nsIBrowserHistory).lastPageVisited;
+ break;
+ }
+
+ if (aWindow.arguments[0] == homepage)
+ {
+ aWindow.arguments[0] = null;
+ }
+
+ return !aWindow.arguments[0];
+}
+
+function getWindowDimension(aWindow, aAttribute)
+{
+ if (aAttribute == "sizemode")
+ {
+ return (aWindow.windowState == aWindow.STATE_MAXIMIZED)?"maximized":"normal";
+ }
+
+ var equivalents = { width: "outerWidth", height: "outerHeight" };
+ var attribute = equivalents[aAttribute] || aAttribute;
+ var dimension = (attribute in aWindow)?aWindow[attribute]:"";
+
+ if (aWindow.windowState == aWindow.STATE_NORMAL)
+ {
+ return dimension;
+ }
+ return aWindow.document.documentElement.getAttribute(aAttribute) || dimension;
+}
+
+function checkPrivacyLevel(aURL)
+{
+ return gPrefs.privacy_level < ((aURL.substr(0, 6) == "https:")?1:2);
+}
+
+function ensureBrowser(aBrowser)
+{
+ if (aBrowser.localName == "browser")
+ {
+ return aBrowser;
+ }
+
+ var children = aBrowser.childNodes;
+ for (var i = children.length - 1; i >= 0; i--)
+ {
+ if (children[i].localName == "browser")
+ {
+ return children[i];
+ }
+ }
+
+ return aBrowser.getElementsByTagName("browser")[0] || null;
+}
+
+function getStringBundle(aURI)
+{
+ return Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService).createBundle(aURI, Cc["@mozilla.org/intl/nslocaleservice;1"].getService(Ci.nsILocaleService).getApplicationLocale());
+}
+
+
+/* :::::::: Storage API ::::::::::::::: */
+
+function getPref(aName, aDefault, aUseRootBranch)
+{
+ try
+ {
+ var pb = (aUseRootBranch)?gPrefRoot:gPrefBranch;
+ switch (pb.getPrefType(aName))
+ {
+ case pb.PREF_STRING:
+ return pb.getCharPref(aName);
+ case pb.PREF_BOOL:
+ return pb.getBoolPref(aName);
+ case pb.PREF_INT:
+ return pb.getIntPref(aName);
+ }
+ }
+ catch (ex) { /* return the default value */ }
+
+ return aDefault;
+}
+
+function readFile(aFile)
+{
+ if (!aFile.exists())
+ {
+ return null;
+ }
+
+ var stream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
+ stream.init(aFile, 0x01, 0, 0);
+ var cvstream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream);
+ cvstream.init(stream, "UTF-8", 1024, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+
+ var content = "";
+ var data = {};
+ while (cvstream.readString(4096, data))
+ {
+ content += data.value;
+ }
+ cvstream.close();
+
+ return content.replace(/\r\n?/g, "\n");
+}
+
+function writeFile(aFile, aData)
+{
+ var stream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
+ stream.init(aFile, 0x02 | 0x08 | 0x20, 0600, 0);
+ var cvstream = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(Ci.nsIConverterOutputStream);
+ cvstream.init(stream, "UTF-8", 0, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+
+ cvstream.writeString(aData.replace(/\n/g, getEOL()));
+ cvstream.flush();
+ cvstream.close();
+}
+
+function getEOL()
+{
+ if (!Ci.nsIXULRuntime) // SeaMonkey
+ {
+ return "\r\n";
+ }
+
+ var OS = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
+ return /win|os[\/_]?2/i.test(OS)?"\r\n":/mac/i.test(OS)?"\r":"\n";
+}
+
+function delFile(aFile)
+{
+ try
+ {
+ if (aFile.exists())
+ {
+ aFile.remove(false);
+ }
+ }
+ catch (ex) { report(ex); }
+}
+
+
+/* :::::::: File Format Conversion ::::::::::::::: */
+
+function encodeINI(aObj, aPrefix)
+{
+ aPrefix = (aPrefix)?aPrefix + ".":"";
+
+ var ini = [], iniChildren = [];
+
+ for (var key in aObj)
+ {
+ if (!key || /[;\[\]=]/.test(key))
+ {
+ report("Ignoring invalid key name: '" + key + "'!");
+ continue;
+ }
+ else if (key.charAt(0) == "_")
+ {
+ continue;
+ }
+
+ var value = aObj[key];
+ if (typeof value == "boolean" || typeof value == "number")
+ {
+ ini.push(key + "=" + value);
+ }
+ else if (typeof value == "string" && value)
+ {
+ ini.push(key + "=" + ((/^\s|[%\t\r\n;]|\s$/.test(value))?encodeURI(value).replace(/;/g, "%3B"):value));
+ }
+ else if (value instanceof Array)
+ {
+ for (var i = 0; i < value.length; i++)
+ {
+ if (value[i] instanceof Object)
+ {
+ iniChildren.push("[" + aPrefix + key + (i + 1) + "]");
+ iniChildren.push(encodeINI(value[i], aPrefix + key + (i + 1)));
+ }
+ }
+ }
+ else if (typeof value == "object" && value)
+ {
+ iniChildren.push("[" + aPrefix + key + "]");
+ iniChildren.push(encodeINI(value, aPrefix + key));
+ }
+ }
+
+ return ini.concat(iniChildren).join("\n");
+}
+
+function decodeINI(aIniString)
+{
+ if (CR_ini_isOldFormat(aIniString))
+ {
+ return CR_ini_decodeOldFormat(aIniString);
+ }
+
+ var rootObject = {};
+ var obj = rootObject;
+ var lines = aIniString.split("\n");
+
+ for (var i = 0; i < lines.length; i++)
+ {
+ try
+ {
+ if (lines[i].charAt(0) == "[")
+ {
+ obj = ini_getObjForHeader(rootObject, lines[i]);
+ }
+ else if (lines[i] && lines[i].charAt(0) != ";")
+ {
+ ini_setValueForLine(obj, lines[i]);
+ }
+ }
+ catch (ex)
+ {
+ throw new Error("Error at line " + (i + 1) + ": " + ex.description);
+ }
+ }
+
+ return rootObject;
+}
+
+function ini_getObjForHeader(aObj, aLine)
+{
+ var names = aLine.split("]")[0].substr(1).split(".");
+
+ for (var i = 0; i < names.length; i++)
+ {
+ var name = names[i];
+ if (!names[i])
+ {
+ throw new Error("Invalid header: [" + names.join(".") + "]!");
+ }
+ if (/(\d+)$/.test(names[i]))
+ {
+ names[i] = names[i].slice(0, -RegExp.$1.length);
+ var ix = parseInt(RegExp.$1) - 1;
+ aObj = aObj[names[i]] = aObj[names[i]] || [];
+ aObj = aObj[ix] = aObj[ix] || {};
+ }
+ else
+ {
+ aObj = aObj[names[i]] = aObj[names[i]] || {};
+ }
+ }
+
+ return aObj;
+}
+
+function ini_setValueForLine(aObj, aLine)
+{
+ var ix = aLine.indexOf("=");
+ if (ix < 1)
+ {
+ throw new Error("Invalid entry: " + aLine + "!");
+ }
+
+ var value = aLine.substr(ix + 1);
+ if (value == "true" || value == "false")
+ {
+ value = (value == "true");
+ }
+ else if (/^\d+$/.test(value))
+ {
+ value = parseInt(value);
+ }
+ else if (value.indexOf("%") > -1)
+ {
+ value = decodeURI(value.replace(/%3B/gi, ";"));
+ }
+
+ aObj[aLine.substr(0, ix)] = value;
+}
+
+function CR_ini_isOldFormat(aString)
+{
+ return /^-?\d+.*~~~~/.test(aString);
+}
+
+function CR_ini_decodeOldFormat(aString)
+{
+ aString = aString.replace(/^(.*?) ~~~~( .*)?/, "$1");
+ var root = { CrashRecovery: { state: (RegExp.$2)?"running":"stopped" } };
+
+ root.Window = aString.split("\n- WINDOW -----\n").map(function(aWindow) {
+ var winData = {};
+ var tabs = aWindow.split("\n-- TAB ----\n");
+ var cookies = tabs.shift().split("\n");
+ var features = cookies.shift();
+
+ winData.selected = parseInt(features) + 1;
+ if (/ dims:(\S+)/.test(features))
+ {
+ RegExp.$1.split(",").forEach(function(aFeat) {
+ if (/^(\S+)=(.*)/.test(aFeat)) winData[RegExp.$1] = decodeURI(RegExp.$2);
+ });
+ }
+ if (/ hide:(\S+)/.test(features)) winData.hidden = RegExp.$1;
+ winData.sidebar = (/ sidebar:(\S+)/.test(features))?RegExp.$1:"";
+
+ cookies.forEach(function(aCookie) {
+ if (!window.Cookies) window.Cookies = { count: 0 };
+ var cookie = aCookie.split(" ");
+ window.Cookies["domain" + ++window.Cookies.count] = cookie[0];
+ window.Cookies["value" + window.Cookies.count] = decodeURI(cookie[1]);
+ });
+
+ winData.Tab = tabs.map(CR_ini_decodeOldFormatTab);
+
+ return winData;
+ });
+
+ return root;
+}
+
+function CR_ini_decodeOldFormatTab(aTab)
+{
+ function parseEntry(aTabs, aIx, aPrefix)
+ {
+ aPrefix = aPrefix || "";
+ var entries = aTabs[aIx].split(" ");
+ var entry = {
+ uri: entries[0].substr(aPrefix.length), scroll: entries[1],
+ postdata: decodeURI(entries[2] || ""), title: decodeURI(entries[3] || ""),
+ subframe: (entries[4] || "") == "1", Child: []
+ };
+
+ aPrefix += "+";
+ while (aTabs[aIx + 1] && aTabs[aIx + 1].substr(0, aPrefix.length) == aPrefix)
+ {
+ entry.Child.push(parseEntry(aTabs, aIx + 1, aPrefix));
+ aTabs.splice(aIx + 1, 1);
+ }
+
+ return entry;
+ }
+
+ var tabData = { Entry: [], index: 0 };
+ var tabs = aTab.split("\n");
+ if (/^(\d+) zoom:(\S+)/.test(tabs.shift()))
+ {
+ tabData.index = parseInt(RegExp.$1) + 1;
+ tabData.zoom = RegExp.$2;
+ }
+
+ for (var i = 0; i < tabs.length; i++)
+ {
+ if (tabs[i].charAt(0) == "@") break;
+ tabData.Entry.push(parseEntry(tabs, i));
+ }
+ for (; i < tabs.length; i++)
+ {
+ if (/^@(text|xulattr|disallow) (.*)/.test(tabs[i]))
+ {
+ tabData[RegExp.$1] = RegExp.$2;
+ }
+ }
+
+ return tabData;
+}
+
+
+/* :::::::: Service Registration & Initialization ::::::::::::::: */
+
+/*const*/ var CrashRecoveryModuleAndFactory = {
+
+/* ........ nsIModule .............. */
+
+ getClassObject: function(aCompMgr, aCID, aIID)
+ {
+ if (aCID.equals(CrashRecoveryService.mCID))
+ {
+ return this.QueryInterface(aIID);
+ }
+
+ Components.returnCode = Cr.NS_ERROR_NOT_REGISTERED;
+ return null;
+ },
+
+ registerSelf: function(aCompMgr, aFileSpec, aLocation, aType)
+ {
+ aCompMgr.QueryInterface(Ci.nsIComponentRegistrar);
+ aCompMgr.registerFactoryLocation(CrashRecoveryService.mCID, CrashRecoveryService.mClassName, CrashRecoveryService.mContractID, aFileSpec, aLocation, aType);
+
+ Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager).addCategoryEntry("app-startup", CrashRecoveryService.mClassName, "service," + CrashRecoveryService.mContractID, true, true);
+ },
+
+ unregisterSelf: function(aCompMgr, aLocation, aType)
+ {
+ aCompMgr.QueryInterface(Ci.nsIComponentRegistrar);
+ aCompMgr.unregisterFactoryLocation(CrashRecoveryService.mCID, aLocation);
+
+ Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager).deleteCategoryEntry("app-startup", "service," + CrashRecoveryService.mContractID, true);
+ },
+
+ canUnload: function(aCompMgr)
+ {
+ return true;
+ },
+
+/* ........ nsIFactory .............. */
+
+ createInstance: function(aOuter, aIID)
+ {
+ if (aOuter != null)
+ {
+ Components.returnCode = Cr.NS_ERROR_NO_AGGREGATION;
+ return null;
+ }
+
+ return CrashRecoveryService.QueryInterface(aIID);
+ },
+
+ lockFactory: function(aLock) { },
+
+/* ........ QueryInterface .............. */
+
+ QueryInterface: function(aIID)
+ {
+ if (!aIID.equals(Ci.nsISupports) && !aIID.equals(Ci.nsIModule) && !aIID.equals(Ci.nsIFactory))
+ {
+ Components.returnCode = Cr.NS_ERROR_NO_INTERFACE;
+ return null;
+ }
+
+ return this;
+ }
+};
+
+function NSGetModule(aComMgr, aFileSpec)
+{
+ return CrashRecoveryModuleAndFactory;
+}
diff --git a/xpfe/global/jar.mn b/xpfe/global/jar.mn
index 6ba5a5f1..4c629d55 100644
--- a/xpfe/global/jar.mn
+++ b/xpfe/global/jar.mn
@@ -90,6 +90,20 @@ toolkit.jar:
content/global/fontpackage.xul (resources/content/fontpackage.xul)
content/global/fontpackage.js (resources/content/fontpackage.js)
content/global/XPCNativeWrapper.js (resources/content/XPCNativeWrapper.js)
+ content/global/extensions/sessionmanager/sessionmanager.xul (resources/content/extensions/sessionmanager/sessionmanager.xul)
+ content/global/extensions/sessionmanager/zzz_closewindow_hack.xul (resources/content/extensions/sessionmanager/zzz_closewindow_hack.xul)
+ content/global/extensions/sessionmanager/options.xul (resources/content/extensions/sessionmanager/options.xul)
+ content/global/extensions/sessionmanager/restore_prompt.xul (resources/content/extensions/sessionmanager/restore_prompt.xul)
+ content/global/extensions/sessionmanager/session_prompt.xul (resources/content/extensions/sessionmanager/session_prompt.xul)
+ content/global/extensions/sessionmanager/sessionmanager.js (resources/content/extensions/sessionmanager/sessionmanager.js)
+ content/global/extensions/sessionmanager/options.js (resources/content/extensions/sessionmanager/options.js)
+ content/global/extensions/sessionmanager/session_prompt.js (resources/content/extensions/sessionmanager/session_prompt.js)
+ content/global/extensions/sessionmanager/contents.rdf (resources/content/extensions/sessionmanager/contents.rdf)
+ content/global/extensions/sessionmanager/skin/contents.rdf (resources/content/extensions/sessionmanager/skin/contents.rdf)
+ content/global/extensions/sessionmanager/skin/dougeeebear.png (resources/content/extensions/sessionmanager/skin/dougeeebear.png)
+ content/global/extensions/sessionmanager/skin/icon.png (resources/content/extensions/sessionmanager/skin/icon.png)
+ content/global/extensions/sessionmanager/skin/sessionmanager.css (resources/content/extensions/sessionmanager/skin/sessionmanager.css)
+ content/global/extensions/sessionmanager/skin/toolbar.png (resources/content/extensions/sessionmanager/skin/toolbar.png)
#ifdef MOZ_SVG
content/global/svg/svgBindings.xml (/layout/svg/base/src/resources/content/svgBindings.xml)
#endif
@@ -123,6 +137,10 @@ en-US.jar:
locale/en-US/global/fontpackage.dtd (resources/locale/en-US/fontpackage.dtd)
locale/en-US/global/fontpackage.properties (resources/locale/en-US/fontpackage.properties)
locale/en-US/global/tree.dtd (resources/locale/en-US/tree.dtd)
+ locale/en-US/global/extensions/sessionmanager/contents.rdf (resources/locale/en-US/extensions/sessionmanager/contents.rdf)
+ locale/en-US/global/extensions/sessionmanager/options.dtd (resources/locale/en-US/extensions/sessionmanager/options.dtd)
+ locale/en-US/global/extensions/sessionmanager/sessionmanager.dtd (resources/locale/en-US/extensions/sessionmanager/sessionmanager.dtd)
+ locale/en-US/global/extensions/sessionmanager/sessionmanager.properties (resources/locale/en-US/extensions/sessionmanager/sessionmanager.properties)
US.jar:
* locale/US/global-region/contents.rdf (resources/locale/en-US/contents-region.rdf)
diff --git a/xpfe/global/resources/content/extensions/sessionmanager/contents.rdf b/xpfe/global/resources/content/extensions/sessionmanager/contents.rdf
new file mode 100644
index 00000000..976cdf3f
--- /dev/null
+++ b/xpfe/global/resources/content/extensions/sessionmanager/contents.rdf
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ chrome://sessionmanager/content/sessionmanager.xul
+
+
diff --git a/xpfe/global/resources/content/extensions/sessionmanager/options.js b/xpfe/global/resources/content/extensions/sessionmanager/options.js
new file mode 100644
index 00000000..9fd129ea
--- /dev/null
+++ b/xpfe/global/resources/content/extensions/sessionmanager/options.js
@@ -0,0 +1,77 @@
+gSessionManager._onLoad = gSessionManager.onLoad;
+gSessionManager.onLoad = function() {
+ this._onLoad(true);
+
+ var resume_session = _("resume_session");
+ var sessions = this.getSessions();
+ resume_session.appendItem(this._string("startup_none"), "", "");
+ resume_session.appendItem(this._string("startup_prompt"), this.mPromptSessionName, "");
+ if (!sessions.some(function(aSession) { return aSession.fileName == this.mBackupSessionName; }, this))
+ {
+ resume_session.appendItem(this._string("startup_resume"), this.mBackupSessionName, "");
+ }
+ sessions.forEach(function(aSession) {
+ resume_session.appendItem(aSession.name, aSession.fileName, "");
+ });
+ resume_session.value = _("extensions.sessionmanager.resume_session").value;
+
+ _("SessionManagerPrefs").selectedIndex = _("extensions.sessionmanager.options_selected_tab").value;
+};
+gSessionManager.onUnload = function() {
+ _("extensions.sessionmanager.options_selected_tab").valueFromPreferences = _("SessionManagerPrefs").selectedIndex;
+};
+
+var _disable = gSessionManager.setDisabled;
+
+function readMaxClosedUndo()
+{
+ var value = _("extensions.sessionmanager.max_closed_undo").value;
+
+ _disable(_("save_window_list"), value == 0);
+
+ return value;
+}
+
+function readMaxTabsUndo()
+{
+ var value = _("extensions.sessionmanager.max_tabs_undo").value;
+
+ _disable(_("save_closed_tabs"), value == 0);
+ _disable(document.getElementsByAttribute("control", "save_closed_tabs")[0], value == 0);
+
+ return value;
+}
+
+function promptClearUndoList()
+{
+ var max_tabs_undo = _("max_tabs").value;
+
+ gSessionManager.clearUndoListPrompt();
+
+ _("max_tabs").value = max_tabs_undo;
+};
+
+function readInterval()
+{
+ return _("extensions.crashrecovery.interval").value / 1000;
+}
+
+function writeInterval()
+{
+ return Math.round(parseFloat(_("interval").value) * 1000 || 0);
+}
+
+function readPrivacyLevel()
+{
+ var value = _("extensions.crashrecovery.privacy_level").value;
+
+ _disable(_("postdata"), value > 1);
+ _disable(document.getElementsByAttribute("control", "postdata")[0], value > 1);
+
+ return value;
+}
+
+function _(aId)
+{
+ return document.getElementById(aId);
+}
diff --git a/xpfe/global/resources/content/extensions/sessionmanager/options.xul b/xpfe/global/resources/content/extensions/sessionmanager/options.xul
new file mode 100644
index 00000000..b553852b
--- /dev/null
+++ b/xpfe/global/resources/content/extensions/sessionmanager/options.xul
@@ -0,0 +1,170 @@
+
+
+
+
+ %sessionmanagerDTD;
+
+ %optionsDTD;
+]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ &name_format.desc;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xpfe/global/resources/content/extensions/sessionmanager/restore_prompt.xul b/xpfe/global/resources/content/extensions/sessionmanager/restore_prompt.xul
new file mode 100644
index 00000000..ebd59874
--- /dev/null
+++ b/xpfe/global/resources/content/extensions/sessionmanager/restore_prompt.xul
@@ -0,0 +1,51 @@
+
+
+
+
+
diff --git a/xpfe/global/resources/content/extensions/sessionmanager/session_prompt.js b/xpfe/global/resources/content/extensions/sessionmanager/session_prompt.js
new file mode 100644
index 00000000..637517db
--- /dev/null
+++ b/xpfe/global/resources/content/extensions/sessionmanager/session_prompt.js
@@ -0,0 +1,176 @@
+var gParams = window.arguments[0].QueryInterface(Components.interfaces.nsIDialogParamBlock);
+var gSessionList = null;
+var gTextBox = null;
+var gAcceptButton = null;
+var gSessionNames = {};
+var gExistingName = 0;
+var gNeedSelection = false;
+
+gSessionManager._onLoad = gSessionManager.onLoad;
+gSessionManager.onLoad = function() {
+ this._onLoad(true);
+
+ _("mac_title").hidden = !/mac/i.test(navigator.platform);
+ setDescription(_("session_label"), gParams.GetString(1));
+
+ gAcceptButton = document.documentElement.getButton("accept");
+ gAcceptButton.label = gParams.GetString(2) || gAcceptButton.label;
+
+ var sessions = this.getSessions();
+ if (gParams.GetInt(1) & 1) // add a "virtual" current session
+ {
+ sessions.unshift({ name: this._string("current_session"), fileName: "*" });
+ }
+
+ gSessionList = _("session_list");
+ gSessionList.selType = (gParams.GetInt(1) & 2)?"multiple":"single";
+
+ if (gParams.GetString(4)) // enable text box
+ {
+ _("text_container").hidden = false;
+ setDescription(_("text_label"), gParams.GetString(4));
+ gTextBox = _("text_box");
+
+ sessions.forEach(function(aSession, aIx) {
+ gSessionNames[aSession.name.trim().toLowerCase()] = aIx + 1;
+ });
+
+ onTextboxInput(gParams.GetString(6));
+ if (gExistingName && !(gParams.GetInt(1) & 256))
+ {
+ gParams.SetString(3, sessions[gExistingName - 1].fileName);
+ gTextBox.value = "";
+ onTextboxInput();
+ }
+ }
+ if (gParams.GetInt(1) & 4) // show the "Don't show [...] again" checkbox
+ {
+ _("checkbox_container").hidden = false;
+ }
+
+ sessions.forEach(function(aSession) {
+ var item = gSessionList.appendItem(aSession.name, aSession.fileName);
+ if (aSession.fileName == gParams.GetString(3))
+ {
+ setTimeout(function(aItem) { gSessionList.selectItem(aItem); }, 0, item);
+ }
+ });
+
+ if ((gNeedSelection = !gTextBox || !gParams.GetString(5)) || (gParams.GetInt(1) & 256)) // when no textbox or renaming
+ {
+ gSessionList.addEventListener("select", onListboxSelect, false);
+ onListboxSelect();
+ }
+
+ // add accessibility shortcuts (single-click / double-click / return)
+ for (var i = 0; i < gSessionList.childNodes.length; i++)
+ {
+ gSessionList.childNodes[i].setAttribute("ondblclick", "if (event.button == 0 && !event.ctrlKey && !event.shiftKey && !event.altKey) gAcceptButton.doCommand();");
+ if (gTextBox && !(gParams.GetInt(1) & 256))
+ {
+ gSessionList.childNodes[i].setAttribute("onclick", "if (event.button == 0 && !event.ctrlKey && !event.shiftKey && !event.altKey) onTextboxInput(gSessionList.childNodes[gSessionList.selectedIndex].label);");
+ }
+ }
+ if (gTextBox)
+ {
+ gSessionList.setAttribute("onkeypress", "if (event.keyCode == event.DOM_VK_RETURN && this.selectedIndex > -1) { event.button = 0; eval(this.selectedItem.getAttribute('onclick')); event.preventDefault(); }");
+ }
+
+ if (gSessionList.hasAttribute("height"))
+ {
+ gSessionList.height = gSessionList.getAttribute("height");
+ }
+ if (!window.opener)
+ {
+ document.documentElement.removeAttribute("screenX");
+ document.documentElement.removeAttribute("screenY");
+ }
+ window.sizeToContent();
+
+ gParams.SetInt(0, 1);
+};
+
+gSessionManager.onUnload = function() {
+ function persist(aObj, aAttr, aValue)
+ {
+ aObj.setAttribute(aAttr, aValue);
+ document.persist(aObj.id, aAttr);
+ }
+
+ if (window.opener)
+ {
+ persist(document.documentElement, "screenX", window.screenX - window.opener.screenX);
+ persist(document.documentElement, "screenY", window.screenY - window.opener.screenY);
+ }
+ persist(gSessionList, "height", gSessionList.boxObject.height);
+
+ gParams.SetInt(1, (_("checkbox").checked)?1:0);
+};
+
+function onListboxSelect()
+{
+ if (!gTextBox)
+ {
+ gAcceptButton.disabled = gSessionList.selectedCount == 0;
+ }
+ else
+ {
+ onTextboxInput();
+ }
+}
+
+function onTextboxInput(aNewValue)
+{
+ if (aNewValue)
+ {
+ gTextBox.value = aNewValue;
+ setTimeout(function() { gTextBox.select(); gTextBox.focus(); }, 0);
+ }
+
+ var input = gTextBox.value.trim().toLowerCase();
+ var oldWeight = !!gAcceptButton.style.fontWeight;
+
+ gExistingName = gSessionNames[input] || 0;
+ var newWeight = gExistingName || ((gParams.GetInt(1) & 256) && gSessionList.selectedCount > 0);
+
+ if (!gNeedSelection && oldWeight != newWeight)
+ {
+ gAcceptButton.label = (newWeight)?gParams.GetString(5):gParams.GetString(2);
+ gAcceptButton.style.fontWeight = (newWeight)?"bold":"";
+ }
+ gAcceptButton.disabled = !input || gNeedSelection && (gSessionList.selectedCount == 0 || gExistingName);
+}
+
+function onAcceptDialog()
+{
+ gParams.SetInt(0, 0);
+ if (gNeedSelection || ((gParams.GetInt(1) & 256) && gSessionList.selectedCount > 0))
+ {
+ gParams.SetString(3, gSessionList.selectedItems.map(function(aItem) { return aItem.value || ""; }).join("\n"));
+ }
+ else if (gExistingName)
+ {
+ gParams.SetString(3, gSessionList.childNodes[gExistingName - 1].value);
+ }
+ else
+ {
+ gParams.SetString(3, "");
+ }
+ gParams.SetString(6, _("text_box").value.trim());
+}
+
+String.prototype.trim = function() {
+ return this.replace(/^\s+|\s+$/g, "").replace(/\s+/g, " ");
+};
+
+function setDescription(aObj, aValue)
+{
+ aValue.split("\n").forEach(function(aLine) {
+ aObj.appendChild(document.createElement("description")).setAttribute("value", aLine);
+ });
+}
+
+function _(aId)
+{
+ return document.getElementById(aId);
+}
diff --git a/xpfe/global/resources/content/extensions/sessionmanager/session_prompt.xul b/xpfe/global/resources/content/extensions/sessionmanager/session_prompt.xul
new file mode 100644
index 00000000..9d393d3b
--- /dev/null
+++ b/xpfe/global/resources/content/extensions/sessionmanager/session_prompt.xul
@@ -0,0 +1,48 @@
+
+
+
+
+
+
diff --git a/xpfe/global/resources/content/extensions/sessionmanager/sessionmanager.js b/xpfe/global/resources/content/extensions/sessionmanager/sessionmanager.js
new file mode 100644
index 00000000..189a1408
--- /dev/null
+++ b/xpfe/global/resources/content/extensions/sessionmanager/sessionmanager.js
@@ -0,0 +1,1277 @@
+/*const*/ var gSessionManager = {
+ mCrashRecoveryService: Components.classes["@zeniko/crashrecoveryservice;1"].getService(Components.interfaces.nsICrashRecoveryService),
+ mObserverService: Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService),
+ mPrefRoot: Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch2),
+ mWindowMediator: Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator),
+ mPromptService: Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService),
+ mProfileDirectory: Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsILocalFile),
+ mIOService: Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService),
+ mComponents: Components,
+
+ mObserving: ["crashrecovery:windowclosed", "browser:purge-session-history", "quit-application-granted", "quit-application"],
+ mPrefBranchName: "extensions.sessionmanager.",
+
+ mClosedWindowFile: "sessionmanager.dat",
+ mDataTabAttribute: "CR_closed_tabs",
+ mBackupSessionName: "backup.session",
+ mPromptSessionName: "?",
+ mSessionExt: ".session",
+
+ mClosedTabs: [],
+ mSessionCache: {},
+ mDataTab: null,
+
+/* ........ Listeners / Observers.............. */
+
+ onLoad_proxy: function()
+ {
+ this.removeEventListener("load", gSessionManager.onLoad_proxy, false);
+ gSessionManager.onLoad();
+ },
+
+ onLoad: function(aDialog)
+ {
+ this.mBundle = document.getElementById("bundle_sessionmanager");
+ this.mTitle = this._string("sessionManager");
+ this.mEOL = this.getEOL();
+
+ this.mPrefBranch = this.mPrefRoot.QueryInterface(Components.interfaces.nsIPrefService).getBranch(this.mPrefBranchName).QueryInterface(Components.interfaces.nsIPrefBranch2);
+
+ if (aDialog || this.mFullyLoaded)
+ {
+ return;
+ }
+
+ if (this.getPref("_resume_session"))
+ {
+ this.setResumeCurrent(true);
+ this.delPref("_resume_session");
+ }
+
+ this.mObserving.forEach(function(aTopic) {
+ this.mObserverService.addObserver(this, aTopic, false);
+ }, this);
+
+ this.mPref_backup_session = this.getPref("backup_session", 1);
+ this.mPref_max_backup_keep = this.getPref("max_backup_keep", 0);
+ this.mPref_max_closed_undo = this.getPref("max_closed_undo", 10);
+ this.mPref_max_tabs_undo = this.getPref("max_tabs_undo", 10);
+ this.mPref_name_format = this.getPref("name_format", "%40t-%d");
+ this.mPref_overwrite = this.getPref("overwrite", false);
+ this.mPref_reload = this.getPref("reload", false);
+ this.mPref_resume_session = this.getPref("resume_session", "");
+ this.mPref_save_closed_tabs = this.getPref("save_closed_tabs", 0);
+ this.mPref_save_window_list = this.getPref("save_window_list", false);
+ this.mPref_session_list_order = this.getPref("session_list_order", 1);
+ this.mPref_submenus = this.getPref("submenus", false);
+ this.mPref__running = this.getPref("_running", false);
+ this.mPrefBranch.addObserver("", this, false);
+
+ getBrowser().addEventListener("CRTabRestoring", this.onTabRestoring_proxy, false);
+ gBrowser.addEventListener("CRTabRestored", this.onTabRestored_proxy, false);
+ gBrowser.addEventListener("SMTabClosing", this.onTabClosing_proxy, false);
+ gBrowser.addEventListener("load", this.onTabLoading_proxy, true);
+
+ this.recoverSession();
+ this.patchTabBrowser();
+ this.updateToolbarButton();
+
+ if (!this.mPref__running)
+ {
+ this.setPref("_running", true);
+ this.mPrefRoot.savePrefFile(null);
+ }
+ this.mFullyLoaded = true;
+ },
+
+ onUnload_proxy: function()
+ {
+ this.removeEventListener("unload", gSessionManager.onUnload_proxy, false);
+ gSessionManager.onUnload();
+ },
+
+ onUnload: function()
+ {
+ this.mObserving.forEach(function(aTopic) {
+ this.mObserverService.removeObserver(this, aTopic);
+ }, this);
+ this.mPrefBranch.removeObserver("", this);
+
+ gBrowser.removeEventListener("CRTabRestoring", this.onTabRestoring_proxy, false);
+ gBrowser.removeEventListener("CRTabRestored", this.onTabRestored_proxy, false);
+ gBrowser.removeEventListener("SMTabClosing", this.onTabClosing_proxy, false);
+ gBrowser.removeEventListener("load", this.onTabLoading_proxy, true);
+
+ if (this.mPref__running && this.getBrowserWindows().length == 0)
+ {
+ this.mObserverService.addObserver(this, "quit-application", false);
+ this.mObserverService.addObserver(this, "domwindowopened", false);
+
+ this._string_preserve_session = this._string("preserve_session");
+ this._string_backup_session = this._string("backup_session");
+ this._string_old_backup_session = this._string("old_backup_session");
+
+ this.setPref("_hibernating", true);
+ }
+
+ this.mBundle = null;
+ this.mSessions = null;
+ this.mClosedTabs = null;
+ this.mFullyLoaded = false;
+ },
+
+ observe: function(aSubject, aTopic, aData)
+ {
+ switch (aTopic)
+ {
+ case "crashrecovery:windowclosed":
+ if (aSubject == window)
+ {
+ this.appendClosedWindow(aData);
+ }
+ else if (this.mPref_max_closed_undo > 0)
+ {
+ this.updateToolbarButton(true);
+ }
+ break;
+ case "browser:purge-session-history":
+ this.clearUndoData("all");
+ this.delFile(this.getSessionDir(this.mBackupSessionName));
+ break;
+ case "nsPref:changed":
+ this["mPref_" + aData] = this.getPref(aData);
+
+ switch (aData)
+ {
+ case "max_closed_undo":
+ if (this.mPref_max_closed_undo == 0)
+ {
+ this.clearUndoData("window", true);
+ }
+ break;
+ case "max_tabs_undo":
+ if (this.mPref_max_tabs_undo == 0)
+ {
+ this.clearUndoData("tab", true);
+ }
+ break;
+ case "resume_session":
+ this.setResumeCurrent(this.mPref_resume_session == this.mBackupSessionName);
+ break;
+ case "save_closed_tabs":
+ if (!this.mPref_save_closed_tabs)
+ {
+ this.clearUndoData("datatab");
+ }
+ else if (this.mClosedTabs.length > 0)
+ {
+ this.persistClosedTabList();
+ }
+ break;
+ }
+ break;
+ case "quit-application-granted":
+ case "quit-application":
+ if (this.getPref("_running"))
+ {
+ this.delPref("_running");
+ this.delPref("_hibernating");
+ if (!this.mPref_save_window_list)
+ {
+ this.clearUndoData("window", true);
+ }
+ if (this.doResumeCurrent(true))
+ {
+ this.setPref("_resume_session_once", (this.mPref__resume_session_once = true))
+ }
+ this.backupCurrentSession();
+ }
+ break;
+ case "domwindowopened":
+ aSubject.__gSeMa = this;
+ aSubject.addEventListener("load", this.onDomWindowOpened_proxy, false);
+ break;
+ }
+ },
+
+ onDomWindowOpened_proxy: function()
+ {
+ this.removeEventListener("load", this.__gSeMa.onDomWindowOpened_proxy, false);
+ if (this.document.documentElement.getAttribute("windowtype") == "navigator:browser")
+ {
+ this.__gSeMa.mObserverService.removeObserver(this.__gSeMa, "quit-application");
+ this.__gSeMa.mObserverService.removeObserver(this.__gSeMa, "domwindowopened");
+ }
+ delete this.__gSeMa;
+ },
+
+ onTabRestoring_proxy: function(aEvent)
+ {
+ gSessionManager.onTabRestoring(aEvent.originalTarget);
+ },
+
+ onTabRestoring: function(aTab)
+ {
+ if (aTab.hasAttribute(this.mDataTabAttribute))
+ {
+ if (this.mDataTab && this.mDataTab != aTab)
+ {
+ this.clearUndoData("datatab");
+ }
+ this.mDataTab = aTab;
+
+ var serializedTabs = aTab.getAttribute(this.mDataTabAttribute);
+ this.mClosedTabs = serializedTabs.split("\f\f").map(function(aData) {
+ if (/^(\d+) (.*)\n([\s\S]*)/.test(aData))
+ {
+ return { name: RegExp.$2, pos: parseInt(RegExp.$1), state: RegExp.$3 };
+ }
+ return null;
+ }).filter(function(aTab) { return aTab != null; }).slice(0, this.mPref_max_tabs_undo);
+
+ this.updateToolbarButton((this.mClosedTabs.length > 0)?true:undefined);
+
+ if (!this.mPref_save_closed_tabs)
+ {
+ this.clearUndoData("datatab");
+ }
+ }
+ },
+
+ onTabRestored_proxy: function(aEvent)
+ {
+ var browser = this.getBrowserForTab(aEvent.originalTarget);
+
+ if (gSessionManager.mPref_reload && gSessionManager._allowReload && !browser.__CR_data && !gSessionManager.mIOService.offline)
+ {
+ var nsIWebNavigation = Components.interfaces.nsIWebNavigation;
+ var webNav = browser.webNavigation;
+ try
+ {
+ webNav = webNav.sessionHistory.QueryInterface(nsIWebNavigation);
+ }
+ catch (ex) { }
+ webNav.reload(nsIWebNavigation.LOAD_FLAGS_BYPASS_PROXY | nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE);
+ }
+ },
+
+ onTabClosing_proxy: function(aEvent)
+ {
+ gSessionManager.onTabClosing(aEvent.originalTarget);
+ },
+
+ onTabClosing: function(aTab)
+ {
+ if (this.mPref_max_tabs_undo == 0)
+ {
+ return;
+ }
+ if (this.mDataTab && this.mDataTab == aTab)
+ {
+ var dataTabData = aTab.getAttribute(this.mDataTabAttribute);
+ this.mDataTab = gBrowser.mTabs[(aTab.previousSibling)?0:1] || null;
+ if (this.mDataTab && dataTabData)
+ {
+ this.mDataTab.setAttribute(this.mDataTabAttribute, dataTabData);
+ dataTabData = null;
+ }
+ aTab.removeAttribute(this.mDataTabAttribute);
+ }
+ if (!this._ignoreRemovedTabs && !this.isCleanBrowser(gBrowser.getBrowserForTab(aTab)))
+ {
+ var state = this.getSessionState(null, true);
+ var position = (aTab._tPos != undefined)?aTab._tPos + 1:0;
+ var title = aTab.label;
+ if (!position || gBrowser.mTabs[position - 1] != aTab)
+ {
+ for (position = 1; (aTab = aTab.previousSibling); position++);
+ }
+
+ this.appendClosedTab(state, position, title, this.mDataTab || gBrowser.mTabs[(aTab.previousSibling)?0:1] || null);
+ }
+ else if (dataTabData)
+ {
+ this.mDataTab = aTab;
+ this.mDataTab.setAttribute(this.mDataTabAttribute, dataTabData);
+ }
+ },
+
+ onTabLoading_proxy: function(aEvent)
+ {
+ if (aEvent.originalTarget && aEvent.originalTarget.loadOverlay)
+ {
+ aEvent.originalTarget.loadOverlay("chrome://sessionmanager/content/zzz_closewindow_hack.xul", null);
+ }
+ },
+
+ onToolbarClick: function(aEvent, aButton)
+ {
+ if (aEvent.button == 1)
+ {
+ eval("var event = { shiftKey: true }; " + aButton.getAttribute("oncommand"));
+ }
+ else if (aEvent.button == 2 && aButton.getAttribute("disabled") != "true")
+ {
+ aButton.open = true;
+ }
+ },
+
+/* ........ Menu Event Handlers .............. */
+
+ init: function(aPopup, aIsToolbar)
+ {
+ function get_(a_id) { return aPopup.getElementsByAttribute("_id", a_id)[0] || null; }
+
+ var separator = get_("separator");
+ var startSep = get_("start-separator");
+
+ for (var item = startSep.nextSibling; item != separator; item = startSep.nextSibling)
+ {
+ aPopup.removeChild(item);
+ }
+
+ this.mSessions = this.getSessions();
+ this.mSessions.forEach(function(aSession, aIx) {
+ var key = (aIx < 9)?aIx + 1:(aIx == 9)?"0":"";
+ var menuitem = document.createElement("menuitem");
+ menuitem.setAttribute("label", ((key)?key + ") ":"") + aSession.name);
+ menuitem.setAttribute("oncommand", 'gSessionManager.load("' + aSession.fileName + '", (event.shiftKey && event.ctrlKey)?"overwrite":(event.shiftKey)?"newwindow":(event.ctrlKey)?"append":"");');
+ menuitem.setAttribute("onclick", 'if (event.button == 1) gSessionManager.load("' + aSession.fileName + '", "newwindow");');
+ menuitem.setAttribute("accesskey", key);
+ aPopup.insertBefore(menuitem, separator);
+ });
+ separator.hidden = (this.mSessions.length == 0);
+ this.setDisabled(separator.nextSibling, separator.hidden);
+ this.setDisabled(separator.nextSibling.nextSibling, separator.hidden);
+
+ try
+ {
+ get_("resume").setAttribute("checked", this.doResumeCurrent());
+ get_("overwrite").setAttribute("checked", this.mPref_overwrite);
+ get_("reload").setAttribute("checked", this.mPref_reload);
+ }
+ catch (ex) { } // not available for Firefox
+
+ var undoMenu = get_("undo-menu");
+ while (aPopup.lastChild != undoMenu)
+ {
+ aPopup.removeChild(aPopup.lastChild);
+ }
+
+ var undoDisabled = (this.mPref_max_closed_undo == 0 && this.mPref_max_tabs_undo == 0);
+ var divertedMenu = aIsToolbar && document.getElementById("sessionmanager-undo");
+ var canUndo = !undoDisabled && !divertedMenu && this.initUndo(undoMenu.firstChild);
+
+ undoMenu.hidden = undoDisabled || divertedMenu || !this.mPref_submenus;
+ undoMenu.previousSibling.hidden = !canUndo && undoMenu.hidden;
+ this.setDisabled(undoMenu, !canUndo);
+
+ if (!this.mPref_submenus && canUndo)
+ {
+ for (item = undoMenu.firstChild.firstChild; item; item = item.nextSibling)
+ {
+ aPopup.appendChild(item.cloneNode(true));
+ }
+ }
+
+ // in case the popup belongs to a collapsed element
+ aPopup.style.visibility = "visible";
+ },
+
+ uninit: function(aPopup)
+ {
+ aPopup.style.visibility = "";
+
+ this.mSessions = null;
+ },
+
+ save: function(aName, aFileName, aOneWindow)
+ {
+ var values = { text: this.getFormattedName(content.document.title || "about:blank", new Date()) || (new Date()).toLocaleString() };
+ if (!aName)
+ {
+ if (!this.prompt(this._string("save2_session"), this._string("save_" + ((aOneWindow)?"window":"session") + "_ok"), values, this._string("save_" + ((aOneWindow)?"window":"session")), this._string("save_session_ok2")))
+ {
+ return;
+ }
+ aName = values.text;
+ aFileName = values.name;
+ }
+ if (aName)
+ {
+ var file = this.getSessionDir(aFileName || this.makeFileName(aName), !aFileName);
+ try
+ {
+ this.writeFile(file, this.getSessionState(aName, aOneWindow, this.mPref_save_closed_tabs < 2));
+ }
+ catch (ex)
+ {
+ this.ioError(ex);
+ }
+ }
+ },
+
+ saveWindow: function(aName, aFileName)
+ {
+ this.save(aName, aFileName, true);
+ },
+
+ load: function(aFileName, aMode)
+ {
+ var state = this.readSessionFile(this.getSessionDir(aFileName));
+ if (!state)
+ {
+ this.ioError();
+ return;
+ }
+
+ var newWindow = false;
+ var overwriteTabs = true;
+ var tabsToMove = null;
+
+ aMode = aMode || "default";
+ if (aMode == "startup")
+ {
+ overwriteTabs = this.isCmdLineEmpty();
+ tabsToMove = (!overwriteTabs)?Array.slice(gBrowser.mTabs):null;
+ }
+ else if (aMode == "append")
+ {
+ overwriteTabs = false;
+ }
+ else if (aMode == "newwindow" || (aMode != "overwrite" && !this.mPref_overwrite))
+ {
+ newWindow = true;
+ }
+ else
+ {
+ this.getBrowserWindows().forEach(function(aWindow) {
+ if (aWindow != window) { aWindow.close(); }
+ });
+ this.mObserverService.notifyObservers(window, "crashrecovery:windowclosed", this.getSessionState(null, true));
+ }
+
+ setTimeout(function() {
+ var tabcount = gBrowser.mTabs.length;
+ gSessionManager.restoreSession((!newWindow)?window:null, state, overwriteTabs, true);
+ if (tabsToMove)
+ {
+ var endPos = gBrowser.mTabs.length - 1;
+ tabsToMove.forEach(function(aTab) { gBrowser.moveTabTo(aTab, endPos); });
+ }
+ else if (!overwriteTabs && gBrowser.mTabs[tabcount])
+ {
+ setTimeout(function(aTab) {
+ gBrowser.selectedTab = aTab;
+ }, 100, gBrowser.mTabs[tabcount]);
+ }
+ }, 0);
+ },
+
+ rename: function()
+ {
+ var values = {};
+ if (!this.prompt(this._string("rename_session"), this._string("rename_session_ok"), values, this._string("rename2_session")))
+ {
+ return;
+ }
+ var file = this.getSessionDir(values.name);
+ var filename = this.makeFileName(values.text);
+ var newFile = (filename != file.leafName)?this.getSessionDir(filename, true):null;
+
+ try
+ {
+ this.writeFile(newFile || file, this.nameState(this.readSessionFile(file), values.text));
+ if (newFile)
+ {
+ if (this.mPref_resume_session == file.leafName && this.mPref_resume_session != this.mBackupSessionName)
+ {
+ this.setPref("resume_session", filename);
+ }
+ this.delFile(file);
+ }
+ }
+ catch (ex)
+ {
+ this.ioError(ex);
+ }
+ },
+
+ remove: function(aSession)
+ {
+ if (!aSession)
+ {
+ aSession = this.selectSession(this._string("remove_session"), this._string("remove_session_ok"), { multiSelect: true });
+ }
+ if (aSession)
+ {
+ aSession.split("\n").forEach(function(aFileName) {
+ this.delFile(this.getSessionDir(aFileName));
+ }, this);
+ }
+ },
+
+ openFolder: function()
+ {
+ try
+ {
+ this.getSessionDir().launch();
+ }
+ catch (ex)
+ {
+ this.ioError(ex);
+ }
+ },
+
+ openOptions: function()
+ {
+ openDialog("chrome://sessionmanager/content/options.xul", "_blank", "chrome,dialog,modal,titlebar,centerscreen");
+ },
+
+ toggleResume: function()
+ {
+ this.setResumeCurrent(!this.doResumeCurrent());
+ },
+
+ toggleReload: function()
+ {
+ this.setPref("reload", !this.mPref_reload);
+ },
+
+ toggleOverwrite: function()
+ {
+ this.setPref("overwrite", !this.mPref_overwrite);
+ },
+
+/* ........ Undo Menu Event Handlers .............. */
+
+ initUndo: function(aPopup, aStandAlone)
+ {
+ function get_(a_id) { return aPopup.getElementsByAttribute("_id", a_id)[0] || null; }
+
+ var separator = get_("closed-separator");
+ var label = get_("windows");
+
+ for (var item = separator.previousSibling; item != label; item = separator.previousSibling)
+ {
+ aPopup.removeChild(item);
+ }
+
+ var closedWindows = this.getClosedWindows();
+ closedWindows.forEach(function(aWindow, aIx) {
+ var menuitem = document.createElement("menuitem");
+ menuitem.setAttribute("label", aWindow.name);
+ menuitem.setAttribute("oncommand", 'gSessionManager.undoCloseWindow(' + aIx + ', (event.shiftKey && event.ctrlKey)?"overwrite":(event.ctrlKey)?"append":"");');
+ aPopup.insertBefore(menuitem, separator);
+ });
+ label.hidden = (closedWindows.length == 0);
+
+ var listEnd = get_("end-separator");
+ for (item = separator.nextSibling.nextSibling; item != listEnd; item = separator.nextSibling.nextSibling)
+ {
+ aPopup.removeChild(item);
+ }
+
+ this.mClosedTabs.forEach(function(aTab, aIx) {
+ var menuitem = document.createElement("menuitem");
+ menuitem.setAttribute("label", aTab.name);
+ menuitem.setAttribute("oncommand", 'gSessionManager.undoCloseTab(' + aIx + ');');
+ aPopup.insertBefore(menuitem, listEnd);
+ });
+ separator.nextSibling.hidden = (this.mClosedTabs.length == 0);
+ separator.hidden = separator.nextSibling.hidden || label.hidden;
+
+ var showPopup = closedWindows.length + this.mClosedTabs.length > 0;
+
+ if (aStandAlone)
+ {
+ if (!showPopup)
+ {
+ this.updateToolbarButton(false);
+ setTimeout(function(aPopup) { aPopup.parentNode.open = false; }, 0, aPopup);
+ }
+ else
+ {
+ aPopup.style.visibility = "visible";
+ }
+ }
+
+ return showPopup;
+ },
+
+ uninitUndo: function(aPopup)
+ {
+ aPopup.style.visibility = "";
+ },
+
+ undoCloseWindow: function(aIx, aMode)
+ {
+ var closedWindows = this.getClosedWindows();
+ if (closedWindows[aIx || 0])
+ {
+ var state = closedWindows.splice(aIx || 0, 1)[0].state;
+ this.storeClosedWindows(closedWindows);
+
+ if (aMode == "overwrite")
+ {
+ this.mObserverService.notifyObservers(window, "crashrecovery:windowclosed", this.getSessionState(null, true));
+ }
+ else if (aMode == "append")
+ {
+ state = this.stripTabUndoData(state);
+ }
+
+ this.restoreSession((aMode == "overwrite" || aMode == "append")?window:null, state, aMode != "append");
+ }
+ },
+
+ undoCloseTab: function(aIx)
+ {
+ if (this.mClosedTabs[aIx || 0])
+ {
+ var tabData = this.mClosedTabs.splice(aIx || 0, 1)[0];
+ this.restoreSession(window, tabData.state);
+ if (this.mClosedTabs.length == 0)
+ {
+ this.updateToolbarButton();
+ }
+
+ var newTab = document.getAnonymousElementByAttribute(gBrowser, "linkedpanel", gBrowser.mPanelContainer.lastChild.id);
+ if (gBrowser.mTabs.length == 2 && !this.getPref("browser.tabs.autoHide", true, true) && this.isCleanBrowser(gBrowser.selectedBrowser))
+ {
+ gBrowser.removeTab(gBrowser.selectedTab);
+ }
+ if (tabData.pos && tabData.pos < gBrowser.mTabs.length)
+ {
+ gBrowser.moveTabTo(newTab, tabData.pos - 1);
+ }
+ gBrowser.selectedTab = newTab;
+ }
+ },
+
+ clearUndoList: function()
+ {
+ var max_tabs_undo = this.getPref("max_tabs_undo", 10);
+
+ this.setPref("max_tabs_undo", 0);
+ this.setPref("max_tabs_undo", max_tabs_undo);
+
+ this.clearUndoData("window");
+ },
+
+/* ........ User Prompts .............. */
+
+ prompt: function(aSessionLabel, aAcceptLabel, aValues, aTextLabel, aAcceptExistingLabel)
+ {
+ var params = Components.classes["@mozilla.org/embedcomp/dialogparam;1"].createInstance(Components.interfaces.nsIDialogParamBlock);
+ aValues = aValues || {};
+
+ params.SetNumberStrings(7);
+ params.SetString(1, aSessionLabel);
+ params.SetString(2, aAcceptLabel);
+ params.SetString(3, aValues.name || "");
+ params.SetString(4, aTextLabel || "");
+ params.SetString(5, aAcceptExistingLabel || "");
+ params.SetString(6, aValues.text || "");
+ params.SetInt(1, ((aValues.addCurrentSession)?1:0) | ((aValues.multiSelect)?2:0) | ((aValues.ignorable)?4:0) | ((aValues.allowNamedReplace)?256:0));
+
+ this.openWindow("chrome://sessionmanager/content/session_prompt.xul", "chrome,modal,centerscreen,titlebar,resizable", params, (this.mFullyLoaded)?window:null);
+
+ aValues.name = params.GetString(3);
+ aValues.text = params.GetString(6);
+ aValues.ignore = params.GetInt(1);
+
+ return !params.GetInt(0);
+ },
+
+ selectSession: function(aSessionLabel, aAcceptLabel, aValues)
+ {
+ var values = aValues || {};
+
+ if (this.prompt(aSessionLabel, aAcceptLabel, values))
+ {
+ return values.name;
+ }
+
+ return null;
+ },
+
+ ioError: function(aException)
+ {
+ this.mPromptService.alert(window, this.mTitle, (this.mBundle)?this.mBundle.getFormattedString("io_error", [(aException)?aException.message:this._string("unknown_error")]):aException);
+ },
+
+ openWindow: function(aChromeURL, aFeatures, aArgument, aParent)
+ {
+ if (!aArgument || typeof aArgument == "string")
+ {
+ var argString = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
+ argString.data = aArgument || "";
+ aArgument = argString;
+ }
+
+ return Components.classes["@mozilla.org/embedcomp/window-watcher;1"].getService(Components.interfaces.nsIWindowWatcher).openWindow(aParent || null, aChromeURL, "_blank", aFeatures, aArgument);
+ },
+
+ clearUndoListPrompt: function()
+ {
+ if (this.mPromptService.confirm(window, this.mTitle, this._string("clear_list_prompt")))
+ {
+ this.clearUndoList();
+ }
+ },
+
+/* ........ File Handling .............. */
+
+ getProfileFile: function(aFileName)
+ {
+ var file = this.mProfileDirectory.clone();
+ file.append(aFileName);
+ return file;
+ },
+
+ getSessionDir: function(aFileName, aUnique)
+ {
+ var dir = this.getProfileFile("sessions");
+ if (!dir.exists())
+ {
+ dir.create(this.mComponents.interfaces.nsIFile.DIRECTORY_TYPE, 0700);
+ }
+ if (aFileName)
+ {
+ dir.append(aFileName);
+ if (aUnique)
+ {
+ var postfix = 1, ext = "";
+ if (aFileName.slice(-this.mSessionExt.length) == this.mSessionExt)
+ {
+ aFileName = aFileName.slice(0, -this.mSessionExt.length);
+ ext = this.mSessionExt;
+ }
+ while (dir.exists())
+ {
+ dir = dir.parent;
+ dir.append(aFileName + "-" + (++postfix) + ext);
+ }
+ }
+ }
+ return dir.QueryInterface(this.mComponents.interfaces.nsILocalFile);
+ },
+
+ getSessions: function()
+ {
+ var sessions = [];
+
+ var filesEnum = this.getSessionDir().directoryEntries.QueryInterface(this.mComponents.interfaces.nsISimpleEnumerator);
+ while (filesEnum.hasMoreElements())
+ {
+ var file = filesEnum.getNext().QueryInterface(this.mComponents.interfaces.nsIFile);
+ var fileName = file.leafName;
+ var cached = this.mSessionCache[fileName] || null;
+ if (cached && cached.time == file.lastModifiedTime)
+ {
+ sessions.push({ fileName: fileName, name: cached.name, timestamp: cached.timestamp });
+ continue;
+ }
+ if (/^\[SessionManager\]\n(?:name=(.*)\n)?(?:timestamp=(\d+))?/m.test(this.readSessionFile(file)))
+ {
+ var timestamp = parseInt(RegExp.$2) || file.lastModifiedTime;
+ sessions.push({ fileName: fileName, name: RegExp.$1, timestamp: timestamp });
+ this.mSessionCache[fileName] = { name: RegExp.$1, timestamp: timestamp, time: file.lastModifiedTime };
+ }
+ }
+
+ if (!this.mPref_session_list_order)
+ {
+ this.mPref_session_list_order = this.getPref("session_list_order", 1);
+ }
+ switch (Math.abs(this.mPref_session_list_order))
+ {
+ case 1: // alphabetically
+ sessions = sessions.sort(function(a, b) { return a.name.toLowerCase().localeCompare(b.name.toLowerCase()); });
+ break;
+ case 2: // chronologically
+ sessions = sessions.sort(function(a, b) { return a.timestamp - b.timestamp; });
+ break;
+ }
+
+ return (this.mPref_session_list_order < 0)?sessions.reverse():sessions;
+ },
+
+ getClosedWindows: function()
+ {
+ var data = this.readFile(this.getProfileFile(this.mClosedWindowFile));
+ return (data)?data.split("\n\n").map(function(aEntry) {
+ var parts = aEntry.split("\n");
+ return { name: parts.shift(), state: parts.join("\n") };
+ }):[];
+ },
+
+ storeClosedWindows: function(aList)
+ {
+ this.writeFile(this.getProfileFile(this.mClosedWindowFile), aList.map(function(aEntry) {
+ return aEntry.name + "\n" + aEntry.state;
+ }).join("\n\n"));
+
+ this.updateToolbarButton(aList.length + this.mClosedTabs.length > 0);
+ },
+
+ appendClosedWindow: function(aState)
+ {
+ if (this.mPref_max_closed_undo == 0 || Array.every(gBrowser.browsers, this.isCleanBrowser))
+ {
+ return;
+ }
+
+ var name = content.document.title || ((gBrowser.currentURI.spec != "about:blank")?gBrowser.currentURI.spec:this._string("untitled_window"));
+ var windows = this.getClosedWindows();
+
+ aState = aState.replace(/^\n+|\n+$/g, "").replace(/\n{2,}/g, "\n");
+ windows.unshift({ name: name, state: aState });
+ this.storeClosedWindows(windows.slice(0, this.mPref_max_closed_undo));
+ },
+
+ clearUndoData: function(aType, aSilent)
+ {
+ if (aType == "window" || aType == "all")
+ {
+ this.delFile(this.getProfileFile(this.mClosedWindowFile), aSilent);
+ }
+ if (aType == "tab" || aType == "all")
+ {
+ this.mClosedTabs = [];
+ }
+ if ((aType == "tab" || aType == "datatab" || aType == "all") && this.mDataTab)
+ {
+ this.mDataTab.removeAttribute(this.mDataTabAttribute);
+ this.mDataTab = null;
+ }
+ this.updateToolbarButton((aType == "all")?false:undefined);
+ },
+
+ backupCurrentSession: function()
+ {
+ var backup = this.getPref("backup_session", 1);
+ if (backup == 2 && !this.mPref__resume_session_once)
+ {
+ backup = (this.mPromptService.confirmEx(null, this.mTitle, this._string_preserve_session || this._string("preserve_session"), this.mPromptService.BUTTON_TITLE_YES * this.mPromptService.BUTTON_POS_0 + this.mPromptService.BUTTON_TITLE_NO * this.mPromptService.BUTTON_POS_1, null, null, null, null, {}) == 1)?-1:1;
+ }
+ if (backup > 0)
+ {
+ this.keepOldBackups();
+ try
+ {
+ var state = this.getSessionState(this._string_backup_session || this._string("backup_session"));
+ this.writeFile(this.getSessionDir(this.mBackupSessionName), state);
+ }
+ catch (ex)
+ {
+ this.ioError(ex);
+ }
+ }
+ else
+ {
+ this.setPref("_resume_session", this.doResumeCurrent());
+ this.setResumeCurrent(false);
+ this.delFile(this.getProfileFile("crashrecovery.dat"), true);
+ this.delFile(this.getProfileFile("crashrecovery.bak"), true);
+ this.delFile(this.getSessionDir(this.mBackupSessionName), true);
+ this.keepOldBackups();
+ }
+ },
+
+ keepOldBackups: function()
+ {
+ var backup = this.getSessionDir(this.mBackupSessionName);
+ if (backup.exists() && this.mPref_max_backup_keep)
+ {
+ var oldBackup = this.getSessionDir(this.mBackupSessionName, true);
+ var name = this.getFormattedName("", new Date(), this._string_old_backup_session || this._string("old_backup_session"));
+ this.writeFile(oldBackup, this.nameState(this.readSessionFile(backup), name));
+ }
+
+ if (this.mPref_max_backup_keep != -1)
+ {
+ this.getSessions().filter(function(aSession) {
+ return /^backup-\d+\.session$/.test(aSession.fileName);
+ }).sort(function(a, b) {
+ return b.timestamp - a.timestamp;
+ }).slice(this.mPref_max_backup_keep).forEach(function(aSession) {
+ this.delFile(this.getSessionDir(aSession.fileName), true);
+ }, this);
+ }
+ },
+
+ readSessionFile: function(aFile)
+ {
+ var state = this.readFile(aFile);
+
+ if (/^-?\d+.*~~~~/.test(state)) // old file format
+ {
+ if ("@mozilla.org/extensions/manager;1" in Components.classes)
+ {
+ var GUID = "{1280606b-2510-4fe0-97ef-9b5a22eafe30}";
+ var component = Components.classes["@mozilla.org/extensions/manager;1"].getService(Components.interfaces.nsIExtensionManager).getInstallLocation(GUID).getItemFile(GUID, "components/crashrecovery.js");
+ }
+ else // SeaMonkey
+ {
+ component = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ComsD", Components.interfaces.nsILocalFile);
+ component.append("crashrecovery.js");
+ }
+ var context = {};
+
+ Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader).loadSubScript(this.mIOService.getProtocolHandler("file").QueryInterface(Components.interfaces.nsIFileProtocolHandler).getURLSpecFromFile(component), context);
+
+ state = state.replace(/^(.*? ~~~~)( .*)?/, "$1");
+ var name = RegExp.$2.substr(1) || this._string("untitled_window");
+ state = context.encodeINI(context.CR_ini_decodeOldFormat(state));
+ state = this.nameState(state.replace(/\n\[/g, "\n$&") + "\n", name);
+
+ this.writeFile(aFile, state);
+ }
+
+ return state;
+ },
+
+ readFile: function(aFile)
+ {
+ try
+ {
+ var stream = this.mComponents.classes["@mozilla.org/network/file-input-stream;1"].createInstance(this.mComponents.interfaces.nsIFileInputStream);
+ stream.init(aFile, 0x01, 0, 0);
+ var cvstream = this.mComponents.classes["@mozilla.org/intl/converter-input-stream;1"].createInstance(this.mComponents.interfaces.nsIConverterInputStream);
+ cvstream.init(stream, "UTF-8", 1024, this.mComponents.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+
+ var content = "";
+ var data = {};
+ while (cvstream.readString(4096, data))
+ {
+ content += data.value;
+ }
+ cvstream.close();
+
+ return content.replace(/\r\n?/g, "\n");
+ }
+ catch (ex) { }
+
+ return null;
+ },
+
+ writeFile: function(aFile, aData)
+ {
+ var stream = this.mComponents.classes["@mozilla.org/network/file-output-stream;1"].createInstance(this.mComponents.interfaces.nsIFileOutputStream);
+ stream.init(aFile, 0x02 | 0x08 | 0x20, 0600, 0);
+ var cvstream = this.mComponents.classes["@mozilla.org/intl/converter-output-stream;1"].createInstance(this.mComponents.interfaces.nsIConverterOutputStream);
+ cvstream.init(stream, "UTF-8", 0, this.mComponents.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+
+ cvstream.writeString(aData.replace(/\n/g, this.mEOL));
+ cvstream.flush();
+ cvstream.close();
+ },
+
+ delFile: function(aFile, aSilent)
+ {
+ if (aFile.exists())
+ {
+ try
+ {
+ aFile.remove(false);
+ }
+ catch (ex)
+ {
+ if (!aSilent)
+ {
+ this.ioError(ex);
+ }
+ }
+ }
+ },
+
+/* ........ Preference Access .............. */
+
+ getPref: function(aName, aDefault, aUseRootBranch)
+ {
+ var pb = (aUseRootBranch)?this.mPrefRoot:this.mPrefBranch;
+ switch (pb.getPrefType(aName))
+ {
+ case pb.PREF_STRING:
+ return pb.getCharPref(aName);
+ case pb.PREF_BOOL:
+ return pb.getBoolPref(aName);
+ case pb.PREF_INT:
+ return pb.getIntPref(aName);
+ default:
+ return aDefault;
+ }
+ },
+
+ setPref: function(aName, aValue, aUseRootBranch)
+ {
+ var pb = (aUseRootBranch)?this.mPrefRoot:this.mPrefBranch;
+ switch (typeof aValue)
+ {
+ case "boolean":
+ pb.setBoolPref(aName, aValue);
+ break;
+ case "number":
+ pb.setIntPref(aName, parseInt(aValue));
+ break;
+ default:
+ pb.setCharPref(aName, "" + aValue);
+ break;
+ }
+ },
+
+ delPref: function(aName, aUseRootBranch)
+ {
+ ((aUseRootBranch)?this.mPrefRoot:this.mPrefBranch).deleteBranch(aName);
+ },
+
+/* ........ Miscellaneous Enhancements .............. */
+
+ recoverSession: function()
+ {
+ var recovering = this.getPref("_recovering");
+ var recoverOnly = recovering || this.mPref__running && !this.getPref("_hibernating") || this.doResumeCurrent() || this.getPref("_resume_session_once");
+ if (recovering)
+ {
+ this.delPref("_recovering");
+ this.load(recovering, "startup");
+ }
+ else if (!recoverOnly && this.mPref_resume_session && this.getSessions().length > 0)
+ {
+ var values = { ignorable: true };
+ var session = (this.mPref_resume_session == this.mPromptSessionName)?this.selectSession(this._string("resume_session"), this._string("resume_session_ok"), values):this.mPref_resume_session;
+ if (session && this.getSessionDir(session).exists())
+ {
+ this.load(session, "startup");
+ }
+ if (values.ignore)
+ {
+ this.setPref("resume_session", session || "");
+ }
+ }
+ this.delPref("_hibernating");
+ this.delPref("_resume_session_once");
+ },
+
+ isCmdLineEmpty: function()
+ {
+ var homepage = null;
+
+ switch (this.getPref("browser.startup.page", 1, true))
+ {
+ case 0:
+ homepage = "about:blank";
+ break;
+ case 1:
+ try
+ {
+ homepage = this.mPrefRoot.getComplexValue("browser.startup.homepage", Components.interfaces.nsIPrefLocalizedString).data;
+ }
+ catch (ex)
+ {
+ homepage = this.getPref("browser.startup.homepage", "", true);
+ }
+ break;
+ }
+ if (window.arguments.length > 0 && window.arguments[0].split("\n")[0] == homepage)
+ {
+ window.arguments.shift();
+ }
+
+ return (window.arguments.length == 0);
+ },
+
+ patchTabBrowser: function()
+ {
+ eval("gBrowser.removeTab = " + gBrowser.removeTab.toString().replace(/\{/, '$& var $$SM_event = document.createEvent("Events"); $$SM_event.initEvent("SMTabClosing", true, false); ((aTab.localName != "tab")?this.mCurrentTab:aTab).dispatchEvent($$SM_event);'));
+
+ if (!gBrowser.undoRemoveTab) // tweak for Tab Clicking Options
+ {
+ gBrowser.undoRemoveTab = function() { gSessionManager.undoCloseTab(); };
+ }
+ },
+
+ updateToolbarButton: function(aEnable)
+ {
+ var button = (document)?document.getElementById("sessionmanager-undo"):null;
+ if (button)
+ {
+ this.setDisabled(button, (aEnable != undefined)?!aEnable:this.mClosedTabs.length == 0 && this.getClosedWindows().length == 0);
+ }
+ },
+
+ appendClosedTab: function(aState, aPosition, aTitle, aNewDataTab)
+ {
+ var oneTabRE = /\n\[Window(1\.Tab\d+)\]\n[\s\S]*?(?=\n\[Window(?!\1)|$)/;
+ var tabData = aState.substr(aState.indexOf("\n[Window1.Tab" + aPosition + "]")).match(oneTabRE)[0].replace(/^(\[Window1\.Tab)\d+/gm, "$11");
+
+ this.mClosedTabs.unshift({ name: aTitle, pos: aPosition, state: tabData });
+ this.mClosedTabs.splice(this.mPref_max_tabs_undo);
+
+ this.persistClosedTabList(aNewDataTab);
+ this.updateToolbarButton(true);
+ },
+
+ persistClosedTabList: function(aNewDataTab)
+ {
+ if (!this.mDataTab && this.mPref_save_closed_tabs)
+ {
+ this.mDataTab = aNewDataTab || gBrowser.selectedTab;
+ }
+ if (this.mDataTab)
+ {
+ var serializedTabs = this.mClosedTabs.map(function(aTabData) {
+ return aTabData.pos + " " + aTabData.name + "\n" + aTabData.state;
+ }).join("\f\f");
+ this.mDataTab.setAttribute(this.mDataTabAttribute, serializedTabs);
+ }
+ },
+
+/* ........ Auxiliary Functions .............. */
+
+ getSessionState: function(aName, aOneWindow, aNoUndoData)
+ {
+ var state = (aOneWindow)?this.mCrashRecoveryService.getWindowState(window):this.mCrashRecoveryService.getCurrentState();
+
+ if (aNoUndoData)
+ {
+ state = this.stripTabUndoData(state);
+ }
+
+ return (aName != null)?this.nameState(("[SessionManager]\nname=" + (new Date()).toString() + "\ntimestamp=" + Date.now() + "\n" + state + "\n").replace(/\n\[/g, "\n$&"), aName || ""):state;
+ },
+
+ restoreSession: function(aWindow, aState, aReplaceTabs, aAllowReload)
+ {
+ if (!aWindow)
+ {
+ aWindow = this.openWindow(this.getPref("browser.chromeURL", null, true), "chrome,dialog=no,all");
+ aWindow.__SM_restore = function() {
+ this.removeEventListener("load", this.__SM_restore, true);
+ this.gSessionManager.restoreSession(this, aState, aReplaceTabs, aAllowReload);
+ delete this.__SM_restore;
+ };
+ aWindow.addEventListener("load", aWindow.__SM_restore, true);
+ return;
+ }
+
+ if (aReplaceTabs)
+ {
+ this.clearUndoData("tab");
+
+ if (aState.indexOf("\n[Window2]\n") == -1 && this.getBrowserWindows().length < 2)
+ {
+ aState = aState.replace(/^(\[Window1\]\n([^\[\s].*\n)*)hidden=.*\n/m, "$1");
+ }
+ }
+ this._allowReload = aAllowReload;
+ this._ignoreRemovedTabs = true;
+ this.mCrashRecoveryService.restoreWindow(aWindow || window, aState, aReplaceTabs || false);
+ this._ignoreRemovedTabs = false;
+ },
+
+ nameState: function(aState, aName)
+ {
+ if (!/^\[SessionManager\]/m.test(aState))
+ {
+ return "[SessionManager]\nname=" + aName + "\n\n" + aState;
+ }
+ return aState.replace(/^(\[SessionManager\])(?:\nname=.*)?/m, function($0, $1) { return $1 + "\nname=" + aName; });
+ },
+
+ stripTabUndoData: function(aState)
+ {
+ return aState.replace(new RegExp("^(xultab=)((?:\\S+ )*)" + this.mDataTabAttribute + "=\\S+( )?", "gm"), function($0, $1, $2, $3) { return $1 + ($2 + $3).slice(0, -1); });
+ },
+
+ getFormattedName: function(aTitle, aDate, aFormat)
+ {
+ function cut(aString, aLength)
+ {
+ return aString.replace(new RegExp("^(.{" + (aLength - 3) + "}).{4,}$"), "$1...");
+ }
+ function toISO8601(aDate)
+ {
+ return [aDate.getFullYear(), pad2(aDate.getMonth() + 1), pad2(aDate.getDate())].join("-");
+ }
+ function pad2(a) { return (a < 10)?"0" + a:a; }
+
+ return (aFormat || this.mPref_name_format).split("%%").map(function(aPiece) {
+ return aPiece.replace(/%(\d*)([tdm])/g, function($0, $1, $2) {
+ $0 = ($2 == "t")?aTitle:($2 == "d")?toISO8601(aDate):pad2(aDate.getHours()) + ":" + pad2(aDate.getMinutes());
+ return ($1)?cut($0, Math.max(parseInt($1), 3)):$0;
+ });
+ }).join("%");
+ },
+
+ makeFileName: function(aString)
+ {
+ return aString.replace(/[^\w ',;!()@&*+=~\x80-\xFE-]/g, "_").substr(0, 64) + this.mSessionExt;
+ },
+
+ getBrowserWindows: function()
+ {
+ var windowsEnum = this.mWindowMediator.getEnumerator("navigator:browser");
+ var windows = [];
+
+ while (windowsEnum.hasMoreElements())
+ {
+ windows.push(windowsEnum.getNext());
+ }
+
+ return windows;
+ },
+
+ doResumeCurrent: function(aOnce)
+ {
+ return this.getPref("extensions.crashrecovery.resume_session" + ((aOnce)?"_once":""), false, true);
+ },
+
+ setResumeCurrent: function(aValue)
+ {
+ this.setPref("extensions.crashrecovery.resume_session", aValue, true);
+ },
+
+ isCleanBrowser: function(aBrowser)
+ {
+ return aBrowser.sessionHistory.count < 2 && aBrowser.currentURI.spec == "about:blank";
+ },
+
+ setDisabled: function(aObj, aValue)
+ {
+ if (aValue)
+ {
+ aObj.setAttribute("disabled", "true");
+ }
+ else
+ {
+ aObj.removeAttribute("disabled");
+ }
+ },
+
+ getEOL: function()
+ {
+ return /win|os[\/_]?2/i.test(navigator.platform)?"\r\n":/mac/i.test(navigator.platform)?"\r":"\n";
+ },
+
+ _string: function(aName)
+ {
+ return this.mBundle.getString(aName);
+ }
+};
+
+window.addEventListener("load", gSessionManager.onLoad_proxy, false);
+window.addEventListener("unload", gSessionManager.onUnload_proxy, false);
+
+window.addEventListener("load", function() {
+ if (!window.SessionManager) // if Tab Mix Plus isn't installed
+ {
+ window.SessionManager = gSessionManager;
+ }
+ if (typeof tabBarScrollStatus == "function") // hack for some Tab Mix Plus startup issue
+ {
+ setTimeout(tabBarScrollStatus, 0);
+ }
+}, false);
diff --git a/xpfe/global/resources/content/extensions/sessionmanager/sessionmanager.xul b/xpfe/global/resources/content/extensions/sessionmanager/sessionmanager.xul
new file mode 100644
index 00000000..d8554031
--- /dev/null
+++ b/xpfe/global/resources/content/extensions/sessionmanager/sessionmanager.xul
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xpfe/global/resources/content/extensions/sessionmanager/skin/contents.rdf b/xpfe/global/resources/content/extensions/sessionmanager/skin/contents.rdf
new file mode 100644
index 00000000..ecaa8c37
--- /dev/null
+++ b/xpfe/global/resources/content/extensions/sessionmanager/skin/contents.rdf
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xpfe/global/resources/content/extensions/sessionmanager/skin/dougeeebear.png b/xpfe/global/resources/content/extensions/sessionmanager/skin/dougeeebear.png
new file mode 100644
index 00000000..4cb39912
Binary files /dev/null and b/xpfe/global/resources/content/extensions/sessionmanager/skin/dougeeebear.png differ
diff --git a/xpfe/global/resources/content/extensions/sessionmanager/skin/icon.png b/xpfe/global/resources/content/extensions/sessionmanager/skin/icon.png
new file mode 100644
index 00000000..df9366c1
Binary files /dev/null and b/xpfe/global/resources/content/extensions/sessionmanager/skin/icon.png differ
diff --git a/xpfe/global/resources/content/extensions/sessionmanager/skin/sessionmanager.css b/xpfe/global/resources/content/extensions/sessionmanager/skin/sessionmanager.css
new file mode 100644
index 00000000..956b7fb8
--- /dev/null
+++ b/xpfe/global/resources/content/extensions/sessionmanager/skin/sessionmanager.css
@@ -0,0 +1,46 @@
+#sessionmanager-menu menuitem[_id="windows"],
+#sessionmanager-toolbar menuitem[_id="windows"],
+#sessionmanager-undo menuitem[_id="windows"],
+#sessionmanager-menu menuitem[_id="tabs"],
+#sessionmanager-toolbar menuitem[_id="tabs"],
+#sessionmanager-undo menuitem[_id="tabs"] {
+ font-size: 80%;
+}
+
+#sessionmanager-menu menuitem[marked="true"],
+#sessionmanager-toolbar menuitem[marked="true"] {
+ font-weight: bold;
+}
+
+#sessionmanager-toolbar,
+#sessionmanager-undo {
+ list-style-image: url("chrome://global/content/extensions/sessionmanager/skin/toolbar.png");
+}
+
+#sessionmanager-toolbar {
+ -moz-image-region: rect(0px, 24px, 24px, 0px);
+}
+#sessionmanager-undo {
+ -moz-image-region: rect(0px, 48px, 24px, 24px);
+}
+#sessionmanager-undo[disabled="true"] {
+ -moz-image-region: rect(0px, 72px, 24px, 48px);
+}
+
+toolbar[iconsize="small"] #sessionmanager-toolbar {
+ -moz-image-region: rect(24px, 16px, 40px, 0px);
+}
+toolbar[iconsize="small"] #sessionmanager-undo {
+ -moz-image-region: rect(24px, 40px, 40px, 24px);
+}
+toolbar[iconsize="small"] #sessionmanager-undo[disabled="true"] {
+ -moz-image-region: rect(24px, 64px, 40px, 48px);
+}
+
+#sessionmanager-toolbar {
+ list-style-image: url("chrome://global/content/extensions/sessionmanager/skin/dougeeebear.png");
+ -moz-image-region: rect(8px, 56px, 32px, 32px);
+}
+toolbar[iconsize="small"] #sessionmanager-toolbar {
+ -moz-image-region: rect(15px, 72px, 31px, 56px);
+}
diff --git a/xpfe/global/resources/content/extensions/sessionmanager/skin/toolbar.png b/xpfe/global/resources/content/extensions/sessionmanager/skin/toolbar.png
new file mode 100644
index 00000000..af3aecc7
Binary files /dev/null and b/xpfe/global/resources/content/extensions/sessionmanager/skin/toolbar.png differ
diff --git a/xpfe/global/resources/content/extensions/sessionmanager/zzz_closewindow_hack.xul b/xpfe/global/resources/content/extensions/sessionmanager/zzz_closewindow_hack.xul
new file mode 100644
index 00000000..cce98f85
--- /dev/null
+++ b/xpfe/global/resources/content/extensions/sessionmanager/zzz_closewindow_hack.xul
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
diff --git a/xpfe/global/resources/locale/en-US/extensions/sessionmanager/contents.rdf b/xpfe/global/resources/locale/en-US/extensions/sessionmanager/contents.rdf
new file mode 100644
index 00000000..c077efe6
--- /dev/null
+++ b/xpfe/global/resources/locale/en-US/extensions/sessionmanager/contents.rdf
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xpfe/global/resources/locale/en-US/extensions/sessionmanager/options.dtd b/xpfe/global/resources/locale/en-US/extensions/sessionmanager/options.dtd
new file mode 100644
index 00000000..30617aac
--- /dev/null
+++ b/xpfe/global/resources/locale/en-US/extensions/sessionmanager/options.dtd
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xpfe/global/resources/locale/en-US/extensions/sessionmanager/sessionmanager.dtd b/xpfe/global/resources/locale/en-US/extensions/sessionmanager/sessionmanager.dtd
new file mode 100644
index 00000000..a9ac3b81
--- /dev/null
+++ b/xpfe/global/resources/locale/en-US/extensions/sessionmanager/sessionmanager.dtd
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/xpfe/global/resources/locale/en-US/extensions/sessionmanager/sessionmanager.properties b/xpfe/global/resources/locale/en-US/extensions/sessionmanager/sessionmanager.properties
new file mode 100644
index 00000000..e14cffb5
--- /dev/null
+++ b/xpfe/global/resources/locale/en-US/extensions/sessionmanager/sessionmanager.properties
@@ -0,0 +1,41 @@
+extensions.{1280606b-2510-4fe0-97ef-9b5a22eafe30}.description=Saves and restores the state of all windows.
+
+sessionManager = Session Manager
+
+save_session = Save the current browsing session as:
+save_window = Save the current window as:
+save2_session = Double-click an existing session to replace it:
+save_session_ok = Save Session
+save_window_ok = Save Window
+save_session_ok2 = Replace Session
+
+rename_session = Which session do you want to rename?
+rename2_session = Rename that session to:
+rename_session_ok = Rename
+
+remove_session = Which session(s) do you want to delete?
+remove_session_ok = Delete
+
+recover_session = Your current browsing session crashed. Which session do you want to recover?
+recover_session_ok = Recover Session
+
+resume_session = Which session do you want to resume?
+resume_session_ok = Resume Session
+
+preserve_session = Do you want to preserve this session for resuming?
+
+current_session = [ Current Browsing Session ]
+backup_session = [ Previous Browsing Session ]
+crashed_session = [ Crashed Session (%d %m) ]
+old_backup_session = [ Older Browsing Session (%d %m) ]
+
+startup_none = < None (load the homepage) >
+startup_prompt = < Prompt for a session >
+startup_resume = < Previous Browsing Session >
+
+untitled_window = (Untitled)
+
+clear_list_prompt = Do you really want to clear the list of recently closed windows and tabs?
+
+io_error = This operation failed due to a file access error:\n%S
+unknown_error = unknown error
diff --git a/xpinstall/packager/win_gre/config.ini b/xpinstall/packager/win_gre/config.ini
index 3b6fda68..125ddab6 100644
--- a/xpinstall/packager/win_gre/config.ini
+++ b/xpinstall/packager/win_gre/config.ini
@@ -142,7 +142,7 @@ Show Dialog=TRUE
;*** LOCALIZE ME BABY ***
Title=GRE Setup - Welcome
;*** LOCALIZE ME BABY ***
-Message0=Welcome to %s Setup. You are about to install %s version 1.0.0.0000000000.
+Message0=Welcome to %s Setup. You are about to install %s version 1.1.0.0000000000.
;*** LOCALIZE ME BABY ***
Message1=It is strongly recommended that you exit all Windows programs before running this Setup program.
;*** LOCALIZE ME BABY ***
@@ -655,7 +655,7 @@ Timing=post smartupdate
Root Key=HKEY_LOCAL_MACHINE
Key=[REGPATH]\Uninstall
Name=Description
-Name Value=GRE (1.0)
+Name Value=GRE (1.1)
Type=REG_SZ
Decrypt Key=TRUE
Decrypt Name=FALSE
diff --git a/xpinstall/packager/win_gre/gre.js b/xpinstall/packager/win_gre/gre.js
index 5b78dfc9..db97d4e5 100644
--- a/xpinstall/packager/win_gre/gre.js
+++ b/xpinstall/packager/win_gre/gre.js
@@ -191,7 +191,7 @@ function registerMainKeys(winreg)
subkey = regRootKey + "\\Uninstall";
winreg.createKey(subkey,"");
err = winreg.setValueString(subkey, "Uninstall Log Folder", fProgram + "Uninstall");
- err = winreg.setValueString(subkey, "Description", "GRE (1.0)");
+ err = winreg.setValueString(subkey, "Description", "GRE (1.1)");
}
// main
@@ -210,7 +210,7 @@ var regRootKey;
regRootKey = new String(Install.arguments);
srDest = 1;
-err = initInstall("GRE", "GRE", "1.0.0.0000000000");
+err = initInstall("GRE", "GRE", "1.1.0.0000000000");
logComment("initInstall: " + err);
fProgram = getFolder("Program");
diff --git a/xpinstall/packager/win_gre/xpcom.js b/xpinstall/packager/win_gre/xpcom.js
index 07a2b389..99b184d9 100644
--- a/xpinstall/packager/win_gre/xpcom.js
+++ b/xpinstall/packager/win_gre/xpcom.js
@@ -116,7 +116,7 @@ var fileMsvcrt;
var fileMsvcirt;
srDest = 1;
-err = initInstall("Mozilla XPCOM", "XPCOM", "1.0.0.0000000000");
+err = initInstall("Mozilla XPCOM", "XPCOM", "1.1.0.0000000000");
logComment("initInstall: " + err);
fProgram = getFolder("Program");
@@ -137,7 +137,7 @@ if(verifyDiskSpace(fProgram, srDest))
upgradeCleanup();
err = addDirectory("",
- "1.0.0.0000000000",
+ "1.1.0.0000000000",
"bin", // dir name in jar to extract
fProgram, // Where to put this file (Returned from GetFolder)
"", // subdir name to create relative to fProgram
@@ -156,7 +156,7 @@ if(verifyDiskSpace(fProgram, srDest))
{
logComment("File not found: " + fileMsvcrt);
addFile("/Microsoft/Shared/msvcrt.dll",
- "1.0.0.0000000000",
+ "1.1.0.0000000000",
"msvcrt.dll", // dir name in jar to extract
fWindowsSystem, // Where to put this file (Returned from getFolder)
"", // subdir name to create relative to fProgram
@@ -178,7 +178,7 @@ if(verifyDiskSpace(fProgram, srDest))
{
logComment("File not found: " + fileMsvcirt);
addFile("/Microsoft/Shared/msvcirt.dll",
- "1.0.0.0000000000",
+ "1.1.0.0000000000",
"msvcirt.dll", // dir name in jar to extract
fWindowsSystem, // Where to put this file (Returned from getFolder)
"", // subdir name to create relative to fProgram
diff --git a/xpinstall/packager/windows/browser.js b/xpinstall/packager/windows/browser.js
index dbc2c917..b215c002 100644
--- a/xpinstall/packager/windows/browser.js
+++ b/xpinstall/packager/windows/browser.js
@@ -105,12 +105,12 @@ function registerProgramFolderKey(winreg, fFolderPath)
subkey = "SOFTWARE\\RetroZilla\\RetroZilla";
winreg.createKey(subkey,"");
- err = winreg.setValueString(subkey, "CurrentVersion", "1.0 (en)");
+ err = winreg.setValueString(subkey, "CurrentVersion", "1.1 (en)");
- subkey = "SOFTWARE\\RetroZilla\\RetroZilla\\1.0 (en)";
+ subkey = "SOFTWARE\\RetroZilla\\RetroZilla\\1.1 (en)";
winreg.createKey(subkey,"");
- subkey = "SOFTWARE\\RetroZilla\\RetroZilla\\1.0 (en)\\Main";
+ subkey = "SOFTWARE\\RetroZilla\\RetroZilla\\1.1 (en)\\Main";
winreg.createKey(subkey,"");
err = winreg.setValueString(subkey, "Program Folder Path", fFolderPath);
}
@@ -219,7 +219,7 @@ function createShortcuts()
}
logComment("folderQuickLaunchExists: " + folderQuickLaunchExists);
- subkey = "SOFTWARE\\RetroZilla\\RetroZilla\\1.0 (en)\\Main";
+ subkey = "SOFTWARE\\RetroZilla\\RetroZilla\\1.1 (en)\\Main";
fFolderPathStr = winreg.getValueString(subkey, "Program Folder Path");
if((fFolderPathStr == "") || (fFolderPathStr == null))
{
@@ -293,7 +293,7 @@ function createShortcuts()
fileDelete(fFolderPath);
}
- subkey = "SOFTWARE\\RetroZilla\\RetroZilla\\1.0 (en)\\Setup";
+ subkey = "SOFTWARE\\RetroZilla\\RetroZilla\\1.1 (en)\\Setup";
regvalue = winreg.getValueString(subkey, "browserargs");
/* log this so if the user turns on turbo mode in the browser the uninstaller will undo it */
@@ -366,12 +366,12 @@ function registerMainKeys(winreg)
subkey = "SOFTWARE\\RetroZilla\\RetroZilla";
winreg.createKey(subkey,"");
- err = winreg.setValueString(subkey, "CurrentVersion", "1.0 (en)");
+ err = winreg.setValueString(subkey, "CurrentVersion", "1.1 (en)");
- subkey = "SOFTWARE\\RetroZilla\\RetroZilla\\1.0 (en)";
+ subkey = "SOFTWARE\\RetroZilla\\RetroZilla\\1.1 (en)";
winreg.createKey(subkey,"");
- subkey = "SOFTWARE\\RetroZilla\\RetroZilla\\1.0 (en)\\Main";
+ subkey = "SOFTWARE\\RetroZilla\\RetroZilla\\1.1 (en)\\Main";
winreg.createKey(subkey,"");
err = winreg.setValueString(subkey, "Install Directory", fProgram);
@@ -379,20 +379,20 @@ function registerMainKeys(winreg)
// The following keys are required to be created to supply information
// about the location of the Gecko Embedded Client to 3rd party apps.
// "SOFTWARE\\Mozilla" must not be localized!
- subkey = "SOFTWARE\\Mozilla\\RetroZilla 1.0";
+ subkey = "SOFTWARE\\Mozilla\\RetroZilla 1.1";
winreg.createKey(subkey,"");
err = winreg.setValueString(subkey, "GeckoVer", "$GreVersion$");
- subkey = "SOFTWARE\\Mozilla\\RetroZilla 1.0\\Extensions";
+ subkey = "SOFTWARE\\Mozilla\\RetroZilla 1.1\\Extensions";
winreg.createKey(subkey,"");
err = winreg.setValueString(subkey, "Components", fProgram + "Components");
err = winreg.setValueString(subkey, "Plugins", fProgram + "Plugins");
- subkey = "SOFTWARE\\Mozilla\\RetroZilla 1.0\\bin";
+ subkey = "SOFTWARE\\Mozilla\\RetroZilla 1.1\\bin";
winreg.createKey(subkey,"");
err = winreg.setValueString(subkey, "PathToExe", fProgram + "RetroZilla.exe");
- subkey = "SOFTWARE\\RetroZilla\\RetroZilla\\1.0 (en)\\Main";
+ subkey = "SOFTWARE\\RetroZilla\\RetroZilla\\1.1 (en)\\Main";
err = winreg.setValueString(subkey, "PathToExe", fProgram + "RetroZilla.exe");
// Register as a windows XP internet browser
@@ -416,7 +416,7 @@ function registerMainKeys(winreg)
data = "\"" + fProgram + "RetroZilla.exe\"";
winreg.setValueString(subkey + "\\shell\\open\\command", "", data);
- data = "\"" + fProgram + "uninstall\\retrozillaUninstall.exe\" /ua \"1.0 (en)\" /hs browser";
+ data = "\"" + fProgram + "uninstall\\retrozillaUninstall.exe\" /ua \"1.1 (en)\" /hs browser";
winreg.setValueString(subkey + "\\InstallInfo", "HideIconsCommand", data);
winreg.setValueNumber(subkey + "\\InstallInfo", "IconsVisible", 1);
@@ -424,7 +424,7 @@ function registerMainKeys(winreg)
data = "\"" + fProgram + "RetroZilla.exe\" -silent -nosplash -setDefaultBrowser ";
winreg.setValueString(subkey + "\\InstallInfo", "ReinstallCommand", data);
- data = "\"" + fProgram + "uninstall\\retrozillaUninstall.exe\" /ua \"1.0 (en)\" /ss browser";
+ data = "\"" + fProgram + "uninstall\\retrozillaUninstall.exe\" /ua \"1.1 (en)\" /ss browser";
winreg.setValueString(subkey + "\\InstallInfo", "ShowIconsCommand", data);
}
}
@@ -725,7 +725,7 @@ if(args == "-greLocal")
gGreLocal = true;
srDest = 1;
-err = initInstall("RetroZilla", "Browser", "1.0.0.0000000000");
+err = initInstall("RetroZilla", "Browser", "1.1.0.0000000000");
logComment("initInstall: " + err);
fProgram = getFolder("Program");
@@ -738,7 +738,7 @@ if(verifyDiskSpace(fProgram, srDest))
upgradeCleanup();
err = addDirectory("",
- "1.0.0.0000000000",
+ "1.1.0.0000000000",
"bin", // dir name in jar to extract
fProgram, // Where to put this file (Returned from GetFolder)
"", // subdir name to create relative to fProgram
@@ -830,7 +830,7 @@ if(verifyDiskSpace(fProgram, srDest))
if (! ('buildID' in Install))
{
logComment("Running Pre-Mozilla 0.9.1");
- initInstall("Post-install Cleanup Utility", "Browser/xpicleanup", "1.0.0.0000000000");
+ initInstall("Post-install Cleanup Utility", "Browser/xpicleanup", "1.1.0.0000000000");
cleanupUtility = getFolder(fProgram, "xpicleanup.exe");
err = File.execute(cleanupUtility);
logComment("execute() returned: " + err);
diff --git a/xpinstall/packager/windows/chatzilla.js b/xpinstall/packager/windows/chatzilla.js
index 89e922ba..4db1c409 100644
--- a/xpinstall/packager/windows/chatzilla.js
+++ b/xpinstall/packager/windows/chatzilla.js
@@ -95,7 +95,7 @@ function getPlatform()
return platformNode;
}
-var err = initInstall("Chatzilla v0.5", "Chatzilla", "1.0.0.0000000000");
+var err = initInstall("Chatzilla v0.5", "Chatzilla", "1.1.0.0000000000");
logComment("initInstall: " + err);
addFile("Chatzilla service",
diff --git a/xpinstall/packager/windows/config.ini b/xpinstall/packager/windows/config.ini
index 687ea1d0..5f271d7e 100644
--- a/xpinstall/packager/windows/config.ini
+++ b/xpinstall/packager/windows/config.ini
@@ -10,7 +10,7 @@ Run Mode=Normal
Company Name=RetroZilla
Product Name=RetroZilla
Product NameInternal=RetroZilla
-User Agent=1.0 (en)
+User Agent=1.1 (en)
; Destination Path values:
; PROGRAMFILESDIR
@@ -188,7 +188,7 @@ Show Dialog=TRUE
;*** LOCALIZE ME BABY ***
Title=RetroZilla Setup - Welcome
;*** LOCALIZE ME BABY ***
-Message0=Welcome to %s Setup. You are about to install %s version 1.0.0.0000000000.
+Message0=Welcome to %s Setup. You are about to install %s version 1.1.0.0000000000.
;*** LOCALIZE ME BABY ***
Message1=It is strongly recommended that you exit all Windows programs before running this Setup program.
;*** LOCALIZE ME BABY ***
@@ -618,7 +618,7 @@ Install Size System=1
Install Size Archive=1
Attributes=SELECTED|UNCOMPRESS|SUPERSEDE|LAUNCHAPP|INVISIBLE
;*** LOCALIZE ME BABY ***
-Parameter=-mmi -ms -app "RetroZilla 1.0 (en)" -app_path "[SETUP PATH]\RetroZilla.exe"
+Parameter=-mmi -ms -app "RetroZilla 1.1 (en)" -app_path "[SETUP PATH]\RetroZilla.exe"
SupersedeType=GRE
SupersedeWinReg0=HKEY_LOCAL_MACHINE\Software\mozilla.org\GRE
SupersedeVersion0=0.0.0.0
@@ -1025,7 +1025,7 @@ Timing=pre smartupdate
[Windows Registry2]
Root Key=HKEY_LOCAL_MACHINE
;*** LOCALIZE ME BABY ***
-Key=Software\RetroZilla\RetroZilla\1.0 (en)
+Key=Software\RetroZilla\RetroZilla\1.1 (en)
Name=
Name Value=
Type=REG_SZ
@@ -1039,7 +1039,7 @@ Timing=pre smartupdate
[Windows Registry3]
Root Key=HKEY_LOCAL_MACHINE
;*** LOCALIZE ME BABY ***
-Key=Software\RetroZilla\RetroZilla\1.0 (en)\Main
+Key=Software\RetroZilla\RetroZilla\1.1 (en)\Main
Name=Program Folder Path
Name Value=[Default Folder]
Type=REG_SZ
@@ -1053,9 +1053,9 @@ Timing=pre smartupdate
[Windows Registry4]
Root Key=HKEY_LOCAL_MACHINE
;*** LOCALIZE ME BABY ***
-Key=Software\RetroZilla\RetroZilla\1.0 (en)\Uninstall
+Key=Software\RetroZilla\RetroZilla\1.1 (en)\Uninstall
Name=Description
-Name Value=RetroZilla (1.0)
+Name Value=RetroZilla (1.1)
Type=REG_SZ
Decrypt Key=FALSE
Decrypt Name=FALSE
@@ -1067,7 +1067,7 @@ Timing=pre smartupdate
[Windows Registry5]
Root Key=HKEY_LOCAL_MACHINE
;*** LOCALIZE ME BABY ***
-Key=Software\RetroZilla\RetroZilla\1.0 (en)\Uninstall
+Key=Software\RetroZilla\RetroZilla\1.1 (en)\Uninstall
Name=Uninstall Log Folder
Name Value=[SETUP PATH]\uninstall
Type=REG_SZ
@@ -1109,7 +1109,7 @@ Timing=pre smartupdate
[Windows Registry8]
Root Key=HKEY_CURRENT_USER
;*** LOCALIZE ME BABY ***
-Key=Software\RetroZilla\RetroZilla\1.0 (en)
+Key=Software\RetroZilla\RetroZilla\1.1 (en)
Name=
Name Value=
Type=REG_SZ
@@ -1123,7 +1123,7 @@ Timing=pre smartupdate
[Windows Registry9]
Root Key=HKEY_CURRENT_USER
;*** LOCALIZE ME BABY ***
-Key=Software\RetroZilla\RetroZilla\1.0 (en)\Main
+Key=Software\RetroZilla\RetroZilla\1.1 (en)\Main
Name=Program Folder Path
Name Value=[Default Folder]
Type=REG_SZ
@@ -1137,9 +1137,9 @@ Timing=pre smartupdate
[Windows Registry10]
Root Key=HKEY_CURRENT_USER
;*** LOCALIZE ME BABY ***
-Key=Software\RetroZilla\RetroZilla\1.0 (en)\Uninstall
+Key=Software\RetroZilla\RetroZilla\1.1 (en)\Uninstall
Name=Description
-Name Value=RetroZilla (1.0)
+Name Value=RetroZilla (1.1)
Type=REG_SZ
Decrypt Key=FALSE
Decrypt Name=FALSE
@@ -1151,7 +1151,7 @@ Timing=pre smartupdate
[Windows Registry11]
Root Key=HKEY_CURRENT_USER
;*** LOCALIZE ME BABY ***
-Key=Software\RetroZilla\RetroZilla\1.0 (en)\Uninstall
+Key=Software\RetroZilla\RetroZilla\1.1 (en)\Uninstall
Name=Uninstall Log Folder
Name Value=[SETUP PATH]\uninstall
Type=REG_SZ
@@ -1164,9 +1164,9 @@ Timing=pre smartupdate
[Windows Registry12]
Root Key=HKEY_LOCAL_MACHINE
-Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\RetroZilla (1.0)
+Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\RetroZilla (1.1)
Name=DisplayName
-Name Value=RetroZilla (1.0)
+Name Value=RetroZilla (1.1)
Type=REG_SZ
Decrypt Key=FALSE
Decrypt Name=FALSE
@@ -1177,10 +1177,10 @@ Timing=post smartupdate
[Windows Registry13]
Root Key=HKEY_LOCAL_MACHINE
-Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\RetroZilla (1.0)
+Key=Software\Microsoft\Windows\CurrentVersion\Uninstall\RetroZilla (1.1)
Name=UninstallString
;*** LOCALIZE ME BABY ***
-Name Value=[WINDIR]\retrozillaUninstall.exe /ua "1.0 (en)"
+Name Value=[WINDIR]\retrozillaUninstall.exe /ua "1.1 (en)"
Type=REG_SZ
Decrypt Key=FALSE
Decrypt Name=FALSE
@@ -1208,12 +1208,12 @@ Timing=pre smartupdate
Reg Key Root0=HKEY_LOCAL_MACHINE
Product Name0=RetroZilla
Product Reg Key0=Software\RetroZilla\RetroZilla
-Current Version0=1.0 (en)
+Current Version0=1.1 (en)
Reg Key Root1=HKEY_CURRENT_USER
Product Name1=RetroZilla
Product Reg Key1=Software\RetroZilla\RetroZilla
-Current Version1=1.0 (en)
+Current Version1=1.1 (en)
@@ -1249,7 +1249,7 @@ Program Folder=[Default Folder]
[Program Folder0-Shortcut0]
File=[SETUP PATH]\uninstall\retrozillaUninstall.exe
-Arguments=/ua "1.0 (en)"
+Arguments=/ua "1.1 (en)"
Working Dir=[SETUP PATH]
Description=Uninstall RetroZilla
Icon Path=[SETUP PATH]\uninstall\retrozillaUninstall.exe
diff --git a/xpinstall/packager/windows/deflenus.js b/xpinstall/packager/windows/deflenus.js
index 49254bd5..b140ef97 100644
--- a/xpinstall/packager/windows/deflenus.js
+++ b/xpinstall/packager/windows/deflenus.js
@@ -106,7 +106,7 @@ var regName = "defaults/mozilla/en-US";
// --- END CHANGABLE STUFF ---
srDest = 1;
-err = initInstall(prettyName, regName, "1.0.0.0000000000");
+err = initInstall(prettyName, regName, "1.1.0.0000000000");
logComment("initInstall: " + err);
fProgram = getFolder("Program");
@@ -117,7 +117,7 @@ if(verifyDiskSpace(fProgram, srDest))
setPackageFolder(fProgram);
err = addDirectory("",
- "1.0.0.0000000000",
+ "1.1.0.0000000000",
"bin", // dir name in jar to extract
fProgram, // Where to put this file (Returned from GetFolder)
"", // subdir name to create relative to fProgram
diff --git a/xpinstall/packager/windows/inspector.js b/xpinstall/packager/windows/inspector.js
index 1ddf48db..375f5af1 100644
--- a/xpinstall/packager/windows/inspector.js
+++ b/xpinstall/packager/windows/inspector.js
@@ -95,13 +95,13 @@ function getPlatform()
return platformNode;
}
-var err = initInstall("DOM Inspector", "Inspector", "1.0.0.0000000000");
+var err = initInstall("DOM Inspector", "Inspector", "1.1.0.0000000000");
logComment("initInstall: " + err);
var fProgram = getFolder("Program");
logComment("fProgram: " + fProgram);
-err = addDirectory("", "1.0.0.0000000000", "bin", fProgram, "", true);
+err = addDirectory("", "1.1.0.0000000000", "bin", fProgram, "", true);
logComment("addDirectory: " + err);
addFile("Inspector Command Line Handler",
diff --git a/xpinstall/packager/windows/langenus.js b/xpinstall/packager/windows/langenus.js
index bdc2aa14..fbe42713 100644
--- a/xpinstall/packager/windows/langenus.js
+++ b/xpinstall/packager/windows/langenus.js
@@ -117,7 +117,7 @@ var platformName = langcode + "-" + platformNode + ".jar";
var localeName = "locale/" + chromeNode + "/";
srDest = 1;
-err = initInstall(prettyName, regName, "1.0.0.0000000000");
+err = initInstall(prettyName, regName, "1.1.0.0000000000");
logComment("initInstall: " + err);
fProgram = getFolder("Program");
diff --git a/xpinstall/packager/windows/mail.js b/xpinstall/packager/windows/mail.js
index 744777d9..e033d6c5 100644
--- a/xpinstall/packager/windows/mail.js
+++ b/xpinstall/packager/windows/mail.js
@@ -128,12 +128,12 @@ function registerProgramFolderKey(winreg, fFolderPath)
subkey = "SOFTWARE\\RetroZilla\\RetroZilla";
winreg.createKey(subkey,"");
- err = winreg.setValueString(subkey, "CurrentVersion", "1.0 (en)");
+ err = winreg.setValueString(subkey, "CurrentVersion", "1.1 (en)");
- subkey = "SOFTWARE\\RetroZilla\\RetroZilla\\1.0 (en)";
+ subkey = "SOFTWARE\\RetroZilla\\RetroZilla\\1.1 (en)";
winreg.createKey(subkey,"");
- subkey = "SOFTWARE\\RetroZilla\\RetroZilla\\1.0 (en)\\Main";
+ subkey = "SOFTWARE\\RetroZilla\\RetroZilla\\1.1 (en)\\Main";
winreg.createKey(subkey,"");
err = winreg.setValueString(subkey, "Program Folder Path", fFolderPath);
}
@@ -256,7 +256,7 @@ function createShortcuts()
}
logComment("folderQuickLaunchExists: " + folderQuickLaunchExists);
- subkey = "SOFTWARE\\RetroZilla\\RetroZilla\\1.0 (en)\\Main";
+ subkey = "SOFTWARE\\RetroZilla\\RetroZilla\\1.1 (en)\\Main";
fFolderPathStr = winreg.getValueString(subkey, "Program Folder Path");
if((fFolderPathStr == "") || (fFolderPathStr == null))
{
@@ -351,7 +351,7 @@ function createShortcuts()
data = "\"" + fProgram + "RetroZilla.exe\" -mail";
winreg.setValueString(subkey + "\\shell\\open\\command", "", data);
- data = "\"" + fProgram + "uninstall\\retrozillaUninstall.exe\" /ua \"1.0 (en)\" /hs mail";
+ data = "\"" + fProgram + "uninstall\\retrozillaUninstall.exe\" /ua \"1.1 (en)\" /hs mail";
winreg.setValueString(subkey + "\\InstallInfo", "HideIconsCommand", data);
// set this value to 0 because we're not creating the mail shortcuts yet.
@@ -360,7 +360,7 @@ function createShortcuts()
data = "\"" + fProgram + "RetroZilla.exe\" -silent -nosplash -setDefaultMail";
winreg.setValueString(subkey + "\\InstallInfo", "ReinstallCommand", data);
- data = "\"" + fProgram + "uninstall\\retrozillaUninstall.exe\" /ua \"1.0 (en)\" /ss mail";
+ data = "\"" + fProgram + "uninstall\\retrozillaUninstall.exe\" /ua \"1.1 (en)\" /ss mail";
winreg.setValueString(subkey + "\\InstallInfo", "ShowIconsCommand", data);
}
}
@@ -407,7 +407,7 @@ function updateMapi()
// uninstaller already has a special way to deal with restoring the
// appropriate previous Mapi32.dll.
addFile("",
- "1.0.0.0000000000",
+ "1.1.0.0000000000",
"bin/mozMapi32.dll", // file name in jar to extract
getFolder("Win System"), // Where to put this file (Returned from getFolder)
"Mapi32.dll", // new name when installed
@@ -473,7 +473,7 @@ var err;
var fProgram;
srDest = 1;
-err = initInstall("RetroZilla Mail", "Mail", "1.0.0.0000000000");
+err = initInstall("RetroZilla Mail", "Mail", "1.1.0.0000000000");
logComment("initInstall: " + err);
fProgram = getFolder("Program");
@@ -485,7 +485,7 @@ if(verifyDiskSpace(fProgram, srDest))
upgradeCleanup();
err = addDirectory("",
- "1.0.0.0000000000",
+ "1.1.0.0000000000",
"bin", // dir name in jar to extract
fProgram, // Where to put this file (Returned from GetFolder)
"", // subdir name to create relative to fProgram
diff --git a/xpinstall/packager/windows/regus.js b/xpinstall/packager/windows/regus.js
index a66b0999..96beca27 100644
--- a/xpinstall/packager/windows/regus.js
+++ b/xpinstall/packager/windows/regus.js
@@ -112,7 +112,7 @@ var chromeName = chromeNode + ".jar";
var localeName = "locale/" + chromeNode + "/";
srDest = 1;
-err = initInstall(prettyName, regName, "1.0.0.0000000000");
+err = initInstall(prettyName, regName, "1.1.0.0000000000");
logComment("initInstall: " + err);
if (platformNode == 'mac')
diff --git a/xpinstall/packager/windows/reporter.js b/xpinstall/packager/windows/reporter.js
index 1cbe4c38..1297bf05 100644
--- a/xpinstall/packager/windows/reporter.js
+++ b/xpinstall/packager/windows/reporter.js
@@ -95,7 +95,7 @@ function getPlatform()
return platformNode;
}
-var err = initInstall("Website Reporter", "Reporter", "1.0.0.0000000000");
+var err = initInstall("Website Reporter", "Reporter", "1.1.0.0000000000");
logComment("initInstall: " + err);
var fProgram = getFolder("Program");
@@ -104,7 +104,7 @@ var srDest = 1;
if (verifyDiskSpace(fProgram, srDest))
{
- err = addDirectory("", "1.0.0.0000000000", "bin", fProgram, "", true);
+ err = addDirectory("", "1.1.0.0000000000", "bin", fProgram, "", true);
logComment("addDirectory: " + err);
var jarFolder = getFolder("Chrome", "reporter.jar");
diff --git a/xpinstall/packager/windows/spellcheck.js b/xpinstall/packager/windows/spellcheck.js
index ecbed001..38beacf6 100644
--- a/xpinstall/packager/windows/spellcheck.js
+++ b/xpinstall/packager/windows/spellcheck.js
@@ -97,7 +97,7 @@ function getPlatform()
var srDest = 1;
-var err = initInstall("RetroZilla Myspell Spellchecker", "Spellchecker", "1.0.0.0000000000");
+var err = initInstall("RetroZilla Myspell Spellchecker", "Spellchecker", "1.1.0.0000000000");
logComment("initInstall: " + err);
fProgram = getFolder("Program");
@@ -108,7 +108,7 @@ if (verifyDiskSpace(fProgram, srDest))
setPackageFolder(fProgram);
addDirectory("Spellchecker",
- "1.0.0.0000000000",
+ "1.1.0.0000000000",
"bin",
fProgram,
"");
diff --git a/xpinstall/packager/windows/sroaming.js b/xpinstall/packager/windows/sroaming.js
index ee5ad5cc..8354c14d 100644
--- a/xpinstall/packager/windows/sroaming.js
+++ b/xpinstall/packager/windows/sroaming.js
@@ -95,13 +95,13 @@ function getPlatform()
return platformNode;
}
-var err = initInstall("SRoaming v0.1", "Roaming", "1.0.0.0000000000");
+var err = initInstall("SRoaming v0.1", "Roaming", "1.1.0.0000000000");
logComment("initInstall: " + err);
var fProgram = getFolder("Program");
logComment("fProgram: " + fProgram);
-err = addDirectory("", "1.0.0.0000000000", "bin", fProgram, "", true);
+err = addDirectory("", "1.1.0.0000000000", "bin", fProgram, "", true);
logComment("addDirectory: " + err);
addFile("SRoaming Chrome",
diff --git a/xpinstall/packager/windows/talkback.js b/xpinstall/packager/windows/talkback.js
index 46aa5847..763d4fa6 100644
--- a/xpinstall/packager/windows/talkback.js
+++ b/xpinstall/packager/windows/talkback.js
@@ -108,7 +108,7 @@ var err;
var communicatorFolder;
srDest = 1;
-err = initInstall("Quality Feedback Utility", "Quality Feedback Utility", "1.0.0.0000000000");
+err = initInstall("Quality Feedback Utility", "Quality Feedback Utility", "1.1.0.0000000000");
logComment("initInstall: " + err);
communicatorFolder = getFolder("Communicator");
@@ -120,7 +120,7 @@ if(verifyDiskSpace(communicatorFolder, srDest))
upgradeCleanup();
err = addDirectory("",
- "1.0.0.0000000000",
+ "1.1.0.0000000000",
"bin", // dir name in jar to extract
communicatorFolder, // Where to put this file (Returned from getFolder)
"", // subdir name to create relative to communicatorFolder
diff --git a/xpinstall/packager/windows/venkman.js b/xpinstall/packager/windows/venkman.js
index f50174e8..5f959661 100644
--- a/xpinstall/packager/windows/venkman.js
+++ b/xpinstall/packager/windows/venkman.js
@@ -95,7 +95,7 @@ function getPlatform()
return platformNode;
}
-var err = initInstall("JavaScript Debugger", "Venkman", "1.0.0.0000000000");
+var err = initInstall("JavaScript Debugger", "Venkman", "1.1.0.0000000000");
logComment("initInstall: " + err);
addFile("Venkman Service",
diff --git a/xpinstall/packager/windows/xpcom.js b/xpinstall/packager/windows/xpcom.js
index 07a2b389..99b184d9 100644
--- a/xpinstall/packager/windows/xpcom.js
+++ b/xpinstall/packager/windows/xpcom.js
@@ -116,7 +116,7 @@ var fileMsvcrt;
var fileMsvcirt;
srDest = 1;
-err = initInstall("Mozilla XPCOM", "XPCOM", "1.0.0.0000000000");
+err = initInstall("Mozilla XPCOM", "XPCOM", "1.1.0.0000000000");
logComment("initInstall: " + err);
fProgram = getFolder("Program");
@@ -137,7 +137,7 @@ if(verifyDiskSpace(fProgram, srDest))
upgradeCleanup();
err = addDirectory("",
- "1.0.0.0000000000",
+ "1.1.0.0000000000",
"bin", // dir name in jar to extract
fProgram, // Where to put this file (Returned from GetFolder)
"", // subdir name to create relative to fProgram
@@ -156,7 +156,7 @@ if(verifyDiskSpace(fProgram, srDest))
{
logComment("File not found: " + fileMsvcrt);
addFile("/Microsoft/Shared/msvcrt.dll",
- "1.0.0.0000000000",
+ "1.1.0.0000000000",
"msvcrt.dll", // dir name in jar to extract
fWindowsSystem, // Where to put this file (Returned from getFolder)
"", // subdir name to create relative to fProgram
@@ -178,7 +178,7 @@ if(verifyDiskSpace(fProgram, srDest))
{
logComment("File not found: " + fileMsvcirt);
addFile("/Microsoft/Shared/msvcirt.dll",
- "1.0.0.0000000000",
+ "1.1.0.0000000000",
"msvcirt.dll", // dir name in jar to extract
fWindowsSystem, // Where to put this file (Returned from getFolder)
"", // subdir name to create relative to fProgram