r100757 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r100756‎ | r100757 | r100758 >
Date:22:28, 25 October 2011
Author:catrope
Status:deferred
Tags:
Comment:
Various fixes and refactoring in prepareInsertion(). Passes the tests now, but is still incomplete. We'll have to come up with new test cases that break it now
Modified paths:
  • /trunk/parsers/wikidom/lib/hype/models/es.DocumentModel.js (modified) (history)

Diff [purge]

Index: trunk/parsers/wikidom/lib/hype/models/es.DocumentModel.js
@@ -580,7 +580,15 @@
581581 * @returns {es.Transaction}
582582 */
583583 es.DocumentModel.prototype.prepareInsertion = function( offset, data ) {
584 - function containsStructuralElements( data ) {
 584+ /**
 585+ * Returns true if data starts with an opening element and ends with a closing element
 586+ */
 587+ /*function isStructuralData( data ) {
 588+ return data.length >= 2 &&
 589+ data[0].type !== undefined && data[0].type.charAt( 0 ) != '/' &&
 590+ data[data.length - 1].type !== undefined && data[data.length - 1].type.charAt( 0 ) == '/';
 591+ }*/
 592+ function isStructuralData( data ) {
585593 var i;
586594 for ( i = 0; i < data.length; i++ ) {
587595 if ( data[i].type !== undefined ) {
@@ -596,20 +604,76 @@
597605 // * The end of the document (offset length-1)
598606 // * Any location between elements, i.e. the item before is a closing and the item after is an opening
599607 return offset <= 0 || offset >= data.length - 1 || (
600 - data[offset - 1].type !== undefined && data[offset - 1].type.charAt( 0 ) != '/' &&
601 - data[offset].type !== undefined && data[offset].type.charAt( 0 ) == '/'
 608+ data[offset - 1].type !== undefined && data[offset - 1].type.charAt( 0 ) == '/' &&
 609+ data[offset].type !== undefined && data[offset].type.charAt( 0 ) != '/'
602610 );
603611 }
 612+
 613+ /**
 614+ * Balances mismatched openings/closings in data
 615+ * @return data itself if nothing was changed, or a clone of data with balancing changes made. data itself is never touched
 616+ */
 617+ function balance( data ) {
 618+ var i, stack = [], element, workingData = null;
 619+
 620+ for ( i = 0; i < data.length; i++ ) {
 621+ if ( data[i].type === undefined ) {
 622+ // Not an opening or a closing, skip
 623+ } else if ( data[i].type.charAt( 0 ) != '/' ) {
 624+ // Opening
 625+ stack.push( data[i].type );
 626+ } else {
 627+ // Closing
 628+ if ( stack.length == 0 ) {
 629+ // The stack is empty, so this is an unopened closing
 630+ // Remove it
 631+ if ( workingData === null ) {
 632+ workingData = data.slice( 0 );
 633+ }
 634+ workingData.splice( i, 1 );
 635+ }
 636+
 637+ element = stack.pop();
 638+ if ( element != data[i].type.substr( 1 ) ) {
 639+ // Closing doesn't match what's expected
 640+ // This means the input is malformed and cannot possibly
 641+ // have been a fragment taken from well-formed data
 642+ throw 'Input is malformed: expected /' + element + ' but got ' + data[i].type + ' at index ' + i;
 643+ }
 644+ }
 645+ }
 646+
 647+ // Check whether there are any unclosed tags and close them
 648+ if ( stack.length > 0 && workingData === null ) {
 649+ workingData = data.slice( 0 );
 650+ }
 651+ while ( stack.length > 0 ) {
 652+ element = stack.pop();
 653+ workingData.push( { 'type': '/' + element } );
 654+ }
 655+
 656+ // TODO
 657+ // Check whether there is any raw unenclosed content and deal with that somehow
 658+
 659+ return workingData || data;
 660+ }
604661
605 - var tx = new es.Transaction(), insertedData = data;
 662+ var tx = new es.Transaction(),
 663+ insertedData = data, // may be cloned and modified
 664+ isStructuralLoc = isStructuralLocation( offset, this.data );
 665+
606666 if ( offset > 0 ) {
607667 tx.pushRetain( offset );
608668 }
609 - // TODO check for structural changes
610 - if ( containsStructuralElements( insertedData ) ) {
611 - // TODO
 669+
 670+ if ( isStructuralData( insertedData ) ) {
 671+ if ( isStructuralLoc ) {
 672+ insertedData = balance( insertedData );
 673+ } else {
 674+ // TODO close and reopen the element the insertion point is in
 675+ }
612676 } else {
613 - if ( isStructuralLocation( offset, this.data ) ) {
 677+ if ( isStructuralLoc ) {
614678 // We're inserting content into a structural location,
615679 // so we need to wrap the inserted content in a paragraph.
616680 insertedData = [ { 'type': 'paragraph' }, { 'type': '/paragraph' } ];

Status & tagging log