зеркало из https://github.com/mozilla/gecko-dev.git
Bug 644409 - Make scratchpads save their state across restarts
This commit is contained in:
Родитель
e0606bbf76
Коммит
08b16fcbdc
|
@ -8900,14 +8900,16 @@ var Scratchpad = {
|
|||
prefEnabledName: "devtools.scratchpad.enabled",
|
||||
|
||||
openScratchpad: function SP_openScratchpad() {
|
||||
const SCRATCHPAD_WINDOW_URL = "chrome://browser/content/scratchpad.xul";
|
||||
const SCRATCHPAD_WINDOW_FEATURES = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
|
||||
|
||||
return Services.ww.openWindow(null, SCRATCHPAD_WINDOW_URL, "_blank",
|
||||
SCRATCHPAD_WINDOW_FEATURES, null);
|
||||
},
|
||||
return this.ScratchpadManager.openScratchpad();
|
||||
}
|
||||
};
|
||||
|
||||
XPCOMUtils.defineLazyGetter(Scratchpad, "ScratchpadManager", function() {
|
||||
let tmp = {};
|
||||
Cu.import("resource:///modules/devtools/scratchpad-manager.jsm", tmp);
|
||||
return tmp.ScratchpadManager;
|
||||
});
|
||||
|
||||
|
||||
XPCOMUtils.defineLazyGetter(window, "gShowPageResizers", function () {
|
||||
#ifdef XP_WIN
|
||||
|
|
|
@ -140,6 +140,11 @@ XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
|
|||
return NetUtil;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "ScratchpadManager", function() {
|
||||
Cu.import("resource:///modules/devtools/scratchpad-manager.jsm");
|
||||
return ScratchpadManager;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "CookieSvc",
|
||||
"@mozilla.org/cookiemanager;1", "nsICookieManager2");
|
||||
|
||||
|
@ -1582,6 +1587,10 @@ SessionStoreService.prototype = {
|
|||
this._capClosedWindows();
|
||||
}
|
||||
|
||||
if (lastSessionState.scratchpads) {
|
||||
ScratchpadManager.restoreSession(lastSessionState.scratchpads);
|
||||
}
|
||||
|
||||
// Set data that persists between sessions
|
||||
this._recentCrashes = lastSessionState.session &&
|
||||
lastSessionState.session.recentCrashes || 0;
|
||||
|
@ -2488,11 +2497,15 @@ SessionStoreService.prototype = {
|
|||
recentCrashes: this._recentCrashes
|
||||
};
|
||||
|
||||
// get open Scratchpad window states too
|
||||
var scratchpads = ScratchpadManager.getSessionState();
|
||||
|
||||
return {
|
||||
windows: total,
|
||||
selectedWindow: ix + 1,
|
||||
_closedWindows: lastClosedWindowsCopy,
|
||||
session: session
|
||||
session: session,
|
||||
scratchpads: scratchpads
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -2700,6 +2713,10 @@ SessionStoreService.prototype = {
|
|||
this.restoreHistoryPrecursor(aWindow, tabs, winData.tabs,
|
||||
(aOverwriteTabs ? (parseInt(winData.selected) || 1) : 0), 0, 0);
|
||||
|
||||
if (aState.scratchpads) {
|
||||
ScratchpadManager.restoreSession(aState.scratchpads);
|
||||
}
|
||||
|
||||
// This will force the keypress listener that Panorama has to attach if it
|
||||
// isn't already. This will be the case if tab view wasn't entered or there
|
||||
// were only visible tabs when TabView.init was first called.
|
||||
|
|
|
@ -149,6 +149,7 @@ _BROWSER_TEST_FILES = \
|
|||
browser_628270.js \
|
||||
browser_635418.js \
|
||||
browser_636279.js \
|
||||
browser_644409-scratchpads.js \
|
||||
browser_645428.js \
|
||||
browser_659591.js \
|
||||
browser_662812.js \
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const testState = {
|
||||
windows: [{
|
||||
tabs: [
|
||||
{ entries: [{ url: "about:blank" }] },
|
||||
]
|
||||
}],
|
||||
scratchpads: [
|
||||
{ text: "text1", executionContext: 1 },
|
||||
{ text: "", executionContext: 2, filename: "test.js" }
|
||||
]
|
||||
};
|
||||
|
||||
// only finish() when correct number of windows opened
|
||||
var restored = [];
|
||||
function addState(state) {
|
||||
restored.push(state);
|
||||
|
||||
if (restored.length == testState.scratchpads.length) {
|
||||
ok(statesMatch(restored, testState.scratchpads),
|
||||
"Two scratchpad windows restored");
|
||||
|
||||
Services.ww.unregisterNotification(windowObserver);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
Services.ww.registerNotification(windowObserver);
|
||||
|
||||
ss.setBrowserState(JSON.stringify(testState));
|
||||
}
|
||||
|
||||
function windowObserver(aSubject, aTopic, aData) {
|
||||
if (aTopic == "domwindowopened") {
|
||||
let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
|
||||
win.addEventListener("load", function() {
|
||||
if (win.Scratchpad) {
|
||||
let state = win.Scratchpad.getState();
|
||||
win.close();
|
||||
addState(state);
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
}
|
||||
|
||||
function statesMatch(restored, states) {
|
||||
return states.every(function(state) {
|
||||
return restored.some(function(restoredState) {
|
||||
return state.filename == restoredState.filename &&
|
||||
state.text == restoredState.text &&
|
||||
state.executionContext == restoredState.executionContext;
|
||||
})
|
||||
});
|
||||
}
|
|
@ -51,11 +51,8 @@ DIRS = \
|
|||
webconsole \
|
||||
sourceeditor \
|
||||
styleinspector \
|
||||
scratchpad \
|
||||
shared \
|
||||
$(NULL)
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
DIRS += scratchpad/test
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
#
|
||||
# ***** 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 Scratchpad Build Code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is The Mozilla Foundation.
|
||||
#
|
||||
# Portions created by the Initial Developer are Copyright (C) 2011
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Rob Campbell <rcampbell@mozilla.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either 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
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
DIRS += test
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
libs::
|
||||
$(NSINSTALL) $(srcdir)/*.jsm $(FINAL_TARGET)/modules/devtools
|
|
@ -0,0 +1,174 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et tw=80:
|
||||
* ***** 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 Scratchpad
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Heather Arthur <fayearthur@gmail.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either 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 *****/
|
||||
|
||||
"use strict";
|
||||
|
||||
var EXPORTED_SYMBOLS = ["ScratchpadManager"];
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
const SCRATCHPAD_WINDOW_URL = "chrome://browser/content/scratchpad.xul";
|
||||
const SCRATCHPAD_WINDOW_FEATURES = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
var ScratchpadManager = {
|
||||
|
||||
_scratchpads: [],
|
||||
|
||||
/**
|
||||
* 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 = [];
|
||||
|
||||
let enumerator = Services.wm.getEnumerator("devtools:scratchpad");
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let win = enumerator.getNext();
|
||||
if (!win.closed) {
|
||||
this._scratchpads.push(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 = null;
|
||||
if (aState) {
|
||||
if (typeof aState != 'object') {
|
||||
return;
|
||||
}
|
||||
params = Cc["@mozilla.org/embedcomp/dialogparam;1"]
|
||||
.createInstance(Ci.nsIDialogParamBlock);
|
||||
params.SetNumberStrings(1);
|
||||
params.SetString(0, JSON.stringify(aState));
|
||||
}
|
||||
let win = Services.ww.openWindow(null, SCRATCHPAD_WINDOW_URL, "_blank",
|
||||
SCRATCHPAD_WINDOW_FEATURES, params);
|
||||
// Only add shutdown observer if we've opened a scratchpad window
|
||||
ShutdownObserver.init();
|
||||
|
||||
return win;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 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");
|
||||
}
|
||||
};
|
|
@ -59,12 +59,12 @@ Cu.import("resource://gre/modules/Services.jsm");
|
|||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
Cu.import("resource:///modules/PropertyPanel.jsm");
|
||||
Cu.import("resource:///modules/source-editor.jsm");
|
||||
Cu.import("resource:///modules/devtools/scratchpad-manager.jsm");
|
||||
|
||||
|
||||
const SCRATCHPAD_CONTEXT_CONTENT = 1;
|
||||
const SCRATCHPAD_CONTEXT_BROWSER = 2;
|
||||
const SCRATCHPAD_WINDOW_URL = "chrome://browser/content/scratchpad.xul";
|
||||
const SCRATCHPAD_L10N = "chrome://browser/locale/devtools/scratchpad.properties";
|
||||
const SCRATCHPAD_WINDOW_FEATURES = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
|
||||
const DEVTOOLS_CHROME_ENABLED = "devtools.chrome.enabled";
|
||||
|
||||
/**
|
||||
|
@ -132,6 +132,55 @@ var Scratchpad = {
|
|||
this.editor.setText(aText, aStart, aEnd);
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the filename in the scratchpad UI and object
|
||||
*
|
||||
* @param string aFilename
|
||||
* The new filename
|
||||
*/
|
||||
setFilename: function SP_setFilename(aFilename)
|
||||
{
|
||||
document.title = this.filename = aFilename;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the current state of the scratchpad. Called by the
|
||||
* Scratchpad Manager for session storing.
|
||||
*
|
||||
* @return object
|
||||
* An object with 3 properties: filename, text, and
|
||||
* executionContext.
|
||||
*/
|
||||
getState: function SP_getState()
|
||||
{
|
||||
return {
|
||||
filename: this.filename,
|
||||
text: this.getText(),
|
||||
executionContext: this.executionContext
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the filename and execution context using the given state. Called
|
||||
* when scratchpad is being restored from a previous session.
|
||||
*
|
||||
* @param object aState
|
||||
* An object with filename and executionContext properties.
|
||||
*/
|
||||
setState: function SP_getState(aState)
|
||||
{
|
||||
if (aState.filename) {
|
||||
this.setFilename(aState.filename);
|
||||
}
|
||||
|
||||
if (aState.executionContext == SCRATCHPAD_CONTEXT_BROWSER) {
|
||||
this.setBrowserContext();
|
||||
}
|
||||
else {
|
||||
this.setContentContext();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the most recent chrome window of type navigator:browser.
|
||||
*/
|
||||
|
@ -442,8 +491,7 @@ var Scratchpad = {
|
|||
*/
|
||||
openScratchpad: function SP_openScratchpad()
|
||||
{
|
||||
Services.ww.openWindow(null, SCRATCHPAD_WINDOW_URL, "_blank",
|
||||
SCRATCHPAD_WINDOW_FEATURES, null);
|
||||
ScratchpadManager.openScratchpad();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -541,7 +589,7 @@ var Scratchpad = {
|
|||
Ci.nsIFilePicker.modeOpen);
|
||||
fp.defaultString = "";
|
||||
if (fp.show() != Ci.nsIFilePicker.returnCancel) {
|
||||
document.title = this.filename = fp.file.path;
|
||||
this.setFilename(fp.file.path);
|
||||
this.importFromFile(fp.file);
|
||||
}
|
||||
},
|
||||
|
@ -680,12 +728,20 @@ var Scratchpad = {
|
|||
errorConsoleCommand.removeAttribute("disabled");
|
||||
}
|
||||
|
||||
let initialText = this.strings.GetStringFromName("scratchpadIntro");
|
||||
if ("arguments" in window &&
|
||||
window.arguments[0] instanceof Ci.nsIDialogParamBlock) {
|
||||
let state = JSON.parse(window.arguments[0].GetString(0));
|
||||
this.setState(state);
|
||||
initialText = state.text;
|
||||
}
|
||||
|
||||
this.editor = new SourceEditor();
|
||||
|
||||
let config = {
|
||||
mode: SourceEditor.MODES.JAVASCRIPT,
|
||||
showLineNumbers: true,
|
||||
placeholderText: this.strings.GetStringFromName("scratchpadIntro"),
|
||||
placeholderText: initialText
|
||||
};
|
||||
|
||||
let editorPlaceholder = document.getElementById("scratchpad-editor");
|
||||
|
|
|
@ -53,6 +53,8 @@ _BROWSER_TEST_FILES = \
|
|||
browser_scratchpad_ui.js \
|
||||
browser_scratchpad_bug_646070_chrome_context_pref.js \
|
||||
browser_scratchpad_bug_660560_tab.js \
|
||||
browser_scratchpad_open.js \
|
||||
browser_scratchpad_restore.js \
|
||||
|
||||
libs:: $(_BROWSER_TEST_FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
var ScratchpadManager = Scratchpad.ScratchpadManager;
|
||||
|
||||
// only finish() when correct number of tests are done
|
||||
const expected = 3;
|
||||
var count = 0;
|
||||
|
||||
function done()
|
||||
{
|
||||
if (++count == expected) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
testOpen();
|
||||
testOpenWithState();
|
||||
testOpenInvalidState();
|
||||
}
|
||||
|
||||
function testOpen()
|
||||
{
|
||||
let win = ScratchpadManager.openScratchpad();
|
||||
|
||||
win.addEventListener("load", function() {
|
||||
is(win.Scratchpad.filename, undefined, "Default filename is undefined");
|
||||
is(win.Scratchpad.getText(),
|
||||
win.Scratchpad.strings.GetStringFromName("scratchpadIntro"),
|
||||
"Default text is loaded")
|
||||
is(win.Scratchpad.executionContext, win.SCRATCHPAD_CONTEXT_CONTENT,
|
||||
"Default execution context is content");
|
||||
|
||||
win.close();
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
function testOpenWithState()
|
||||
{
|
||||
let state = {
|
||||
filename: "testfile",
|
||||
executionContext: 2,
|
||||
text: "test text"
|
||||
};
|
||||
|
||||
let win = ScratchpadManager.openScratchpad(state);
|
||||
|
||||
win.addEventListener("load", function() {
|
||||
is(win.Scratchpad.filename, state.filename, "Filename loaded from state");
|
||||
is(win.Scratchpad.executionContext, state.executionContext, "Execution context loaded from state");
|
||||
is(win.Scratchpad.getText(), state.text, "Content loaded from state");
|
||||
|
||||
win.close();
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
function testOpenInvalidState()
|
||||
{
|
||||
let state = 7;
|
||||
|
||||
let win = ScratchpadManager.openScratchpad(state);
|
||||
ok(!win, "no scratchpad opened if state is not an object");
|
||||
done();
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
var ScratchpadManager = Scratchpad.ScratchpadManager;
|
||||
|
||||
/* Call the iterator for each item in the list,
|
||||
calling the final callback with all the results
|
||||
after every iterator call has sent its result */
|
||||
function asyncMap(items, iterator, callback)
|
||||
{
|
||||
let expected = items.length;
|
||||
let results = [];
|
||||
|
||||
items.forEach(function(item) {
|
||||
iterator(item, function(result) {
|
||||
results.push(result);
|
||||
if (results.length == expected) {
|
||||
callback(results);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
testRestore();
|
||||
}
|
||||
|
||||
function testRestore()
|
||||
{
|
||||
let states = [
|
||||
{
|
||||
filename: "testfile",
|
||||
text: "test1",
|
||||
executionContext: 2
|
||||
},
|
||||
{
|
||||
text: "text2",
|
||||
executionContext: 1
|
||||
},
|
||||
{
|
||||
text: "text3",
|
||||
executionContext: 1
|
||||
}
|
||||
];
|
||||
|
||||
asyncMap(states, function(state, done) {
|
||||
// Open some scratchpad windows
|
||||
let win = ScratchpadManager.openScratchpad(state);
|
||||
win.addEventListener("load", function() {
|
||||
done(win);
|
||||
})
|
||||
}, function(wins) {
|
||||
// Then save the windows to session store
|
||||
ScratchpadManager.saveOpenWindows();
|
||||
|
||||
// Then get their states
|
||||
let session = ScratchpadManager.getSessionState();
|
||||
|
||||
// Then close them
|
||||
wins.forEach(function(win) {
|
||||
win.close();
|
||||
});
|
||||
|
||||
// Clear out session state for next tests
|
||||
ScratchpadManager.saveOpenWindows();
|
||||
|
||||
// Then restore them
|
||||
let restoredWins = ScratchpadManager.restoreSession(session);
|
||||
|
||||
is(restoredWins.length, 3, "Three scratchad windows restored");
|
||||
|
||||
asyncMap(restoredWins, function(restoredWin, done) {
|
||||
restoredWin.addEventListener("load", function() {
|
||||
let state = restoredWin.Scratchpad.getState();
|
||||
restoredWin.close();
|
||||
done(state);
|
||||
});
|
||||
}, function(restoredStates) {
|
||||
// Then make sure they were restored with the right states
|
||||
ok(statesMatch(restoredStates, states),
|
||||
"All scratchpad window states restored correctly");
|
||||
|
||||
// Yay, we're done!
|
||||
finish();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function statesMatch(restoredStates, states)
|
||||
{
|
||||
return states.every(function(state) {
|
||||
return restoredStates.some(function(restoredState) {
|
||||
return state.filename == restoredState.filename
|
||||
&& state.text == restoredState.text
|
||||
&& state.executionContext == restoredState.executionContext;
|
||||
})
|
||||
});
|
||||
}
|
Загрузка…
Ссылка в новой задаче