| /* |
| 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; |