1 |
|
/* |
2 |
|
Copyright (c) 2012, Yahoo! Inc. All rights reserved. |
3 |
|
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. |
4 |
|
*/ |
5 |
|
|
6 |
1 |
function InsertionText(text, consumeBlanks) { |
7 |
204 |
this.text = text; |
8 |
204 |
this.origLength = text.length; |
9 |
204 |
this.offsets = []; |
10 |
204 |
this.consumeBlanks = consumeBlanks; |
11 |
204 |
this.startPos = this.findFirstNonBlank(); |
12 |
204 |
this.endPos = this.findLastNonBlank(); |
13 |
|
} |
14 |
|
|
15 |
1 |
var WHITE_RE = /[ \f\n\r\t\v\u00A0\u2028\u2029]/; |
16 |
|
|
17 |
1 |
InsertionText.prototype = { |
18 |
|
|
19 |
|
findFirstNonBlank: function () { |
20 |
204 |
var pos = -1, |
21 |
|
text = this.text, |
22 |
|
len = text.length, |
23 |
|
i; |
24 |
204 |
for (i = 0; i < len; i += 1) { |
25 |
692 |
if (!text.charAt(i).match(WHITE_RE)) { |
26 |
148 |
pos = i; |
27 |
148 |
break; |
28 |
|
} |
29 |
|
} |
30 |
204 |
return pos; |
31 |
|
}, |
32 |
|
findLastNonBlank: function () { |
33 |
204 |
var text = this.text, |
34 |
|
len = text.length, |
35 |
|
pos = text.length + 1, |
36 |
|
i; |
37 |
204 |
for (i = len - 1; i >= 0; i -= 1) { |
38 |
164 |
if (!text.charAt(i).match(WHITE_RE)) { |
39 |
148 |
pos = i; |
40 |
148 |
break; |
41 |
|
} |
42 |
|
} |
43 |
204 |
return pos; |
44 |
|
}, |
45 |
|
originalLength: function () { |
46 |
101 |
return this.origLength; |
47 |
|
}, |
48 |
|
|
49 |
|
insertAt: function (col, str, insertBefore, consumeBlanks) { |
50 |
83 |
consumeBlanks = typeof consumeBlanks === 'undefined' ? this.consumeBlanks : consumeBlanks; |
51 |
83 |
col = col > this.originalLength() ? this.originalLength() : col; |
52 |
83 |
col = col < 0 ? 0 : col; |
53 |
|
|
54 |
83 |
if (consumeBlanks) { |
55 |
54 |
if (col <= this.startPos) { |
56 |
18 |
col = 0; |
57 |
|
} |
58 |
54 |
if (col > this.endPos) { |
59 |
26 |
col = this.origLength; |
60 |
|
} |
61 |
|
} |
62 |
|
|
63 |
83 |
var len = str.length, |
64 |
|
offset = this.findOffset(col, len, insertBefore), |
65 |
|
realPos = col + offset, |
66 |
|
text = this.text; |
67 |
83 |
this.text = text.substring(0, realPos) + str + text.substring(realPos); |
68 |
83 |
return this; |
69 |
|
}, |
70 |
|
|
71 |
|
findOffset: function (pos, len, insertBefore) { |
72 |
83 |
var offsets = this.offsets, |
73 |
|
offsetObj, |
74 |
|
cumulativeOffset = 0, |
75 |
|
i; |
76 |
|
|
77 |
83 |
for (i = 0; i < offsets.length; i += 1) { |
78 |
50 |
offsetObj = offsets[i]; |
79 |
50 |
if (offsetObj.pos < pos || (offsetObj.pos === pos && !insertBefore)) { |
80 |
46 |
cumulativeOffset += offsetObj.len; |
81 |
|
} |
82 |
50 |
if (offsetObj.pos >= pos) { |
83 |
9 |
break; |
84 |
|
} |
85 |
|
} |
86 |
83 |
if (offsetObj && offsetObj.pos === pos) { |
87 |
8 |
offsetObj.len += len; |
88 |
|
} else { |
89 |
75 |
offsets.splice(i, 0, { pos: pos, len: len }); |
90 |
|
} |
91 |
83 |
return cumulativeOffset; |
92 |
|
}, |
93 |
|
|
94 |
|
wrap: function (startPos, startText, endPos, endText, consumeBlanks) { |
95 |
34 |
this.insertAt(startPos, startText, true, consumeBlanks); |
96 |
34 |
this.insertAt(endPos, endText, false, consumeBlanks); |
97 |
34 |
return this; |
98 |
|
}, |
99 |
|
|
100 |
|
wrapLine: function (startText, endText) { |
101 |
1 |
this.wrap(0, startText, this.originalLength(), endText); |
102 |
|
}, |
103 |
|
|
104 |
|
toString: function () { |
105 |
186 |
return this.text; |
106 |
|
} |
107 |
|
}; |
108 |
|
|
109 |
1 |
module.exports = InsertionText; |