Merge from mozilla-central to mozilla-inbound

This commit is contained in:
Matt Brubeck 2012-02-28 10:08:33 -08:00
Родитель 33741aa775 abdcd511fc
Коммит 10b225a1d6
20 изменённых файлов: 748 добавлений и 343 удалений

Просмотреть файл

@ -1681,11 +1681,16 @@ SessionStoreService.prototype = {
// If we're still here, then the window is usable. Look at the open tabs in
// comparison to home pages. If all the tabs are home pages then we'll end
// up overwriting all of them. Otherwise we'll just close the tabs that
// match home pages.
let homePages = aWindow.gHomeButton.getHomePage().split("|");
// match home pages. Tabs with the about:blank URI will always be
// overwritten.
let homePages = ["about:blank"];
let removableTabs = [];
let tabbrowser = aWindow.gBrowser;
let normalTabsLen = tabbrowser.tabs.length - tabbrowser._numPinnedTabs;
let startupPref = this._prefBranch.getIntPref("startup.page");
if (startupPref == 1)
homePages = homePages.concat(aWindow.gHomeButton.getHomePage().split("|"));
for (let i = tabbrowser._numPinnedTabs; i < tabbrowser.tabs.length; i++) {
let tab = tabbrowser.tabs[i];
if (homePages.indexOf(tab.linkedBrowser.currentURI.spec) != -1) {

Просмотреть файл

@ -75,6 +75,8 @@ const BUTTON_POSITION_DONT_SAVE = 2;
* The scratchpad object handles the Scratchpad window functionality.
*/
var Scratchpad = {
_initialWindowTitle: document.title,
/**
* The script execution context. This tells Scratchpad in which context the
* script shall execute.
@ -151,7 +153,22 @@ var Scratchpad = {
*/
setFilename: function SP_setFilename(aFilename)
{
document.title = this.filename = aFilename;
this.filename = aFilename;
this._updateTitle();
},
/**
* Update the Scratchpad window title based on the current state.
* @private
*/
_updateTitle: function SP__updateTitle()
{
if (this.filename) {
document.title = (this.editor && this.editor.dirty ? "*" : "") +
this.filename;
} else {
document.title = this._initialWindowTitle;
}
},
/**
@ -168,7 +185,7 @@ var Scratchpad = {
filename: this.filename,
text: this.getText(),
executionContext: this.executionContext,
saved: this.saved
saved: !this.editor.dirty,
};
},
@ -184,7 +201,9 @@ var Scratchpad = {
if (aState.filename) {
this.setFilename(aState.filename);
}
this.saved = aState.saved;
if (this.editor) {
this.editor.dirty = !aState.saved;
}
if (aState.executionContext == SCRATCHPAD_CONTEXT_BROWSER) {
this.setBrowserContext();
@ -638,7 +657,7 @@ var Scratchpad = {
fp.defaultString = "";
if (fp.show() != Ci.nsIFilePicker.returnCancel) {
this.setFilename(fp.file.path);
this.importFromFile(fp.file, false, this.onTextSaved.bind(this));
this.importFromFile(fp.file, false);
}
},
@ -658,7 +677,9 @@ var Scratchpad = {
file.initWithPath(this.filename);
this.exportToFile(file, true, false, function(aStatus) {
this.onTextSaved();
if (Components.isSuccessCode(aStatus)) {
this.editor.dirty = false;
}
if (aCallback) {
aCallback(aStatus);
}
@ -681,7 +702,9 @@ var Scratchpad = {
this.setFilename(fp.file.path);
this.exportToFile(fp.file, true, false, function(aStatus) {
this.onTextSaved();
if (Components.isSuccessCode(aStatus)) {
this.editor.dirty = false;
}
if (aCallback) {
aCallback(aStatus);
}
@ -783,7 +806,6 @@ var Scratchpad = {
if (aEvent.target != document) {
return;
}
let chrome = Services.prefs.getBoolPref(DEVTOOLS_CHROME_ENABLED);
if (chrome) {
let environmentMenu = document.getElementById("sp-environment-menu");
@ -794,10 +816,11 @@ var Scratchpad = {
errorConsoleCommand.removeAttribute("disabled");
}
let state = null;
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));
state = JSON.parse(window.arguments[0].GetString(0));
this.setState(state);
initialText = state.text;
}
@ -808,32 +831,34 @@ var Scratchpad = {
mode: SourceEditor.MODES.JAVASCRIPT,
showLineNumbers: true,
initialText: initialText,
contextMenu: "scratchpad-text-popup",
};
let editorPlaceholder = document.getElementById("scratchpad-editor");
this.editor.init(editorPlaceholder, config, this.onEditorLoad.bind(this));
this.editor.init(editorPlaceholder, config,
this._onEditorLoad.bind(this, state));
},
/**
* The load event handler for the source editor. This method does post-load
* editor initialization.
*
* @private
* @param object aState
* The initial Scratchpad state object.
*/
onEditorLoad: function SP_onEditorLoad()
_onEditorLoad: function SP__onEditorLoad(aState)
{
this.editor.addEventListener(SourceEditor.EVENTS.CONTEXT_MENU,
this.onContextMenu);
this.editor.addEventListener(SourceEditor.EVENTS.DIRTY_CHANGED,
this._onDirtyChanged);
this.editor.focus();
this.editor.setCaretOffset(this.editor.getCharCount());
if (aState) {
this.editor.dirty = !aState.saved;
}
this.initialized = true;
if (this.filename && !this.saved) {
this.onTextChanged();
}
else if (this.filename && this.saved) {
this.onTextSaved();
}
this._triggerObservers("Ready");
},
@ -851,36 +876,17 @@ var Scratchpad = {
},
/**
* The contextmenu event handler for the source editor. This method opens the
* Scratchpad context menu popup at the pointer location.
* The Source Editor DirtyChanged event handler. This function updates the
* Scratchpad window title to show an asterisk when there are unsaved changes.
*
* @private
* @see SourceEditor.EVENTS.DIRTY_CHANGED
* @param object aEvent
* An event object coming from the SourceEditor. This object needs to
* hold the screenX and screenY properties.
* The DirtyChanged event object.
*/
onContextMenu: function SP_onContextMenu(aEvent)
_onDirtyChanged: function SP__onDirtyChanged(aEvent)
{
let menu = document.getElementById("scratchpad-text-popup");
if (menu.state == "closed") {
menu.openPopupAtScreen(aEvent.screenX, aEvent.screenY, true);
}
},
/**
* The popupshowing event handler for the Edit menu. This method updates the
* enabled/disabled state of the Undo and Redo commands, based on the editor
* state such that the menu items render correctly for the user when the menu
* shows.
*/
onEditPopupShowing: function SP_onEditPopupShowing()
{
goUpdateGlobalEditMenuItems();
let undo = document.getElementById("sp-cmd-undo");
undo.setAttribute("disabled", !this.editor.canUndo());
let redo = document.getElementById("sp-cmd-redo");
redo.setAttribute("disabled", !this.editor.canRedo());
Scratchpad._updateTitle();
},
/**
@ -899,36 +905,6 @@ var Scratchpad = {
this.editor.redo();
},
/**
* This method adds a listener to the editor for text changes. Called when
* a scratchpad is saved, opened from file, or restored from a saved file.
*/
onTextSaved: function SP_onTextSaved(aStatus)
{
if (aStatus && !Components.isSuccessCode(aStatus)) {
return;
}
if (!document || !this.initialized) {
return; // file saved to disk after window has closed
}
document.title = document.title.replace(/^\*/, "");
this.saved = true;
this.editor.addEventListener(SourceEditor.EVENTS.TEXT_CHANGED,
this.onTextChanged);
},
/**
* The scratchpad handler for editor text change events. This handler
* indicates that there are unsaved changes in the UI.
*/
onTextChanged: function SP_onTextChanged()
{
document.title = "*" + document.title;
Scratchpad.saved = false;
Scratchpad.editor.removeEventListener(SourceEditor.EVENTS.TEXT_CHANGED,
Scratchpad.onTextChanged);
},
/**
* The Scratchpad window unload event handler. This method unloads/destroys
* the source editor.
@ -942,8 +918,8 @@ var Scratchpad = {
}
this.resetContext();
this.editor.removeEventListener(SourceEditor.EVENTS.CONTEXT_MENU,
this.onContextMenu);
this.editor.removeEventListener(SourceEditor.EVENTS.DIRTY_CHANGED,
this._onDirtyChanged);
this.editor.destroy();
this.editor = null;
this.initialized = false;
@ -953,13 +929,18 @@ var Scratchpad = {
* Prompt to save scratchpad if it has unsaved changes.
*
* @param function aCallback
* Optional function you want to call when file is saved
* Optional function you want to call when file is saved. The callback
* receives three arguments:
* - toClose (boolean) - tells if the window should be closed.
* - saved (boolen) - tells if the file has been saved.
* - status (number) - the file save status result (if the file was
* saved).
* @return boolean
* Whether the window should be closed
*/
promptSave: function SP_promptSave(aCallback)
{
if (this.filename && !this.saved) {
if (this.filename && this.editor.dirty) {
let ps = Services.prompt;
let flags = ps.BUTTON_POS_0 * ps.BUTTON_TITLE_SAVE +
ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL +
@ -971,12 +952,25 @@ var Scratchpad = {
flags, null, null, null, null, {});
if (button == BUTTON_POSITION_CANCEL) {
if (aCallback) {
aCallback(false, false);
}
return false;
}
if (button == BUTTON_POSITION_SAVE) {
this.saveFile(aCallback);
this.saveFile(function(aStatus) {
if (aCallback) {
aCallback(true, true, aStatus);
}
});
return true;
}
}
if (aCallback) {
aCallback(true, false);
}
return true;
},
@ -988,10 +982,22 @@ var Scratchpad = {
*/
onClose: function SP_onClose(aEvent)
{
let toClose = this.promptSave();
if (!toClose) {
aEvent.preventDefault();
if (this._skipClosePrompt) {
return;
}
this.promptSave(function(aShouldClose, aSaved, aStatus) {
let shouldClose = aShouldClose;
if (aSaved && !Components.isSuccessCode(aStatus)) {
shouldClose = false;
}
if (shouldClose) {
this._skipClosePrompt = true;
window.close();
}
}.bind(this));
aEvent.preventDefault();
},
/**
@ -1003,10 +1009,20 @@ var Scratchpad = {
*/
close: function SP_close(aCallback)
{
let toClose = this.promptSave(aCallback);
if (toClose) {
window.close();
}
this.promptSave(function(aShouldClose, aSaved, aStatus) {
let shouldClose = aShouldClose;
if (aSaved && !Components.isSuccessCode(aStatus)) {
shouldClose = false;
}
if (shouldClose) {
this._skipClosePrompt = true;
window.close();
}
if (aCallback) {
aCallback();
}
}.bind(this));
},
_observers: [],

Просмотреть файл

@ -81,11 +81,11 @@
<command id="sp-cmd-resetContext" oncommand="Scratchpad.resetContext();"/>
<command id="sp-cmd-errorConsole" oncommand="Scratchpad.openErrorConsole();" disabled="true"/>
<command id="sp-cmd-webConsole" oncommand="Scratchpad.openWebConsole();"/>
<command id="sp-cmd-undo" oncommand="Scratchpad.undo();" disabled="true"/>
<command id="sp-cmd-redo" oncommand="Scratchpad.redo();" disabled="true"/>
<command id="sp-cmd-documentationLink" oncommand="Scratchpad.openDocumentationPage();"/>
</commandset>
<keyset id="sourceEditorKeys"/>
<keyset id="sp-keyset">
<key id="sp-key-window"
key="&newWindowCmd.commandkey;"
@ -123,9 +123,9 @@
modifiers="accel"/>
<key id="key_selectAll" key="&selectAllCmd.key;" modifiers="accel"/>
<key id="key_undo" key="&undoCmd.key;" modifiers="accel"
oncommand="Scratchpad.undo();"/>
command="se-cmd-undo"/>
<key id="key_redo" key="&undoCmd.key;" modifiers="accel,shift"
oncommand="Scratchpad.redo();"/>
command="se-cmd-redo"/>
<key id="sp-key-run"
key="&run.key;"
command="sp-cmd-run"
@ -168,10 +168,6 @@
command="cmd_findPrevious"
modifiers="shift"/>
#endif
<key id="key_gotoLine"
key="&gotoLineCmd.key;"
command="cmd_gotoLine"
modifiers="accel"/>
<key id="key_openHelp"
keycode="VK_F1"
command="sp-cmd-documentationLink"/>
@ -223,17 +219,17 @@
<menu id="sp-edit-menu" label="&editMenu.label;"
accesskey="&editMenu.accesskey;">
<menupopup id="sp-menu_editpopup"
onpopupshowing="Scratchpad.onEditPopupShowing()">
onpopupshowing="goUpdateGlobalEditMenuItems()">
<menuitem id="sp-menu-undo"
label="&undoCmd.label;"
key="key_undo"
accesskey="&undoCmd.accesskey;"
command="sp-cmd-undo"/>
command="se-cmd-undo"/>
<menuitem id="sp-menu-redo"
label="&redoCmd.label;"
key="key_redo"
accesskey="&redoCmd.accesskey;"
command="sp-cmd-redo"/>
command="se-cmd-redo"/>
<menuseparator/>
<menuitem id="sp-menu-cut"
label="&cutCmd.label;"

Просмотреть файл

@ -46,9 +46,10 @@ function test()
function testNew()
{
openScratchpad(function(win) {
win.Scratchpad.close();
ok(win.closed, "new scratchpad window should close without prompting")
done();
win.Scratchpad.close(function() {
ok(win.closed, "new scratchpad window should close without prompting")
done();
});
}, {noFocus: true});
}
@ -56,11 +57,11 @@ function testSavedFile()
{
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();
win.Scratchpad.editor.dirty = false;
win.Scratchpad.close(function() {
ok(win.closed, "scratchpad from file with no changes should close")
done();
});
}, {noFocus: true});
}
@ -74,17 +75,16 @@ function testUnsaved()
function testUnsavedFileCancel()
{
openScratchpad(function(win) {
win.Scratchpad.filename = "test.js";
win.Scratchpad.saved = false;
win.Scratchpad.setFilename("test.js");
win.Scratchpad.editor.dirty = true;
promptButton = win.BUTTON_POSITION_CANCEL;
win.Scratchpad.close();
ok(!win.closed, "cancelling dialog shouldn't close scratchpad");
win.close();
done();
win.Scratchpad.close(function() {
ok(!win.closed, "cancelling dialog shouldn't close scratchpad");
win.close();
done();
});
}, {noFocus: true});
}
@ -92,8 +92,7 @@ function testUnsavedFileSave()
{
openScratchpad(function(win) {
win.Scratchpad.importFromFile(gFile, true, function(status, content) {
win.Scratchpad.filename = gFile.path;
win.Scratchpad.onTextSaved();
win.Scratchpad.setFilename(gFile.path);
let text = "new text";
win.Scratchpad.setText(text);
@ -101,13 +100,12 @@ function testUnsavedFileSave()
promptButton = win.BUTTON_POSITION_SAVE;
win.Scratchpad.close(function() {
ok(win.closed, 'pressing "Save" in dialog should close scratchpad');
readFile(gFile, function(savedContent) {
is(savedContent, text, 'prompted "Save" worked when closing scratchpad');
done();
});
});
ok(win.closed, 'pressing "Save" in dialog should close scratchpad');
});
}, {noFocus: true});
}
@ -115,15 +113,15 @@ function testUnsavedFileSave()
function testUnsavedFileDontSave()
{
openScratchpad(function(win) {
win.Scratchpad.filename = gFile.path;
win.Scratchpad.saved = false;
win.Scratchpad.setFilename(gFile.path);
win.Scratchpad.editor.dirty = true;
promptButton = win.BUTTON_POSITION_DONT_SAVE;
win.Scratchpad.close();
ok(win.closed, 'pressing "Don\'t Save" in dialog should close scratchpad');
done();
win.Scratchpad.close(function() {
ok(win.closed, 'pressing "Don\'t Save" in dialog should close scratchpad');
done();
});
}, {noFocus: true});
}

Просмотреть файл

@ -3,7 +3,7 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
// only finish() when correct number of tests are done
const expected = 5;
const expected = 4;
var count = 0;
function done()
{
@ -20,7 +20,6 @@ function test()
waitForExplicitFinish();
testListeners();
testErrorStatus();
testRestoreNotFromFile();
testRestoreFromFileSaved();
testRestoreFromFileUnsaved();
@ -34,36 +33,30 @@ function testListeners()
aScratchpad.setText("new text");
ok(!isStar(aWin), "no star if scratchpad isn't from a file");
aScratchpad.onTextSaved();
aScratchpad.editor.dirty = false;
ok(!isStar(aWin), "no star before changing text");
aScratchpad.setFilename("foo.js");
aScratchpad.setText("new text2");
ok(isStar(aWin), "shows star if scratchpad text changes");
aScratchpad.onTextSaved();
aScratchpad.editor.dirty = false;
ok(!isStar(aWin), "no star if scratchpad was just saved");
aScratchpad.setText("new text3");
ok(isStar(aWin), "shows star if scratchpad has more changes");
aScratchpad.undo();
ok(isStar(aWin), "star if scratchpad undo");
ok(!isStar(aWin), "no star if scratchpad undo to save point");
aScratchpad.undo();
ok(isStar(aWin), "star if scratchpad undo past save point");
aWin.close();
done();
}, {noFocus: true});
}
function testErrorStatus()
{
openScratchpad(function(aWin, aScratchpad) {
aScratchpad.onTextSaved(Components.results.NS_ERROR_FAILURE);
aScratchpad.setText("new text");
ok(!isStar(aWin), "no star if file save failed");
aWin.close();
done();
}, {noFocus: true});
}
function testRestoreNotFromFile()
{
let session = [{

Просмотреть файл

@ -32,8 +32,6 @@ function runTests()
"sp-text-resetContext": "resetContext",
"sp-menu-content": "setContentContext",
"sp-menu-browser": "setBrowserContext",
"sp-menu-undo": "undo",
"sp-menu-redo": "redo",
};
let lastMethodCalled = null;

Просмотреть файл

@ -146,6 +146,8 @@ function SourceEditor() {
Services.prefs.getBoolPref(SourceEditor.PREFS.EXPAND_TAB);
this._onOrionSelection = this._onOrionSelection.bind(this);
this._onTextChanged = this._onTextChanged.bind(this);
this._onOrionContextMenu = this._onOrionContextMenu.bind(this);
this._eventTarget = {};
this._eventListenersQueue = [];
@ -172,6 +174,8 @@ SourceEditor.prototype = {
_iframeWindow: null,
_eventTarget: null,
_eventListenersQueue: null,
_contextMenu: null,
_dirty: false,
/**
* The Source Editor user interface manager.
@ -279,7 +283,21 @@ SourceEditor.prototype = {
this._view.addEventListener("Load", onOrionLoad);
if (config.highlightCurrentLine || Services.appinfo.OS == "Linux") {
this._view.addEventListener("Selection", this._onOrionSelection);
this.addEventListener(SourceEditor.EVENTS.SELECTION,
this._onOrionSelection);
}
this.addEventListener(SourceEditor.EVENTS.TEXT_CHANGED,
this._onTextChanged);
if (typeof config.contextMenu == "string") {
let chromeDocument = this.parentElement.ownerDocument;
this._contextMenu = chromeDocument.getElementById(config.contextMenu);
} else if (typeof config.contextMenu == "object" ) {
this._contextMenu = config._contextMenu;
}
if (this._contextMenu) {
this.addEventListener(SourceEditor.EVENTS.CONTEXT_MENU,
this._onOrionContextMenu);
}
let KeyBinding = window.require("orion/textview/keyBinding").KeyBinding;
@ -587,6 +605,44 @@ SourceEditor.prototype = {
}
},
/**
* The TextChanged event handler which tracks the dirty state of the editor.
*
* @see SourceEditor.EVENTS.TEXT_CHANGED
* @see SourceEditor.EVENTS.DIRTY_CHANGED
* @see SourceEditor.dirty
* @private
*/
_onTextChanged: function SE__onTextChanged()
{
this._updateDirty();
},
/**
* The Orion contextmenu event handler. This method opens the default or
* the custom context menu popup at the pointer location.
*
* @param object aEvent
* The contextmenu event object coming from Orion. This object should
* hold the screenX and screenY properties.
*/
_onOrionContextMenu: function SE__onOrionContextMenu(aEvent)
{
if (this._contextMenu.state == "closed") {
this._contextMenu.openPopupAtScreen(aEvent.screenX || 0,
aEvent.screenY || 0, true);
}
},
/**
* Update the dirty state of the editor based on the undo stack.
* @private
*/
_updateDirty: function SE__updateDirty()
{
this.dirty = !this._undoStack.isClean();
},
/**
* Update the X11 PRIMARY buffer to hold the current selection.
* @private
@ -866,18 +922,28 @@ SourceEditor.prototype = {
/**
* Undo a change in the editor.
*
* @return boolean
* True if there was a change undone, false otherwise.
*/
undo: function SE_undo()
{
return this._undoStack.undo();
let result = this._undoStack.undo();
this.ui._onUndoRedo();
return result;
},
/**
* Redo a change in the editor.
*
* @return boolean
* True if there was a change redone, false otherwise.
*/
redo: function SE_redo()
{
return this._undoStack.redo();
let result = this._undoStack.redo();
this.ui._onUndoRedo();
return result;
},
/**
@ -903,11 +969,54 @@ SourceEditor.prototype = {
},
/**
* Reset the Undo stack
* Reset the Undo stack.
*/
resetUndo: function SE_resetUndo()
{
this._undoStack.reset();
this._updateDirty();
this.ui._onUndoRedo();
},
/**
* Set the "dirty" state of the editor. Set this to false when you save the
* text being edited. The dirty state will become true once the user makes
* changes to the text.
*
* @param boolean aNewValue
* The new dirty state: true if the text is not saved, false if you
* just saved the text.
*/
set dirty(aNewValue)
{
if (aNewValue == this._dirty) {
return;
}
let event = {
type: SourceEditor.EVENTS.DIRTY_CHANGED,
oldValue: this._dirty,
newValue: aNewValue,
};
this._dirty = aNewValue;
if (!this._dirty && !this._undoStack.isClean()) {
this._undoStack.markClean();
}
this._dispatchEvent(event);
},
/**
* Get the editor "dirty" state. This tells if the text is considered saved or
* not.
*
* @see SourceEditor.EVENTS.DIRTY_CHANGED
* @return boolean
* True if there are changes which are not saved, false otherwise.
*/
get dirty()
{
return this._dirty;
},
/**
@ -1326,10 +1435,22 @@ SourceEditor.prototype = {
destroy: function SE_destroy()
{
if (this._config.highlightCurrentLine || Services.appinfo.OS == "Linux") {
this._view.removeEventListener("Selection", this._onOrionSelection);
this.removeEventListener(SourceEditor.EVENTS.SELECTION,
this._onOrionSelection);
}
this._onOrionSelection = null;
this.removeEventListener(SourceEditor.EVENTS.TEXT_CHANGED,
this._onTextChanged);
this._onTextChanged = null;
if (this._contextMenu) {
this.removeEventListener(SourceEditor.EVENTS.CONTEXT_MENU,
this._onOrionContextMenu);
this._contextMenu = null;
}
this._onOrionContextMenu = null;
if (this._primarySelectionTimeout) {
let window = this.parentElement.ownerDocument.defaultView;
window.clearTimeout(this._primarySelectionTimeout);

Просмотреть файл

@ -35,13 +35,80 @@
- the terms of any one of the MPL, the GPL or the LGPL.
-
- ***** END LICENSE BLOCK ***** -->
<!DOCTYPE overlay SYSTEM "chrome://browser/locale/devtools/sourceeditor.dtd">
<overlay id="sourceEditorOverlay"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<!-- This Source Editor overlay requires the editMenuOverlay.xul to be loaded.
The globalOverlay.js script is also required in the XUL document where
the source-editor-overlay.xul is loaded. -->
<commandset id="sourceEditorCommands">
<command id="cmd_find" oncommand="goDoCommand('cmd_find')"/>
<command id="cmd_findAgain" oncommand="goDoCommand('cmd_findAgain')" disabled="true"/>
<command id="cmd_findPrevious" oncommand="goDoCommand('cmd_findPrevious')" disabled="true"/>
<command id="cmd_gotoLine" oncommand="goDoCommand('cmd_gotoLine')"/>
<command id="se-cmd-undo" oncommand="goDoCommand('se-cmd-undo')" disabled="true"/>
<command id="se-cmd-redo" oncommand="goDoCommand('se-cmd-redo')" disabled="true"/>
</commandset>
<keyset id="sourceEditorKeys">
<key id="key_gotoLine"
key="&gotoLineCmd.key;"
command="cmd_gotoLine"
modifiers="accel"/>
</keyset>
<menupopup id="sourceEditorContextMenu"
onpopupshowing="goUpdateGlobalEditMenuItems()">
<menuitem id="se-menu-undo"
label="&undoCmd.label;"
key="key_undo"
accesskey="&undoCmd.accesskey;"
command="se-cmd-undo"/>
<menuseparator/>
<menuitem id="se-menu-cut"
label="&cutCmd.label;"
key="key_cut"
accesskey="&cutCmd.accesskey;"
command="cmd_cut"/>
<menuitem id="se-menu-copy"
label="&copyCmd.label;"
key="key_copy"
accesskey="&copyCmd.accesskey;"
command="cmd_copy"/>
<menuitem id="se-menu-paste"
label="&pasteCmd.label;"
key="key_paste"
accesskey="&pasteCmd.accesskey;"
command="cmd_paste"/>
<menuitem id="se-menu-delete"
label="&deleteCmd.label;"
key="key_delete"
accesskey="&deleteCmd.accesskey;"
command="cmd_delete"/>
<menuseparator/>
<menuitem id="se-menu-selectAll"
label="&selectAllCmd.label;"
key="key_selectAll"
accesskey="&selectAllCmd.accesskey;"
command="cmd_selectAll"/>
<menuseparator/>
<menuitem id="se-menu-find"
label="&findCmd.label;"
accesskey="&findCmd.accesskey;"
key="key_find"
command="cmd_find"/>
<menuitem id="se-menu-findAgain"
label="&findAgainCmd.label;"
accesskey="&findAgainCmd.accesskey;"
key="key_findAgain"
command="cmd_findAgain"/>
<menuseparator/>
<menuitem id="se-menu-gotoLine"
label="&gotoLineCmd.label;"
accesskey="&gotoLineCmd.accesskey;"
key="key_gotoLine"
command="cmd_gotoLine"/>
</menupopup>
</overlay>

Просмотреть файл

@ -50,6 +50,7 @@ var EXPORTED_SYMBOLS = ["SourceEditorUI"];
function SourceEditorUI(aEditor)
{
this.editor = aEditor;
this._onDirtyChanged = this._onDirtyChanged.bind(this);
}
SourceEditorUI.prototype = {
@ -72,6 +73,8 @@ SourceEditorUI.prototype = {
if (this._ownerWindow.controllers) {
this._controller = new SourceEditorController(this.editor);
this._ownerWindow.controllers.insertControllerAt(0, this._controller);
this.editor.addEventListener(this.editor.EVENTS.DIRTY_CHANGED,
this._onDirtyChanged);
}
},
@ -177,12 +180,40 @@ SourceEditorUI.prototype = {
}
},
/**
* This is executed after each undo/redo operation.
* @private
*/
_onUndoRedo: function SEU__onUndoRedo()
{
if (this._ownerWindow.goUpdateCommand) {
this._ownerWindow.goUpdateCommand("se-cmd-undo");
this._ownerWindow.goUpdateCommand("se-cmd-redo");
}
},
/**
* The DirtyChanged event handler for the editor. This tracks the editor state
* changes to make sure the Source Editor overlay Undo/Redo commands are kept
* up to date.
* @private
*/
_onDirtyChanged: function SEU__onDirtyChanged()
{
this._onUndoRedo();
},
/**
* Destroy the SourceEditorUI instance. This is called by the
* SourceEditor.destroy() method.
*/
destroy: function SEU_destroy()
{
if (this._ownerWindow.controllers) {
this.editor.removeEventListener(this.editor.EVENTS.DIRTY_CHANGED,
this._onDirtyChanged);
}
this._ownerWindow = null;
this.editor = null;
this._controller = null;
@ -220,6 +251,8 @@ SourceEditorController.prototype = {
case "cmd_findAgain":
case "cmd_findPrevious":
case "cmd_gotoLine":
case "se-cmd-undo":
case "se-cmd-redo":
result = true;
break;
default:
@ -251,6 +284,12 @@ SourceEditorController.prototype = {
case "cmd_findPrevious":
result = this._editor.lastFind && this._editor.lastFind.lastFound != -1;
break;
case "se-cmd-undo":
result = this._editor.canUndo();
break;
case "se-cmd-redo":
result = this._editor.canRedo();
break;
default:
result = false;
break;
@ -281,6 +320,12 @@ SourceEditorController.prototype = {
case "cmd_gotoLine":
this._editor.ui.gotoLine();
break;
case "se-cmd-undo":
this._editor.undo();
break;
case "se-cmd-redo":
this._editor.redo();
break;
}
},

Просмотреть файл

@ -199,6 +199,22 @@ SourceEditor.DEFAULTS = {
* @type array
*/
keys: null,
/**
* The editor context menu you want to display when the user right-clicks
* within the editor. This property can be:
* - a string that tells the ID of the xul:menupopup you want. This needs to
* be available within the editor parentElement.ownerDocument.
* - an nsIDOMElement object reference pointing to the xul:menupopup you
* want to open when the contextmenu event is fired.
*
* Set this property to a falsey value to disable the default context menu.
*
* @see SourceEditor.EVENTS.CONTEXT_MENU for more control over the contextmenu
* event.
* @type string|nsIDOMElement
*/
contextMenu: "sourceEditorContextMenu",
};
/**
@ -216,6 +232,8 @@ SourceEditor.EVENTS = {
* This value comes from the DOM contextmenu event.screenX property.
* - screenY - the pointer location on the y axis, relative to the screen.
* This value comes from the DOM contextmenu event.screenY property.
*
* @see SourceEditor.DEFAULTS.contextMenu
*/
CONTEXT_MENU: "ContextMenu",
@ -282,6 +300,15 @@ SourceEditor.EVENTS = {
* condition.
*/
BREAKPOINT_CHANGE: "BreakpointChange",
/**
* The DirtyChanged event is fired when the dirty state of the editor is
* changed. The dirty state of the editor tells if the are text changes that
* have not been saved yet. Event object properties: oldValue and newValue.
* Both are booleans telling the old dirty state and the new state,
* respectively.
*/
DIRTY_CHANGED: "DirtyChanged",
};
/**
@ -303,6 +330,12 @@ function extend(aDestination, aSource)
* Add methods common to all components.
*/
extend(SourceEditor.prototype, {
// Expose the static constants on the SourceEditor instances.
EVENTS: SourceEditor.EVENTS,
MODES: SourceEditor.MODES,
THEMES: SourceEditor.THEMES,
DEFAULTS: SourceEditor.DEFAULTS,
_lastFind: null,
/**

Просмотреть файл

@ -58,6 +58,7 @@ _BROWSER_TEST_FILES = \
browser_bug725388_mouse_events.js \
browser_bug707987_debugger_breakpoints.js \
browser_bug712982_line_ruler_click.js \
browser_bug700893_dirty_state.js \
head.js \
libs:: $(_BROWSER_TEST_FILES)

Просмотреть файл

@ -0,0 +1,94 @@
/* 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";
function test() {
let temp = {};
Cu.import("resource:///modules/source-editor.jsm", temp);
let SourceEditor = temp.SourceEditor;
let component = Services.prefs.getCharPref(SourceEditor.PREFS.COMPONENT);
if (component == "textarea") {
ok(true, "skip test for bug 700893: only applicable for non-textarea components");
return;
}
waitForExplicitFinish();
let editor;
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 700893' width='600' height='500'><hbox flex='1'/></window>";
const windowFeatures = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
let 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, {initialText: "foobar"}, editorLoaded);
}
function editorLoaded()
{
editor.focus();
is(editor.dirty, false, "editory is not dirty");
let event = null;
let eventHandler = function(aEvent) {
event = aEvent;
};
editor.addEventListener(SourceEditor.EVENTS.DIRTY_CHANGED, eventHandler);
editor.setText("omg");
is(editor.dirty, true, "editor is dirty");
ok(event, "DirtyChanged event fired")
is(event.oldValue, false, "event.oldValue is correct");
is(event.newValue, true, "event.newValue is correct");
event = null;
editor.setText("foo 2");
ok(!event, "no DirtyChanged event fired");
editor.dirty = false;
is(editor.dirty, false, "editor marked as clean");
ok(event, "DirtyChanged event fired")
is(event.oldValue, true, "event.oldValue is correct");
is(event.newValue, false, "event.newValue is correct");
event = null;
editor.setText("foo 3");
is(editor.dirty, true, "editor is dirty after changes");
ok(event, "DirtyChanged event fired")
is(event.oldValue, false, "event.oldValue is correct");
is(event.newValue, true, "event.newValue is correct");
editor.undo();
is(editor.dirty, false, "editor is not dirty after undo");
ok(event, "DirtyChanged event fired")
is(event.oldValue, true, "event.oldValue is correct");
is(event.newValue, false, "event.newValue is correct");
editor.removeEventListener(SourceEditor.EVENTS.DIRTY_CHANGED, eventHandler);
editor.destroy();
testWin.close();
testWin = editor = null;
waitForFocus(finish, window);
}
}

Просмотреть файл

@ -45,6 +45,8 @@
<?xml-stylesheet href="chrome://browser/skin/devtools/splitview.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/styleeditor.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/devtools/styleeditor.css" type="text/css"?>
<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
<?xul-overlay href="chrome://browser/content/source-editor-overlay.xul"?>
<xul:window xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns="http://www.w3.org/1999/xhtml"
id="style-editor-chrome-window"
@ -54,10 +56,18 @@
persist="screenX screenY width height sizemode">
<xul:script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
<xul:popupset id="style-editor-popups">
<xul:menupopup id="sourceEditorContextMenu"/>
</xul:popupset>
<xul:commandset id="editMenuCommands"/>
<xul:commandset id="sourceEditorCommands"/>
<xul:commandset id="style-editor-commandset">
<xul:command id="style-editor-cmd-close" oncommand="window.close();"/>
</xul:commandset>
<xul:keyset id="editMenuKeys"/>
<xul:keyset id="sourceEditorKeys"/>
<xul:keyset id="style-editor-keyset">
<xul:key id="style-editor-key-close"
key="&closeCmd.key;"

Просмотреть файл

@ -0,0 +1,32 @@
<!-- LOCALIZATION NOTE : FILE This file contains the Source Editor component
- strings. The source editor component is used within the Scratchpad and
- Style Editor tools. -->
<!-- LOCALIZATION NOTE : FILE Do not translate commandkeys -->
<!-- LOCALIZATION NOTE : FILE The correct localization of this file might be to
- keep it in English, or another language commonly spoken among web developers.
- You want to make that choice consistent across the developer tools.
- A good criteria is the language in which you'd find the best
- documentation on web development on the web. -->
<!ENTITY undoCmd.label "Undo">
<!ENTITY undoCmd.accesskey "U">
<!ENTITY cutCmd.label "Cut">
<!ENTITY cutCmd.accesskey "t">
<!ENTITY copyCmd.label "Copy">
<!ENTITY copyCmd.accesskey "C">
<!ENTITY pasteCmd.label "Paste">
<!ENTITY pasteCmd.accesskey "P">
<!ENTITY deleteCmd.label "Delete">
<!ENTITY deleteCmd.accesskey "D">
<!ENTITY selectAllCmd.label "Select All">
<!ENTITY selectAllCmd.accesskey "A">
<!ENTITY findCmd.label "Find…">
<!ENTITY findCmd.accesskey "F">
<!ENTITY findAgainCmd.label "Find Again…">
<!ENTITY findAgainCmd.accesskey "g">
<!ENTITY gotoLineCmd.label "Jump to line…">
<!ENTITY gotoLineCmd.key "J">
<!ENTITY gotoLineCmd.accesskey "J">

Просмотреть файл

@ -30,6 +30,7 @@
locale/browser/devtools/styleinspector.dtd (%chrome/browser/devtools/styleinspector.dtd)
locale/browser/devtools/webConsole.dtd (%chrome/browser/devtools/webConsole.dtd)
locale/browser/devtools/sourceeditor.properties (%chrome/browser/devtools/sourceeditor.properties)
locale/browser/devtools/sourceeditor.dtd (%chrome/browser/devtools/sourceeditor.dtd)
locale/browser/newTab.dtd (%chrome/browser/newTab.dtd)
locale/browser/newTab.properties (%chrome/browser/newTab.properties)
locale/browser/openLocation.dtd (%chrome/browser/openLocation.dtd)

Просмотреть файл

@ -904,22 +904,25 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest,
if (mFinalListener) {
mType = newType;
mSrcStreamLoading = true;
rv = mFinalListener->OnStartRequest(aRequest, aContext);
mSrcStreamLoading = false;
if (NS_FAILED(rv)) {
#ifdef XP_MACOSX
// Shockwave on Mac is special and returns an error here even when it
// handles the content
if (mContentType.EqualsLiteral("application/x-director")) {
rv = NS_OK; // otherwise, the AutoFallback will make us fall back
if (NS_SUCCEEDED(rv)) {
// Plugins need to set up for NPRuntime.
if (mType == eType_Plugin) {
NotifyContentObjectWrapper();
}
} else {
// Plugins don't fall back if there is an error here.
if (mType == eType_Plugin) {
rv = NS_OK; // this is necessary to avoid auto-fallback
return NS_BINDING_ABORTED;
}
#endif
Fallback(false);
} else if (mType == eType_Plugin) {
NotifyContentObjectWrapper();
}
return rv;
}

Просмотреть файл

@ -42,6 +42,8 @@ var OPTIONS = {
return request.responseText;
};
SimpleTest.waitForExplicitFinish();
function start() {
var kIsWindows = false;
@ -62,6 +64,34 @@ function start() {
.getService(Components.interfaces.nsIPropertyBag2)
.getProperty("version");
kIsWindowsVistaOrHigher = (parseFloat(version) >= 6.0);
// Workaround for Windows 2000 (driver?) which may crash itself.
if (parseFloat(version) <= 5.0) {
todo(false, "Test disabled on Windows 2000 and older. (To prevent possible system crash.)");
SimpleTest.finish();
return;
}
}
// we currently disable this test on version of Mac OSX older than 10.6,
// due to various weird failures, including one making getRenderbufferParameter tests
// on DEPTH_STENCIL fail
var kDarwinVersion = 0;
if (kIsMac) {
// code borrowed from browser/modules/test/browser_taskbar_preview.js
var is106orHigher = false;
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
kDarwinVersion = parseFloat(Components.classes["@mozilla.org/system-info;1"]
.getService(Components.interfaces.nsIPropertyBag2)
.getProperty("version"));
// the next line is correct: Mac OS 10.6 corresponds to Darwin version 10 !
// Mac OS 10.5 would be Darwin version 9. the |version| string we've got here
// is the Darwin version.
is106orHigher = (kDarwinVersion >= 10.0);
if (!is106orHigher) {
dump("WebGL mochitest disabled on Mac OSX versions older than 10.6\n");
SimpleTest.finish();
return;
}
}
function getEnv(env) {
@ -343,37 +373,18 @@ function start() {
} else {
var errmsg = "Can't create a WebGL context";
reporter.fullResultsNode.textContent = errmsg;
ok(false, errmsg);
// Workaround for SeaMonkey tinderboxes which don't support WebGL.
if (navigator.userAgent.match(/ SeaMonkey\//))
todo(false, errmsg + " (This is expected on SeaMonkey (tinderboxes).)");
else
ok(false, errmsg);
dump("WebGL mochitest failed: " + errmsg + "\n");
reporter.finishedTestSuite();
}
};
SimpleTest.waitForExplicitFinish();
SimpleTest.requestLongerTimeout(3);
// we currently disable this test on version of Mac OSX older than 10.6,
// due to various weird failures, including one making getRenderbufferParameter tests
// on DEPTH_STENCIL fail
var kDarwinVersion = 0;
if (kIsMac) {
// code borrowed from browser/modules/test/browser_taskbar_preview.js
var is106orHigher = false;
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
kDarwinVersion = parseFloat(Components.classes["@mozilla.org/system-info;1"]
.getService(Components.interfaces.nsIPropertyBag2)
.getProperty("version"));
// the next line is correct: Mac OS 10.6 corresponds to Darwin version 10 !
// Mac OS 10.5 would be Darwin version 9. the |version| string we've got here
// is the Darwin version.
is106orHigher = (kDarwinVersion >= 10.0);
if (!is106orHigher) {
dump("WebGL mochitest disabled on Mac OSX versions older than 10.6\n");
SimpleTest.finish();
return;
}
}
var statusElem = document.getElementById("status");
var statusTextNode = document.createTextNode('');
statusElem.appendChild(statusTextNode);
@ -431,7 +442,7 @@ function start() {
</script>
</head>
<body onload="start()">
<body onload="start();">
<p id="display"></p>
<div id="content" style="display: none">

Просмотреть файл

@ -792,8 +792,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Create transaction manager instance ... ");
nsCOMPtr<nsITransactionManager> mgr =
do_CreateInstance(NS_TRANSACTIONMANAGER_CONTRACTID, &result);
if (NS_FAILED(result) || !mgr) {
@ -801,7 +799,7 @@ quick_test(TestTransactionFactory *factory)
return NS_ERROR_OUT_OF_MEMORY;
}
printf("passed\n");
passed("Create transaction manager instance");
/*******************************************************************
*
@ -809,7 +807,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Call DoTransaction() with null transaction ... ");
result = mgr->DoTransaction(0);
if (result != NS_ERROR_NULL_POINTER) {
@ -817,7 +814,7 @@ quick_test(TestTransactionFactory *factory)
return result;
}
printf("passed\n");
passed("Call DoTransaction() with null transaction");
/*******************************************************************
*
@ -825,7 +822,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Call UndoTransaction() with empty undo stack ... ");
result = mgr->UndoTransaction();
if (NS_FAILED(result)) {
@ -833,7 +829,7 @@ quick_test(TestTransactionFactory *factory)
return result;
}
printf("passed\n");
passed("Call UndoTransaction() with empty undo stack");
/*******************************************************************
*
@ -841,7 +837,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Call RedoTransaction() with empty redo stack ... ");
result = mgr->RedoTransaction();
if (NS_FAILED(result)) {
@ -849,7 +844,7 @@ quick_test(TestTransactionFactory *factory)
return result;
}
printf("passed\n");
passed("Call RedoTransaction() with empty redo stack");
/*******************************************************************
*
@ -857,7 +852,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Call SetMaxTransactionCount(-1) with empty undo and redo stacks ... ");
result = mgr->SetMaxTransactionCount(-1);
if (NS_FAILED(result)) {
@ -865,7 +859,7 @@ quick_test(TestTransactionFactory *factory)
return result;
}
printf("passed\n");
passed("Call SetMaxTransactionCount(-1) with empty undo and redo stacks");
/*******************************************************************
*
@ -873,7 +867,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Call SetMaxTransactionCount(0) with empty undo and redo stacks ... ");
result = mgr->SetMaxTransactionCount(0);
if (NS_FAILED(result)) {
@ -881,7 +874,7 @@ quick_test(TestTransactionFactory *factory)
return result;
}
printf("passed\n");
passed("Call SetMaxTransactionCount(0) with empty undo and redo stacks");
/*******************************************************************
*
@ -889,7 +882,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Call SetMaxTransactionCount(10) with empty undo and redo stacks ... ");
result = mgr->SetMaxTransactionCount(10);
if (NS_FAILED(result)) {
@ -897,7 +889,7 @@ quick_test(TestTransactionFactory *factory)
return result;
}
printf("passed\n");
passed("Call SetMaxTransactionCount(10) with empty undo and redo stacks");
/*******************************************************************
*
@ -905,15 +897,13 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Call Clear() with empty undo and redo stack ... ");
result = mgr->Clear();
if (NS_FAILED(result)) {
printf("ERROR: Clear on empty undo and redo stack failed. (%d)\n", result);
return result;
}
printf("passed\n");
passed("Call Clear() with empty undo and redo stack");
PRInt32 numitems;
@ -923,7 +913,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Call GetNumberOfUndoItems() with empty undo stack ... ");
result = mgr->GetNumberOfUndoItems(&numitems);
if (NS_FAILED(result)) {
@ -938,7 +927,7 @@ quick_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Call GetNumberOfUndoItems() with empty undo stack");
/*******************************************************************
*
@ -946,7 +935,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Call GetNumberOfRedoItems() with empty redo stack ... ");
result = mgr->GetNumberOfRedoItems(&numitems);
if (NS_FAILED(result)) {
@ -961,7 +949,7 @@ quick_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Call GetNumberOfRedoItems() with empty redo stack");
nsITransaction *tx;
@ -971,8 +959,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Call PeekUndoStack() with empty undo stack ... ");
tx = 0;
result = mgr->PeekUndoStack(&tx);
@ -988,7 +974,7 @@ quick_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Call PeekUndoStack() with empty undo stack");
/*******************************************************************
*
@ -996,8 +982,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Call PeekRedoStack() with empty undo stack ... ");
tx = 0;
result = mgr->PeekRedoStack(&tx);
@ -1013,7 +997,7 @@ quick_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Call PeekRedoStack() with empty undo stack");
/*******************************************************************
*
@ -1021,8 +1005,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Call AddListener() with null listener ... ");
result = mgr->AddListener(0);
if (result != NS_ERROR_NULL_POINTER) {
@ -1030,7 +1012,7 @@ quick_test(TestTransactionFactory *factory)
return result;
}
printf("passed\n");
passed("Call AddListener() with null listener");
/*******************************************************************
*
@ -1038,8 +1020,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Call RemoveListener() with null listener ... ");
result = mgr->RemoveListener(0);
if (result != NS_ERROR_NULL_POINTER) {
@ -1047,7 +1027,7 @@ quick_test(TestTransactionFactory *factory)
return result;
}
printf("passed\n");
passed("Call RemoveListener() with null listener");
PRInt32 i;
TestTransaction *tximpl;
@ -1063,8 +1043,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Test coalescing of transactions ... ");
result = mgr->SetMaxTransactionCount(10);
if (NS_FAILED(result)) {
@ -1211,7 +1189,7 @@ quick_test(TestTransactionFactory *factory)
return result;
}
printf("passed\n");
passed("Test coalescing of transactions");
/*******************************************************************
*
@ -1220,8 +1198,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Execute 20 transactions ... ");
for (i = 1; i <= 20; i++) {
tximpl = factory->create(mgr, NONE_FLAG);
@ -1275,7 +1251,7 @@ quick_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Execute 20 transactions");
/*******************************************************************
*
@ -1284,8 +1260,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Execute 20 transient transactions ... ");
u1 = u2 = r1 = r2 = 0;
result = mgr->PeekUndoStack(&u1);
@ -1387,7 +1361,7 @@ quick_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Execute 20 transient transactions");
/*******************************************************************
*
@ -1396,8 +1370,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Undo 4 transactions ... ");
for (i = 1; i <= 4; i++) {
result = mgr->UndoTransaction();
if (NS_FAILED(result)) {
@ -1434,7 +1406,7 @@ quick_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Undo 4 transactions");
/*******************************************************************
*
@ -1443,8 +1415,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Redo 2 transactions ... ");
for (i = 1; i <= 2; ++i) {
result = mgr->RedoTransaction();
if (NS_FAILED(result)) {
@ -1481,7 +1451,7 @@ quick_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Redo 2 transactions");
/*******************************************************************
*
@ -1489,8 +1459,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Check if new transactions prune the redo stack ... ");
tximpl = factory->create(mgr, NONE_FLAG);
if (!tximpl) {
@ -1543,7 +1511,7 @@ quick_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Check if new transactions prune the redo stack");
/*******************************************************************
*
@ -1551,8 +1519,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Undo 4 transactions then clear the undo and redo stacks ... ");
for (i = 1; i <= 4; ++i) {
result = mgr->UndoTransaction();
if (NS_FAILED(result)) {
@ -1624,7 +1590,7 @@ quick_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Undo 4 transactions then clear the undo and redo stacks");
/*******************************************************************
*
@ -1632,8 +1598,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Execute 5 transactions ... ");
for (i = 1; i <= 5; i++) {
tximpl = factory->create(mgr, NONE_FLAG);
@ -1687,7 +1651,7 @@ quick_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Execute 5 transactions");
/*******************************************************************
*
@ -1695,8 +1659,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Test transaction DoTransaction() error ... ");
tximpl = factory->create(mgr, THROWS_DO_ERROR_FLAG);
if (!tximpl) {
@ -1798,7 +1760,7 @@ quick_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Test transaction DoTransaction() error");
/*******************************************************************
*
@ -1806,8 +1768,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Test transaction UndoTransaction() error ... ");
tximpl = factory->create(mgr, THROWS_UNDO_ERROR_FLAG);
if (!tximpl) {
@ -1916,7 +1876,7 @@ quick_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Test transaction UndoTransaction() error");
/*******************************************************************
*
@ -1924,8 +1884,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Test transaction RedoTransaction() error ... ");
tximpl = factory->create(mgr, THROWS_REDO_ERROR_FLAG);
if (!tximpl) {
@ -2080,7 +2038,7 @@ quick_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Test transaction RedoTransaction() error");
/*******************************************************************
*
@ -2090,8 +2048,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Test max transaction count of zero ... ");
result = mgr->SetMaxTransactionCount(0);
if (NS_FAILED(result)) {
@ -2180,7 +2136,7 @@ quick_test(TestTransactionFactory *factory)
}
}
printf("passed\n");
passed("Test max transaction count of zero");
/*******************************************************************
*
@ -2190,8 +2146,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Test SetMaxTransactionCount() greater than num stack items ... ");
result = mgr->SetMaxTransactionCount(-1);
if (NS_FAILED(result)) {
@ -2373,7 +2327,7 @@ quick_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Test SetMaxTransactionCount() greater than num stack items");
/*******************************************************************
*
@ -2383,8 +2337,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Test SetMaxTransactionCount() pruning undo stack ... ");
u1 = u2 = r1 = r2 = 0;
result = mgr->PeekUndoStack(&u1);
@ -2468,7 +2420,7 @@ quick_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Test SetMaxTransactionCount() pruning undo stack");
/*******************************************************************
*
@ -2478,8 +2430,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Test SetMaxTransactionCount() pruning redo stack ... ");
u1 = u2 = r1 = r2 = 0;
result = mgr->PeekUndoStack(&u1);
@ -2563,7 +2513,7 @@ quick_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Test SetMaxTransactionCount() pruning redo stack");
/*******************************************************************
*
@ -2572,8 +2522,6 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Release the transaction manager ... ");
result = mgr->SetMaxTransactionCount(-1);
if (NS_FAILED(result)) {
@ -2678,7 +2626,7 @@ quick_test(TestTransactionFactory *factory)
return result;
}
printf("passed\n");
passed("Release the transaction manager");
/*******************************************************************
*
@ -2687,16 +2635,14 @@ quick_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Number of transactions created and destroyed match ... ");
if (sConstructorCount != sDestructorCount) {
printf("ERROR: Transaction constructor count (%d) != destructor count (%d).\n",
sConstructorCount, sDestructorCount);
return NS_ERROR_FAILURE;
}
printf("passed\n");
printf("%d transactions processed during quick test.\n", sConstructorCount);
passed("Number of transactions created and destroyed match");
passed("%d transactions processed during quick test", sConstructorCount);
return NS_OK;
}
@ -2774,8 +2720,6 @@ quick_batch_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Create transaction manager instance ... ");
nsCOMPtr<nsITransactionManager> mgr =
do_CreateInstance(NS_TRANSACTIONMANAGER_CONTRACTID, &result);
if (NS_FAILED(result) || !mgr) {
@ -2783,7 +2727,7 @@ quick_batch_test(TestTransactionFactory *factory)
return NS_ERROR_OUT_OF_MEMORY;
}
printf("passed\n");
passed("Create transaction manager instance");
PRInt32 numitems;
@ -2794,8 +2738,6 @@ quick_batch_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Test unbalanced EndBatch() with empty undo stack ... ");
result = mgr->GetNumberOfUndoItems(&numitems);
if (NS_FAILED(result)) {
@ -2831,8 +2773,7 @@ quick_batch_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Test unbalanced EndBatch() with empty undo stack");
/*******************************************************************
*
@ -2841,8 +2782,6 @@ quick_batch_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Test empty batch ... ");
result = mgr->GetNumberOfUndoItems(&numitems);
if (NS_FAILED(result)) {
@ -2899,7 +2838,7 @@ quick_batch_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Test empty batch");
PRInt32 i;
TestTransaction *tximpl;
@ -2912,8 +2851,6 @@ quick_batch_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Execute 20 batched transactions ... ");
result = mgr->BeginBatch();
if (NS_FAILED(result)) {
@ -2981,7 +2918,7 @@ quick_batch_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Execute 20 batched transactions");
nsITransaction *u1, *u2;
nsITransaction *r1, *r2;
@ -2993,8 +2930,6 @@ quick_batch_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Execute 20 batched transient transactions ... ");
u1 = u2 = r1 = r2 = 0;
result = mgr->PeekUndoStack(&u1);
@ -3110,7 +3045,7 @@ quick_batch_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Execute 20 batched transient transactions");
/*******************************************************************
*
@ -3119,8 +3054,6 @@ quick_batch_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Test nested batched transactions ... ");
result = mgr->BeginBatch();
if (NS_FAILED(result)) {
@ -3285,7 +3218,7 @@ quick_batch_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Test nested batched transactions");
/*******************************************************************
*
@ -3294,8 +3227,6 @@ quick_batch_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Undo 2 batch transactions ... ");
for (i = 1; i <= 2; ++i) {
result = mgr->UndoTransaction();
if (NS_FAILED(result)) {
@ -3332,7 +3263,7 @@ quick_batch_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Undo 2 batch transactions");
/*******************************************************************
*
@ -3341,9 +3272,6 @@ quick_batch_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Redo 2 batch transactions ... ");
for (i = 1; i <= 2; ++i) {
result = mgr->RedoTransaction();
if (NS_FAILED(result)) {
@ -3380,7 +3308,7 @@ quick_batch_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Redo 2 batch transactions");
/*******************************************************************
*
@ -3389,8 +3317,6 @@ quick_batch_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Undo a batched transaction that was redone ... ");
result = mgr->UndoTransaction();
if (NS_FAILED(result)) {
@ -3426,7 +3352,7 @@ quick_batch_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Undo a batched transaction that was redone");
/*******************************************************************
*
@ -3435,8 +3361,6 @@ quick_batch_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Test effect of unbalanced EndBatch() on undo and redo stacks ... ");
result = mgr->EndBatch();
if (result != NS_ERROR_FAILURE) {
@ -3472,7 +3396,7 @@ quick_batch_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Test effect of unbalanced EndBatch() on undo and redo stacks");
/*******************************************************************
*
@ -3482,8 +3406,6 @@ quick_batch_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Test effect of empty batch on undo and redo stacks ... ");
result = mgr->BeginBatch();
if (NS_FAILED(result)) {
@ -3554,9 +3476,7 @@ quick_batch_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Test effect of empty batch on undo and redo stacks");
/*******************************************************************
*
@ -3564,8 +3484,6 @@ quick_batch_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Check if new batched transactions prune the redo stack ... ");
result = mgr->BeginBatch();
if (NS_FAILED(result)) {
@ -3661,7 +3579,7 @@ quick_batch_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Check if new batched transactions prune the redo stack");
/*******************************************************************
*
@ -3669,8 +3587,6 @@ quick_batch_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Call undo ... ");
// Move a transaction over to the redo stack, so that we have one
// transaction on the undo stack, and one on the redo stack!
@ -3709,7 +3625,7 @@ quick_batch_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Call undo");
/*******************************************************************
*
@ -3717,9 +3633,6 @@ quick_batch_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Test transaction DoTransaction() error ... ");
tximpl = factory->create(mgr, THROWS_DO_ERROR_FLAG);
if (!tximpl) {
@ -3835,7 +3748,7 @@ quick_batch_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Test transaction DoTransaction() error");
/*******************************************************************
*
@ -3843,8 +3756,6 @@ quick_batch_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Test transaction UndoTransaction() error ... ");
tximpl = factory->create(mgr, THROWS_UNDO_ERROR_FLAG);
if (!tximpl) {
@ -3967,7 +3878,7 @@ quick_batch_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Test transaction UndoTransaction() error");
/*******************************************************************
*
@ -3975,8 +3886,6 @@ quick_batch_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Test transaction RedoTransaction() error ... ");
tximpl = factory->create(mgr, THROWS_REDO_ERROR_FLAG);
if (!tximpl) {
@ -4145,7 +4054,7 @@ quick_batch_test(TestTransactionFactory *factory)
return NS_ERROR_FAILURE;
}
printf("passed\n");
passed("Test transaction RedoTransaction() error");
/*******************************************************************
*
@ -4155,8 +4064,6 @@ quick_batch_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Test max transaction count of zero ... ");
result = mgr->SetMaxTransactionCount(0);
if (NS_FAILED(result)) {
@ -4259,7 +4166,7 @@ quick_batch_test(TestTransactionFactory *factory)
}
}
printf("passed\n");
passed("Test max transaction count of zero");
/*******************************************************************
*
@ -4268,8 +4175,6 @@ quick_batch_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Release the transaction manager ... ");
result = mgr->SetMaxTransactionCount(-1);
if (NS_FAILED(result)) {
@ -4388,7 +4293,7 @@ quick_batch_test(TestTransactionFactory *factory)
return result;
}
printf("passed\n");
passed("Release the transaction manager");
/*******************************************************************
*
@ -4397,16 +4302,14 @@ quick_batch_test(TestTransactionFactory *factory)
*
*******************************************************************/
printf("Number of transactions created and destroyed match ... ");
if (sConstructorCount != sDestructorCount) {
printf("ERROR: Transaction constructor count (%d) != destructor count (%d).\n",
sConstructorCount, sDestructorCount);
return NS_ERROR_FAILURE;
}
printf("passed\n");
printf("%d transactions processed during quick batch test.\n",
passed("Number of transactions created and destroyed match");
passed("%d transactions processed during quick batch test",
sConstructorCount);
return NS_OK;
@ -4581,6 +4484,8 @@ stress_test(TestTransactionFactory *factory, PRInt32 iterations)
printf("%i ", j);
} // for, iterations.
printf("passed\n");
result = mgr->Clear();
if (NS_FAILED(result)) {
printf("ERROR: Clear() failed. (%d)\n", result);
@ -4593,9 +4498,7 @@ stress_test(TestTransactionFactory *factory, PRInt32 iterations)
return NS_ERROR_FAILURE;
}
printf("passed\n");
printf("%d transactions processed during stress test.\n", sConstructorCount);
passed("%d transactions processed during stress test", sConstructorCount);
return NS_OK;
}

Просмотреть файл

@ -66,6 +66,15 @@ NS_IMPL_ISUPPORTS_INHERITED1(GfxInfo, GfxInfoBase, nsIGfxInfoDebug)
static const PRUint32 allWindowsVersions = 0xffffffff;
/** Bug 711656
* HACK HACK HACK, one specific configuration seems broken, even with the
* blocklist: Intel 4500/HD
* Rather than backing this out, add a special case for this set.
* This should get backed out eventually.
*/
static PRUint32 gDeviceID;
static PRUint32 gVendorID;
#define V(a,b,c,d) GFX_DRIVER_VERSION(a,b,c,d)
@ -383,6 +392,10 @@ GfxInfo::Init()
SetupDiDestroyDeviceInfoList(devinfo);
}
/** Bug 711656: HACK HACK HACK */
gVendorID = ParseIDFromDeviceID(mDeviceID, "VEN_", 4);
gDeviceID = ParseIDFromDeviceID(mDeviceID, "&DEV_", 4);
mAdapterVendorID.AppendPrintf("0x%04x", ParseIDFromDeviceID(mDeviceID, "VEN_", 4));
mAdapterDeviceID.AppendPrintf("0x%04x", ParseIDFromDeviceID(mDeviceID, "&DEV_", 4));
mAdapterSubsysID = ParseIDFromDeviceID(mDeviceID, "&SUBSYS_", 8);
@ -901,6 +914,63 @@ GfxInfo::GetFeatureStatusImpl(PRInt32 aFeature,
if (aOS)
*aOS = os;
/** Bug 711656: HACK HACK HACK
* Special case this, even though it's already in the blocklist.
* Note that we're getting the driver version twice because the first one
* happens within the 'if (!aDriverInfo->Length())' check, but we don't want to
* modify that. Scope this within an anonymous block so that it's easier to
* remove later and clearer what is part of the hack.
*/
{
nsAutoString adapterDriverVersionString;
GetAdapterDriverVersion(adapterDriverVersionString);
PRUint64 driverVersion;
if (!ParseDriverVersion(adapterDriverVersionString, &driverVersion)) {
return NS_ERROR_FAILURE;
}
static PRUint32 IntelGMAX4500HD[] = {
0x2a42, /* IntelGMA4500MHD_1 */
0x2a43, /* IntelGMA4500MHD_2 */
0x2e42, /* IntelB43_1 */
0x2e43, /* IntelB43_2 */
0x2e92, /* IntelB43_3 */
0x2e93, /* IntelB43_4 */
0x2e32, /* IntelG41_1 */
0x2e33, /* IntelG41_2 */
0x2e22, /* IntelG45_1 */
0x2e23, /* IntelG45_2 */
0x2e12, /* IntelQ45_1 */
0x2e13, /* IntelQ45_2 */
0x0042, /* IntelHDGraphics */
0x0046, /* IntelMobileHDGraphics */
0x0102, /* IntelSandyBridge_1 */
0x0106, /* IntelSandyBridge_2 */
0x0112, /* IntelSandyBridge_3 */
0x0116, /* IntelSandyBridge_4 */
0x0122, /* IntelSandyBridge_5 */
0x0126, /* IntelSandyBridge_6 */
0x010a, /* IntelSandyBridge_7 */
0x0080 /* IntelIvyBridge */
};
if (((mWindowsVersion == gfxWindowsPlatform::kWindowsXP &&
driverVersion < V(6,14,10,5284)) ||
(mWindowsVersion == gfxWindowsPlatform::kWindowsVista &&
driverVersion < V(8,15,10,2202)) ||
(mWindowsVersion == gfxWindowsPlatform::kWindows7 &&
driverVersion < V(8,15,10,2202))) &&
gVendorID == 0x8086 /* Intel */) {
for (PRUint32 i = 0; i < ArrayLength(IntelGMAX4500HD); i++) {
if (IntelGMAX4500HD[i] == gDeviceID) {
*aStatus = nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION;
return NS_OK;
}
}
}
}
// Don't evaluate special cases if we're checking the downloaded blocklist.
if (!aDriverInfo.Length()) {
nsAutoString adapterVendorID;

Просмотреть файл

@ -94,13 +94,21 @@ void fail(const char* msg, ...)
}
/**
* Prints the given string prepending "TEST-PASS | " for the benefit of
* the test harness and with "\n" at the end, to be used at the end of a
* successful test function.
* Prints the given success message and arguments using printf, prepending
* "TEST-PASS " for the benefit of the test harness and
* appending "\n" to eliminate having to type it at each call site.
*/
void passed(const char* test)
void passed(const char* msg, ...)
{
printf("TEST-PASS | %s\n", test);
va_list ap;
printf("TEST-PASS | ");
va_start(ap, msg);
vprintf(msg, ap);
va_end(ap);
putchar('\n');
}
//-----------------------------------------------------------------------------