Bug 983623 - Async transactions: Add a preference for turning it, implement undo & redo commands. r=mak

This commit is contained in:
Asaf Romano 2014-03-15 23:49:07 +02:00
parent d8b7e0920c
commit 0377790278
4 changed files with 99 additions and 13 deletions

View File

@ -124,11 +124,38 @@ PlacesController.prototype = {
},
isCommandEnabled: function PC_isCommandEnabled(aCommand) {
if (PlacesUIUtils.useAsyncTransactions) {
switch (aCommand) {
case "cmd_cut":
case "placesCmd_cut":
case "cmd_copy":
case "cmd_paste":
case "cmd_delete":
case "placesCmd_delete":
case "placesCmd_moveBookmarks":
case "cmd_paste":
case "placesCmd_paste":
case "placesCmd_new:folder":
case "placesCmd_new:livemark":
case "placesCmd_new:bookmark":
case "placesCmd_new:separator":
case "placesCmd_sortBy:name":
case "placesCmd_createBookmark":
return false;
}
}
switch (aCommand) {
case "cmd_undo":
return PlacesUtils.transactionManager.numberOfUndoItems > 0;
if (!PlacesUIUtils.useAsyncTransactions)
return PlacesUtils.transactionManager.numberOfUndoItems > 0;
return PlacesTransactions.topUndoEntry != null;
case "cmd_redo":
return PlacesUtils.transactionManager.numberOfRedoItems > 0;
if (!PlacesUIUtils.useAsyncTransactions)
return PlacesUtils.transactionManager.numberOfRedoItems > 0;
return PlacesTransactions.topRedoEntry != null;
case "cmd_cut":
case "placesCmd_cut":
var nodes = this._view.selectedNodes;

View File

@ -1022,6 +1022,14 @@ XPCOMUtils.defineLazyGetter(PlacesUIUtils, "ellipsis", function() {
Ci.nsIPrefLocalizedString).data;
});
XPCOMUtils.defineLazyGetter(PlacesUIUtils, "useAsyncTransactions", function() {
try {
return Services.prefs.getBoolPref("browser.places.useAsyncTransactions");
}
catch(ex) { }
return false;
});
XPCOMUtils.defineLazyServiceGetter(this, "URIFixup",
"@mozilla.org/docshell/urifixup;1",
"nsIURIFixup");

View File

@ -121,6 +121,7 @@ this.EXPORTED_SYMBOLS = ["PlacesTransactions"];
*/
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
"resource://gre/modules/Promise.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Task",
@ -132,6 +133,18 @@ XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
XPCOMUtils.defineLazyModuleGetter(this, "console",
"resource://gre/modules/devtools/Console.jsm");
// Updates commands in the undo group of the active window commands.
// Inactive windows commands will be updated on focus.
function updateCommandsOnActiveWindow() {
// Updating "undo" will cause a group update including "redo".
try {
let win = Services.focus.activeWindow;
if (win)
win.updateCommands("undo");
}
catch(ex) { console.error(ex, "Couldn't update undo commands"); }
}
// The internal object for managing the transactions history.
// The public API is included in PlacesTransactions.
// TODO bug 982099: extending the array "properly" makes it painful to implement
@ -173,6 +186,7 @@ TransactionsHistory.__proto__ = {
}
}
this._undoPosition++;
updateCommandsOnActiveWindow();
},
/**
@ -201,6 +215,7 @@ TransactionsHistory.__proto__ = {
}
}
this._undoPosition--;
updateCommandsOnActiveWindow();
},
/**
@ -222,6 +237,7 @@ TransactionsHistory.__proto__ = {
else {
this[this.undoPosition].unshift(aTransaction);
}
updateCommandsOnActiveWindow();
},
/**
@ -411,7 +427,7 @@ let PlacesTransactions = {
* @note the returned array is a clone of the history entry and is not
* kept in sync with the original entry if it changes.
*/
item: function (aIndex) {
entry: function (aIndex) {
if (!Number.isInteger(aIndex) || aIndex < 0 || aIndex >= this.length)
throw new Error("Invalid index");
@ -425,6 +441,16 @@ let PlacesTransactions = {
* Entries at and past this point are redo entries.
*/
get undoPosition() TransactionsHistory.undoPosition,
/**
* Shortcut for accessing the top undo entry in the transaction history.
*/
get topUndoEntry() TransactionsHistory.topUndoEntry,
/**
* Shortcut for accessing the top redo entry in the transaction history.
*/
get topRedoEntry() TransactionsHistory.topRedoEntry
};
/**

View File

@ -116,18 +116,43 @@ function run_test() {
run_next_test();
}
function ensureUndoState(aEntries = [], aUndoPosition = 0) {
do_check_eq(PT.length, aEntries.length);
do_check_eq(PT.undoPosition, aUndoPosition);
function sanityCheckTransactionHistory() {
do_check_true(PT.undoPosition <= PT.length);
for (let i = 0; i < aEntries.length; i++) {
let testEntry = aEntries[i];
let undoEntry = PT.item(i);
do_check_eq(testEntry.length, undoEntry.length);
for (let j = 0; j < testEntry.length; j++) {
do_check_eq(testEntry[j], undoEntry[j]);
}
let check_entry_throws = f => {
try {
f();
do_throw("PT.entry should throw for invalid input");
} catch(ex) {}
};
check_entry_throws( () => PT.entry(-1) );
check_entry_throws( () => PT.entry({}) );
check_entry_throws( () => PT.entry(PT.length) );
if (PT.undoPosition < PT.length)
do_check_eq(PT.topUndoEntry, PT.entry(PT.undoPosition));
else
do_check_null(PT.topUndoEntry);
if (PT.undoPosition > 0)
do_check_eq(PT.topRedoEntry, PT.entry(PT.undoPosition - 1));
else
do_check_null(PT.topRedoEntry);
}
function ensureUndoState(aExpectedEntries = [], aExpectedUndoPosition = 0) {
// ensureUndoState is called in various places during this test, so it's
// a good places to sanity-check the transaction-history APIs in all
// cases.
sanityCheckTransactionHistory();
do_check_eq(PT.length, aExpectedEntries.length);
do_check_eq(PT.undoPosition, aExpectedUndoPosition);
function checkEqualEntries(aExpectedEntry, aActualEntry) {
do_check_eq(aExpectedEntry.length, aActualEntry.length);
aExpectedEntry.forEach( (t, i) => do_check_eq(t, aActualEntry[i]) );
}
aExpectedEntries.forEach( (e, i) => checkEqualEntries(e, PT.entry(i)) );
}
function ensureItemsAdded(...items) {