OLD | NEW |
| (Empty) |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 self['Common'] = self['Common'] || {}; | |
6 | |
7 /** | |
8 * @unrestricted | |
9 */ | |
10 Common.Text = class { | |
11 /** | |
12 * @param {string} value | |
13 */ | |
14 constructor(value) { | |
15 this._value = value; | |
16 } | |
17 | |
18 /** | |
19 * @return {!Array<number>} | |
20 */ | |
21 lineEndings() { | |
22 if (!this._lineEndings) | |
23 this._lineEndings = this._value.computeLineEndings(); | |
24 return this._lineEndings; | |
25 } | |
26 | |
27 /** | |
28 * @return {string} | |
29 */ | |
30 value() { | |
31 return this._value; | |
32 } | |
33 | |
34 /** | |
35 * @return {number} | |
36 */ | |
37 lineCount() { | |
38 var lineEndings = this.lineEndings(); | |
39 return lineEndings.length; | |
40 } | |
41 | |
42 /** | |
43 * @param {number} lineNumber | |
44 * @param {number} columnNumber | |
45 * @return {number} | |
46 */ | |
47 offsetFromPosition(lineNumber, columnNumber) { | |
48 return (lineNumber ? this.lineEndings()[lineNumber - 1] + 1 : 0) + columnNum
ber; | |
49 } | |
50 | |
51 /** | |
52 * @param {number} offset | |
53 * @return {!Common.Text.Position} | |
54 */ | |
55 positionFromOffset(offset) { | |
56 var lineEndings = this.lineEndings(); | |
57 var lineNumber = lineEndings.lowerBound(offset); | |
58 return {lineNumber: lineNumber, columnNumber: offset - (lineNumber && (lineE
ndings[lineNumber - 1] + 1))}; | |
59 } | |
60 | |
61 /** | |
62 * @return {string} | |
63 */ | |
64 lineAt(lineNumber) { | |
65 var lineEndings = this.lineEndings(); | |
66 var lineStart = lineNumber > 0 ? lineEndings[lineNumber - 1] + 1 : 0; | |
67 var lineEnd = lineEndings[lineNumber]; | |
68 var lineContent = this._value.substring(lineStart, lineEnd); | |
69 if (lineContent.length > 0 && lineContent.charAt(lineContent.length - 1) ===
'\r') | |
70 lineContent = lineContent.substring(0, lineContent.length - 1); | |
71 return lineContent; | |
72 } | |
73 | |
74 /** | |
75 * @param {!Common.TextRange} range | |
76 * @return {!Common.SourceRange} | |
77 */ | |
78 toSourceRange(range) { | |
79 var start = this.offsetFromPosition(range.startLine, range.startColumn); | |
80 var end = this.offsetFromPosition(range.endLine, range.endColumn); | |
81 return new Common.SourceRange(start, end - start); | |
82 } | |
83 | |
84 /** | |
85 * @param {!Common.SourceRange} sourceRange | |
86 * @return {!Common.TextRange} | |
87 */ | |
88 toTextRange(sourceRange) { | |
89 var cursor = new Common.TextCursor(this.lineEndings()); | |
90 var result = Common.TextRange.createFromLocation(0, 0); | |
91 | |
92 cursor.resetTo(sourceRange.offset); | |
93 result.startLine = cursor.lineNumber(); | |
94 result.startColumn = cursor.columnNumber(); | |
95 | |
96 cursor.advance(sourceRange.offset + sourceRange.length); | |
97 result.endLine = cursor.lineNumber(); | |
98 result.endColumn = cursor.columnNumber(); | |
99 return result; | |
100 } | |
101 | |
102 /** | |
103 * @param {!Common.TextRange} range | |
104 * @param {string} replacement | |
105 * @return {string} | |
106 */ | |
107 replaceRange(range, replacement) { | |
108 var sourceRange = this.toSourceRange(range); | |
109 return this._value.substring(0, sourceRange.offset) + replacement + | |
110 this._value.substring(sourceRange.offset + sourceRange.length); | |
111 } | |
112 | |
113 /** | |
114 * @param {!Common.TextRange} range | |
115 * @return {string} | |
116 */ | |
117 extract(range) { | |
118 var sourceRange = this.toSourceRange(range); | |
119 return this._value.substr(sourceRange.offset, sourceRange.length); | |
120 } | |
121 }; | |
122 | |
123 /** @typedef {{lineNumber: number, columnNumber: number}} */ | |
124 Common.Text.Position; | |
125 | |
126 /** | |
127 * @unrestricted | |
128 */ | |
129 Common.TextCursor = class { | |
130 /** | |
131 * @param {!Array<number>} lineEndings | |
132 */ | |
133 constructor(lineEndings) { | |
134 this._lineEndings = lineEndings; | |
135 this._offset = 0; | |
136 this._lineNumber = 0; | |
137 this._columnNumber = 0; | |
138 } | |
139 | |
140 /** | |
141 * @param {number} offset | |
142 */ | |
143 advance(offset) { | |
144 this._offset = offset; | |
145 while (this._lineNumber < this._lineEndings.length && this._lineEndings[this
._lineNumber] < this._offset) | |
146 ++this._lineNumber; | |
147 this._columnNumber = this._lineNumber ? this._offset - this._lineEndings[thi
s._lineNumber - 1] - 1 : this._offset; | |
148 } | |
149 | |
150 /** | |
151 * @return {number} | |
152 */ | |
153 offset() { | |
154 return this._offset; | |
155 } | |
156 | |
157 /** | |
158 * @param {number} offset | |
159 */ | |
160 resetTo(offset) { | |
161 this._offset = offset; | |
162 this._lineNumber = this._lineEndings.lowerBound(offset); | |
163 this._columnNumber = this._lineNumber ? this._offset - this._lineEndings[thi
s._lineNumber - 1] - 1 : this._offset; | |
164 } | |
165 | |
166 /** | |
167 * @return {number} | |
168 */ | |
169 lineNumber() { | |
170 return this._lineNumber; | |
171 } | |
172 | |
173 /** | |
174 * @return {number} | |
175 */ | |
176 columnNumber() { | |
177 return this._columnNumber; | |
178 } | |
179 }; | |
OLD | NEW |