diff --git a/lib/editor/atto/plugins/undo/yui/build/moodle-atto_undo-button/moodle-atto_undo-button-debug.js b/lib/editor/atto/plugins/undo/yui/build/moodle-atto_undo-button/moodle-atto_undo-button-debug.js index 50a76a4da80..81ceac4af17 100644 --- a/lib/editor/atto/plugins/undo/yui/build/moodle-atto_undo-button/moodle-atto_undo-button-debug.js +++ b/lib/editor/atto/plugins/undo/yui/build/moodle-atto_undo-button/moodle-atto_undo-button-debug.js @@ -25,6 +25,8 @@ YUI.add('moodle-atto_undo-button', function (Y, NAME) { * @module moodle-atto_undo-button */ +var LOGNAME = 'moodle-atto_undo-button'; + /** * Atto text editor undo plugin. * @@ -86,34 +88,168 @@ Y.namespace('M.atto_undo').Button = Y.Base.create('button', Y.M.editor_atto.Edit keys: 89 }); - this.get('host').on('atto:selectionchanged', this._changeListener, this); + // Enable the undo once everything has loaded. + this.get('host').on('pluginsloaded', function() { + // Adds the current value to the stack. + this._addToUndo(this._getHTML()); + this.get('host').on('atto:selectionchanged', this._changeListener, this); + }, this); + + this._updateButtonsStates(); + }, + + /** + * Adds an element to the redo stack. + * + * @method _addToRedo + * @private + * @param {String} html The HTML content to save. + */ + _addToRedo: function(html) { + this._redoStack.push(html); + }, + + /** + * Adds an element to the undo stack. + * + * @method _addToUndo + * @private + * @param {String} html The HTML content to save. + * @param {Boolean} [clearRedo=false] Whether or not we should clear the redo stack. + */ + _addToUndo: function(html, clearRedo) { + var last = this._undoStack[this._undoStack.length - 1]; + + if (typeof clearRedo === 'undefined') { + clearRedo = false; + } + + if (typeof last === 'undefined') { + Y.log('Oops, nothing was in the undo stack! There should always be something in there.', 'warn', LOGNAME); + } + + if (last !== html) { + this._undoStack.push(html); + if (clearRedo) { + this._redoStack = []; + } + } + + while (this._undoStack.length > this._maxUndos) { + this._undoStack.shift(); + } + }, + + /** + * Get the editor HTML. + * + * @method _getHTML + * @private + * @return {String} The HTML. + */ + _getHTML: function() { + return this.get('host').getCleanHTML(); + }, + + /** + * Get an element on the redo stack. + * + * @method _getRedo + * @private + * @return {String} The HTML to restore, or undefined. + */ + _getRedo: function() { + return this._redoStack.pop(); + }, + + /** + * Get an element on the undo stack. + * + * @method _getUndo + * @private + * @param {String} current The current HTML. + * @return {String} The HTML to restore. + */ + _getUndo: function(current) { + if (this._undoStack.length === 1) { + return this._undoStack[0]; + } + + last = this._undoStack.pop(); + if (last === current) { + // Oops, the latest undo step is the current content, we should unstack once more. + // There is no need to do that in a loop as the same stack should never contain duplicates. + last = this._undoStack.pop(); + } + + // We always need to keep the first element of the stack. + if (this._undoStack.length === 0) { + this._addToUndo(last); + } + + return last; + }, + + /** + * Restore a value from a stack. + * + * @method _restoreValue + * @private + * @param {String} html The HTML to restore in the editor. + */ + _restoreValue: function(html) { + this.editor.setHTML(html); + // We always add the restored value to the stack, otherwise an event could think that + // the content has changed and clear the redo stack. + this._addToUndo(html); + }, + + /** + * Update the states of the buttons. + * + * @method _updateButtonsStates + * @private + */ + _updateButtonsStates: function() { + if (this._undoStack.length > 1) { + this.enableButtons('undo'); + } else { + this.disableButtons('undo'); + } + + if (this._redoStack.length > 0) { + this.enableButtons('redo'); + } else { + this.disableButtons('redo'); + } }, /** * Handle a click on undo * * @method _undoHandler + * @param {Event} The click event * @private */ - _undoHandler: function() { - var html = this.editor.getHTML(); + _undoHandler: function(e) { + e.preventDefault(); + var html = this._getHTML(), + undo = this._getUndo(html); - this._redoStack.push(html); - var last = this._undoStack.pop(); - if (last === html) { - last = this._undoStack.pop(); - } - if (last) { - this.editor.setHTML(last); - // Put it back in the undo stack so a new event wont clear the redo stack. - this._undoStack.push(last); - this.highlightButtons('redo'); + // Edge case, but that could happen. We do nothing when the content equals the undo step. + if (html === undo) { + this._updateButtonsStates(); + return; } - if (this._undoStack.length === 0) { - // If there are no undos left, unhighlight the undo button. - this.unHighlightButtons('undo'); - } + // Restore the value. + this._restoreValue(undo); + + // Add to the redo stack. + this._addToRedo(html); + + // Update the button states. + this._updateButtonsStates(); }, /** @@ -125,12 +261,19 @@ Y.namespace('M.atto_undo').Button = Y.Base.create('button', Y.M.editor_atto.Edit */ _redoHandler: function(e) { e.preventDefault(); - var html = this.editor.getHTML(); + var html = this._getHTML(), + redo = this._getRedo(); - this._undoStack.push(html); - var last = this._redoStack.pop(); - this.editor.setHTML(last); - this._undoStack.push(last); + // Edge case, but that could happen. We do nothing when the content equals the redo step. + if (html === redo) { + this._updateButtonsStates(); + return; + } + // Restore the value. + this._restoreValue(redo); + + // Update the button states. + this._updateButtonsStates(); }, /** @@ -144,36 +287,16 @@ Y.namespace('M.atto_undo').Button = Y.Base.create('button', Y.M.editor_atto.Edit if (e.event.type.indexOf('key') !== -1) { // These are the 4 arrow keys. if ((e.event.keyCode !== 39) && - (e.event.keyCode !== 37) && - (e.event.keyCode !== 40) && - (e.event.keyCode !== 38)) { + (e.event.keyCode !== 37) && + (e.event.keyCode !== 40) && + (e.event.keyCode !== 38)) { // Skip this event type. We only want focus/mouse/arrow events. return; } } - if (typeof this._undoStack === 'undefined') { - this._undoStack = []; - } - - var last = this._undoStack[this._undoStack.length-1]; - var html = this.editor.getHTML(); - if (last !== html) { - this._undoStack.push(this.editor.getHTML()); - this._redoStack = []; - this.unHighlightButtons('redo'); - } - - while (this._undoStack.length > this._maxUndos) { - this._undoStack.shift(); - } - - // Show in the buttons if undo/redo is possible. - if (this._undoStack.length) { - this.highlightButtons('undo'); - } else { - this.unHighlightButtons('undo'); - } + this._addToUndo(this._getHTML(), true); + this._updateButtonsStates(); } }); diff --git a/lib/editor/atto/plugins/undo/yui/build/moodle-atto_undo-button/moodle-atto_undo-button-min.js b/lib/editor/atto/plugins/undo/yui/build/moodle-atto_undo-button/moodle-atto_undo-button-min.js index 0c1a4ef5789..c93d2166e34 100644 --- a/lib/editor/atto/plugins/undo/yui/build/moodle-atto_undo-button/moodle-atto_undo-button-min.js +++ b/lib/editor/atto/plugins/undo/yui/build/moodle-atto_undo-button/moodle-atto_undo-button-min.js @@ -1 +1 @@ -YUI.add("moodle-atto_undo-button",function(e,t){e.namespace("M.atto_undo").Button=e.Base.create("button",e.M.editor_atto.EditorPlugin,[],{_maxUndos:40,_undoStack:null,_redoStack:null,initializer:function(){this._undoStack=[],this._redoStack=[],this.addButton({icon:"e/undo",callback:this._undoHandler,buttonName:"undo",keys:90}),this.addButton({icon:"e/redo",callback:this._redoHandler,buttonName:"redo",keys:89}),this.get("host").on("atto:selectionchanged",this._changeListener,this)},_undoHandler:function(){var e=this.editor.getHTML();this._redoStack.push(e);var t=this._undoStack.pop();t===e&&(t=this._undoStack.pop()),t&&(this.editor.setHTML(t),this._undoStack.push(t),this.highlightButtons("redo")),this._undoStack.length===0&&this.unHighlightButtons("undo")},_redoHandler:function(e){e.preventDefault();var t=this.editor.getHTML();this._undoStack.push(t);var n=this._redoStack.pop();this.editor.setHTML(n),this._undoStack.push(n)},_changeListener:function(e){if(e.event.type.indexOf("key")!==-1&&e.event.keyCode!==39&&e.event.keyCode!==37&&e.event.keyCode!==40&&e.event.keyCode!==38)return;typeof this._undoStack=="undefined"&&(this._undoStack=[]);var t=this._undoStack[this._undoStack.length-1],n=this.editor.getHTML();t!==n&&(this._undoStack.push(this.editor.getHTML()),this._redoStack=[],this.unHighlightButtons("redo"));while(this._undoStack.length>this._maxUndos)this._undoStack.shift();this._undoStack.length?this.highlightButtons("undo"):this.unHighlightButtons("undo")}})},"@VERSION@",{requires:["moodle-editor_atto-plugin"]}); +YUI.add("moodle-atto_undo-button",function(e,t){var n="moodle-atto_undo-button";e.namespace("M.atto_undo").Button=e.Base.create("button",e.M.editor_atto.EditorPlugin,[],{_maxUndos:40,_undoStack:null,_redoStack:null,initializer:function(){this._undoStack=[],this._redoStack=[],this.addButton({icon:"e/undo",callback:this._undoHandler,buttonName:"undo",keys:90}),this.addButton({icon:"e/redo",callback:this._redoHandler,buttonName:"redo",keys:89}),this.get("host").on("pluginsloaded",function(){this._addToUndo(this._getHTML()),this.get("host").on("atto:selectionchanged",this._changeListener,this)},this),this._updateButtonsStates()},_addToRedo:function(e){this._redoStack.push(e)},_addToUndo:function(e,t){var n=this._undoStack[this._undoStack.length-1];typeof t=="undefined"&&(t=!1),typeof n=="undefined",n!==e&&(this._undoStack.push(e),t&&(this._redoStack=[]));while(this._undoStack.length>this._maxUndos)this._undoStack.shift()},_getHTML:function(){return this.get("host").getCleanHTML()},_getRedo:function(){return this._redoStack.pop()},_getUndo:function(e){return this._undoStack.length===1?this._undoStack[0]:(last=this._undoStack.pop(),last===e&&(last=this._undoStack.pop()),this._undoStack.length===0&&this._addToUndo(last),last)},_restoreValue:function(e){this.editor.setHTML(e),this._addToUndo(e)},_updateButtonsStates:function(){this._undoStack.length>1?this.enableButtons("undo"):this.disableButtons("undo"),this._redoStack.length>0?this.enableButtons("redo"):this.disableButtons("redo")},_undoHandler:function(e){e.preventDefault();var t=this._getHTML(),n=this._getUndo(t);if(t===n){this._updateButtonsStates();return}this._restoreValue(n),this._addToRedo(t),this._updateButtonsStates()},_redoHandler:function(e){e.preventDefault();var t=this._getHTML(),n=this._getRedo();if(t===n){this._updateButtonsStates();return}this._restoreValue(n),this._updateButtonsStates()},_changeListener:function(e){if(e.event.type.indexOf("key")!==-1&&e.event.keyCode!==39&&e.event.keyCode!==37&&e.event.keyCode!==40&&e.event.keyCode!==38)return;this._addToUndo(this._getHTML(),!0),this._updateButtonsStates()}})},"@VERSION@",{requires:["moodle-editor_atto-plugin"]}); diff --git a/lib/editor/atto/plugins/undo/yui/build/moodle-atto_undo-button/moodle-atto_undo-button.js b/lib/editor/atto/plugins/undo/yui/build/moodle-atto_undo-button/moodle-atto_undo-button.js index 50a76a4da80..f13bcedee64 100644 --- a/lib/editor/atto/plugins/undo/yui/build/moodle-atto_undo-button/moodle-atto_undo-button.js +++ b/lib/editor/atto/plugins/undo/yui/build/moodle-atto_undo-button/moodle-atto_undo-button.js @@ -25,6 +25,8 @@ YUI.add('moodle-atto_undo-button', function (Y, NAME) { * @module moodle-atto_undo-button */ +var LOGNAME = 'moodle-atto_undo-button'; + /** * Atto text editor undo plugin. * @@ -86,34 +88,167 @@ Y.namespace('M.atto_undo').Button = Y.Base.create('button', Y.M.editor_atto.Edit keys: 89 }); - this.get('host').on('atto:selectionchanged', this._changeListener, this); + // Enable the undo once everything has loaded. + this.get('host').on('pluginsloaded', function() { + // Adds the current value to the stack. + this._addToUndo(this._getHTML()); + this.get('host').on('atto:selectionchanged', this._changeListener, this); + }, this); + + this._updateButtonsStates(); + }, + + /** + * Adds an element to the redo stack. + * + * @method _addToRedo + * @private + * @param {String} html The HTML content to save. + */ + _addToRedo: function(html) { + this._redoStack.push(html); + }, + + /** + * Adds an element to the undo stack. + * + * @method _addToUndo + * @private + * @param {String} html The HTML content to save. + * @param {Boolean} [clearRedo=false] Whether or not we should clear the redo stack. + */ + _addToUndo: function(html, clearRedo) { + var last = this._undoStack[this._undoStack.length - 1]; + + if (typeof clearRedo === 'undefined') { + clearRedo = false; + } + + if (typeof last === 'undefined') { + } + + if (last !== html) { + this._undoStack.push(html); + if (clearRedo) { + this._redoStack = []; + } + } + + while (this._undoStack.length > this._maxUndos) { + this._undoStack.shift(); + } + }, + + /** + * Get the editor HTML. + * + * @method _getHTML + * @private + * @return {String} The HTML. + */ + _getHTML: function() { + return this.get('host').getCleanHTML(); + }, + + /** + * Get an element on the redo stack. + * + * @method _getRedo + * @private + * @return {String} The HTML to restore, or undefined. + */ + _getRedo: function() { + return this._redoStack.pop(); + }, + + /** + * Get an element on the undo stack. + * + * @method _getUndo + * @private + * @param {String} current The current HTML. + * @return {String} The HTML to restore. + */ + _getUndo: function(current) { + if (this._undoStack.length === 1) { + return this._undoStack[0]; + } + + last = this._undoStack.pop(); + if (last === current) { + // Oops, the latest undo step is the current content, we should unstack once more. + // There is no need to do that in a loop as the same stack should never contain duplicates. + last = this._undoStack.pop(); + } + + // We always need to keep the first element of the stack. + if (this._undoStack.length === 0) { + this._addToUndo(last); + } + + return last; + }, + + /** + * Restore a value from a stack. + * + * @method _restoreValue + * @private + * @param {String} html The HTML to restore in the editor. + */ + _restoreValue: function(html) { + this.editor.setHTML(html); + // We always add the restored value to the stack, otherwise an event could think that + // the content has changed and clear the redo stack. + this._addToUndo(html); + }, + + /** + * Update the states of the buttons. + * + * @method _updateButtonsStates + * @private + */ + _updateButtonsStates: function() { + if (this._undoStack.length > 1) { + this.enableButtons('undo'); + } else { + this.disableButtons('undo'); + } + + if (this._redoStack.length > 0) { + this.enableButtons('redo'); + } else { + this.disableButtons('redo'); + } }, /** * Handle a click on undo * * @method _undoHandler + * @param {Event} The click event * @private */ - _undoHandler: function() { - var html = this.editor.getHTML(); + _undoHandler: function(e) { + e.preventDefault(); + var html = this._getHTML(), + undo = this._getUndo(html); - this._redoStack.push(html); - var last = this._undoStack.pop(); - if (last === html) { - last = this._undoStack.pop(); - } - if (last) { - this.editor.setHTML(last); - // Put it back in the undo stack so a new event wont clear the redo stack. - this._undoStack.push(last); - this.highlightButtons('redo'); + // Edge case, but that could happen. We do nothing when the content equals the undo step. + if (html === undo) { + this._updateButtonsStates(); + return; } - if (this._undoStack.length === 0) { - // If there are no undos left, unhighlight the undo button. - this.unHighlightButtons('undo'); - } + // Restore the value. + this._restoreValue(undo); + + // Add to the redo stack. + this._addToRedo(html); + + // Update the button states. + this._updateButtonsStates(); }, /** @@ -125,12 +260,19 @@ Y.namespace('M.atto_undo').Button = Y.Base.create('button', Y.M.editor_atto.Edit */ _redoHandler: function(e) { e.preventDefault(); - var html = this.editor.getHTML(); + var html = this._getHTML(), + redo = this._getRedo(); - this._undoStack.push(html); - var last = this._redoStack.pop(); - this.editor.setHTML(last); - this._undoStack.push(last); + // Edge case, but that could happen. We do nothing when the content equals the redo step. + if (html === redo) { + this._updateButtonsStates(); + return; + } + // Restore the value. + this._restoreValue(redo); + + // Update the button states. + this._updateButtonsStates(); }, /** @@ -144,36 +286,16 @@ Y.namespace('M.atto_undo').Button = Y.Base.create('button', Y.M.editor_atto.Edit if (e.event.type.indexOf('key') !== -1) { // These are the 4 arrow keys. if ((e.event.keyCode !== 39) && - (e.event.keyCode !== 37) && - (e.event.keyCode !== 40) && - (e.event.keyCode !== 38)) { + (e.event.keyCode !== 37) && + (e.event.keyCode !== 40) && + (e.event.keyCode !== 38)) { // Skip this event type. We only want focus/mouse/arrow events. return; } } - if (typeof this._undoStack === 'undefined') { - this._undoStack = []; - } - - var last = this._undoStack[this._undoStack.length-1]; - var html = this.editor.getHTML(); - if (last !== html) { - this._undoStack.push(this.editor.getHTML()); - this._redoStack = []; - this.unHighlightButtons('redo'); - } - - while (this._undoStack.length > this._maxUndos) { - this._undoStack.shift(); - } - - // Show in the buttons if undo/redo is possible. - if (this._undoStack.length) { - this.highlightButtons('undo'); - } else { - this.unHighlightButtons('undo'); - } + this._addToUndo(this._getHTML(), true); + this._updateButtonsStates(); } }); diff --git a/lib/editor/atto/plugins/undo/yui/src/button/js/button.js b/lib/editor/atto/plugins/undo/yui/src/button/js/button.js index d95b725234b..026e4a24409 100644 --- a/lib/editor/atto/plugins/undo/yui/src/button/js/button.js +++ b/lib/editor/atto/plugins/undo/yui/src/button/js/button.js @@ -23,6 +23,8 @@ * @module moodle-atto_undo-button */ +var LOGNAME = 'moodle-atto_undo-button'; + /** * Atto text editor undo plugin. * @@ -84,34 +86,168 @@ Y.namespace('M.atto_undo').Button = Y.Base.create('button', Y.M.editor_atto.Edit keys: 89 }); - this.get('host').on('atto:selectionchanged', this._changeListener, this); + // Enable the undo once everything has loaded. + this.get('host').on('pluginsloaded', function() { + // Adds the current value to the stack. + this._addToUndo(this._getHTML()); + this.get('host').on('atto:selectionchanged', this._changeListener, this); + }, this); + + this._updateButtonsStates(); + }, + + /** + * Adds an element to the redo stack. + * + * @method _addToRedo + * @private + * @param {String} html The HTML content to save. + */ + _addToRedo: function(html) { + this._redoStack.push(html); + }, + + /** + * Adds an element to the undo stack. + * + * @method _addToUndo + * @private + * @param {String} html The HTML content to save. + * @param {Boolean} [clearRedo=false] Whether or not we should clear the redo stack. + */ + _addToUndo: function(html, clearRedo) { + var last = this._undoStack[this._undoStack.length - 1]; + + if (typeof clearRedo === 'undefined') { + clearRedo = false; + } + + if (typeof last === 'undefined') { + Y.log('Oops, nothing was in the undo stack! There should always be something in there.', 'warn', LOGNAME); + } + + if (last !== html) { + this._undoStack.push(html); + if (clearRedo) { + this._redoStack = []; + } + } + + while (this._undoStack.length > this._maxUndos) { + this._undoStack.shift(); + } + }, + + /** + * Get the editor HTML. + * + * @method _getHTML + * @private + * @return {String} The HTML. + */ + _getHTML: function() { + return this.get('host').getCleanHTML(); + }, + + /** + * Get an element on the redo stack. + * + * @method _getRedo + * @private + * @return {String} The HTML to restore, or undefined. + */ + _getRedo: function() { + return this._redoStack.pop(); + }, + + /** + * Get an element on the undo stack. + * + * @method _getUndo + * @private + * @param {String} current The current HTML. + * @return {String} The HTML to restore. + */ + _getUndo: function(current) { + if (this._undoStack.length === 1) { + return this._undoStack[0]; + } + + last = this._undoStack.pop(); + if (last === current) { + // Oops, the latest undo step is the current content, we should unstack once more. + // There is no need to do that in a loop as the same stack should never contain duplicates. + last = this._undoStack.pop(); + } + + // We always need to keep the first element of the stack. + if (this._undoStack.length === 0) { + this._addToUndo(last); + } + + return last; + }, + + /** + * Restore a value from a stack. + * + * @method _restoreValue + * @private + * @param {String} html The HTML to restore in the editor. + */ + _restoreValue: function(html) { + this.editor.setHTML(html); + // We always add the restored value to the stack, otherwise an event could think that + // the content has changed and clear the redo stack. + this._addToUndo(html); + }, + + /** + * Update the states of the buttons. + * + * @method _updateButtonsStates + * @private + */ + _updateButtonsStates: function() { + if (this._undoStack.length > 1) { + this.enableButtons('undo'); + } else { + this.disableButtons('undo'); + } + + if (this._redoStack.length > 0) { + this.enableButtons('redo'); + } else { + this.disableButtons('redo'); + } }, /** * Handle a click on undo * * @method _undoHandler + * @param {Event} The click event * @private */ - _undoHandler: function() { - var html = this.editor.getHTML(); + _undoHandler: function(e) { + e.preventDefault(); + var html = this._getHTML(), + undo = this._getUndo(html); - this._redoStack.push(html); - var last = this._undoStack.pop(); - if (last === html) { - last = this._undoStack.pop(); - } - if (last) { - this.editor.setHTML(last); - // Put it back in the undo stack so a new event wont clear the redo stack. - this._undoStack.push(last); - this.highlightButtons('redo'); + // Edge case, but that could happen. We do nothing when the content equals the undo step. + if (html === undo) { + this._updateButtonsStates(); + return; } - if (this._undoStack.length === 0) { - // If there are no undos left, unhighlight the undo button. - this.unHighlightButtons('undo'); - } + // Restore the value. + this._restoreValue(undo); + + // Add to the redo stack. + this._addToRedo(html); + + // Update the button states. + this._updateButtonsStates(); }, /** @@ -123,12 +259,19 @@ Y.namespace('M.atto_undo').Button = Y.Base.create('button', Y.M.editor_atto.Edit */ _redoHandler: function(e) { e.preventDefault(); - var html = this.editor.getHTML(); + var html = this._getHTML(), + redo = this._getRedo(); - this._undoStack.push(html); - var last = this._redoStack.pop(); - this.editor.setHTML(last); - this._undoStack.push(last); + // Edge case, but that could happen. We do nothing when the content equals the redo step. + if (html === redo) { + this._updateButtonsStates(); + return; + } + // Restore the value. + this._restoreValue(redo); + + // Update the button states. + this._updateButtonsStates(); }, /** @@ -142,35 +285,15 @@ Y.namespace('M.atto_undo').Button = Y.Base.create('button', Y.M.editor_atto.Edit if (e.event.type.indexOf('key') !== -1) { // These are the 4 arrow keys. if ((e.event.keyCode !== 39) && - (e.event.keyCode !== 37) && - (e.event.keyCode !== 40) && - (e.event.keyCode !== 38)) { + (e.event.keyCode !== 37) && + (e.event.keyCode !== 40) && + (e.event.keyCode !== 38)) { // Skip this event type. We only want focus/mouse/arrow events. return; } } - if (typeof this._undoStack === 'undefined') { - this._undoStack = []; - } - - var last = this._undoStack[this._undoStack.length-1]; - var html = this.editor.getHTML(); - if (last !== html) { - this._undoStack.push(this.editor.getHTML()); - this._redoStack = []; - this.unHighlightButtons('redo'); - } - - while (this._undoStack.length > this._maxUndos) { - this._undoStack.shift(); - } - - // Show in the buttons if undo/redo is possible. - if (this._undoStack.length) { - this.highlightButtons('undo'); - } else { - this.unHighlightButtons('undo'); - } + this._addToUndo(this._getHTML(), true); + this._updateButtonsStates(); } });