Index: trunk/parsers/wikidom/lib/es/es.Surface.js |
— | — | @@ -181,12 +181,19 @@ |
182 | 182 | var val = surface.$input.val(); |
183 | 183 | surface.$input.val( '' ); |
184 | 184 | if ( val.length > 0 ) { |
185 | | - var block = surface.location.block, |
186 | | - offset = surface.location.offset, |
187 | | - insertAt = offset; |
| 185 | + if ( surface.selection.from && surface.selection.to ) { |
| 186 | + var deleteSelection = surface.selection; |
| 187 | + deleteSelection.normalize(); |
| 188 | + surface.location = surface.selection.start; |
| 189 | + surface.selection = new Selection(); |
| 190 | + surface.deleteContent( deleteSelection ); |
| 191 | + } |
| 192 | + var insertLocation = surface.location; |
188 | 193 | surface.selection = new Selection(); |
189 | | - surface.location = new Location( block, offset + val.length ); |
190 | | - block.insertContent( insertAt, val.split('')); |
| 194 | + surface.location = new Location( |
| 195 | + surface.location.block, surface.location.offset + val.length |
| 196 | + ); |
| 197 | + surface.insertContent( insertLocation, val.split('') ); |
191 | 198 | } |
192 | 199 | }, 10 ); |
193 | 200 | break; |
— | — | @@ -216,25 +223,36 @@ |
217 | 224 | }; |
218 | 225 | |
219 | 226 | Surface.prototype.handleBackspace = function() { |
220 | | - var block = this.location.block, |
221 | | - offset = this.location.offset; |
222 | | - |
223 | | - if ( offset > 0 ) { |
224 | | - offset--; |
| 227 | + if ( this.selection.from && this.selection.to ) { |
| 228 | + var deleteSelection = this.selection; |
| 229 | + deleteSelection.normalize(); |
| 230 | + this.location = this.selection.start; |
225 | 231 | this.selection = new Selection(); |
226 | | - this.location = new Location( block, offset ); |
227 | | - block.deleteContent( offset, offset + 1 ); |
| 232 | + this.deleteContent( deleteSelection ); |
| 233 | + } else if ( this.location.offset > 0 ) { |
| 234 | + var deleteSelection = new Selection( |
| 235 | + new Location( this.location.block, this.location.offset - 1 ), this.location |
| 236 | + ); |
| 237 | + this.selection = new Selection(); |
| 238 | + this.location = deleteSelection.from; |
| 239 | + this.deleteContent( deleteSelection ); |
228 | 240 | } |
229 | 241 | }; |
230 | 242 | |
231 | 243 | Surface.prototype.handleDelete = function() { |
232 | | - var block = this.location.block, |
233 | | - offset = this.location.offset; |
234 | | - |
235 | | - if ( offset < block.getLength() - 1 ) { |
| 244 | + if ( this.selection.from && this.selection.to ) { |
| 245 | + var deleteSelection = this.selection; |
| 246 | + deleteSelection.normalize(); |
| 247 | + this.location = this.selection.end; |
236 | 248 | this.selection = new Selection(); |
237 | | - this.location = new Location( block, offset ); |
238 | | - block.deleteContent( offset, offset + 1); |
| 249 | + this.deleteContent( deleteSelection ); |
| 250 | + } else if ( this.location.offset < block.getLength() - 1 ) { |
| 251 | + var deleteSelection = new Selection( |
| 252 | + new Location( this.location.block, this.location.offset + 1 ), this.location |
| 253 | + ); |
| 254 | + this.selection = new Selection(); |
| 255 | + this.location = deleteSelection.from; |
| 256 | + this.deleteContent( deleteSelection ); |
239 | 257 | } |
240 | 258 | }; |
241 | 259 | |
— | — | @@ -554,6 +572,44 @@ |
555 | 573 | this.location = new Location( block, offset ); |
556 | 574 | }; |
557 | 575 | |
| 576 | +Surface.prototype.insertContent = function( location, content ) { |
| 577 | + if ( this.selection.from && this.selection.to ) { |
| 578 | + this.deleteContent( this.selection ); |
| 579 | + } |
| 580 | + this.location.block.insertContent( location.offset, content ); |
| 581 | +}; |
| 582 | + |
| 583 | +Surface.prototype.deleteContent = function( selection ) { |
| 584 | + if ( !selection.from && !selection.to ) { |
| 585 | + throw 'Invalid selection error. Properties for from and to locations expected.'; |
| 586 | + } |
| 587 | + selection.normalize(); |
| 588 | + var from = selection.start, |
| 589 | + to = selection.end; |
| 590 | + if ( from.block === to.block ) { |
| 591 | + // Single block deletion |
| 592 | + from.block.deleteContent( from.offset, to.offset ); |
| 593 | + } else { |
| 594 | + // Multiple block deletion |
| 595 | + var block; |
| 596 | + for ( var i = from.block.getIndex(), end = to.block.getIndex(); i <= end; i++ ) { |
| 597 | + block = this.doc.blocks[i]; |
| 598 | + if ( block === from.block ) { |
| 599 | + // From offset to length |
| 600 | + block.deleteContent( from.offset, block.getLength() ); |
| 601 | + } else if ( block === to.block ) { |
| 602 | + // From 0 to offset |
| 603 | + block.deleteContent( 0, to.offset ); |
| 604 | + } else { |
| 605 | + // Full coverage |
| 606 | + block.deleteContent( 0, block.getLength() ); |
| 607 | + } |
| 608 | + } |
| 609 | + } |
| 610 | + // TODO: Merge first and last blocks that have been deleted from and remove blocks that have |
| 611 | + // been cleared entirely |
| 612 | +}; |
| 613 | + |
558 | 614 | /** |
559 | 615 | * Applies an annotation to a given selection. |
560 | 616 | * |
— | — | @@ -563,33 +619,30 @@ |
564 | 620 | * @param annotation {Object} Annotation to apply |
565 | 621 | * @param selection {Selection} Range to apply annotation to |
566 | 622 | */ |
567 | | -Surface.prototype.annotateContent= function( method, annotation, selection ) { |
568 | | - // Fall back to current selection if no selection argument was given |
569 | | - if ( selection === undefined ) { |
570 | | - selection = this.selection; |
| 623 | +Surface.prototype.annotateContent = function( method, annotation, selection ) { |
| 624 | + if ( !selection.from && !selection.to ) { |
| 625 | + throw 'Invalid selection error. Properties for from and to locations expected.'; |
571 | 626 | } |
572 | | - if ( selection.from && selection.to ) { |
573 | | - selection.normalize(); |
574 | | - var from = selection.start, |
575 | | - to = selection.end; |
576 | | - if ( from.block === to.block ) { |
577 | | - // Single block annotation |
578 | | - from.block.annotateContent( method, annotation, from.offset, to.offset ); |
579 | | - } else { |
580 | | - // Multiple block annotation |
581 | | - var block; |
582 | | - for ( var i = from.block.getIndex(), end = to.block.getIndex(); i <= end; i++ ) { |
583 | | - block = this.doc.blocks[i]; |
584 | | - if ( block === from.block ) { |
585 | | - // From offset to length |
586 | | - block.annotateContent( method, annotation, from.offset, block.getLength() ); |
587 | | - } else if ( block === to.block ) { |
588 | | - // From 0 to offset |
589 | | - block.annotateContent( method, annotation, 0, to.offset ); |
590 | | - } else { |
591 | | - // Full coverage |
592 | | - block.annotateContent( method, annotation, 0, block.getLength() ); |
593 | | - } |
| 627 | + selection.normalize(); |
| 628 | + var from = selection.start, |
| 629 | + to = selection.end; |
| 630 | + if ( from.block === to.block ) { |
| 631 | + // Single block annotation |
| 632 | + from.block.annotateContent( method, annotation, from.offset, to.offset ); |
| 633 | + } else { |
| 634 | + // Multiple block annotation |
| 635 | + var block; |
| 636 | + for ( var i = from.block.getIndex(), end = to.block.getIndex(); i <= end; i++ ) { |
| 637 | + block = this.doc.blocks[i]; |
| 638 | + if ( block === from.block ) { |
| 639 | + // From offset to length |
| 640 | + block.annotateContent( method, annotation, from.offset, block.getLength() ); |
| 641 | + } else if ( block === to.block ) { |
| 642 | + // From 0 to offset |
| 643 | + block.annotateContent( method, annotation, 0, to.offset ); |
| 644 | + } else { |
| 645 | + // Full coverage |
| 646 | + block.annotateContent( method, annotation, 0, block.getLength() ); |
594 | 647 | } |
595 | 648 | } |
596 | 649 | } |