Bug 702331 - Update Orion from upstream; r=rcampbell

This commit is contained in:
Mihai Sucan 2011-12-10 19:03:57 +02:00
parent ca70db066b
commit 9d9bdec4f2
33 changed files with 4199 additions and 2327 deletions

View File

@ -38,11 +38,19 @@ function test() {
function windowObserver(aSubject, aTopic, aData) {
if (aTopic == "domwindowopened") {
let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
win.addEventListener("load", function() {
win.addEventListener("load", function onLoad() {
win.removeEventListener("load", onLoad, false);
if (win.Scratchpad) {
let state = win.Scratchpad.getState();
win.close();
addState(state);
win.Scratchpad.addObserver({
onReady: function() {
win.Scratchpad.removeObserver(this);
let state = win.Scratchpad.getState();
win.close();
addState(state);
},
});
}
}, false);
}
@ -56,4 +64,4 @@ function statesMatch(restored, states) {
state.executionContext == restoredState.executionContext;
})
});
}
}

View File

@ -2,7 +2,7 @@ browser.jar:
* content/browser/inspector.html (highlighter/inspector.html)
content/browser/NetworkPanel.xhtml (webconsole/NetworkPanel.xhtml)
* content/browser/scratchpad.xul (scratchpad/scratchpad.xul)
* content/browser/scratchpad.js (scratchpad/scratchpad.js)
content/browser/scratchpad.js (scratchpad/scratchpad.js)
* content/browser/styleeditor.xul (styleeditor/styleeditor.xul)
content/browser/splitview.css (styleeditor/splitview.css)
content/browser/styleeditor.css (styleeditor/styleeditor.css)

View File

@ -104,7 +104,7 @@ var ScratchpadManager = {
let enumerator = Services.wm.getEnumerator("devtools:scratchpad");
while (enumerator.hasMoreElements()) {
let win = enumerator.getNext();
if (!win.closed) {
if (!win.closed && win.Scratchpad.initialized) {
this._scratchpads.push(win.Scratchpad.getState());
}
}

View File

@ -86,6 +86,13 @@ var Scratchpad = {
*/
executionContext: SCRATCHPAD_CONTEXT_CONTENT,
/**
* Tells if this Scratchpad is initialized and ready for use.
* @boolean
* @see addObserver
*/
initialized: false,
/**
* Retrieve the xul:notificationbox DOM element. It notifies the user when
* the current code execution context is SCRATCHPAD_CONTEXT_BROWSER.
@ -733,7 +740,7 @@ var Scratchpad = {
},
/**
* The Scratchpad window DOMContentLoaded event handler. This method
* The Scratchpad window load event handler. This method
* initializes the Scratchpad window and source editor.
*
* @param nsIDOMEvent aEvent
@ -784,7 +791,9 @@ var Scratchpad = {
this.onContextMenu);
this.editor.focus();
this.editor.setCaretOffset(this.editor.getCharCount());
this.initialized = true;
if (this.filename && !this.saved) {
this.onTextChanged();
}
@ -866,7 +875,7 @@ var Scratchpad = {
if (aStatus && !Components.isSuccessCode(aStatus)) {
return;
}
if (!document) {
if (!document || !this.initialized) {
return; // file saved to disk after window has closed
}
document.title = document.title.replace(/^\*/, "");
@ -904,6 +913,7 @@ var Scratchpad = {
this.onContextMenu);
this.editor.destroy();
this.editor = null;
this.initialized = false;
},
/**
@ -1033,6 +1043,6 @@ XPCOMUtils.defineLazyGetter(Scratchpad, "strings", function () {
return Services.strings.createBundle(SCRATCHPAD_L10N);
});
addEventListener("DOMContentLoaded", Scratchpad.onLoad.bind(Scratchpad), false);
addEventListener("load", Scratchpad.onLoad.bind(Scratchpad), false);
addEventListener("unload", Scratchpad.onUnload.bind(Scratchpad), false);
addEventListener("close", Scratchpad.onClose.bind(Scratchpad), false);

View File

@ -2,24 +2,21 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
let gOldPref;
let DEVTOOLS_CHROME_ENABLED = "devtools.chrome.enabled";
function test()
{
waitForExplicitFinish();
gOldPref = Services.prefs.getBoolPref(DEVTOOLS_CHROME_ENABLED);
Services.prefs.setBoolPref(DEVTOOLS_CHROME_ENABLED, true);
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
ok(Scratchpad, "Scratchpad variable exists");
ok(window.Scratchpad, "Scratchpad variable exists");
gScratchpadWindow = Scratchpad.openScratchpad();
gScratchpadWindow.addEventListener("load", runTests, false);
openScratchpad(runTests);
}, true);
content.location = "data:text/html,Scratchpad test for bug 646070 - chrome context preference";
@ -27,8 +24,6 @@ function test()
function runTests()
{
gScratchpadWindow.removeEventListener("load", arguments.callee, false);
let sp = gScratchpadWindow.Scratchpad;
ok(sp, "Scratchpad object exists in new window");
@ -50,7 +45,7 @@ function runTests()
ok(!chromeContextCommand.hasAttribute("disabled"),
"Chrome context command is disabled");
Services.prefs.setBoolPref(DEVTOOLS_CHROME_ENABLED, gOldPref);
Services.prefs.clearUserPref(DEVTOOLS_CHROME_ENABLED);
finish();
}

View File

@ -17,10 +17,10 @@ function done()
}
}
var ScratchpadManager = Scratchpad.ScratchpadManager;
var gFile;
var oldPrompt = Services.prompt;
var promptButton = -1;
function test()
{
@ -29,6 +29,12 @@ function test()
gFile = createTempFile("fileForBug653427.tmp");
writeFile(gFile, "text", testUnsaved.call(this));
Services.prompt = {
confirmEx: function() {
return promptButton;
}
};
testNew();
testSavedFile();
@ -37,28 +43,23 @@ function test()
function testNew()
{
let win = ScratchpadManager.openScratchpad();
win.addEventListener("load", function() {
openScratchpad(function(win) {
win.Scratchpad.close();
ok(win.closed, "new scratchpad window should close without prompting")
done();
});
}, {noFocus: true});
}
function testSavedFile()
{
let win = ScratchpadManager.openScratchpad();
win.addEventListener("load", function() {
openScratchpad(function(win) {
win.Scratchpad.filename = "test.js";
win.Scratchpad.saved = true;
win.Scratchpad.close();
ok(win.closed, "scratchpad from file with no changes should close")
done();
});
}, {noFocus: true});
}
function testUnsaved()
@ -70,17 +71,11 @@ function testUnsaved()
function testUnsavedFileCancel()
{
let win = ScratchpadManager.openScratchpad();
win.addEventListener("load", function() {
openScratchpad(function(win) {
win.Scratchpad.filename = "test.js";
win.Scratchpad.saved = false;
Services.prompt = {
confirmEx: function() {
return win.BUTTON_POSITION_CANCEL;
}
}
promptButton = win.BUTTON_POSITION_CANCEL;
win.Scratchpad.close();
@ -88,14 +83,12 @@ function testUnsavedFileCancel()
win.close();
done();
});
}, {noFocus: true});
}
function testUnsavedFileSave()
{
let win = ScratchpadManager.openScratchpad();
win.addEventListener("load", function() {
openScratchpad(function(win) {
win.Scratchpad.importFromFile(gFile, true, function(status, content) {
win.Scratchpad.filename = gFile.path;
win.Scratchpad.onTextSaved();
@ -103,11 +96,7 @@ function testUnsavedFileSave()
let text = "new text";
win.Scratchpad.setText(text);
Services.prompt = {
confirmEx: function() {
return win.BUTTON_POSITION_SAVE;
}
}
promptButton = win.BUTTON_POSITION_SAVE;
win.Scratchpad.close(function() {
readFile(gFile, function(savedContent) {
@ -118,28 +107,22 @@ function testUnsavedFileSave()
ok(win.closed, 'pressing "Save" in dialog should close scratchpad');
});
});
}, {noFocus: true});
}
function testUnsavedFileDontSave()
{
let win = ScratchpadManager.openScratchpad();
win.addEventListener("load", function() {
openScratchpad(function(win) {
win.Scratchpad.filename = gFile.path;
win.Scratchpad.saved = false;
Services.prompt = {
confirmEx: function() {
return win.BUTTON_POSITION_DONT_SAVE;
}
}
promptButton = win.BUTTON_POSITION_DONT_SAVE;
win.Scratchpad.close();
ok(win.closed, 'pressing "Don\'t Save" in dialog should close scratchpad');
done();
});
}, {noFocus: true});
}
function cleanup()

View File

@ -2,8 +2,6 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
var ScratchpadManager = Scratchpad.ScratchpadManager;
function test()
{
waitForExplicitFinish();
@ -16,14 +14,7 @@ function test()
Services.prefs.setIntPref("devtools.editor.tabsize", 5);
gScratchpadWindow = Scratchpad.openScratchpad();
gScratchpadWindow.addEventListener("load", function onScratchpadLoad() {
gScratchpadWindow.removeEventListener("load", onScratchpadLoad, false);
gScratchpadWindow.Scratchpad.addObserver({
onReady: runTests
});
}, false);
openScratchpad(runTests);
}, true);
content.location = "data:text/html,Scratchpad test for the Tab key, bug 660560";
@ -34,9 +25,6 @@ function runTests()
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;");
@ -70,19 +58,12 @@ function runTests()
Services.prefs.setIntPref("devtools.editor.tabsize", 6);
Services.prefs.setBoolPref("devtools.editor.expandtab", false);
gScratchpadWindow = Scratchpad.openScratchpad();
gScratchpadWindow.addEventListener("load", function onScratchpadLoad() {
gScratchpadWindow.removeEventListener("load", onScratchpadLoad, false);
gScratchpadWindow.Scratchpad.addObserver({
onReady: runTests2
});
}, false);
openScratchpad(runTests2);
}
function runTests2()
{
let sp = gScratchpadWindow.Scratchpad;
sp.removeObserver(this);
sp.setText("window.foo;");
sp.editor.setCaretOffset(0);

View File

@ -30,57 +30,37 @@ function test()
function testListeners()
{
let win = ScratchpadManager.openScratchpad();
openScratchpad(function(aWin, aScratchpad) {
aScratchpad.setText("new text");
ok(!isStar(aWin), "no star if scratchpad isn't from a file");
win.addEventListener("load", function onScratchpadLoad() {
win.removeEventListener("load", onScratchpadLoad, false);
aScratchpad.onTextSaved();
ok(!isStar(aWin), "no star before changing text");
win.Scratchpad.addObserver({
onReady: function (aScratchpad) {
aScratchpad.removeObserver(this);
aScratchpad.setText("new text2");
ok(isStar(aWin), "shows star if scratchpad text changes");
aScratchpad.setText("new text");
ok(!isStar(win), "no star if scratchpad isn't from a file");
aScratchpad.onTextSaved();
ok(!isStar(aWin), "no star if scratchpad was just saved");
aScratchpad.onTextSaved();
ok(!isStar(win), "no star before changing text");
aScratchpad.undo();
ok(isStar(aWin), "star if scratchpad undo");
aScratchpad.setText("new text2");
ok(isStar(win), "shows star if scratchpad text changes");
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);
aWin.close();
done();
}, {noFocus: true});
}
function testErrorStatus()
{
let win = ScratchpadManager.openScratchpad();
openScratchpad(function(aWin, aScratchpad) {
aScratchpad.onTextSaved(Components.results.NS_ERROR_FAILURE);
aScratchpad.setText("new text");
ok(!isStar(aWin), "no star if file save failed");
win.addEventListener("load", function onScratchpadLoad() {
win.removeEventListener("load", onScratchpadLoad, false);
win.Scratchpad.addObserver({
onReady: function (aScratchpad) {
aScratchpad.removeObserver(this);
aScratchpad.onTextSaved(Components.results.NS_ERROR_FAILURE);
aScratchpad.setText("new text");
ok(!isStar(win), "no star if file save failed");
win.close();
done();
}
});
}, false);
aWin.close();
done();
}, {noFocus: true});
}
@ -92,21 +72,13 @@ function testRestoreNotFromFile()
}];
let [win] = ScratchpadManager.restoreSession(session);
win.addEventListener("load", function onScratchpadLoad() {
win.removeEventListener("load", onScratchpadLoad, false);
openScratchpad(function(aWin, aScratchpad) {
aScratchpad.setText("new text");
ok(!isStar(win), "no star if restored scratchpad isn't from a file");
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);
win.close();
done();
}, {window: win, noFocus: true});
}
function testRestoreFromFileSaved()
@ -119,23 +91,15 @@ function testRestoreFromFileSaved()
}];
let [win] = ScratchpadManager.restoreSession(session);
win.addEventListener("load", function onScratchpadLoad() {
win.removeEventListener("load", onScratchpadLoad, false);
openScratchpad(function(aWin, aScratchpad) {
ok(!isStar(win), "no star before changing text in scratchpad restored from file");
win.Scratchpad.addObserver({
onReady: function (aScratchpad) {
aScratchpad.removeObserver(this);
aScratchpad.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");
aScratchpad.setText("new text");
ok(isStar(win), "star when text changed from scratchpad restored from file");
win.close();
done();
}
});
}, false);
win.close();
done();
}, {window: win, noFocus: true});
}
function testRestoreFromFileUnsaved()
@ -148,20 +112,12 @@ function testRestoreFromFileUnsaved()
}];
let [win] = ScratchpadManager.restoreSession(session);
win.addEventListener("load", function onScratchpadLoad() {
win.removeEventListener("load", onScratchpadLoad, false);
openScratchpad(function() {
ok(isStar(win), "star with scratchpad restored with unsaved text");
win.Scratchpad.addObserver({
onReady: function (aScratchpad) {
aScratchpad.removeObserver(this);
ok(isStar(win), "star with scratchpad restored with unsaved text");
win.close();
done();
}
});
}, false);
win.close();
done();
}, {window: win, noFocus: true});
}
function isStar(win)

View File

@ -2,28 +2,21 @@
/* 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();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
gScratchpadWindow = Scratchpad.openScratchpad();
gScratchpadWindow.addEventListener("load", testFalsy, false);
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
openScratchpad(testFalsy);
}, true);
content.location = "data:text/html,<p>test falsy display() values in Scratchpad";
}
function testFalsy(sp)
function testFalsy()
{
gScratchpadWindow.removeEventListener("load", testFalsy, false);
let sp = gScratchpadWindow.Scratchpad;
verifyFalsies(sp);

View File

@ -13,9 +13,7 @@ function test()
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
gScratchpadWindow = Scratchpad.openScratchpad();
gScratchpadWindow.addEventListener("load", runTests, false);
openScratchpad(runTests);
}, true);
content.location = "data:text/html,test Edit menu updates Scratchpad - bug 699130";
@ -23,8 +21,6 @@ function test()
function runTests()
{
gScratchpadWindow.removeEventListener("load", runTests, false);
let sp = gScratchpadWindow.Scratchpad;
let doc = gScratchpadWindow.document;
let winUtils = gScratchpadWindow.QueryInterface(Ci.nsIInterfaceRequestor).

View File

@ -2,19 +2,14 @@
/* 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();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
gScratchpadWindow = Scratchpad.openScratchpad();
gScratchpadWindow.addEventListener("load", runTests, false);
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
openScratchpad(runTests);
}, true);
content.location = "data:text/html,test context switch in Scratchpad";
@ -22,8 +17,6 @@ function test()
function runTests()
{
gScratchpadWindow.removeEventListener("load", arguments.callee, false);
let sp = gScratchpadWindow.Scratchpad;
let contentMenu = gScratchpadWindow.document.getElementById("sp-menu-content");
@ -42,7 +35,7 @@ function runTests()
is(contentMenu.getAttribute("checked"), "true",
"content menuitem is checked");
ok(!chromeMenu.hasAttribute("checked"),
isnot(chromeMenu.getAttribute("checked"), "true",
"chrome menuitem is not checked");
ok(!notificationBox.currentNotification,
@ -66,7 +59,7 @@ function runTests()
is(chromeMenu.getAttribute("checked"), "true",
"chrome menuitem is checked");
ok(!contentMenu.hasAttribute("checked"),
isnot(contentMenu.getAttribute("checked"), "true",
"content menuitem is not checked");
ok(notificationBox.currentNotification,

View File

@ -7,11 +7,9 @@ function test()
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
gScratchpadWindow = Scratchpad.openScratchpad();
gScratchpadWindow.addEventListener("load", runTests, false);
gBrowser.selectedBrowser.addEventListener("load", function onTabLoad() {
gBrowser.selectedBrowser.removeEventListener("load", onTabLoad, true);
openScratchpad(runTests);
}, true);
content.location = "data:text/html,<p>test run() and display() in Scratchpad";
@ -19,8 +17,6 @@ function test()
function runTests()
{
gScratchpadWindow.removeEventListener("load", arguments.callee, false);
let sp = gScratchpadWindow.Scratchpad;
content.wrappedJSObject.foobarBug636725 = 1;

View File

@ -5,9 +5,6 @@
Cu.import("resource://gre/modules/NetUtil.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
// Reference to the Scratchpad chrome window object.
let gScratchpadWindow;
// Reference to the Scratchpad object.
let gScratchpad;
@ -22,11 +19,9 @@ function test()
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
gScratchpadWindow = Scratchpad.openScratchpad();
gScratchpadWindow.addEventListener("load", runTests, false);
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
openScratchpad(runTests);
}, true);
content.location = "data:text/html,<p>test file open and save in Scratchpad";
@ -34,8 +29,6 @@ function test()
function runTests()
{
gScratchpadWindow.removeEventListener("load", arguments.callee, false);
gScratchpad = gScratchpadWindow.Scratchpad;
// Create a temporary file.

View File

@ -2,21 +2,17 @@
/* 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();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
ok(Scratchpad, "Scratchpad variable exists");
ok(window.Scratchpad, "Scratchpad variable exists");
gScratchpadWindow = Scratchpad.openScratchpad();
gScratchpadWindow.addEventListener("load", runTests, false);
openScratchpad(runTests);
}, true);
content.location = "data:text/html,initialization test for Scratchpad";
@ -24,8 +20,6 @@ function test()
function runTests()
{
gScratchpadWindow.removeEventListener("load", arguments.callee, false);
let sp = gScratchpadWindow.Scratchpad;
ok(sp, "Scratchpad object exists in new window");
is(typeof sp.run, "function", "Scratchpad.run() exists");

View File

@ -2,19 +2,14 @@
/* 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();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
gScratchpadWindow = Scratchpad.openScratchpad();
gScratchpadWindow.addEventListener("load", runTests, false);
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
openScratchpad(runTests);
}, true);
content.location = "data:text/html,<title>foobarBug636725</title>" +
@ -23,8 +18,6 @@ function test()
function runTests()
{
gScratchpadWindow.removeEventListener("load", arguments.callee, false);
let sp = gScratchpadWindow.Scratchpad;
sp.setText("document");
@ -34,8 +27,8 @@ function runTests()
let propPanel = document.querySelector(".scratchpad_propertyPanel");
ok(propPanel, "property panel is open");
propPanel.addEventListener("popupshown", function() {
propPanel.removeEventListener("popupshown", arguments.callee, false);
propPanel.addEventListener("popupshown", function onPopupShown() {
propPanel.removeEventListener("popupshown", onPopupShown, false);
let tree = propPanel.querySelector("tree");
ok(tree, "property panel tree found");

View File

@ -2,8 +2,6 @@
/* 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;
@ -15,7 +13,6 @@ function done()
}
}
function test()
{
waitForExplicitFinish();
@ -26,11 +23,7 @@ function test()
function testOpen()
{
let win = ScratchpadManager.openScratchpad();
win.addEventListener("load", function onScratchpadLoad() {
win.removeEventListener("load", onScratchpadLoad, false);
openScratchpad(function(win) {
is(win.Scratchpad.filename, undefined, "Default filename is undefined");
is(win.Scratchpad.getText(),
win.Scratchpad.strings.GetStringFromName("scratchpadIntro"),
@ -40,7 +33,7 @@ function testOpen()
win.close();
done();
}, false);
}, {noFocus: true});
}
function testOpenWithState()
@ -51,25 +44,19 @@ function testOpenWithState()
text: "test text"
};
let win = ScratchpadManager.openScratchpad(state);
win.addEventListener("load", function onScratchpadLoad() {
win.removeEventListener("load", onScratchpadLoad, false);
openScratchpad(function(win) {
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);
}, {state: state, noFocus: true});
}
function testOpenInvalidState()
{
let state = 7;
let win = ScratchpadManager.openScratchpad(state);
let win = openScratchpad(null, {state: 7});
ok(!win, "no scratchpad opened if state is not an object");
done();
}

View File

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

View File

@ -2,8 +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 tab1;
let tab2;
let sp;
@ -14,15 +12,14 @@ function test()
tab1 = gBrowser.addTab();
gBrowser.selectedTab = tab1;
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
gBrowser.selectedBrowser.addEventListener("load", function onLoad1() {
gBrowser.selectedBrowser.removeEventListener("load", onLoad1, true);
tab2 = gBrowser.addTab();
gBrowser.selectedTab = tab2;
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
gScratchpadWindow = Scratchpad.openScratchpad();
gScratchpadWindow.addEventListener("load", runTests, false);
gBrowser.selectedBrowser.addEventListener("load", function onLoad2() {
gBrowser.selectedBrowser.removeEventListener("load", onLoad2, true);
openScratchpad(runTests);
}, true);
content.location = "data:text/html,test context switch in Scratchpad tab 2";
}, true);
@ -32,8 +29,6 @@ function test()
function runTests()
{
gScratchpadWindow.removeEventListener("load", runTests, true);
sp = gScratchpadWindow.Scratchpad;
let contentMenu = gScratchpadWindow.document.getElementById("sp-menu-content");
@ -52,7 +47,7 @@ function runTests()
is(contentMenu.getAttribute("checked"), "true",
"content menuitem is checked");
ok(!browserMenu.hasAttribute("checked"),
isnot(browserMenu.getAttribute("checked"), "true",
"chrome menuitem is not checked");
is(notificationBox.currentNotification, null,

View File

@ -2,19 +2,14 @@
/* 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();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
gScratchpadWindow = Scratchpad.openScratchpad();
gScratchpadWindow.addEventListener("load", runTests, false);
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
openScratchpad(runTests);
}, true);
content.location = "data:text/html,<title>foobarBug636725</title>" +
@ -23,8 +18,6 @@ function test()
function runTests()
{
gScratchpadWindow.removeEventListener("load", arguments.callee, false);
let sp = gScratchpadWindow.Scratchpad;
let doc = gScratchpadWindow.document;

View File

@ -6,6 +6,61 @@
let gScratchpadWindow; // Reference to the Scratchpad chrome window object
/**
* Open a Scratchpad window.
*
* @param function aReadyCallback
* Optional. The function you want invoked when the Scratchpad instance
* is ready.
* @param object aOptions
* Optional. Options for opening the scratchpad:
* - window
* Provide this if there's already a Scratchpad window you want to wait
* loading for.
* - state
* Scratchpad state object. This is used when Scratchpad is open.
* - noFocus
* Boolean that tells you do not want the opened window to receive
* focus.
* @return nsIDOMWindow
* The new window object that holds Scratchpad. Note that the
* gScratchpadWindow global is also updated to reference the new window
* object.
*/
function openScratchpad(aReadyCallback, aOptions)
{
aOptions = aOptions || {};
let win = aOptions.window ||
Scratchpad.ScratchpadManager.openScratchpad(aOptions.state);
if (!win) {
return;
}
let onLoad = function() {
win.removeEventListener("load", onLoad, false);
win.Scratchpad.addObserver({
onReady: function(aScratchpad) {
aScratchpad.removeObserver(this);
if (aOptions.noFocus) {
aReadyCallback(win, aScratchpad);
} else {
waitForFocus(aReadyCallback.bind(null, win, aScratchpad), win);
}
}
});
};
if (aReadyCallback) {
win.addEventListener("load", onLoad, false);
}
gScratchpadWindow = win;
return gScratchpadWindow;
}
function cleanup()
{
if (gScratchpadWindow) {

View File

@ -45,12 +45,17 @@ var js_src = copy.createDataObject();
copy({
source: [
ORION_EDITOR + "/orion/textview/global.js",
ORION_EDITOR + "/orion/textview/eventTarget.js",
ORION_EDITOR + "/orion/editor/regex.js",
ORION_EDITOR + "/orion/textview/keyBinding.js",
ORION_EDITOR + "/orion/textview/rulers.js",
ORION_EDITOR + "/orion/textview/undoStack.js",
ORION_EDITOR + "/orion/textview/textModel.js",
ORION_EDITOR + "/orion/textview/annotations.js",
ORION_EDITOR + "/orion/textview/tooltip.js",
ORION_EDITOR + "/orion/textview/textView.js",
ORION_EDITOR + "/orion/textview/textDND.js",
ORION_EDITOR + "/orion/editor/htmlGrammar.js",
ORION_EDITOR + "/orion/editor/textMateStyler.js",
ORION_EDITOR + "/examples/textview/textStyler.js",
@ -69,6 +74,7 @@ copy({
source: [
ORION_EDITOR + "/orion/textview/textview.css",
ORION_EDITOR + "/orion/textview/rulers.css",
ORION_EDITOR + "/orion/textview/annotations.css",
ORION_EDITOR + "/examples/textview/textstyler.css",
ORION_EDITOR + "/examples/editor/htmlStyles.css",
],

View File

@ -8,25 +8,11 @@ The Orion editor web site: http://www.eclipse.org/orion
To upgrade Orion to a newer version see the UPGRADE file.
Orion version: git clone from 2011-10-26
commit hash 0ab295660e1f7d33ca2bfb8558b3b7492d2c5aa5
+ patch for Eclipse Bug 358623 - Drag and Drop support:
https://github.com/mihaisucan/orion.client/tree/bug-358623
see https://bugs.eclipse.org/bugs/show_bug.cgi?id=358623
+ patch for Eclipse Bug 362286 - Monaco font line height:
https://github.com/mihaisucan/orion.client/tree/bug-362286
see https://bugs.eclipse.org/bugs/show_bug.cgi?id=362286
+ patch for Eclipse Bug 362107 - Ctrl-Up/Down failure on Linux:
https://github.com/mihaisucan/orion.client/tree/bug-362107
see https://bugs.eclipse.org/bugs/show_bug.cgi?id=362107
+ patch for Eclipse Bug 362428 - _getXToOffset() throws:
https://github.com/mihaisucan/orion.client/tree/bug-362428
see https://bugs.eclipse.org/bugs/show_bug.cgi?id=362428
+ patch for Eclipse Bug 362835 - Pasted HTML shows twice:
https://github.com/mihaisucan/orion.client/tree/bug-362835
see https://bugs.eclipse.org/bugs/show_bug.cgi?id=362835
+ patch for Eclipse Bug 363508 - Selection is broken after TextView hide/unhide
see https://bugs.eclipse.org/bugs/show_bug.cgi?id=363508
Orion version: git clone from 2011-12-09
commit hash d8a6dc01d9c561d6eb99f03b64c8c78ce785c59d
+ patch for Eclipse Bug 366312 - right-clicking outside of the selection causes the caret to move
https://github.com/mihaisucan/orion.client/tree/bug-366312
see https://bugs.eclipse.org/bugs/show_bug.cgi?id=366312
# License

View File

@ -2,15 +2,124 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
.viewContainer {
font-size: inherit; /* inherit browser's default monospace font size */
background: -moz-Dialog;
font-family: monospace;
font-size: inherit; /* inherit browser's default monospace font size */
}
.view {
background: #fff;
}
.readonly > .view {
background: #f6f6f6;
}
/* Styles for rulers */
.ruler {
background-color: white;
}
.ruler.lines {
border-right: 1px solid lightgray;
text-align: right;
}
/* Styles for the line number ruler */
.rulerLines {
background: -moz-Dialog;
color: -moz-DialogText;
min-width: 1.4em;
padding-left: 4px;
padding-right: 4px;
text-align: end;
background: -moz-Dialog;
color: -moz-DialogText;
min-width: 1.4em;
padding-left: 4px;
padding-right: 4px;
text-align: end;
}
.token_singleline_comment {
color: green;
}
.token_multiline_comment {
color: green;
}
.token_doc_comment {
color: #00008F;
}
.token_doc_html_markup {
color: #7F7F9F;
}
.token_doc_tag {
color: #7F9FBF;
}
.token_task_tag {
color: #7F9FBF;
}
.token_string {
color: blue;
}
.token_keyword {
color: darkred;
font-weight: bold;
}
.token_space {
/* images/white_space.png */
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAIAAABv85FHAAAABnRSTlMA/wAAAACkwsAdAAAAIUlEQVR4nGP4z8CAC+GUIEXuABhgkTuABEiRw2cmae4EAH05X7xDolNRAAAAAElFTkSuQmCC");
background-repeat: no-repeat;
background-position: center center;
}
.token_tab {
/* images/white_tab.png */
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAJCAIAAACJ2loDAAAABnRSTlMA/wD/AP83WBt9AAAAMklEQVR4nGP4TwRgoK6i52c3bz5w6zMSA6tJn28d2Lx589nnCAYu63AaSLxJRLoJPwAAeNk0aG4opfMAAAAASUVORK5CYII=");
background-repeat: no-repeat;
background-position: left center;
}
.line_caret {
background: #EAF2FE;
}
.readonly .line_caret {
background: #fcfcfc;
}
/* Styling for html syntax highlighting */
.entity-name-tag {
color: #3f7f7f;
}
.entity-other-attribute-name {
color: #7f007f;
}
.punctuation-definition-comment {
color: #3f5fbf;
}
.comment {
color: #3f5fbf
}
.string-quoted {
color: #2a00ff;
font-style: italic;
}
.invalid {
color: red;
font-weight: bold;
}
.annotationRange.currentBracket {
}
.annotationRange.matchingBracket {
outline: 1px solid red;
}

View File

@ -3,9 +3,13 @@
}
.viewContainer {
background-color: #eeeeee;
font-family: monospace;
font-size: 10pt;
}
::-webkit-scrollbar-corner {
background-color: #eeeeee;
}
.viewContent {
}/* Styles for rulers */
@ -25,16 +29,172 @@
text-align: right;
}
.ruler.overview {
border-left: 1px solid lightgray;
width: 14px;
}
/* Styles for the line number ruler */
.rulerLines {
background-color: white;
}
.rulerLines.even
.rulerLines.odd {
}.token_singleline_comment {
}/* Styles for the annotation ruler (all lines) */
.annotation {
}
.annotation.error,
.annotation.warning
.annotation.task,
.annotation.bookmark,
.annotation.breakpoint,
.annotation.collapsed
.annotation.expanded {
}
/* Styles for the annotation ruler (first line) */
.annotationHTML {
cursor: pointer;
width: 16px;
height: 16px;
display: inline-block;
vertical-align: middle;
background-position: center;
background-repeat: no-repeat;
}
.annotationHTML.error {
/* images/error.gif */
background-image: url("data:image/gif;base64,R0lGODlhEAAQANUAAPVvcvWHiPVucvRuc+ttcfV6f91KVN5LU99PV/FZY/JhaM4oN84pONE4Rd1ATfJLWutVYPRgbdxpcsgWKMgZKs4lNfE/UvE/U+artcpdSc5uXveimslHPuBhW/eJhfV5efaCgO2CgP+/v+PExP///////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACUALAAAAAAQABAAAAZ+wJJwSCwaScgkySgkjTQZTkYzWhadnE5oE+pwqkSshwQqkzxfa4kkQXxEpA9J9EFI1KQGQQBAigYCBA14ExEWF0gXihETeA0QD3AkD5QQg0NsDnAJmwkOd5gYFSQKpXAFDBhqaxgLBwQBBAapq00YEg0UDRKqTGtKSL7Cw8JBADs=");
}
.annotationHTML.warning {
/* images/warning.gif */
background-image: url("data:image/gif;base64,R0lGODlhEAAQANUAAP7bc//egf/ij/7ijv/jl/7kl//mnv7lnv/uwf7CTP7DTf7DT/7IW//Na/7Na//NbP7QdP/dmbltAIJNAF03AMSAJMSCLKqASa2DS6uBSquCSrGHTq6ETbCHT7WKUrKIUcCVXL+UXMOYX8GWXsSZYMiib6+ETbOIUcOXX86uhd3Muf///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACsALAAAAAAQABAAAAZowJVwSCwaj0ihikRSJYcoBEL0XKlGkcjImQQhJBREKFnyICoThKeE/AAW6AXgdPyUAgrLJBEo0YsbAQyDhAEdRRwDDw8OaA4NDQImRBgFEJdglxAEGEQZKQcHBqOkKRpFF6mqq1WtrUEAOw==");
}
.annotationHTML.task {
/* images/task.gif */
background-image: url("data:image/gif;base64,R0lGODlhEAAQAMQAAN7s4uTy6ICvY423c2WdP2ugR3mqWYeza2ejOl6VNVqPM1aJMURsJ2GaOnKlT8PbsbPDqGmmO1OCLk98LEhxKGWfOWKaN0t2KkJoJf///////wAAAAAAAAAAAAAAAAAAACH5BAEAABoALAAAAAAQABAAAAVmoCaOZDk+UaquDxkNcCxHJHLceI6QleD/vkCmQrIYjkiDMGAhJRzQ6NKRICkKgYJ2qVWQFktCmEBYkCSNZSbQaDckpAl5TCZMSBdtAaDXX0gUUYJRFCQMSYgGDCQQGI6PkBAmkyUhADs=");
}
.annotationHTML.bookmark {
/* images/bookmark.gif */
background-image: url("data:image/gif;base64,R0lGODlhEAAQALMAAP7//+/VNPzZS/vifeumAPrBOOSlHOSuRP///wAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAgALAAAAAAQABAAAARLEMlJq5Xn3EvIrkenfRIhCB5pmKhRdbAJAGhssuc8n6eJoAKdkOaTAIdEQeWoA1oGsiZhYAnIcqiApVPjElyUbkFSgCkn5XElLYkAADs=");
}
.annotationHTML.breakpoint {
/* images/breakpoint.gif */
background-image: url("data:image/gif;base64,R0lGODlhEAAQANUAAFheoFxkoFxnpmt0pmZxpnF7rYyWwmJwpnaFs3aDrWt8rXGBrYycwmZ3mXuNs42cu77F03GIs3aJrYGVu2J5oKCuxeDj6LK/03GLrYieu3aIoIygu6m4zcLN3MTM1m6Rs2aLriRgkSZilXGXtoGcs7LD0QBLhSZikihol3ScubrO2Yaqu5q4xpO0wpm7yabF0ZO9yaXI0r3X3tHj6P///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAADQALAAAAAAQABAAAAafQJpwSCwWLYZBIDAwWIw0A+FFpW6aRUPCxe1yE4ahhdCCxWSzmSwGgxGeUceKpUqhUCkVa7UK0wgkJCUjJoUmIyWBBEIEGhoeJ4YmJx6OAUIADQ0QIZIhEJoAQgEUFBUgkiAVpZdRCxIPFx8iIh8XDw4FfhYHDhgZHB0dHBkYEwdwUQoTEc3OEwp+QwYHCBMMDBMIB9JESAJLAk5Q5EVBADs=");
}
.annotationHTML.collapsed {
/* images/collapsed.png */
width: 14px;
height: 14px;
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAWBJREFUeNpi/P//PwMlgImBQkCxASzoAp++fo+6de+Z+fXbD/Jev/nAICoiwKCpqrBBTUlqNR835zJ09YzIYfDxy7eo/cevLmXlYGNQUJAEahZieP3mHcODB08Zfv/4w+BoqR3Nz8O1DKcXzt94HPqXmZlBU1+LgZNfkMHazIOBA0hr6uswgMTP33gYijcMLlx/EMAnLs7w7sc/hg9AG0HgPZB+B8S84hJA+UcBeMPg+at3DJIMnAxZzt5wsUhnXzDdsmIVWB6vAcLCfAys3z4wzN64huEfkJ/uH8IwexOQDQymD2/fgeXxekFLRWHD51evGDhZGRi4WSFSnCwgNjB2Xr1m0AbK4zXAQkdhNdPf3wx3r91g+PruLcOqnasYvn54x3Dv2k0G5r+/GMyB8nijEQTefvoadeH6w9Cbtx8GvH//kUFQkJ9BQ1V+g76m/GphPu5lBA0YenmBYgMAAgwA34GIKjmLxOUAAAAASUVORK5CYII=");
}
.annotationHTML.expanded {
/* images/expanded.png */
width: 14px;
height: 14px;
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAT5JREFUeNrUksFKw0AURW+mTWw67SSEiG209U90r4jddFO34l+5U0HdZCHiFwiCOz9AlMSmGEpMOqk1TWJSFGyFbATR2dyZd+Dw3mOENE3xkyP8PYHrBT3OX7uW43ZefA6FUaw1dJPSyrmu1k8KBYOh37Od4XFZLEPXFdRrFMGIw3U9TKMYqw1tb0VjcxLy9eEF425CCIxWE5JcxSQGxCyNloG87gXhwWIHc4J767lTZQw8ShFGSZbxRyaQmZJxd3NRUJ6ffwQNEi6PzG/L2tjdmvFCgcKqKL2F2Olu43MzggDka+IjPuOFI7Sbujn2fUglYKkkzFIi+R0I/QDrGS8UqDX5QkhiOHYfE84hkhSTkGNgOyDJFCzjhYLTq+vDtrG8r1LZtB6fcHtzB+uhD5VWzLx+lvF/8JV/XfAuwADsrJbMGG4l4AAAAABJRU5ErkJggg==");
}
.annotationHTML.multiple {
/* images/multiple.gif */
background-image: url("data:image/gif;base64,R0lGODlhEAAQANUAAOdpa+yJiuFYXOFYXeBYXONwded8f+NwdmhwkHB4iPr7/ezx+fP2+2h4kOzy+Wh4iPr8/gCBwTaczjaXyjaYyjaXyTaYyfr8/QCMzQCMzACHxzao2jal2Dak1zag03iAgI/Ckn64fZrHmX+4fZLCianPopPCiarOoqbLlafLlbnXq7nWq6fLlMTcsoCIeJCQcIiIeKCYaJiQcO16ee16evGVlfGWlfahn/ahoPWhn/WhoPe1tP///////wAAAAAAACH5BAEAAD0ALAAAAAAQABAAAAaRwJ5wSCwaj8WYcslcDmObaDTGq1Zjzw4mk+FQIRcFTzaUeTRoj4zHaI+HL0lkLnnxFgsH7zWEWSoTFBMwVlUwQy6JMDCJjYwuQx8tk5MfOzk4OjcfkSssKCkqHzY0MzQ1nEIJJSYkJCcJAQCzAQlDDyIjISMiCQYEAgMGD0MNIMfHDQUHBc3EQgjR0tPSSNY9QQA7");
}
.annotationHTML.overlay {
/* images/plus.png */
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAAXNSR0IArs4c6QAAAAZiS0dEAAAAAAAA+UO7fwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJEAQvB2JVdrAAAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAD1JREFUCNdtjkESADAEAzemf69f66HMqGlOIhYiFRFRtSQBWAY7mzx+EDTL6sSgb1jTk7Q87rxyqe37fXsAa78gLyZnRgEAAAAASUVORK5CYII=");
background-position: right bottom;
position: relative;
top: -16px;
}
.annotationHTML.currentBracket {
/* images/currentBracket.png */
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sLEBULCGQmEKAAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAnklEQVQ4y7VTsRHDIBATJg1HCUzAHEzFBExAzwZsRMkE9gifKhc72ODYibr/+xcnoQdugq0LAujEwmbn0UxQh4OxpjX1XgshwFqLnPM5PQTQGlprWpbl3RhJ/CSQUm7qPYLp7i8cEpRSoJT6ju0lIaVEQgiKMQ4lHHpQayVjzHWCn5jIOcc8z9dMBADvPZxz3SC1tzCI8vgWdvL+VzwB8JSj2GFTyxIAAAAASUVORK5CYII=");
}
.annotationHTML.matchingBracket {
/* images/matchingBracket.png */
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sLEBUMAsuyb3kAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAoklEQVQ4y61TsQ3EIAw80DcI0USKGIApWIsB2IGGKbJPugxBR3VfvfRRCOSTvw7LPuPzGXgI8f0gwAsFu5rXIYMdDiEOIdnKW5YFzjnEGH+bhwA/KKVwmibu0BhRnpEZY1BrHTaVT7fQJZjnGeu63tOAJFNKVEox53yqQZfAWstt27oidgm01ve3UEqBaBjnspG89wgh3LiFgZXHt3Dh23/FGxKViehm0X85AAAAAElFTkSuQmCC");
}
.annotationHTML.currentLine {
/* images/currentLine.gif */
background-image: url("data:image/gif;base64,R0lGODlhEAAQAMQAALxe0bNWzbdZzrlb0KpPx61RybBTy6VLxadNxZGctIeUroyYsG92hHyMqIKRq2l9nmyAoHGDonaIpStXj6q80k1aXf///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAABYALAAAAAAQABAAAAVCoCWOZGmeKDql5ppOMGXBk/zOoltSNO6XrlXwxIPNYiMGq8SoLC2MaNPygEQkDYdikUg6LQcEoWAICAaA5HPNLoUAADs=");
}
/* Styles for the overview ruler */
.annotationOverview {
cursor: pointer;
border-radius: 2px;
left: 2px;
width: 8px;
}
.annotationOverview.task {
background-color: lightgreen;
border: 1px solid green;
}
.annotationOverview.breakpoint {
background-color: lightblue;
border: 1px solid blue;
}
.annotationOverview.bookmark {
background-color: yellow;
border: 1px solid orange;
}
.annotationOverview.error {
background-color: lightcoral;
border: 1px solid darkred;
}
.annotationOverview.warning {
background-color: Gold;
border: 1px solid black;
}
.annotationOverview.currentBracket {
background-color: lightgray;
border: 1px solid red;
}
.annotationOverview.matchingBracket {
background-color: lightgray;
border: 1px solid red;
}
.annotationOverview.currentLine {
background-color: #EAF2FE;
border: 1px solid black;
}
/* Styles for text range */
.annotationRange {
background-repeat: repeat-x;
background-position: left bottom;
}
.annotationRange.task {
/* images/squiggly_task.png */
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sLDhEoIrb7JmcAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAGUlEQVQI12NggIH/DGdhDCM45z/DfyiBAADgdQjGhI/4DAAAAABJRU5ErkJggg==");
}
.annotationRange.breakpoint {
/* images/squiggly_breakpoint.png */
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sLDhEqHTKradgAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAIklEQVQI11XJMQ0AMAzAMGMafwrFlD19+sUKIJTFo9k+B/kQ+Qr2bIVKOgAAAABJRU5ErkJggg==");
}
.annotationRange.bookmark {
/* images/squiggly_bookmark.png */
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJFhQXEbhTg7YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII=");
}
.annotationRange.error {
/* images/squiggly_error.png */
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg==");
}
.annotationRange.warning {
/* images/squiggly_warning.png */
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJFhQXEbhTg7YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII=");
}
.annotationRange.currentBracket {
}
.annotationRange.matchingBracket {
outline: 1px solid red;
}
/* Styles for lines of text */
.annotationLine {
}
.annotationLine.currentLine {
background-color: #EAF2FE;
}
.token_singleline_comment {
color: green;
}
@ -67,15 +227,6 @@
font-weight: bold;
}
.token_bracket_outline {
outline: 1px solid red;
}
.token_bracket {
color: white;
background-color: grey;
}
.token_space {
/* images/white_space.png */
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAIAAABv85FHAAAABnRSTlMA/wAAAACkwsAdAAAAIUlEQVR4nGP4z8CAC+GUIEXuABhgkTuABEiRw2cmae4EAH05X7xDolNRAAAAAElFTkSuQmCC");

File diff suppressed because it is too large Load Diff

View File

@ -57,8 +57,7 @@ const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
* SourceEditor.THEMES to Orion CSS files.
*/
const ORION_THEMES = {
textmate: ["chrome://browser/content/orion.css",
"chrome://browser/content/orion-mozilla.css"],
mozilla: ["chrome://browser/content/orion-mozilla.css"],
};
/**
@ -71,6 +70,13 @@ const ORION_EVENTS = {
Selection: "Selection",
};
/**
* Known Orion annotation types.
*/
const ORION_ANNOTATION_TYPES = {
currentBracket: "orion.annotation.currentBracket",
matchingBracket: "orion.annotation.matchingBracket",
};
var EXPORTED_SYMBOLS = ["SourceEditor"];
@ -95,12 +101,17 @@ function SourceEditor() {
SourceEditor.prototype = {
_view: null,
_iframe: null,
_model: null,
_undoStack: null,
_lines_ruler: null,
_linesRuler: null,
_styler: null,
_annotationStyler: null,
_annotationModel: null,
_dragAndDrop: null,
_mode: null,
_expandTab: null,
_tabSize: null,
_iframeWindow: null,
/**
* The editor container element.
@ -152,11 +163,7 @@ SourceEditor.prototype = {
let onIframeLoad = (function() {
this._iframe.removeEventListener("load", onIframeLoad, true);
Services.scriptloader.loadSubScript(ORION_SCRIPT,
this._iframe.contentWindow.wrappedJSObject, "utf8");
this._onLoad(aCallback);
this._onIframeLoad();
}).bind(this);
this._iframe.addEventListener("load", onIframeLoad, true);
@ -166,20 +173,23 @@ SourceEditor.prototype = {
aElement.appendChild(this._iframe);
this.parentElement = aElement;
this._config = aConfig;
this._onReadyCallback = aCallback;
},
/**
* The editor iframe load event handler.
*
* @private
* @param function [aCallback]
* Optional function invoked when the editor completes loading.
*/
_onLoad: function SE__onLoad(aCallback)
_onIframeLoad: function SE__onIframeLoad()
{
this._iframeWindow = this._iframe.contentWindow.wrappedJSObject;
let window = this._iframeWindow;
let config = this._config;
let window = this._iframe.contentWindow.wrappedJSObject;
let textview = window.orion.textview;
Services.scriptloader.loadSubScript(ORION_SCRIPT, window, "utf8");
let TextModel = window.require("orion/textview/textModel").TextModel;
let TextView = window.require("orion/textview/textView").TextView;
this._expandTab = typeof config.expandTab != "undefined" ?
config.expandTab : SourceEditor.DEFAULTS.EXPAND_TAB;
@ -188,73 +198,74 @@ SourceEditor.prototype = {
let theme = config.theme || SourceEditor.DEFAULTS.THEME;
let stylesheet = theme in ORION_THEMES ? ORION_THEMES[theme] : theme;
this._view = new textview.TextView({
model: new textview.TextModel(config.placeholderText),
this._model = new TextModel(config.placeholderText);
this._view = new TextView({
model: this._model,
parent: "editor",
stylesheet: stylesheet,
tabSize: this._tabSize,
expandTab: this._expandTab,
readonly: config.readOnly,
themeClass: "mozilla" + (config.readOnly ? " readonly" : ""),
});
let onOrionLoad = function() {
this._view.removeEventListener("Load", onOrionLoad);
this._onOrionLoad();
}.bind(this);
this._view.addEventListener("Load", onOrionLoad);
let KeyBinding = window.require("orion/textview/keyBinding").KeyBinding;
let TextDND = window.require("orion/textview/textDND").TextDND;
let LineNumberRuler = window.require("orion/textview/rulers").LineNumberRuler;
let UndoStack = window.require("orion/textview/undoStack").UndoStack;
let AnnotationModel = window.require("orion/textview/annotations").AnnotationModel;
this._annotationModel = new AnnotationModel(this._model);
if (config.showLineNumbers) {
this._lines_ruler = new textview.LineNumberRuler(null, "left",
this._linesRuler = new LineNumberRuler(this._annotationModel, "left",
{styleClass: "rulerLines"}, {styleClass: "rulerLine odd"},
{styleClass: "rulerLine even"});
this._view.addRuler(this._lines_ruler);
this._view.addRuler(this._linesRuler);
}
this.setMode(config.mode || SourceEditor.DEFAULTS.MODE);
this._undoStack = new textview.UndoStack(this._view,
this._undoStack = new UndoStack(this._view,
config.undoLimit || SourceEditor.DEFAULTS.UNDO_LIMIT);
this._initEditorFeatures();
this._dragAndDrop = new TextDND(this._view, this._undoStack);
this._view.setAction("tab", this._doTab.bind(this));
let shiftTabKey = new KeyBinding(Ci.nsIDOMKeyEvent.DOM_VK_TAB, false, true);
this._view.setAction("Unindent Lines", this._doUnindentLines.bind(this));
this._view.setKeyBinding(shiftTabKey, "Unindent Lines");
this._view.setAction("enter", this._doEnter.bind(this));
(config.keys || []).forEach(function(aKey) {
let binding = new textview.KeyBinding(aKey.code, aKey.accel, aKey.shift,
aKey.alt);
let binding = new KeyBinding(aKey.code, aKey.accel, aKey.shift, aKey.alt);
this._view.setKeyBinding(binding, aKey.action);
if (aKey.callback) {
this._view.setAction(aKey.action, aKey.callback);
}
}, this);
if (aCallback) {
let iframe = this._view._frame;
let document = iframe.contentDocument;
if (!document || document.readyState != "complete") {
let onIframeLoad = function () {
iframe.contentWindow.removeEventListener("load", onIframeLoad, false);
aCallback(this);
}.bind(this);
iframe.contentWindow.addEventListener("load", onIframeLoad, false);
} else {
aCallback(this);
}
}
},
/**
* Initialize the custom Orion editor features.
* The Orion "Load" event handler. This is called when the Orion editor
* completes the initialization.
* @private
*/
_initEditorFeatures: function SE__initEditorFeatures()
_onOrionLoad: function SE__onOrionLoad()
{
let window = this._iframe.contentWindow.wrappedJSObject;
let textview = window.orion.textview;
this._view.setAction("tab", this._doTab.bind(this));
let shiftTabKey = new textview.KeyBinding(Ci.nsIDOMKeyEvent.DOM_VK_TAB,
false, true);
this._view.setAction("Unindent Lines", this._doUnindentLines.bind(this));
this._view.setKeyBinding(shiftTabKey, "Unindent Lines");
this._view.setAction("enter", this._doEnter.bind(this));
if (this._expandTab) {
this._view.setAction("deletePrevious", this._doDeletePrevious.bind(this));
if (this._onReadyCallback) {
this._onReadyCallback(this);
this._onReadyCallback = null;
}
},
@ -302,34 +313,9 @@ SourceEditor.prototype = {
this._view.setSelection(newSelectionStart, newSelectionEnd);
this.endCompoundChange();
} else {
this.setText(indent, selection.start, selection.end);
return true;
}
return true;
},
/**
* The "deletePrevious" editor action implementation. This adds unindentation
* support to the Backspace key implementation.
* @private
*/
_doDeletePrevious: function SE__doDeletePrevious()
{
let selection = this.getSelection();
if (selection.start == selection.end && this._expandTab) {
let model = this._model;
let lineIndex = model.getLineAtOffset(selection.start);
let lineStart = model.getLineStart(lineIndex);
let offset = selection.start - lineStart;
if (offset >= this._tabSize && (offset % this._tabSize) == 0) {
let text = this.getText(lineStart, selection.start);
if (!/[^ ]/.test(text)) {
this.setText("", selection.start - this._tabSize, selection.end);
return true;
}
}
}
return false;
},
@ -357,7 +343,7 @@ SourceEditor.prototype = {
for (let line, i = firstLine; i <= lastLine; i++) {
line = model.getLine(i, true);
if (line.indexOf(indent) != 0) {
return false;
return true;
}
lines.push(line.substring(indent.length));
}
@ -425,15 +411,6 @@ SourceEditor.prototype = {
return true;
},
/**
* Get the Orion Model, the TextModel object instance we use.
* @private
* @type object
*/
get _model() {
return this._view.getModel();
},
/**
* Get the editor element.
*
@ -453,15 +430,12 @@ SourceEditor.prototype = {
* The event type you want to listen for.
* @param function aCallback
* The function you want executed when the event is triggered.
* @param mixed [aData]
* Optional data to pass to the callback when the event is triggered.
*/
addEventListener:
function SE_addEventListener(aEventType, aCallback, aData)
function SE_addEventListener(aEventType, aCallback)
{
if (aEventType in ORION_EVENTS) {
this._view.addEventListener(ORION_EVENTS[aEventType], true,
aCallback, aData);
this._view.addEventListener(ORION_EVENTS[aEventType], aCallback);
} else {
throw new Error("SourceEditor.addEventListener() unknown event " +
"type " + aEventType);
@ -478,15 +452,12 @@ SourceEditor.prototype = {
* The event type you have a listener for.
* @param function aCallback
* The function you have as the event handler.
* @param mixed [aData]
* The optional data passed to the callback.
*/
removeEventListener:
function SE_removeEventListener(aEventType, aCallback, aData)
function SE_removeEventListener(aEventType, aCallback)
{
if (aEventType in ORION_EVENTS) {
this._view.removeEventListener(ORION_EVENTS[aEventType], true,
aCallback, aData);
this._view.removeEventListener(ORION_EVENTS[aEventType], aCallback);
} else {
throw new Error("SourceEditor.removeEventListener() unknown event " +
"type " + aEventType);
@ -587,7 +558,7 @@ SourceEditor.prototype = {
*/
hasFocus: function SE_hasFocus()
{
return this._iframe.ownerDocument.activeElement === this._iframe;
return this._view.hasFocus();
},
/**
@ -726,21 +697,41 @@ SourceEditor.prototype = {
this._styler.destroy();
this._styler = null;
}
if (this._annotationStyler) {
this._annotationStyler.destroy();
this._annotationStyler = null;
}
let window = this._iframe.contentWindow.wrappedJSObject;
let TextStyler = window.examples.textview.TextStyler;
let TextMateStyler = window.orion.editor.TextMateStyler;
let HtmlGrammar = window.orion.editor.HtmlGrammar;
let window = this._iframeWindow;
switch (aMode) {
case SourceEditor.MODES.JAVASCRIPT:
case SourceEditor.MODES.CSS:
this._styler = new TextStyler(this._view, aMode);
let TextStyler =
window.require("examples/textview/textStyler").TextStyler;
this._styler = new TextStyler(this._view, aMode, this._annotationModel);
this._styler.setFoldingEnabled(false);
this._styler.setHighlightCaretLine(true);
let AnnotationStyler =
window.require("orion/textview/annotations").AnnotationStyler;
this._annotationStyler =
new AnnotationStyler(this._view, this._annotationModel);
this._annotationStyler.
addAnnotationType(ORION_ANNOTATION_TYPES.matchingBracket);
this._annotationStyler.
addAnnotationType(ORION_ANNOTATION_TYPES.currentBracket);
break;
case SourceEditor.MODES.HTML:
case SourceEditor.MODES.XML:
this._styler = new TextMateStyler(this._view, HtmlGrammar.grammar);
let TextMateStyler =
window.require("orion/editor/textMateStyler").TextMateStyler;
let HtmlGrammar =
window.require("orion/editor/htmlGrammar").HtmlGrammar;
this._styler = new TextMateStyler(this._view, new HtmlGrammar().grammar);
break;
}
@ -765,7 +756,10 @@ SourceEditor.prototype = {
*/
set readOnly(aValue)
{
this._view.readonly = aValue;
this._view.setOptions({
readonly: aValue,
themeClass: "mozilla" + (aValue ? " readonly" : ""),
});
},
/**
@ -774,7 +768,7 @@ SourceEditor.prototype = {
*/
get readOnly()
{
return this._view.readonly;
return this._view.getOptions("readonly");
},
/**
@ -785,11 +779,16 @@ SourceEditor.prototype = {
this._view.destroy();
this.parentElement.removeChild(this._iframe);
this.parentElement = null;
this._iframeWindow = null;
this._iframe = null;
this._undoStack = null;
this._styler = null;
this._lines_ruler = null;
this._linesRuler = null;
this._dragAndDrop = null;
this._annotationModel = null;
this._annotationStyler = null;
this._view = null;
this._model = null;
this._config = null;
},
};

View File

@ -231,7 +231,7 @@ SourceEditor.prototype = {
let listeners = this._listeners[SourceEditor.EVENTS.SELECTION] || [];
listeners.forEach(function(aListener) {
aListener.callback.call(null, sendEvent, aListener.data);
aListener.callback.call(null, sendEvent);
}, this);
this._lastSelection = selection;
@ -256,7 +256,7 @@ SourceEditor.prototype = {
{
let listeners = this._listeners[SourceEditor.EVENTS.TEXT_CHANGED] || [];
listeners.forEach(function(aListener) {
aListener.callback.call(null, aEvent, aListener.data);
aListener.callback.call(null, aEvent);
}, this);
},
@ -279,16 +279,13 @@ SourceEditor.prototype = {
* The event type you want to listen for.
* @param function aCallback
* The function you want executed when the event is triggered.
* @param mixed [aData]
* Optional data to pass to the callback when the event is triggered.
*/
addEventListener:
function SE_addEventListener(aEventType, aCallback, aData)
function SE_addEventListener(aEventType, aCallback)
{
const EVENTS = SourceEditor.EVENTS;
let listener = {
type: aEventType,
data: aData,
callback: aCallback,
};
@ -316,24 +313,20 @@ SourceEditor.prototype = {
* The event type you have a listener for.
* @param function aCallback
* The function you have as the event handler.
* @param mixed [aData]
* The optional data passed to the callback.
*/
removeEventListener:
function SE_removeEventListener(aEventType, aCallback, aData)
function SE_removeEventListener(aEventType, aCallback)
{
let listeners = this._listeners[aEventType];
if (!listeners) {
throw new Error("SourceEditor.removeEventListener() called for an " +
"unknown event.");
return;
}
const EVENTS = SourceEditor.EVENTS;
this._listeners[aEventType] = listeners.filter(function(aListener) {
let isSameListener = aListener.type == aEventType &&
aListener.callback === aCallback &&
aListener.data === aData;
aListener.callback === aCallback;
if (isSameListener && aListener.domType) {
aListener.target.removeEventListener(aListener.domType,
aListener.handler, false);
@ -366,7 +359,7 @@ SourceEditor.prototype = {
};
aDOMEvent.preventDefault();
aListener.callback.call(null, sendEvent, aListener.data);
aListener.callback.call(null, sendEvent);
},
/**

View File

@ -90,7 +90,7 @@ SourceEditor.MODES = {
* Predefined themes for syntax highlighting.
*/
SourceEditor.THEMES = {
TEXTMATE: "textmate",
MOZILLA: "mozilla",
};
/**
@ -98,7 +98,7 @@ SourceEditor.THEMES = {
*/
SourceEditor.DEFAULTS = {
MODE: SourceEditor.MODES.TEXT,
THEME: SourceEditor.THEMES.TEXTMATE,
THEME: SourceEditor.THEMES.MOZILLA,
UNDO_LIMIT: 200,
TAB_SIZE: 4, // overriden by pref
EXPAND_TAB: true, // overriden by pref

View File

@ -50,6 +50,8 @@ _BROWSER_TEST_FILES = \
browser_bug687573_vscroll.js \
browser_bug687568_pagescroll.js \
browser_bug687580_drag_and_drop.js \
browser_bug695035_middle_click_paste.js \
head.js \
libs:: $(_BROWSER_TEST_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)

View File

@ -16,7 +16,6 @@ function test()
ok(true, "skip test for bug 687580: only applicable for Orion");
return; // Testing for the fix requires direct Orion API access.
}
waitForExplicitFinish();
const windowUrl = "data:application/vnd.mozilla.xul+xml,<?xml version='1.0'?>" +
@ -71,7 +70,7 @@ function editorLoaded()
let ds = Cc["@mozilla.org/widget/dragservice;1"].
getService(Ci.nsIDragService);
let target = view._dragNode;
let target = view._clientDiv;
let targetWin = target.ownerDocument.defaultView;
let dataTransfer = null;
@ -93,7 +92,9 @@ function editorLoaded()
target.removeEventListener("drop", onDrop, false);
let selection = editor.getSelection();
is(selection.start, selection.end, "selection is collapsed");
is(selection.end - selection.start,
initialSelection.end - initialSelection.start,
"selection is correct");
is(editor.getText(0, 2), "l3", "drag and drop worked");
let offset = editor.getCaretOffset();

View File

@ -0,0 +1,84 @@
/* 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";
Cu.import("resource:///modules/source-editor.jsm");
let testWin;
let editor;
function test()
{
if (Services.appinfo.OS != "Linux") {
ok(true, "this test only applies to Linux, skipping.")
return;
}
waitForExplicitFinish();
const windowUrl = "data:text/xml,<?xml version='1.0'?>" +
"<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'" +
" title='test for bug 695035' width='600' height='500'><hbox flex='1'/></window>";
const windowFeatures = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
testWin = Services.ww.openWindow(null, windowUrl, "_blank", windowFeatures, null);
testWin.addEventListener("load", function onWindowLoad() {
testWin.removeEventListener("load", onWindowLoad, false);
waitForFocus(initEditor, testWin);
}, false);
}
function initEditor()
{
let hbox = testWin.document.querySelector("hbox");
editor = new SourceEditor();
editor.init(hbox, {}, editorLoaded);
}
function editorLoaded()
{
editor.focus();
let initialText = "initial text!";
editor.setText(initialText);
let expectedString = "foobarBug695035-" + Date.now();
let doCopy = function() {
let clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].
getService(Ci.nsIClipboardHelper);
clipboardHelper.copyStringToClipboard(expectedString,
Ci.nsIClipboard.kSelectionClipboard);
};
let onCopy = function() {
editor.addEventListener(SourceEditor.EVENTS.TEXT_CHANGED, onPaste);
EventUtils.synthesizeMouse(editor.editorElement, 2, 2, {}, testWin);
EventUtils.synthesizeMouse(editor.editorElement, 3, 3, {button: 1}, testWin);
};
let onPaste = function() {
editor.removeEventListener(SourceEditor.EVENTS.TEXT_CHANGED, onPaste);
is(editor.getText(), expectedString + initialText, "middle-click paste works");
executeSoon(testEnd);
};
waitForSelection(expectedString, doCopy, onCopy, testEnd);
}
function testEnd()
{
editor.destroy();
testWin.close();
testWin = editor = null;
waitForFocus(finish, window);
}

View File

@ -412,16 +412,16 @@ function testEclipseBug362107()
editor.setCaretOffset(16);
EventUtils.synthesizeKey("VK_UP", {ctrlKey: true}, testWin);
is(editor.getCaretOffset(), 7, "Ctrl-Up works");
is(editor.getCaretOffset(), 9, "Ctrl-Up works");
EventUtils.synthesizeKey("VK_UP", {ctrlKey: true}, testWin);
is(editor.getCaretOffset(), 0, "Ctrl-Up works twice");
is(editor.getCaretOffset(), 2, "Ctrl-Up works twice");
EventUtils.synthesizeKey("VK_DOWN", {ctrlKey: true}, testWin);
is(editor.getCaretOffset(), 13, "Ctrl-Down works");
is(editor.getCaretOffset(), 9, "Ctrl-Down works");
EventUtils.synthesizeKey("VK_DOWN", {ctrlKey: true}, testWin);
is(editor.getCaretOffset(), 20, "Ctrl-Down works twice");
is(editor.getCaretOffset(), 16, "Ctrl-Down works twice");
}
function testBug687577()

View File

@ -0,0 +1,107 @@
/* 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";
/*
* Polls the X11 primary selection buffer waiting for the expected value. A known
* value different than the expected value is put on the clipboard first (and
* also polled for) so we can be sure the value we get isn't just the expected
* value because it was already in the buffer.
*
* @param aExpectedStringOrValidatorFn
* The string value that is expected to be in the X11 primary selection buffer
* or a validator function getting clipboard data and returning a bool.
* @param aSetupFn
* A function responsible for setting the primary selection buffer to the
* expected value, called after the known value setting succeeds.
* @param aSuccessFn
* A function called when the expected value is found in the primary
* selection buffer.
* @param aFailureFn
* A function called if the expected value isn't found in the primary
* selection buffer within 5s. It can also be called if the known value
* can't be found.
* @param aFlavor [optional] The flavor to look for. Defaults to "text/unicode".
*/
function waitForSelection(aExpectedStringOrValidatorFn, aSetupFn,
aSuccessFn, aFailureFn, aFlavor) {
let requestedFlavor = aFlavor || "text/unicode";
// Build a default validator function for common string input.
var inputValidatorFn = typeof(aExpectedStringOrValidatorFn) == "string"
? function(aData) aData == aExpectedStringOrValidatorFn
: aExpectedStringOrValidatorFn;
let clipboard = Cc["@mozilla.org/widget/clipboard;1"].
getService(Ci.nsIClipboard);
// reset for the next use
function reset() {
waitForSelection._polls = 0;
}
function wait(validatorFn, successFn, failureFn, flavor) {
if (++waitForSelection._polls > 50) {
// Log the failure.
ok(false, "Timed out while polling the X11 primary selection buffer.");
reset();
failureFn();
return;
}
let transferable = Cc["@mozilla.org/widget/transferable;1"].
createInstance(Ci.nsITransferable);
transferable.addDataFlavor(requestedFlavor);
clipboard.getData(transferable, clipboard.kSelectionClipboard);
let str = {};
let strLength = {};
transferable.getTransferData(requestedFlavor, str, strLength);
let data = null;
if (str.value) {
let strValue = str.value.QueryInterface(Ci.nsISupportsString);
data = strValue.data.substring(0, strLength.value / 2);
}
if (validatorFn(data)) {
// Don't show the success message when waiting for preExpectedVal
if (preExpectedVal) {
preExpectedVal = null;
} else {
ok(true, "The X11 primary selection buffer has the correct value");
}
reset();
successFn();
} else {
setTimeout(function() wait(validatorFn, successFn, failureFn, flavor), 100);
}
}
// First we wait for a known value different from the expected one.
var preExpectedVal = waitForSelection._monotonicCounter +
"-waitForSelection-known-value";
let clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].
getService(Ci.nsIClipboardHelper);
clipboardHelper.copyStringToClipboard(preExpectedVal,
Ci.nsIClipboard.kSelectionClipboard);
wait(function(aData) aData == preExpectedVal,
function() {
// Call the original setup fn
aSetupFn();
wait(inputValidatorFn, aSuccessFn, aFailureFn, requestedFlavor);
}, aFailureFn, "text/unicode");
}
waitForSelection._polls = 0;
waitForSelection.__monotonicCounter = 0;
waitForSelection.__defineGetter__("_monotonicCounter", function () {
return waitForSelection.__monotonicCounter++;
});