Index: trunk/extensions/VisualEditor/modules/es/models/es.HistoryModel.js |
— | — | @@ -78,10 +78,10 @@ |
79 | 79 | var absLengthDiff = Math.abs( transaction.getLengthDiff() ); |
80 | 80 | // Unless we should intentionally accumulate transactions or this is the first one for this |
81 | 81 | // state, automatically push state |
82 | | - if ( !accumulate && !this.transactions.length ) { |
| 82 | + if ( !accumulate && this.transactions.length ) { |
83 | 83 | if ( |
84 | 84 | // If the transactions are of a different type |
85 | | - this.transactions[this.transactions.length].type !== transaction.type || |
| 85 | + this.transactions[this.transactions.length - 1].type !== transaction.type || |
86 | 86 | // This transaction would make the state longer than the maximum length |
87 | 87 | this.transactionsDiff + absLengthDiff > this.maxTransactionsDiff |
88 | 88 | ) { |
— | — | @@ -168,3 +168,7 @@ |
169 | 169 | } |
170 | 170 | } |
171 | 171 | }; |
| 172 | + |
| 173 | +/* Inheritance */ |
| 174 | + |
| 175 | +es.extendClass( es.HistoryModel, es.EventEmitter ); |
Index: trunk/extensions/VisualEditor/modules/es/views/es.SurfaceView.js |
— | — | @@ -45,6 +45,9 @@ |
46 | 46 | this.documentView = new es.DocumentView( this.model.getDocument(), this ); |
47 | 47 | this.$.append( this.documentView.$ ); |
48 | 48 | |
| 49 | + // History |
| 50 | + this.history = new es.HistoryModel( this.documentView.getModel() ); |
| 51 | + |
49 | 52 | // Interaction state |
50 | 53 | |
51 | 54 | // There are three different selection modes available for mouse. Selection of: |
— | — | @@ -164,7 +167,7 @@ |
165 | 168 | } else if ( e.originalEvent.detail === 2 ) { // double click |
166 | 169 | this.mouse.selectingMode = 2; // used in mouseMove handler |
167 | 170 | |
168 | | - var wordRange = this.documentView.model.getWordBoundaries( offset ); |
| 171 | + var wordRange = this.documentView.getModel().getWordBoundaries( offset ); |
169 | 172 | if( wordRange ) { |
170 | 173 | this.selection = wordRange; |
171 | 174 | this.mouse.selectedRange = this.selection.clone(); |
— | — | @@ -211,7 +214,7 @@ |
212 | 215 | if ( this.mouse.selectingMode === 1 ) { // selection of chars |
213 | 216 | this.selection.to = offset; |
214 | 217 | } else if ( this.mouse.selectingMode === 2 ) { // selection of words |
215 | | - var wordRange = this.documentView.model.getWordBoundaries( offset ); |
| 218 | + var wordRange = this.documentView.getModel().getWordBoundaries( offset ); |
216 | 219 | if ( wordRange ) { |
217 | 220 | if ( wordRange.to <= this.mouse.selectedRange.from ) { |
218 | 221 | this.selection.from = wordRange.from; |
— | — | @@ -410,15 +413,15 @@ |
411 | 414 | if ( sourceNode === targetNode || |
412 | 415 | ( typeof sourceSplitableNode !== 'undefined' && |
413 | 416 | sourceSplitableNode.getParent() === targetSplitableNode.getParent() ) ) { |
414 | | - tx = this.documentView.model.prepareRemoval( |
| 417 | + tx = this.documentView.getModel().prepareRemoval( |
415 | 418 | new es.Range( targetOffset, sourceOffset ) |
416 | 419 | ); |
417 | | - this.documentView.model.commit ( tx ); |
| 420 | + this.history.commit( tx ); |
418 | 421 | } else { |
419 | | - tx = this.documentView.model.prepareInsertion( |
| 422 | + tx = this.documentView.getModel().prepareInsertion( |
420 | 423 | targetOffset, sourceNode.model.getContent() |
421 | 424 | ); |
422 | | - this.documentView.model.commit( tx ); |
| 425 | + this.history.commit( tx ); |
423 | 426 | |
424 | 427 | var nodeToDelete = sourceNode; |
425 | 428 | es.DocumentNode.traverseUpstream( nodeToDelete, function( node ) { |
— | — | @@ -431,13 +434,13 @@ |
432 | 435 | var range = new es.Range(); |
433 | 436 | range.from = this.documentView.getOffsetFromNode( nodeToDelete, false ); |
434 | 437 | range.to = range.from + nodeToDelete.getElementLength(); |
435 | | - tx = this.documentView.model.prepareRemoval( range ); |
436 | | - this.documentView.model.commit ( tx ); |
| 438 | + tx = this.documentView.getModel().prepareRemoval( range ); |
| 439 | + this.history.commit( tx ); |
437 | 440 | } |
438 | 441 | } else { |
439 | 442 | // selection removal |
440 | | - tx = this.documentView.model.prepareRemoval( this.selection ); |
441 | | - this.documentView.model.commit( tx ); |
| 443 | + tx = this.documentView.getModel().prepareRemoval( this.selection ); |
| 444 | + this.history.commit( tx ); |
442 | 445 | this.documentView.clearSelection(); |
443 | 446 | this.selection.from = this.selection.to = this.selection.start; |
444 | 447 | this.showCursor(); |
— | — | @@ -499,14 +502,14 @@ |
500 | 503 | if ( val.length > 0 ) { |
501 | 504 | var tx; |
502 | 505 | if ( this.selection.from != this.selection.to ) { |
503 | | - tx = this.documentView.model.prepareRemoval( this.selection ); |
504 | | - this.documentView.model.commit( tx ); |
| 506 | + tx = this.documentView.getModel().prepareRemoval( this.selection ); |
| 507 | + this.history.commit( tx ); |
505 | 508 | this.documentView.clearSelection(); |
506 | 509 | this.selection.from = this.selection.to = |
507 | 510 | Math.min( this.selection.from, this.selection.to ); |
508 | 511 | } |
509 | | - tx = this.documentView.model.prepareInsertion( this.selection.from, val.split('') ); |
510 | | - this.documentView.model.commit ( tx ); |
| 512 | + tx = this.documentView.getModel().prepareInsertion( this.selection.from, val.split('') ); |
| 513 | + this.history.commit( tx ); |
511 | 514 | this.selection.from += val.length; |
512 | 515 | this.selection.to += val.length; |
513 | 516 | this.showCursor(); |
— | — | @@ -541,7 +544,7 @@ |
542 | 545 | direction === 'left' ? -1 : 1 |
543 | 546 | ); |
544 | 547 | if ( unit === 'word' ) { |
545 | | - var wordRange = this.documentView.model.getWordBoundaries( |
| 548 | + var wordRange = this.documentView.getModel().getWordBoundaries( |
546 | 549 | direction === 'left' ? to : offset |
547 | 550 | ); |
548 | 551 | if ( wordRange ) { |
— | — | @@ -565,7 +568,7 @@ |
566 | 569 | switch ( unit ) { |
567 | 570 | case 'unit': |
568 | 571 | var toNode = null; |
569 | | - this.documentView.model.traverseLeafNodes( |
| 572 | + this.documentView.getModel().traverseLeafNodes( |
570 | 573 | function( node ) { |
571 | 574 | if ( toNode === null) { |
572 | 575 | toNode = node; |
— | — | @@ -577,7 +580,7 @@ |
578 | 581 | this.documentView.getNodeFromOffset( this.selection.to, false ).getModel(), |
579 | 582 | direction === 'up' ? true : false |
580 | 583 | ); |
581 | | - to = this.documentView.model.getOffsetFromNode( toNode, false ) + 1; |
| 584 | + to = this.documentView.getModel().getOffsetFromNode( toNode, false ) + 1; |
582 | 585 | break; |
583 | 586 | case 'char': |
584 | 587 | /* |