'use strict'; /* 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;