| 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 |