/* Copyright (c) 2012, Yahoo! Inc. All rights reserved. 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(); } var WHITE_RE = /[ \f\n\r\t\v\u00A0\u2028\u2029]/; InsertionText.prototype = { findFirstNonBlank: function () { var pos = -1, text = this.text, len = text.length, i; for (i = 0; i < len; i += 1) { if (!text.charAt(i).match(WHITE_RE)) { pos = i; break; } } return pos; }, findLastNonBlank: function () { var text = this.text, len = text.length, pos = text.length + 1, i; for (i = len - 1; i >= 0; i -= 1) { if (!text.charAt(i).match(WHITE_RE)) { pos = i; break; } } return pos; }, originalLength: function () { return this.origLength; }, insertAt: function (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; } } var len = str.length, offset = this.findOffset(col, len, insertBefore), realPos = col + offset, text = this.text; this.text = text.substring(0, realPos) + str + text.substring(realPos); return this; }, findOffset: function (pos, len, insertBefore) { var offsets = this.offsets, offsetObj, cumulativeOffset = 0, 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: pos, len: len }); } return cumulativeOffset; }, wrap: function (startPos, startText, endPos, endText, consumeBlanks) { this.insertAt(startPos, startText, true, consumeBlanks); this.insertAt(endPos, endText, false, consumeBlanks); return this; }, wrapLine: function (startText, endText) { this.wrap(0, startText, this.originalLength(), endText); }, toString: function () { return this.text; } }; module.exports = InsertionText;