Index: trunk/parsers/wikidom/lib/hype/models/es.DocumentModel.js |
— | — | @@ -264,6 +264,9 @@ |
265 | 265 | }; |
266 | 266 | |
267 | 267 | es.DocumentModel.getIndexOfAnnotation = function( character, annotation ) { |
| 268 | + if ( annotation === undefined || annotation.type === undefined ) { |
| 269 | + throw 'Invalid annotation error. Can not find non-annotation data in character.' |
| 270 | + } |
268 | 271 | if ( $.isArray( character ) ) { |
269 | 272 | // Find the index of a comparable annotation (checking for same value, not reference) |
270 | 273 | for ( var i = 1; i < character.length; i++ ) { |
— | — | @@ -608,7 +611,9 @@ |
609 | 612 | es.DocumentModel.prototype.prepareContentAnnotation = function( range, method, annotation ) { |
610 | 613 | var tx = new es.Transaction(); |
611 | 614 | range.normalize(); |
612 | | - |
| 615 | + if ( annotation.hash === undefined ) { |
| 616 | + annotation.hash = es.DocumentModel.getAnnotationHash( annotation ); |
| 617 | + } |
613 | 618 | var i = range.start, |
614 | 619 | span = i, |
615 | 620 | on = this.data[i].type !== undefined; |
— | — | @@ -621,10 +626,13 @@ |
622 | 627 | on = false; |
623 | 628 | } |
624 | 629 | } else { |
625 | | - var covered = es.DocumentModel.getIndexOfAnnotation( this.data[i] ) !== -1; |
| 630 | + var covered = es.DocumentModel.getIndexOfAnnotation( this.data[i], annotation ) !== -1; |
626 | 631 | if ( covered && method === 'set' || !covered && method === 'clear' ) { |
627 | 632 | // Don't set/clear annotations on content that's already set/cleared |
628 | 633 | if ( on ) { |
| 634 | + if ( span ) { |
| 635 | + tx.pushRetain( span ); |
| 636 | + } |
629 | 637 | tx.pushStopAnnotating( method, annotation ); |
630 | 638 | span = 0; |
631 | 639 | on = false; |
— | — | @@ -642,7 +650,14 @@ |
643 | 651 | } |
644 | 652 | } |
645 | 653 | span++; |
| 654 | + i++; |
646 | 655 | } |
| 656 | + if ( on ) { |
| 657 | + if ( span ) { |
| 658 | + tx.pushRetain( span ); |
| 659 | + } |
| 660 | + tx.pushStopAnnotating( method, annotation ); |
| 661 | + } |
647 | 662 | if ( range.end < this.data.length ) { |
648 | 663 | tx.pushRetain( this.data.length - range.end ); |
649 | 664 | } |
Index: trunk/parsers/wikidom/tests/hype/es.DocumentModel.test.js |
— | — | @@ -201,7 +201,7 @@ |
202 | 202 | new es.ParagraphModel( data[25], 1 ) |
203 | 203 | ]; |
204 | 204 | |
205 | | -test( 'es.DocumentModel', 15, function() { |
| 205 | +test( 'es.DocumentModel', 16, function() { |
206 | 206 | var documentModel = es.DocumentModel.newFromPlainObject( obj ); |
207 | 207 | |
208 | 208 | deepEqual( documentModel.getData(), data, 'Flattening plain objects results in correct data' ); |
— | — | @@ -303,5 +303,41 @@ |
304 | 304 | ); |
305 | 305 | } |
306 | 306 | |
| 307 | + deepEqual( |
| 308 | + documentModel.prepareContentAnnotation( new es.Range( 1, 4 ), 'set', { 'type': 'bold' } ), |
| 309 | + [ |
| 310 | + { 'type': 'retain', 'length': 1 }, |
| 311 | + { |
| 312 | + 'type': 'annotate', |
| 313 | + 'method': 'set', |
| 314 | + 'bias': 'start', |
| 315 | + 'annotation': { 'type': 'bold', 'hash': '#bold' } |
| 316 | + }, |
| 317 | + { 'type': 'retain', 'length': 1 }, |
| 318 | + { |
| 319 | + 'type': 'annotate', |
| 320 | + 'method': 'set', |
| 321 | + 'bias': 'stop', |
| 322 | + 'annotation': { 'type': 'bold', 'hash': '#bold' } |
| 323 | + }, |
| 324 | + { 'type': 'retain', 'length': 1 }, |
| 325 | + { |
| 326 | + 'type': 'annotate', |
| 327 | + 'method': 'set', |
| 328 | + 'bias': 'start', |
| 329 | + 'annotation': { 'type': 'bold', 'hash': '#bold' } |
| 330 | + }, |
| 331 | + { 'type': 'retain', 'length': 1 }, |
| 332 | + { |
| 333 | + 'type': 'annotate', |
| 334 | + 'method': 'set', |
| 335 | + 'bias': 'stop', |
| 336 | + 'annotation': { 'type': 'bold', 'hash': '#bold' } |
| 337 | + }, |
| 338 | + { 'type': 'retain', 'length': 24 } |
| 339 | + ], |
| 340 | + 'prepareContentAnnotation skips over content that is already set or cleared' |
| 341 | + ); |
| 342 | + |
307 | 343 | } ); |
308 | 344 | |