diff options
Diffstat (limited to 'devtools/client/scratchpad/scratchpad-manager.jsm')
-rw-r--r-- | devtools/client/scratchpad/scratchpad-manager.jsm | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/devtools/client/scratchpad/scratchpad-manager.jsm b/devtools/client/scratchpad/scratchpad-manager.jsm new file mode 100644 index 000000000..5b4b3bd0a --- /dev/null +++ b/devtools/client/scratchpad/scratchpad-manager.jsm @@ -0,0 +1,185 @@ +/* vim:set ts=2 sw=2 sts=2 et tw=80: + * 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 = ["ScratchpadManager"]; + +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cu = Components.utils; + +const SCRATCHPAD_WINDOW_URL = "chrome://devtools/content/scratchpad/scratchpad.xul"; +const SCRATCHPAD_WINDOW_FEATURES = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no"; + +const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); +const Services = require("Services"); +const Telemetry = require("devtools/client/shared/telemetry"); + + +/** + * The ScratchpadManager object opens new Scratchpad windows and manages the state + * of open scratchpads for session restore. There's only one ScratchpadManager in + * the life of the browser. + */ +this.ScratchpadManager = { + + _nextUid: 1, + _scratchpads: [], + + _telemetry: new Telemetry(), + + /** + * Get the saved states of open scratchpad windows. Called by + * session restore. + * + * @return array + * The array of scratchpad states. + */ + getSessionState: function SPM_getSessionState() + { + return this._scratchpads; + }, + + /** + * Restore scratchpad windows from the scratchpad session store file. + * Called by session restore. + * + * @param function aSession + * The session object with scratchpad states. + * + * @return array + * The restored scratchpad windows. + */ + restoreSession: function SPM_restoreSession(aSession) + { + if (!Array.isArray(aSession)) { + return []; + } + + let wins = []; + aSession.forEach(function (state) { + let win = this.openScratchpad(state); + wins.push(win); + }, this); + + return wins; + }, + + /** + * Iterate through open scratchpad windows and save their states. + */ + saveOpenWindows: function SPM_saveOpenWindows() { + this._scratchpads = []; + + function clone(src) { + let dest = {}; + + for (let key in src) { + if (src.hasOwnProperty(key)) { + dest[key] = src[key]; + } + } + + return dest; + } + + // We need to clone objects we get from Scratchpad instances + // because such (cross-window) objects have a property 'parent' + // that holds on to a ChromeWindow instance. This means that + // such objects are not primitive-values-only anymore so they + // can leak. + + let enumerator = Services.wm.getEnumerator("devtools:scratchpad"); + while (enumerator.hasMoreElements()) { + let win = enumerator.getNext(); + if (!win.closed && win.Scratchpad.initialized) { + this._scratchpads.push(clone(win.Scratchpad.getState())); + } + } + }, + + /** + * Open a new scratchpad window with an optional initial state. + * + * @param object aState + * Optional. The initial state of the scratchpad, an object + * with properties filename, text, and executionContext. + * + * @return nsIDomWindow + * The opened scratchpad window. + */ + openScratchpad: function SPM_openScratchpad(aState) + { + let params = Cc["@mozilla.org/embedcomp/dialogparam;1"] + .createInstance(Ci.nsIDialogParamBlock); + + params.SetNumberStrings(2); + params.SetString(0, this.createUid()); + + if (aState) { + if (typeof aState != "object") { + return; + } + + params.SetString(1, JSON.stringify(aState)); + } + + let win = Services.ww.openWindow(null, SCRATCHPAD_WINDOW_URL, "_blank", + SCRATCHPAD_WINDOW_FEATURES, params); + + this._telemetry.toolOpened("scratchpad-window"); + let onClose = () => { + this._telemetry.toolClosed("scratchpad-window"); + }; + win.addEventListener("unload", onClose); + + // Only add the shutdown observer if we've opened a scratchpad window. + ShutdownObserver.init(); + + return win; + }, + + /** + * Create a unique ID for a new Scratchpad. + */ + createUid: function SPM_createUid() + { + return JSON.stringify(this._nextUid++); + } +}; + + +/** + * The ShutdownObserver listens for app shutdown and saves the current state + * of the scratchpads for session restore. + */ +var ShutdownObserver = { + _initialized: false, + + init: function SDO_init() + { + if (this._initialized) { + return; + } + + Services.obs.addObserver(this, "quit-application-granted", false); + + this._initialized = true; + }, + + observe: function SDO_observe(aMessage, aTopic, aData) + { + if (aTopic == "quit-application-granted") { + ScratchpadManager.saveOpenWindows(); + this.uninit(); + } + }, + + uninit: function SDO_uninit() + { + Services.obs.removeObserver(this, "quit-application-granted"); + } +}; |