ack.slice(start, this._index); const batch = this._batch; delete this._batch; const entry = { do() { for (const item of batch) { item.do(); } }, undo() { for (let i = batch.length - 1; i >= 0; i--) { batch[i].undo(); } }, }; this._stack.push(entry); this._index = this._stack.length; entry.do(); } /** * Perform an action, adding it to the undo stack. * * @param function toDo Called to perform the action. * @param function undo Called to reverse the action. */ do(toDo, undo) { this.startBatch(); this._batch.push({ do: toDo, undo }); this.endBatch(); } /* * Returns true if undo() will do anything. */ canUndo() { return this._index > 0; } /** * Undo the top of the undo stack. * * @return true if an action was undone. */ undo() { if (!this.canUndo()) { return false; } this._stack[--this._index].undo(); return true; } /** * Returns true if redo() will do anything. */ canRedo() { return this._stack.length > this._index; } /** * Redo the most recently undone action. * * @return true if an action was redone. */ redo() { if (!this.canRedo()) { return false; } this._stack[this._index++].do(); return true; } /** * ViewController implementation for undo/redo. */ /** * Install this object as a command controller. */ installController(controllerWindow) { const controllers = controllerWindow.controllers; // Only available when running in a Firefox panel. if (!controllers || !controllers.appendController) { return; } this._controllerWindow = controllerWindow; controllers.appendController(this); } /** * Uninstall this object from the command controller. */ uninstallController() { if (!this._controllerWindow) { return; } this._controllerWindow.controllers.removeController(this); } supportsCommand(command) { return command == "cmd_undo" || command == "cmd_redo"; } isCommandEnabled(command) { switch (command) { case "cmd_undo": return this.canUndo(); case "cmd_redo": return this.canRedo(); } return false; } doCommand(command) { switch (command) { case "cmd_undo": return this.undo(); case "cmd_redo": return this.redo(); default: return null; } } onEvent() {} } exports.UndoStack = UndoStack; PK