summaryrefslogtreecommitdiff
path: root/application/basilisk/components/sessionstore/SessionMigration.jsm
diff options
context:
space:
mode:
Diffstat (limited to 'application/basilisk/components/sessionstore/SessionMigration.jsm')
-rw-r--r--application/basilisk/components/sessionstore/SessionMigration.jsm106
1 files changed, 106 insertions, 0 deletions
diff --git a/application/basilisk/components/sessionstore/SessionMigration.jsm b/application/basilisk/components/sessionstore/SessionMigration.jsm
new file mode 100644
index 0000000000..1aa22f1a9d
--- /dev/null
+++ b/application/basilisk/components/sessionstore/SessionMigration.jsm
@@ -0,0 +1,106 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+this.EXPORTED_SYMBOLS = ["SessionMigration"];
+
+const Cu = Components.utils;
+Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
+Cu.import("resource://gre/modules/Task.jsm", this);
+Cu.import("resource://gre/modules/osfile.jsm", this);
+
+XPCOMUtils.defineLazyModuleGetter(this, "Utils",
+ "resource://gre/modules/sessionstore/Utils.jsm");
+
+// An encoder to UTF-8.
+XPCOMUtils.defineLazyGetter(this, "gEncoder", function () {
+ return new TextEncoder();
+});
+
+// A decoder.
+XPCOMUtils.defineLazyGetter(this, "gDecoder", function () {
+ return new TextDecoder();
+});
+
+var SessionMigrationInternal = {
+ /**
+ * Convert the original session restore state into a minimal state. It will
+ * only contain:
+ * - open windows
+ * - with tabs
+ * - with history entries with only title, url, triggeringPrincipal
+ * - with pinned state
+ * - with tab group info (hidden + group id)
+ * - with selected tab info
+ * - with selected window info
+ *
+ * The complete state is then wrapped into the "about:welcomeback" page as
+ * form field info to be restored when restoring the state.
+ */
+ convertState: function(aStateObj) {
+ let state = {
+ selectedWindow: aStateObj.selectedWindow,
+ _closedWindows: []
+ };
+ state.windows = aStateObj.windows.map(function(oldWin) {
+ var win = {extData: {}};
+ win.tabs = oldWin.tabs.map(function(oldTab) {
+ var tab = {};
+ // Keep only titles, urls and triggeringPrincipals for history entries
+ tab.entries = oldTab.entries.map(function(entry) {
+ return { url: entry.url,
+ triggeringPrincipal_base64: entry.triggeringPrincipal_base64,
+ title: entry.title };
+ });
+ tab.index = oldTab.index;
+ tab.hidden = oldTab.hidden;
+ tab.pinned = oldTab.pinned;
+ return tab;
+ });
+ win.selected = oldWin.selected;
+ win._closedTabs = [];
+ return win;
+ });
+ let url = "about:welcomeback";
+ let formdata = {id: {sessionData: state}, url};
+ let entry = { url, triggeringPrincipal_base64: Utils.SERIALIZED_SYSTEMPRINCIPAL };
+ return { windows: [{ tabs: [{ entries: [ entry ], formdata}]}]};
+ },
+ /**
+ * Asynchronously read session restore state (JSON) from a path
+ */
+ readState: function(aPath) {
+ return Task.spawn(function() {
+ let bytes = yield OS.File.read(aPath);
+ let text = gDecoder.decode(bytes);
+ let state = JSON.parse(text);
+ throw new Task.Result(state);
+ });
+ },
+ /**
+ * Asynchronously write session restore state as JSON to a path
+ */
+ writeState: function(aPath, aState) {
+ let bytes = gEncoder.encode(JSON.stringify(aState));
+ return OS.File.writeAtomic(aPath, bytes, {tmpPath: aPath + ".tmp"});
+ }
+}
+
+var SessionMigration = {
+ /**
+ * Migrate a limited set of session data from one path to another.
+ */
+ migrate: function(aFromPath, aToPath) {
+ return Task.spawn(function() {
+ let inState = yield SessionMigrationInternal.readState(aFromPath);
+ let outState = SessionMigrationInternal.convertState(inState);
+ // Unfortunately, we can't use SessionStore's own SessionFile to
+ // write out the data because it has a dependency on the profile dir
+ // being known. When the migration runs, there is no guarantee that
+ // that's true.
+ yield SessionMigrationInternal.writeState(aToPath, outState);
+ });
+ }
+};