114 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			114 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
|  | /* | ||
|  |  Copyright 2012-2015, Yahoo Inc. | ||
|  |  Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. | ||
|  |  */ | ||
|  | function InsertionText(text, consumeBlanks) { | ||
|  |     this.text = text; | ||
|  |     this.origLength = text.length; | ||
|  |     this.offsets = []; | ||
|  |     this.consumeBlanks = consumeBlanks; | ||
|  |     this.startPos = this.findFirstNonBlank(); | ||
|  |     this.endPos = this.findLastNonBlank(); | ||
|  | } | ||
|  | 
 | ||
|  | const WHITE_RE = /[ \f\n\r\t\v\u00A0\u2028\u2029]/; | ||
|  | 
 | ||
|  | InsertionText.prototype = { | ||
|  |     findFirstNonBlank() { | ||
|  |         let pos = -1; | ||
|  |         const text = this.text; | ||
|  |         const len = text.length; | ||
|  |         let i; | ||
|  |         for (i = 0; i < len; i += 1) { | ||
|  |             if (!text.charAt(i).match(WHITE_RE)) { | ||
|  |                 pos = i; | ||
|  |                 break; | ||
|  |             } | ||
|  |         } | ||
|  |         return pos; | ||
|  |     }, | ||
|  |     findLastNonBlank() { | ||
|  |         const text = this.text; | ||
|  |         const len = text.length; | ||
|  |         let pos = text.length + 1; | ||
|  |         let i; | ||
|  |         for (i = len - 1; i >= 0; i -= 1) { | ||
|  |             if (!text.charAt(i).match(WHITE_RE)) { | ||
|  |                 pos = i; | ||
|  |                 break; | ||
|  |             } | ||
|  |         } | ||
|  |         return pos; | ||
|  |     }, | ||
|  |     originalLength() { | ||
|  |         return this.origLength; | ||
|  |     }, | ||
|  | 
 | ||
|  |     insertAt(col, str, insertBefore, consumeBlanks) { | ||
|  |         consumeBlanks = | ||
|  |             typeof consumeBlanks === 'undefined' | ||
|  |                 ? this.consumeBlanks | ||
|  |                 : consumeBlanks; | ||
|  |         col = col > this.originalLength() ? this.originalLength() : col; | ||
|  |         col = col < 0 ? 0 : col; | ||
|  | 
 | ||
|  |         if (consumeBlanks) { | ||
|  |             if (col <= this.startPos) { | ||
|  |                 col = 0; | ||
|  |             } | ||
|  |             if (col > this.endPos) { | ||
|  |                 col = this.origLength; | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         const len = str.length; | ||
|  |         const offset = this.findOffset(col, len, insertBefore); | ||
|  |         const realPos = col + offset; | ||
|  |         const text = this.text; | ||
|  |         this.text = text.substring(0, realPos) + str + text.substring(realPos); | ||
|  |         return this; | ||
|  |     }, | ||
|  | 
 | ||
|  |     findOffset(pos, len, insertBefore) { | ||
|  |         const offsets = this.offsets; | ||
|  |         let offsetObj; | ||
|  |         let cumulativeOffset = 0; | ||
|  |         let i; | ||
|  | 
 | ||
|  |         for (i = 0; i < offsets.length; i += 1) { | ||
|  |             offsetObj = offsets[i]; | ||
|  |             if ( | ||
|  |                 offsetObj.pos < pos || | ||
|  |                 (offsetObj.pos === pos && !insertBefore) | ||
|  |             ) { | ||
|  |                 cumulativeOffset += offsetObj.len; | ||
|  |             } | ||
|  |             if (offsetObj.pos >= pos) { | ||
|  |                 break; | ||
|  |             } | ||
|  |         } | ||
|  |         if (offsetObj && offsetObj.pos === pos) { | ||
|  |             offsetObj.len += len; | ||
|  |         } else { | ||
|  |             offsets.splice(i, 0, { pos, len }); | ||
|  |         } | ||
|  |         return cumulativeOffset; | ||
|  |     }, | ||
|  | 
 | ||
|  |     wrap(startPos, startText, endPos, endText, consumeBlanks) { | ||
|  |         this.insertAt(startPos, startText, true, consumeBlanks); | ||
|  |         this.insertAt(endPos, endText, false, consumeBlanks); | ||
|  |         return this; | ||
|  |     }, | ||
|  | 
 | ||
|  |     wrapLine(startText, endText) { | ||
|  |         this.wrap(0, startText, this.originalLength(), endText); | ||
|  |     }, | ||
|  | 
 | ||
|  |     toString() { | ||
|  |         return this.text; | ||
|  |     } | ||
|  | }; | ||
|  | 
 | ||
|  | module.exports = InsertionText; |