@@ -38,6 +38,7 @@ define("orion/editor/textModel", ['orion/editor/eventTarget', 'orion/regex', 'or
3838 this . _lastLineIndex = - 1 ;
3939 this . _text = [ "" ] ;
4040 this . _lineOffsets = [ 0 ] ;
41+ this . _textDirs = [ "" ] ;
4142 this . setText ( text ) ;
4243 this . setLineDelimiter ( lineDelimiter ) ;
4344 }
@@ -370,6 +371,23 @@ define("orion/editor/textModel", ['orion/editor/eventTarget', 'orion/regex', 'or
370371 }
371372 return this . _lineOffsets [ lineIndex ] ;
372373 } ,
374+ /**
375+ * Returns the text direction of the given line.
376+ * <p>
377+ * The valid indices are 0 to line count exclusive. Returns <code>""</code>
378+ * if the index is out of range.
379+ * </p>
380+ *
381+ * @param {Number } lineIndex the zero based index of the line.
382+ * @return {String } the text direction of the line<code>""</code> if out of range.
383+ *
384+ */
385+ getLineTextDir : function ( lineIndex ) {
386+ if ( ! ( 0 <= lineIndex && lineIndex < this . getLineCount ( ) ) ) {
387+ return "" ;
388+ }
389+ return this . _textDirs [ lineIndex ] ;
390+ } ,
373391 /**
374392 * Returns the text for the given range.
375393 * <p>
@@ -416,6 +434,23 @@ define("orion/editor/textModel", ['orion/editor/eventTarget', 'orion/regex', 'or
416434 var afterText = this . _text [ lastChunk ] . substring ( 0 , end - lastOffset ) ;
417435 return beforeText + this . _text . slice ( firstChunk + 1 , lastChunk ) . join ( "" ) + afterText ;
418436 } ,
437+ /**
438+ * Returns the whole text for save. We keep the text direction of each line by adding the ltr/rtl marker.
439+ *
440+ */
441+ getTextForSave : function ( ) {
442+ var text = "" ;
443+ for ( var i = 0 ; i < this . getLineCount ( ) ; i ++ ) {
444+ if ( this . _textDirs [ i ] === "ltr" ) {
445+ text += util . LtrMarker + this . getLine ( i , true ) ;
446+ } else if ( this . _textDirs [ i ] === "rtl" ) {
447+ text += util . RtlMarker + this . getLine ( i , true ) ;
448+ } else {
449+ text += this . getLine ( i , true ) ;
450+ }
451+ }
452+ return text ;
453+ } ,
419454 /**
420455 * Notifies all listeners that the text is about to change.
421456 * <p>
@@ -508,6 +543,8 @@ define("orion/editor/textModel", ['orion/editor/eventTarget', 'orion/regex', 'or
508543 if ( start === undefined ) { start = 0 ; }
509544 if ( end === undefined ) { end = this . getCharCount ( ) ; }
510545 if ( start === end && text === "" ) { return ; }
546+ var ltrMarker = util . LtrMarker ;
547+ var rtlMarker = util . RtlMarker ;
511548 var startLine = this . getLineAtOffset ( start ) ;
512549 var endLine = this . getLineAtOffset ( end ) ;
513550 var eventStart = start ;
@@ -517,12 +554,21 @@ define("orion/editor/textModel", ['orion/editor/eventTarget', 'orion/regex', 'or
517554 var addedLineCount = 0 ;
518555 var lineCount = this . getLineCount ( ) ;
519556
520- var cr = 0 , lf = 0 , index = 0 ;
557+ var cr = 0 , lf = 0 , index = 0 , shift = 0 ;
521558 var newLineOffsets = [ ] ;
522- while ( true ) {
559+ var newTextDirs = [ ] ;
560+ var origText = text ;
561+
562+
563+ while ( true ) {
523564 if ( cr !== - 1 && cr <= index ) { cr = text . indexOf ( "\r" , index ) ; } //$NON-NLS-0$
524565 if ( lf !== - 1 && lf <= index ) { lf = text . indexOf ( "\n" , index ) ; } //$NON-NLS-0$
525566 if ( lf === - 1 && cr === - 1 ) { break ; }
567+ if ( text . substr ( index , ltrMarker . length ) == ltrMarker ) {
568+ shift += ltrMarker . length ;
569+ } else if ( text . substr ( index , rtlMarker . length ) == rtlMarker ) {
570+ shift += rtlMarker . length ;
571+ }
526572 if ( cr !== - 1 && lf !== - 1 ) {
527573 if ( cr + 1 === lf ) {
528574 index = lf + 1 ;
@@ -534,8 +580,20 @@ define("orion/editor/textModel", ['orion/editor/eventTarget', 'orion/regex', 'or
534580 } else {
535581 index = lf + 1 ;
536582 }
537- newLineOffsets . push ( start + index ) ;
583+ newLineOffsets . push ( start + index - shift ) ;
538584 addedLineCount ++ ;
585+ if ( text . substr ( index , ltrMarker . length ) == ltrMarker ) {
586+ newTextDirs . push ( "ltr" ) ; //$NON-NLS-0$
587+ } else if ( text . substr ( index , rtlMarker . length ) == rtlMarker ) {
588+ newTextDirs . push ( "rtl" ) ; //$NON-NLS-0$
589+ } else {
590+ newTextDirs . push ( "" ) ; //$NON-NLS-0$
591+ }
592+ }
593+ if ( text !== ltrMarker && text !== rtlMarker ) {
594+ var re1 = new RegExp ( ltrMarker , "g" ) , re2 = new RegExp ( rtlMarker , "g" ) ;
595+ text = text . replace ( re1 , "" ) . replace ( re2 , "" ) ;
596+ addedCharCount = text . length ;
539597 }
540598
541599 var modelChangingEvent = {
@@ -582,16 +640,26 @@ define("orion/editor/textModel", ['orion/editor/eventTarget', 'orion/regex', 'or
582640 if ( newLineOffsets . length < limit ) {
583641 args = [ startLine + 1 , removedLineCount ] . concat ( newLineOffsets ) ;
584642 Array . prototype . splice . apply ( this . _lineOffsets , args ) ;
643+ args = [ startLine + 1 , removedLineCount ] . concat ( newTextDirs ) ;
644+ Array . prototype . splice . apply ( this . _textDirs , args ) ;
585645 } else {
586646 index = startLine + 1 ;
587647 this . _lineOffsets . splice ( index , removedLineCount ) ;
588648 for ( var k = 0 ; k < newLineOffsets . length ; k += limit ) {
589649 args = [ index , 0 ] . concat ( newLineOffsets . slice ( k , Math . min ( newLineOffsets . length , k + limit ) ) ) ;
590650 Array . prototype . splice . apply ( this . _lineOffsets , args ) ;
651+ args = [ index , 0 ] . concat ( newTextDirs . slice ( k , Math . min ( newTextDirs . length , k + limit ) ) ) ;
652+ Array . prototype . splice . apply ( this . _textDirs , args ) ;
591653 index += limit ;
592654 }
593655 }
594656
657+ if ( origText . indexOf ( ltrMarker ) == 0 ) {
658+ this . _textDirs [ startLine ] = "ltr" ; //$NON-NLS-0$
659+ } else if ( origText . indexOf ( rtlMarker ) == 0 ) {
660+ this . _textDirs [ startLine ] = "rtl" ; //$NON-NLS-0$
661+ }
662+
595663 var offset = 0 , chunk = 0 , length ;
596664 while ( chunk < this . _text . length ) {
597665 length = this . _text [ chunk ] . length ;
0 commit comments