Index: trunk/extensions/VisualEditor/modules/es/views/es.SurfaceView.js |
— | — | @@ -151,6 +151,9 @@ |
152 | 152 | } |
153 | 153 | }; |
154 | 154 | |
| 155 | +var transactionStack = []; |
| 156 | +var undoCounter = 0; |
| 157 | + |
155 | 158 | es.SurfaceView.prototype.onKeyDown = function( e ) { |
156 | 159 | switch ( e.keyCode ) { |
157 | 160 | case 16: // Shift |
— | — | @@ -196,22 +199,50 @@ |
197 | 200 | break; |
198 | 201 | case 8: // Backspace |
199 | 202 | var transaction = this.documentView.model.prepareRemoval( new es.Range( this.selection.to, this.selection.to - 1 ) ); |
| 203 | + transactionStack.push ( transaction ); |
| 204 | + |
200 | 205 | this.documentView.model.commit ( transaction ); |
201 | 206 | this.selection.from = this.selection.to -= 1; |
202 | 207 | this.showCursor(); |
203 | 208 | break; |
204 | 209 | case 46: // Delete |
205 | 210 | var transaction = this.documentView.model.prepareRemoval( new es.Range( this.selection.to, this.selection.to + 1 ) ); |
| 211 | + transactionStack.push ( transaction ); |
206 | 212 | this.documentView.model.commit ( transaction ); |
207 | 213 | break; |
| 214 | + case 89: // Y |
| 215 | + if ( this.keyboard.keys.control ) { |
| 216 | + if ( transactionStack.length > 0 && undoCounter > 0) { |
| 217 | + this.documentView.model.commit ( transactionStack[ transactionStack.length - undoCounter ] ); |
| 218 | + undoCounter--; |
| 219 | + this.selection.from = this.selection.to += 1; |
| 220 | + this.showCursor(); |
| 221 | + } |
| 222 | + } |
| 223 | + break; |
| 224 | + case 90: // Z |
| 225 | + if ( this.keyboard.keys.control ) { |
| 226 | + if ( transactionStack.length > 0 ) { |
| 227 | + this.documentView.model.rollback ( transactionStack[ transactionStack.length - 1 - undoCounter ] ); |
| 228 | + undoCounter++; |
| 229 | + this.selection.from = this.selection.to -= 1; |
| 230 | + this.showCursor(); |
| 231 | + } |
| 232 | + } |
| 233 | + break; |
208 | 234 | default: // Insert content (maybe) |
| 235 | + if (undoCounter) { |
| 236 | + transactionStack = transactionStack.slice(0, transactionStack.length - undoCounter); |
| 237 | + undoCounter = 0; |
| 238 | + } |
| 239 | + |
209 | 240 | if ( this.keyboard.keydownTimeout ) { |
210 | 241 | clearTimeout( this.keyboard.keydownTimeout ); |
211 | 242 | } |
212 | 243 | var surface = this; |
213 | 244 | this.keyboard.keydownTimeout = setTimeout( function () { |
214 | 245 | surface.insertFromInput(); |
215 | | - }, 10 ); |
| 246 | + }, 0 ); |
216 | 247 | break; |
217 | 248 | } |
218 | 249 | return true; |
— | — | @@ -222,6 +253,7 @@ |
223 | 254 | this.$input.val( '' ); |
224 | 255 | if ( val.length > 0 ) { |
225 | 256 | var transaction = this.documentView.model.prepareInsertion( this.selection.to, val.split('') ); |
| 257 | + transactionStack.push ( transaction ); |
226 | 258 | this.documentView.model.commit ( transaction ); |
227 | 259 | this.selection.from = this.selection.to += val.length; |
228 | 260 | this.showCursor(); |