Bug 583041 - Style Editor integration; part 1; r=rcampbell

This commit is contained in:
Cedric Vivier 2011-11-15 16:41:37 +08:00
parent 6cf1bc51f4
commit 9f1f016917
17 changed files with 212 additions and 120 deletions

View File

@ -491,10 +491,12 @@ var Scratchpad = {
/**
* Open a new Scratchpad window.
*
* @return nsIWindow
*/
openScratchpad: function SP_openScratchpad()
{
ScratchpadManager.openScratchpad();
return ScratchpadManager.openScratchpad();
},
/**
@ -768,6 +770,8 @@ var Scratchpad = {
else if (this.filename && this.saved) {
this.onTextSaved();
}
this._triggerObservers("Ready");
},
/**
@ -877,6 +881,68 @@ var Scratchpad = {
this.editor.destroy();
this.editor = null;
},
_observers: [],
/**
* Add an observer for Scratchpad events.
*
* The observer implements IScratchpadObserver := {
* onReady: Called when the Scratchpad and its SourceEditor are ready.
* Arguments: (Scratchpad aScratchpad)
* }
*
* All observer handlers are optional.
*
* @param IScratchpadObserver aObserver
* @see removeObserver
*/
addObserver: function SP_addObserver(aObserver)
{
this._observers.push(aObserver);
},
/**
* Remove an observer for Scratchpad events.
*
* @param IScratchpadObserver aObserver
* @see addObserver
*/
removeObserver: function SP_removeObserver(aObserver)
{
let index = this._observers.indexOf(aObserver);
if (index != -1) {
this._observers.splice(index, 1);
}
},
/**
* Trigger named handlers in Scratchpad observers.
*
* @param string aName
* Name of the handler to trigger.
* @param Array aArgs
* Optional array of arguments to pass to the observer(s).
* @see addObserver
*/
_triggerObservers: function SP_triggerObservers(aName, aArgs)
{
// insert this Scratchpad instance as the first argument
if (!aArgs) {
aArgs = [this];
} else {
aArgs.unshift(this);
}
// trigger all observers that implement this named handler
for (let i = 0; i < this._observers.length; ++i) {
let observer = this._observers[i];
let handler = observer["on" + aName];
if (handler) {
handler.apply(observer, aArgs);
}
}
}
};
XPCOMUtils.defineLazyGetter(Scratchpad, "strings", function () {

View File

@ -58,6 +58,7 @@ _BROWSER_TEST_FILES = \
browser_scratchpad_bug_679467_falsy.js \
browser_scratchpad_bug_699130_edit_ui_updates.js \
browser_scratchpad_bug_669612_unsaved.js \
head.js \
libs:: $(_BROWSER_TEST_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)

View File

@ -2,9 +2,6 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Reference to the Scratchpad chrome window object.
let gScratchpadWindow;
let gOldPref;
let DEVTOOLS_CHROME_ENABLED = "devtools.chrome.enabled";
@ -55,8 +52,5 @@ function runTests()
Services.prefs.setBoolPref(DEVTOOLS_CHROME_ENABLED, gOldPref);
gScratchpadWindow.close();
gScratchpadWindow = null;
gBrowser.removeCurrentTab();
finish();
}

View File

@ -2,23 +2,28 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Reference to the Scratchpad chrome window object.
let gScratchpadWindow;
var ScratchpadManager = Scratchpad.ScratchpadManager;
function test()
{
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
gBrowser.selectedBrowser.addEventListener("load", function onTabLoad() {
gBrowser.selectedBrowser.removeEventListener("load", onTabLoad, true);
ok(window.Scratchpad, "Scratchpad variable exists");
Services.prefs.setIntPref("devtools.editor.tabsize", 5);
gScratchpadWindow = Scratchpad.openScratchpad();
gScratchpadWindow.addEventListener("load", runTests, false);
gScratchpadWindow.addEventListener("load", function onScratchpadLoad() {
gScratchpadWindow.removeEventListener("load", onScratchpadLoad, false);
gScratchpadWindow.Scratchpad.addObserver({
onReady: runTests
});
}, false);
}, true);
content.location = "data:text/html,Scratchpad test for the Tab key, bug 660560";
@ -26,11 +31,12 @@ function test()
function runTests()
{
gScratchpadWindow.removeEventListener("load", arguments.callee, false);
let sp = gScratchpadWindow.Scratchpad;
ok(sp, "Scratchpad object exists in new window");
is(this.onReady, runTests, "the handler runs in the context of the observer");
sp.removeObserver(this);
ok(sp.editor.hasFocus(), "the editor has focus");
sp.setText("window.foo;");
@ -63,15 +69,20 @@ function runTests()
Services.prefs.setIntPref("devtools.editor.tabsize", 6);
Services.prefs.setBoolPref("devtools.editor.expandtab", false);
gScratchpadWindow = Scratchpad.openScratchpad();
gScratchpadWindow.addEventListener("load", runTests2, false);
gScratchpadWindow.addEventListener("load", function onScratchpadLoad() {
gScratchpadWindow.removeEventListener("load", onScratchpadLoad, false);
gScratchpadWindow.Scratchpad.addObserver({
onReady: runTests2
});
}, false);
}
function runTests2()
{
gScratchpadWindow.removeEventListener("load", arguments.callee, false);
let sp = gScratchpadWindow.Scratchpad;
sp.removeObserver(this);
sp.setText("window.foo;");
sp.editor.setCaretOffset(0);
@ -85,9 +96,5 @@ function runTests2()
Services.prefs.clearUserPref("devtools.editor.tabsize");
Services.prefs.clearUserPref("devtools.editor.expandtab");
gScratchpadWindow.close();
gScratchpadWindow = null;
gBrowser.removeCurrentTab();
finish();
}

View File

@ -32,43 +32,55 @@ function testListeners()
{
let win = ScratchpadManager.openScratchpad();
win.addEventListener("load", function() {
let scratchpad = win.Scratchpad;
win.addEventListener("load", function onScratchpadLoad() {
win.removeEventListener("load", onScratchpadLoad, false);
scratchpad.setText("new text");
ok(!isStar(win), "no star if scratchpad isn't from a file");
win.Scratchpad.addObserver({
onReady: function (aScratchpad) {
aScratchpad.removeObserver(this);
scratchpad.onTextSaved();
ok(!isStar(win), "no star before changing text");
aScratchpad.setText("new text");
ok(!isStar(win), "no star if scratchpad isn't from a file");
scratchpad.setText("new text2");
ok(isStar(win), "shows star if scratchpad text changes");
aScratchpad.onTextSaved();
ok(!isStar(win), "no star before changing text");
scratchpad.onTextSaved();
ok(!isStar(win), "no star if scratchpad was just saved");
scratchpad.undo();
ok(isStar(win), "star if scratchpad undo");
aScratchpad.setText("new text2");
ok(isStar(win), "shows star if scratchpad text changes");
win.close();
done();
});
aScratchpad.onTextSaved();
ok(!isStar(win), "no star if scratchpad was just saved");
aScratchpad.undo();
ok(isStar(win), "star if scratchpad undo");
win.close();
done();
}
});
}, false);
}
function testErrorStatus()
{
let win = ScratchpadManager.openScratchpad();
win.addEventListener("load", function() {
let scratchpad = win.Scratchpad;
win.addEventListener("load", function onScratchpadLoad() {
win.removeEventListener("load", onScratchpadLoad, false);
scratchpad.onTextSaved(Components.results.NS_ERROR_FAILURE);
scratchpad.setText("new text");
ok(!isStar(win), "no star if file save failed");
win.Scratchpad.addObserver({
onReady: function (aScratchpad) {
aScratchpad.removeObserver(this);
win.close();
done();
});
aScratchpad.onTextSaved(Components.results.NS_ERROR_FAILURE);
aScratchpad.setText("new text");
ok(!isStar(win), "no star if file save failed");
win.close();
done();
}
});
}, false);
}
@ -80,15 +92,21 @@ function testRestoreNotFromFile()
}];
let [win] = ScratchpadManager.restoreSession(session);
win.addEventListener("load", function() {
let scratchpad = win.Scratchpad;
win.addEventListener("load", function onScratchpadLoad() {
win.removeEventListener("load", onScratchpadLoad, false);
scratchpad.setText("new text");
ok(!isStar(win), "no star if restored scratchpad isn't from a file");
win.close();
done();
});
win.Scratchpad.addObserver({
onReady: function (aScratchpad) {
aScratchpad.removeObserver(this);
aScratchpad.setText("new text");
ok(!isStar(win), "no star if restored scratchpad isn't from a file");
win.close();
done();
}
});
}, false);
}
function testRestoreFromFileSaved()
@ -101,17 +119,23 @@ function testRestoreFromFileSaved()
}];
let [win] = ScratchpadManager.restoreSession(session);
win.addEventListener("load", function() {
let scratchpad = win.Scratchpad;
win.addEventListener("load", function onScratchpadLoad() {
win.removeEventListener("load", onScratchpadLoad, false);
ok(!isStar(win), "no star before changing text in scratchpad restored from file");
win.Scratchpad.addObserver({
onReady: function (aScratchpad) {
aScratchpad.removeObserver(this);
scratchpad.setText("new text");
ok(isStar(win), "star when text changed from scratchpad restored from file");
ok(!isStar(win), "no star before changing text in scratchpad restored from file");
win.close();
done();
});
aScratchpad.setText("new text");
ok(isStar(win), "star when text changed from scratchpad restored from file");
win.close();
done();
}
});
}, false);
}
function testRestoreFromFileUnsaved()
@ -124,14 +148,20 @@ function testRestoreFromFileUnsaved()
}];
let [win] = ScratchpadManager.restoreSession(session);
win.addEventListener("load", function() {
let scratchpad = win.Scratchpad;
win.addEventListener("load", function onScratchpadLoad() {
win.removeEventListener("load", onScratchpadLoad, false);
ok(isStar(win), "star with scratchpad restored with unsaved text");
win.Scratchpad.addObserver({
onReady: function (aScratchpad) {
aScratchpad.removeObserver(this);
win.close();
done();
});
ok(isStar(win), "star with scratchpad restored with unsaved text");
win.close();
done();
}
});
}, false);
}
function isStar(win)

View File

@ -30,9 +30,6 @@ function testFalsy(sp)
sp.setBrowserContext();
verifyFalsies(sp);
gScratchpadWindow.close();
gScratchpadWindow = null;
gBrowser.removeCurrentTab();
finish();
}

View File

@ -6,9 +6,6 @@
Cu.import("resource:///modules/source-editor.jsm");
// Reference to the Scratchpad chrome window object.
let gScratchpadWindow;
function test()
{
waitForExplicitFinish();
@ -18,10 +15,7 @@ function test()
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
gScratchpadWindow = Scratchpad.openScratchpad();
gScratchpadWindow.addEventListener("load", function onScratchpadLoad() {
gScratchpadWindow.removeEventListener("load", onScratchpadLoad, false);
waitForFocus(runTests, gScratchpadWindow);
}, false);
gScratchpadWindow.addEventListener("load", runTests, false);
}, true);
content.location = "data:text/html,test Edit menu updates Scratchpad - bug 699130";
@ -29,6 +23,8 @@ function test()
function runTests()
{
gScratchpadWindow.removeEventListener("load", runTests, false);
let sp = gScratchpadWindow.Scratchpad;
let doc = gScratchpadWindow.document;
let winUtils = gScratchpadWindow.QueryInterface(Ci.nsIInterfaceRequestor).
@ -126,7 +122,12 @@ function runTests()
let hideAfterSelect = function() {
sp.editor.addEventListener(SourceEditor.EVENTS.TEXT_CHANGED, onCut);
EventUtils.synthesizeKey("x", {accelKey: true}, gScratchpadWindow);
waitForFocus(function () {
let selectedText = sp.editor.getSelectedText();
ok(selectedText.length > 0, "non-empty selected text will be cut");
EventUtils.synthesizeKey("x", {accelKey: true}, gScratchpadWindow);
}, gScratchpadWindow);
};
let onCut = function() {
@ -142,7 +143,9 @@ function runTests()
let hideAfterCut = function() {
sp.editor.addEventListener(SourceEditor.EVENTS.TEXT_CHANGED, onPaste);
EventUtils.synthesizeKey("v", {accelKey: true}, gScratchpadWindow);
waitForFocus(function () {
EventUtils.synthesizeKey("v", {accelKey: true}, gScratchpadWindow);
}, gScratchpadWindow);
};
let onPaste = function() {
@ -161,7 +164,7 @@ function runTests()
pass++;
testContextMenu();
} else {
finishTest();
finish();
}
};
@ -182,12 +185,5 @@ function runTests()
openMenu(10, 10, firstShow);
};
let finishTest = function() {
gScratchpadWindow.close();
gScratchpadWindow = null;
gBrowser.removeCurrentTab();
finish();
};
openMenu(10, 10, firstShow);
}

View File

@ -123,8 +123,5 @@ function runTests()
is(sp.run()[2], "undefined",
"global variable no longer exists after changing the context");
gScratchpadWindow.close();
gScratchpadWindow = null;
gBrowser.removeCurrentTab();
finish();
}

View File

@ -2,9 +2,6 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Reference to the Scratchpad chrome window object.
let gScratchpadWindow;
function test()
{
waitForExplicitFinish();
@ -129,8 +126,5 @@ function runTests()
sp.redo();
is(sp.getText(), "foo2", "redo() works");
gScratchpadWindow.close();
gScratchpadWindow = null;
gBrowser.removeCurrentTab();
finish();
}

View File

@ -138,8 +138,5 @@ function fileRead(aInputStream, aStatus)
gFile.remove(false);
gFile = null;
gScratchpad = null;
gScratchpadWindow.close();
gScratchpadWindow = null;
gBrowser.removeCurrentTab();
finish();
}

View File

@ -50,8 +50,5 @@ function runTests()
is(chromeContextCommand.getAttribute("disabled"), "true",
"Chrome context command is disabled");
gScratchpadWindow.close();
gScratchpadWindow = null;
gBrowser.removeCurrentTab();
finish();
}

View File

@ -55,9 +55,6 @@ function runTests()
executeSoon(function() {
propPanel.hidePopup();
gScratchpadWindow.close();
gScratchpadWindow = null;
gBrowser.removeCurrentTab();
finish();
});
}, false);

View File

@ -28,7 +28,9 @@ function testOpen()
{
let win = ScratchpadManager.openScratchpad();
win.addEventListener("load", function() {
win.addEventListener("load", function onScratchpadLoad() {
win.removeEventListener("load", onScratchpadLoad, false);
is(win.Scratchpad.filename, undefined, "Default filename is undefined");
is(win.Scratchpad.getText(),
win.Scratchpad.strings.GetStringFromName("scratchpadIntro"),
@ -38,7 +40,7 @@ function testOpen()
win.close();
done();
});
}, false);
}
function testOpenWithState()
@ -51,14 +53,16 @@ function testOpenWithState()
let win = ScratchpadManager.openScratchpad(state);
win.addEventListener("load", function() {
win.addEventListener("load", function onScratchpadLoad() {
win.removeEventListener("load", onScratchpadLoad, false);
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();
});
}, false);
}
function testOpenInvalidState()

View File

@ -49,9 +49,10 @@ function testRestore()
asyncMap(states, function(state, done) {
// Open some scratchpad windows
let win = ScratchpadManager.openScratchpad(state);
win.addEventListener("load", function() {
win.addEventListener("load", function onScratchpadLoad() {
removeEventListener("load", onScratchpadLoad, false);
done(win);
})
}, false)
}, function(wins) {
// Then save the windows to session store
ScratchpadManager.saveOpenWindows();
@ -73,11 +74,12 @@ function testRestore()
is(restoredWins.length, 3, "Three scratchad windows restored");
asyncMap(restoredWins, function(restoredWin, done) {
restoredWin.addEventListener("load", function() {
restoredWin.addEventListener("load", function onScratchpadLoad() {
restoredWin.removeEventListener("load", onScratchpadLoad, false);
let state = restoredWin.Scratchpad.getState();
restoredWin.close();
done(state);
});
}, false);
}, function(restoredStates) {
// Then make sure they were restored with the right states
ok(statesMatch(restoredStates, states),

View File

@ -99,12 +99,8 @@ function runTests3() {
sp.setText("typeof foosbug653108;");
is(sp.run()[2], "undefined", "global variable does not exist");
gScratchpadWindow.close();
gScratchpadWindow = null;
tab1 = null;
tab2 = null;
sp = null;
gBrowser.removeCurrentTab();
gBrowser.removeCurrentTab();
finish();
}

View File

@ -75,8 +75,5 @@ function runTests()
delete sp.__noSuchMethod__;
gScratchpadWindow.close();
gScratchpadWindow = null;
gBrowser.removeCurrentTab();
finish();
}

View File

@ -0,0 +1,20 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
let gScratchpadWindow; // Reference to the Scratchpad chrome window object
function cleanup()
{
if (gScratchpadWindow) {
gScratchpadWindow.close();
gScratchpadWindow = null;
}
while (gBrowser.tabs.length > 1) {
gBrowser.removeCurrentTab();
}
}
registerCleanupFunction(cleanup);