mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-20 07:17:32 +09:00
Add Pale Moon
This commit is contained in:
parent
dcd9973243
commit
fe8028fa2e
1173 changed files with 143053 additions and 934 deletions
291
application/palemoon/components/sessionstore/nsSessionStartup.js
Normal file
291
application/palemoon/components/sessionstore/nsSessionStartup.js
Normal file
|
|
@ -0,0 +1,291 @@
|
|||
/* 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/. */
|
||||
|
||||
/**
|
||||
* Session Storage and Restoration
|
||||
*
|
||||
* Overview
|
||||
* This service reads user's session file at startup, and makes a determination
|
||||
* as to whether the session should be restored. It will restore the session
|
||||
* under the circumstances described below. If the auto-start Private Browsing
|
||||
* mode is active, however, the session is never restored.
|
||||
*
|
||||
* Crash Detection
|
||||
* The session file stores a session.state property, that
|
||||
* indicates whether the browser is currently running. When the browser shuts
|
||||
* down, the field is changed to "stopped". At startup, this field is read, and
|
||||
* if its value is "running", then it's assumed that the browser had previously
|
||||
* crashed, or at the very least that something bad happened, and that we should
|
||||
* restore the session.
|
||||
*
|
||||
* Forced Restarts
|
||||
* In the event that a restart is required due to application update or extension
|
||||
* installation, set the browser.sessionstore.resume_session_once pref to true,
|
||||
* and the session will be restored the next time the browser starts.
|
||||
*
|
||||
* Always Resume
|
||||
* This service will always resume the session if the integer pref
|
||||
* browser.startup.page is set to 3.
|
||||
*/
|
||||
|
||||
/* :::::::: Constants and Helpers ::::::::::::::: */
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
const Cu = Components.utils;
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Promise.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "_SessionFile",
|
||||
"resource:///modules/sessionstore/_SessionFile.jsm");
|
||||
|
||||
const STATE_RUNNING_STR = "running";
|
||||
|
||||
function debug(aMsg) {
|
||||
aMsg = ("SessionStartup: " + aMsg).replace(/\S{80}/g, "$&\n");
|
||||
Services.console.logStringMessage(aMsg);
|
||||
}
|
||||
|
||||
let gOnceInitializedDeferred = Promise.defer();
|
||||
|
||||
/* :::::::: The Service ::::::::::::::: */
|
||||
|
||||
function SessionStartup() {
|
||||
}
|
||||
|
||||
SessionStartup.prototype = {
|
||||
|
||||
// the state to restore at startup
|
||||
_initialState: null,
|
||||
_sessionType: Ci.nsISessionStartup.NO_SESSION,
|
||||
_initialized: false,
|
||||
|
||||
/* ........ Global Event Handlers .............. */
|
||||
|
||||
/**
|
||||
* Initialize the component
|
||||
*/
|
||||
init: function sss_init() {
|
||||
// do not need to initialize anything in auto-started private browsing sessions
|
||||
if (PrivateBrowsingUtils.permanentPrivateBrowsing) {
|
||||
this._initialized = true;
|
||||
gOnceInitializedDeferred.resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
_SessionFile.read().then(
|
||||
this._onSessionFileRead.bind(this)
|
||||
);
|
||||
},
|
||||
|
||||
// Wrap a string as a nsISupports
|
||||
_createSupportsString: function ssfi_createSupportsString(aData) {
|
||||
let string = Cc["@mozilla.org/supports-string;1"]
|
||||
.createInstance(Ci.nsISupportsString);
|
||||
string.data = aData;
|
||||
return string;
|
||||
},
|
||||
|
||||
_onSessionFileRead: function sss_onSessionFileRead(aStateString) {
|
||||
if (this._initialized) {
|
||||
// Initialization is complete, nothing else to do
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this._initialized = true;
|
||||
|
||||
// Let observers modify the state before it is used
|
||||
let supportsStateString = this._createSupportsString(aStateString);
|
||||
Services.obs.notifyObservers(supportsStateString, "sessionstore-state-read", "");
|
||||
aStateString = supportsStateString.data;
|
||||
|
||||
// No valid session found.
|
||||
if (!aStateString) {
|
||||
this._sessionType = Ci.nsISessionStartup.NO_SESSION;
|
||||
return;
|
||||
}
|
||||
|
||||
// parse the session state into a JS object
|
||||
// remove unneeded braces (added for compatibility with Firefox 2.0 and 3.0)
|
||||
if (aStateString.charAt(0) == '(')
|
||||
aStateString = aStateString.slice(1, -1);
|
||||
let corruptFile = false;
|
||||
try {
|
||||
this._initialState = JSON.parse(aStateString);
|
||||
}
|
||||
catch (ex) {
|
||||
debug("The session file contained un-parse-able JSON: " + ex);
|
||||
// This is not valid JSON, but this might still be valid JavaScript,
|
||||
// as used in FF2/FF3, so we need to eval.
|
||||
// evalInSandbox will throw if aStateString is not parse-able.
|
||||
try {
|
||||
var s = new Cu.Sandbox("about:blank", {sandboxName: 'nsSessionStartup'});
|
||||
this._initialState = Cu.evalInSandbox("(" + aStateString + ")", s);
|
||||
} catch(ex) {
|
||||
debug("The session file contained un-eval-able JSON: " + ex);
|
||||
corruptFile = true;
|
||||
}
|
||||
}
|
||||
let doResumeSessionOnce = Services.prefs.getBoolPref("browser.sessionstore.resume_session_once");
|
||||
let doResumeSession = doResumeSessionOnce ||
|
||||
Services.prefs.getIntPref("browser.startup.page") == 3;
|
||||
|
||||
// If this is a normal restore then throw away any previous session
|
||||
if (!doResumeSessionOnce)
|
||||
delete this._initialState.lastSessionState;
|
||||
|
||||
let resumeFromCrash = Services.prefs.getBoolPref("browser.sessionstore.resume_from_crash");
|
||||
let lastSessionCrashed =
|
||||
this._initialState && this._initialState.session &&
|
||||
this._initialState.session.state &&
|
||||
this._initialState.session.state == STATE_RUNNING_STR;
|
||||
|
||||
// set the startup type
|
||||
if (lastSessionCrashed && resumeFromCrash)
|
||||
this._sessionType = Ci.nsISessionStartup.RECOVER_SESSION;
|
||||
else if (!lastSessionCrashed && doResumeSession)
|
||||
this._sessionType = Ci.nsISessionStartup.RESUME_SESSION;
|
||||
else if (this._initialState)
|
||||
this._sessionType = Ci.nsISessionStartup.DEFER_SESSION;
|
||||
else
|
||||
this._initialState = null; // reset the state
|
||||
|
||||
Services.obs.addObserver(this, "sessionstore-windows-restored", true);
|
||||
|
||||
if (this._sessionType != Ci.nsISessionStartup.NO_SESSION)
|
||||
Services.obs.addObserver(this, "browser:purge-session-history", true);
|
||||
|
||||
} finally {
|
||||
// We're ready. Notify everyone else.
|
||||
Services.obs.notifyObservers(null, "sessionstore-state-finalized", "");
|
||||
gOnceInitializedDeferred.resolve();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle notifications
|
||||
*/
|
||||
observe: function sss_observe(aSubject, aTopic, aData) {
|
||||
switch (aTopic) {
|
||||
case "app-startup":
|
||||
Services.obs.addObserver(this, "final-ui-startup", true);
|
||||
Services.obs.addObserver(this, "quit-application", true);
|
||||
break;
|
||||
case "final-ui-startup":
|
||||
Services.obs.removeObserver(this, "final-ui-startup");
|
||||
Services.obs.removeObserver(this, "quit-application");
|
||||
this.init();
|
||||
break;
|
||||
case "quit-application":
|
||||
// no reason for initializing at this point (cf. bug 409115)
|
||||
Services.obs.removeObserver(this, "final-ui-startup");
|
||||
Services.obs.removeObserver(this, "quit-application");
|
||||
if (this._sessionType != Ci.nsISessionStartup.NO_SESSION)
|
||||
Services.obs.removeObserver(this, "browser:purge-session-history");
|
||||
break;
|
||||
case "sessionstore-windows-restored":
|
||||
Services.obs.removeObserver(this, "sessionstore-windows-restored");
|
||||
// free _initialState after nsSessionStore is done with it
|
||||
this._initialState = null;
|
||||
break;
|
||||
case "browser:purge-session-history":
|
||||
Services.obs.removeObserver(this, "browser:purge-session-history");
|
||||
// reset all state on sanitization
|
||||
this._sessionType = Ci.nsISessionStartup.NO_SESSION;
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/* ........ Public API ................*/
|
||||
|
||||
get onceInitialized() {
|
||||
return gOnceInitializedDeferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the session state as a jsval
|
||||
*/
|
||||
get state() {
|
||||
this._ensureInitialized();
|
||||
return this._initialState;
|
||||
},
|
||||
|
||||
/**
|
||||
* Determines whether there is a pending session restore and makes sure that
|
||||
* we're initialized before returning. If we're not yet this will read the
|
||||
* session file synchronously.
|
||||
* @returns bool
|
||||
*/
|
||||
doRestore: function sss_doRestore() {
|
||||
this._ensureInitialized();
|
||||
return this._willRestore();
|
||||
},
|
||||
|
||||
/**
|
||||
* Determines whether there is a pending session restore.
|
||||
* @returns bool
|
||||
*/
|
||||
_willRestore: function () {
|
||||
return this._sessionType == Ci.nsISessionStartup.RECOVER_SESSION ||
|
||||
this._sessionType == Ci.nsISessionStartup.RESUME_SESSION;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns whether we will restore a session that ends up replacing the
|
||||
* homepage. The browser uses this to not start loading the homepage if
|
||||
* we're going to stop its load anyway shortly after.
|
||||
*
|
||||
* This is meant to be an optimization for the average case that loading the
|
||||
* session file finishes before we may want to start loading the default
|
||||
* homepage. Should this be called before the session file has been read it
|
||||
* will just return false.
|
||||
*
|
||||
* @returns bool
|
||||
*/
|
||||
get willOverrideHomepage() {
|
||||
if (this._initialState && this._willRestore()) {
|
||||
let windows = this._initialState.windows || null;
|
||||
// If there are valid windows with not only pinned tabs, signal that we
|
||||
// will override the default homepage by restoring a session.
|
||||
return windows && windows.some(w => w.tabs.some(t => !t.pinned));
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the type of pending session store, if any.
|
||||
*/
|
||||
get sessionType() {
|
||||
this._ensureInitialized();
|
||||
return this._sessionType;
|
||||
},
|
||||
|
||||
// Ensure that initialization is complete.
|
||||
// If initialization is not complete yet, fall back to a synchronous
|
||||
// initialization and kill ongoing asynchronous initialization
|
||||
_ensureInitialized: function sss__ensureInitialized() {
|
||||
try {
|
||||
if (this._initialized) {
|
||||
// Initialization is complete, nothing else to do
|
||||
return;
|
||||
}
|
||||
let contents = _SessionFile.syncRead();
|
||||
this._onSessionFileRead(contents);
|
||||
} catch(ex) {
|
||||
debug("ensureInitialized: could not read session " + ex + ", " + ex.stack);
|
||||
throw ex;
|
||||
}
|
||||
},
|
||||
|
||||
/* ........ QueryInterface .............. */
|
||||
QueryInterface : XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||
Ci.nsISupportsWeakReference,
|
||||
Ci.nsISessionStartup]),
|
||||
classID: Components.ID("{ec7a6c20-e081-11da-8ad9-0800200c9a66}")
|
||||
};
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SessionStartup]);
|
||||
Loading…
Add table
Add a link
Reference in a new issue