@@ -389,34 +389,36 @@ var ICEcoder = {
389389
390390 // On before change
391391 cMonBeforeChange : function ( thisCM , cMinstance , changeObj , cM ) {
392- var sels , tokenString , range , canMaybeReplace , thisData ;
392+ var sels , tokenInfo , lineContent , range , thisData ;
393393
394394 // For each of the user selections
395395 sels = thisCM . listSelections ( ) ;
396396 for ( var i = 0 ; i < sels . length ; i ++ ) {
397- // Get the token at the cursor start (anchor) position
398- tokenString = thisCM . getTokenAt ( sels [ i ] . anchor ) ;
397+ // Get the token info at the cursor start (anchor) position
398+ tokenInfo = thisCM . getTokenAt ( sels [ i ] . anchor ) ;
399399 // If we're just inside a tag, move along 1 char pos and get token info at that position
400- if ( tokenString . type == "tag bracket" && tokenString . string == "<" ) {
401- tokenString = thisCM . getTokenAt ( { line : sels [ i ] . anchor . line , ch : sels [ i ] . anchor . ch + 1 } ) ;
400+ if ( tokenInfo . type == "tag bracket" && tokenInfo . string == "<" ) {
401+ tokenInfo = thisCM . getTokenAt ( { line : sels [ i ] . anchor . line , ch : sels [ i ] . anchor . ch + 1 } ) ;
402402 }
403403 // If we're inside a tag now
404- if ( tokenString . type == "tag" ) {
404+ if ( tokenInfo . type == "tag" ) {
405+ // Get line content and if more than 1 tag instance of string we're editing, skip
406+ lineContent = thisCM . getLine ( sels [ i ] . anchor . line ) ;
407+ if ( ( lineContent . match ( new RegExp ( "<" + tokenInfo . string , "g" ) ) || [ ] ) . length > 1 ) {
408+ continue ;
409+ }
410+
405411 // Test for range info
406412 range = cM . fold [ 'xml' ] ( thisCM , sels [ i ] . anchor ) ;
407- canMaybeReplace = true ;
408- for ( var j = 0 ; j < top . ICEcoder . endTagReplaceData . length ; j ++ ) {
409- // If we have range info and we're start and end are on the same line
410- if ( "undefined" != typeof range && top . ICEcoder . endTagReplaceData [ j ] . split ( ";" ) [ 1 ] == range . to . line + ":" + range . to . ch ) {
411- canMaybeReplace = false ;
412- }
413- }
414- // If we can still replace and have range info and not undoing/redoing (as that replaces chunks itself)
415- if ( canMaybeReplace && "undefined" != typeof range && changeObj . origin != "undo" && changeObj . origin != "redo" ) {
413+
414+ // If we have range info and not undoing/redoing (as that replaces chunks itself)
415+ if ( "undefined" != typeof range && changeObj . origin != "undo" && changeObj . origin != "redo" ) {
416416 // Work out the data string to set and if not in array, push in ready to handle on change event
417- thisData = tokenString . string + ";" + range . to . line + ":" + range . to . ch ;
417+ thisData = tokenInfo . string + ";" + range . to . line + ":" + range . to . ch ;
418418 if ( top . ICEcoder . endTagReplaceData . indexOf ( thisData ) == - 1 ) {
419419 top . ICEcoder . endTagReplaceData . push ( thisData ) ;
420+ // Also set the position of the end tag on this line if found
421+ top . ICEcoder . thisLinesEndTagPos = lineContent . indexOf ( '/' + tokenInfo . string + '>' ) ;
420422 }
421423 }
422424 }
@@ -425,7 +427,7 @@ var ICEcoder = {
425427
426428 // On change
427429 cMonChange : function ( thisCM , cMinstance , changeObj ) {
428- var rData , thisToken , repl1 , repl2 , tTS , filepath , filename , fileExt ;
430+ var rData , thisLine , thisChar , repl1 , repl2 , thisToken , tTS , filepath , filename , fileExt ;
429431
430432 // If we're not loading the file, it's a change, so update tab
431433 if ( ! top . ICEcoder . loadingFile ) {
@@ -440,27 +442,54 @@ var ICEcoder = {
440442
441443 // If we're replacing end tag strings, do that
442444 if ( top . ICEcoder . endTagReplaceData . length > 0 ) {
443-
444445 // For each one of them, grab our data to work with
445446 for ( var i = 0 ; i < top . ICEcoder . endTagReplaceData . length ; i ++ ) {
447+ // Extract data from that string
446448 rData = top . ICEcoder . endTagReplaceData [ i ] . split ( ";" ) ;
447-
448- // Don't do anything if it's the same line, as we can't rely on fold range data due to nested tags
449- if ( rData [ 1 ] . split ( ":" ) [ 0 ] * 1 == changeObj . from . line ) {
450- continue ;
449+ thisLine = rData [ 1 ] . split ( ":" ) [ 0 ] * 1 ;
450+ thisChar = rData [ 1 ] . split ( ":" ) [ 1 ] * 1 ;
451+
452+ // If the start & end tags are within the same line
453+ if ( thisLine == changeObj . from . line ) {
454+ // Just the 1 tag of that type on this line?
455+ if ( top . ICEcoder . thisLinesEndTagPos > - 1 ) {
456+ repl1 = { line : thisLine , ch : top . ICEcoder . thisLinesEndTagPos + 2 } ;
457+ repl2 = { line : thisLine , ch : top . ICEcoder . thisLinesEndTagPos + 2 + rData [ 0 ] . length } ;
458+ } else {
459+ continue ;
460+ }
461+ // Not within the same line
462+ } else {
463+ // Otherwise, work out the replace ranges
464+ repl1 = { line : thisLine , ch : thisChar + 2 } ;
465+ repl2 = { line : thisLine , ch : thisChar + 2 + rData [ 0 ] . length } ;
451466 }
452- // Otherwise, work out the replace ranges
453- repl1 = { line : rData [ 1 ] . split ( ":" ) [ 0 ] * 1 , ch : ( rData [ 1 ] . split ( ":" ) [ 1 ] * 1 ) + 2 } ;
454- repl2 = { line : rData [ 1 ] . split ( ":" ) [ 0 ] * 1 , ch : ( rData [ 1 ] . split ( ":" ) [ 1 ] * 1 ) + 2 + rData [ 0 ] . length } ;
467+
468+ // Set a blank this token string
469+ tTS = "" ;
470+
455471 // Establish the string to replace with
456- thisToken = thisCM . getTokenAt ( thisCM . listSelections ( ) [ i ] . anchor ) ;
457- tTS = thisToken . string ;
472+ // Traverse backwards through string to get to non whitespace chars
473+ // This allows us to get the tag name and ignore attributes
474+ for ( var j = 0 ; j < 10000 ; j ++ ) {
475+ if ( thisCM . listSelections ( ) [ i ] ) {
476+ thisToken = thisCM . getTokenAt ( { line : thisCM . listSelections ( ) [ i ] . anchor . line , ch : thisCM . listSelections ( ) [ i ] . anchor . ch - j } ) ;
477+ tTS = thisToken . string ;
478+ if ( tTS . trim ( ) != "" ) {
479+ break ;
480+ }
481+ }
482+ }
483+
484+ // If we ended up at the left arrow of the tag, set this token string to blank
458485 if ( tTS == "<" ) {
459486 tTS = "" ;
460487 }
461- // Replace our string over the range
462- // Disabled for now, as buggy
463- // thisCM.replaceRange(tTS, repl1, repl2);
488+
489+ // Replace our string over the range, if this token string isn't blank and the end tag matches our original tag
490+ if ( tTS . trim ( ) != "" && thisCM . getRange ( repl1 , repl2 ) == rData [ 0 ] ) {
491+ thisCM . replaceRange ( tTS , repl1 , repl2 ) ;
492+ }
464493 }
465494
466495 }
0 commit comments