Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(456)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/source_frame/SourceCodeDiff.js

Issue 2608043002: DevTools: extract modules (with extensions) (Closed)
Patch Set: fix externs (PerfUI) Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 /** 4 /**
5 * @unrestricted 5 * @unrestricted
6 */ 6 */
7 Sources.SourceCodeDiff = class { 7 SourceFrame.SourceCodeDiff = class {
8 /** 8 /**
9 * @param {!Promise<?string>} diffBaseline 9 * @param {!Promise<?string>} diffBaseline
10 * @param {!TextEditor.CodeMirrorTextEditor} textEditor 10 * @param {!TextEditor.CodeMirrorTextEditor} textEditor
11 */ 11 */
12 constructor(diffBaseline, textEditor) { 12 constructor(diffBaseline, textEditor) {
13 this._textEditor = textEditor; 13 this._textEditor = textEditor;
14 this._decorations = []; 14 this._decorations = [];
15 this._textEditor.installGutter(Sources.SourceCodeDiff.DiffGutterType, true); 15 this._textEditor.installGutter(SourceFrame.SourceCodeDiff.DiffGutterType, tr ue);
16 this._diffBaseline = diffBaseline; 16 this._diffBaseline = diffBaseline;
17 /** @type {!Array<!TextEditor.TextEditorPositionHandle>}*/ 17 /** @type {!Array<!TextEditor.TextEditorPositionHandle>}*/
18 this._animatedLines = []; 18 this._animatedLines = [];
19 } 19 }
20 20
21 updateDiffMarkersWhenPossible() { 21 updateDiffMarkersWhenPossible() {
22 if (this._updateTimeout) 22 if (this._updateTimeout)
23 clearTimeout(this._updateTimeout); 23 clearTimeout(this._updateTimeout);
24 this._updateTimeout = 24 this._updateTimeout =
25 setTimeout(this.updateDiffMarkersImmediately.bind(this), Sources.SourceC odeDiff.UpdateTimeout); 25 setTimeout(this.updateDiffMarkersImmediately.bind(this), SourceFrame.Sou rceCodeDiff.UpdateTimeout);
26 } 26 }
27 27
28 updateDiffMarkersImmediately() { 28 updateDiffMarkersImmediately() {
29 if (this._updateTimeout) 29 if (this._updateTimeout)
30 clearTimeout(this._updateTimeout); 30 clearTimeout(this._updateTimeout);
31 this._updateTimeout = null; 31 this._updateTimeout = null;
32 this._diffBaseline.then(this._innerUpdate.bind(this)); 32 this._diffBaseline.then(this._innerUpdate.bind(this));
33 } 33 }
34 34
35 /** 35 /**
36 * @param {?string} oldContent 36 * @param {?string} oldContent
37 * @param {?string} newContent 37 * @param {?string} newContent
38 */ 38 */
39 highlightModifiedLines(oldContent, newContent) { 39 highlightModifiedLines(oldContent, newContent) {
40 if (typeof oldContent !== 'string' || typeof newContent !== 'string') 40 if (typeof oldContent !== 'string' || typeof newContent !== 'string')
41 return; 41 return;
42 42
43 var diff = this._computeDiff(oldContent, newContent); 43 var diff = this._computeDiff(oldContent, newContent);
44 var changedLines = []; 44 var changedLines = [];
45 for (var i = 0; i < diff.length; ++i) { 45 for (var i = 0; i < diff.length; ++i) {
46 var diffEntry = diff[i]; 46 var diffEntry = diff[i];
47 if (diffEntry.type === Sources.SourceCodeDiff.GutterDecorationType.Delete) 47 if (diffEntry.type === SourceFrame.SourceCodeDiff.GutterDecorationType.Del ete)
48 continue; 48 continue;
49 for (var lineNumber = diffEntry.from; lineNumber < diffEntry.to; ++lineNum ber) { 49 for (var lineNumber = diffEntry.from; lineNumber < diffEntry.to; ++lineNum ber) {
50 var position = this._textEditor.textEditorPositionHandle(lineNumber, 0); 50 var position = this._textEditor.textEditorPositionHandle(lineNumber, 0);
51 if (position) 51 if (position)
52 changedLines.push(position); 52 changedLines.push(position);
53 } 53 }
54 } 54 }
55 this._updateHighlightedLines(changedLines); 55 this._updateHighlightedLines(changedLines);
56 this._animationTimeout = setTimeout( 56 this._animationTimeout = setTimeout(
57 this._updateHighlightedLines.bind(this, []), 400); // // Keep this time out in sync with sourcesView.css. 57 this._updateHighlightedLines.bind(this, []), 400); // // Keep this time out in sync with sourcesView.css.
58 } 58 }
59 59
60 /** 60 /**
61 * @param {!Array<!TextEditor.TextEditorPositionHandle>} newLines 61 * @param {!Array<!TextEditor.TextEditorPositionHandle>} newLines
62 */ 62 */
63 _updateHighlightedLines(newLines) { 63 _updateHighlightedLines(newLines) {
64 if (this._animationTimeout) 64 if (this._animationTimeout)
65 clearTimeout(this._animationTimeout); 65 clearTimeout(this._animationTimeout);
66 this._animationTimeout = null; 66 this._animationTimeout = null;
67 this._textEditor.operation(operation.bind(this)); 67 this._textEditor.operation(operation.bind(this));
68 68
69 /** 69 /**
70 * @this {Sources.SourceCodeDiff} 70 * @this {SourceFrame.SourceCodeDiff}
71 */ 71 */
72 function operation() { 72 function operation() {
73 toggleLines.call(this, false); 73 toggleLines.call(this, false);
74 this._animatedLines = newLines; 74 this._animatedLines = newLines;
75 toggleLines.call(this, true); 75 toggleLines.call(this, true);
76 } 76 }
77 77
78 /** 78 /**
79 * @param {boolean} value 79 * @param {boolean} value
80 * @this {Sources.SourceCodeDiff} 80 * @this {SourceFrame.SourceCodeDiff}
81 */ 81 */
82 function toggleLines(value) { 82 function toggleLines(value) {
83 for (var i = 0; i < this._animatedLines.length; ++i) { 83 for (var i = 0; i < this._animatedLines.length; ++i) {
84 var location = this._animatedLines[i].resolve(); 84 var location = this._animatedLines[i].resolve();
85 if (location) 85 if (location)
86 this._textEditor.toggleLineClass(location.lineNumber, 'highlight-line- modification', value); 86 this._textEditor.toggleLineClass(location.lineNumber, 'highlight-line- modification', value);
87 } 87 }
88 } 88 }
89 } 89 }
90 90
91 /** 91 /**
92 * @param {!Array<!Sources.SourceCodeDiff.GutterDecoration>} removed 92 * @param {!Array<!SourceFrame.SourceCodeDiff.GutterDecoration>} removed
93 * @param {!Array<!Sources.SourceCodeDiff.GutterDecoration>} added 93 * @param {!Array<!SourceFrame.SourceCodeDiff.GutterDecoration>} added
94 */ 94 */
95 _updateDecorations(removed, added) { 95 _updateDecorations(removed, added) {
96 this._textEditor.operation(operation); 96 this._textEditor.operation(operation);
97 97
98 function operation() { 98 function operation() {
99 for (var decoration of removed) 99 for (var decoration of removed)
100 decoration.remove(); 100 decoration.remove();
101 for (var decoration of added) 101 for (var decoration of added)
102 decoration.install(); 102 decoration.install();
103 } 103 }
104 } 104 }
105 105
106 /** 106 /**
107 * @param {string} baseline 107 * @param {string} baseline
108 * @param {string} current 108 * @param {string} current
109 * @return {!Array<!{type: !Sources.SourceCodeDiff.GutterDecorationType, from: number, to: number}>} 109 * @return {!Array<!{type: !SourceFrame.SourceCodeDiff.GutterDecorationType, f rom: number, to: number}>}
110 */ 110 */
111 _computeDiff(baseline, current) { 111 _computeDiff(baseline, current) {
112 var diff = Diff.Diff.lineDiff(baseline.split('\n'), current.split('\n')); 112 var diff = Diff.Diff.lineDiff(baseline.split('\n'), current.split('\n'));
113 var result = []; 113 var result = [];
114 var hasAdded = false; 114 var hasAdded = false;
115 var hasRemoved = false; 115 var hasRemoved = false;
116 var blockStartLineNumber = 0; 116 var blockStartLineNumber = 0;
117 var currentLineNumber = 0; 117 var currentLineNumber = 0;
118 var isInsideBlock = false; 118 var isInsideBlock = false;
119 for (var i = 0; i < diff.length; ++i) { 119 for (var i = 0; i < diff.length; ++i) {
(...skipping 13 matching lines...) Expand all
133 if (token[0] === Diff.Diff.Operation.Delete) { 133 if (token[0] === Diff.Diff.Operation.Delete) {
134 hasRemoved = true; 134 hasRemoved = true;
135 } else { 135 } else {
136 currentLineNumber += token[1].length; 136 currentLineNumber += token[1].length;
137 hasAdded = true; 137 hasAdded = true;
138 } 138 }
139 } 139 }
140 if (isInsideBlock) 140 if (isInsideBlock)
141 flush(); 141 flush();
142 if (result.length > 1 && result[0].from === 0 && result[1].from === 0) { 142 if (result.length > 1 && result[0].from === 0 && result[1].from === 0) {
143 var merged = {type: Sources.SourceCodeDiff.GutterDecorationType.Modify, fr om: 0, to: result[1].to}; 143 var merged = {type: SourceFrame.SourceCodeDiff.GutterDecorationType.Modify , from: 0, to: result[1].to};
144 result.splice(0, 2, merged); 144 result.splice(0, 2, merged);
145 } 145 }
146 return result; 146 return result;
147 147
148 function flush() { 148 function flush() {
149 var type = Sources.SourceCodeDiff.GutterDecorationType.Insert; 149 var type = SourceFrame.SourceCodeDiff.GutterDecorationType.Insert;
150 var from = blockStartLineNumber; 150 var from = blockStartLineNumber;
151 var to = currentLineNumber; 151 var to = currentLineNumber;
152 if (hasAdded && hasRemoved) { 152 if (hasAdded && hasRemoved) {
153 type = Sources.SourceCodeDiff.GutterDecorationType.Modify; 153 type = SourceFrame.SourceCodeDiff.GutterDecorationType.Modify;
154 } else if (!hasAdded && hasRemoved && from === 0 && to === 0) { 154 } else if (!hasAdded && hasRemoved && from === 0 && to === 0) {
155 type = Sources.SourceCodeDiff.GutterDecorationType.Modify; 155 type = SourceFrame.SourceCodeDiff.GutterDecorationType.Modify;
156 to = 1; 156 to = 1;
157 } else if (!hasAdded && hasRemoved) { 157 } else if (!hasAdded && hasRemoved) {
158 type = Sources.SourceCodeDiff.GutterDecorationType.Delete; 158 type = SourceFrame.SourceCodeDiff.GutterDecorationType.Delete;
159 from -= 1; 159 from -= 1;
160 } 160 }
161 result.push({type: type, from: from, to: to}); 161 result.push({type: type, from: from, to: to});
162 isInsideBlock = false; 162 isInsideBlock = false;
163 hasAdded = false; 163 hasAdded = false;
164 hasRemoved = false; 164 hasRemoved = false;
165 } 165 }
166 } 166 }
167 167
168 /** 168 /**
169 * @param {?string} baseline 169 * @param {?string} baseline
170 */ 170 */
171 _innerUpdate(baseline) { 171 _innerUpdate(baseline) {
172 var current = this._textEditor.text(); 172 var current = this._textEditor.text();
173 if (typeof baseline !== 'string') { 173 if (typeof baseline !== 'string') {
174 this._updateDecorations(this._decorations, [] /* added */); 174 this._updateDecorations(this._decorations, [] /* added */);
175 this._decorations = []; 175 this._decorations = [];
176 return; 176 return;
177 } 177 }
178 178
179 var diff = this._computeDiff(baseline, current); 179 var diff = this._computeDiff(baseline, current);
180 180
181 /** @type {!Map<number, !Sources.SourceCodeDiff.GutterDecoration>} */ 181 /** @type {!Map<number, !SourceFrame.SourceCodeDiff.GutterDecoration>} */
182 var oldDecorations = new Map(); 182 var oldDecorations = new Map();
183 for (var i = 0; i < this._decorations.length; ++i) { 183 for (var i = 0; i < this._decorations.length; ++i) {
184 var decoration = this._decorations[i]; 184 var decoration = this._decorations[i];
185 var lineNumber = decoration.lineNumber(); 185 var lineNumber = decoration.lineNumber();
186 if (lineNumber === -1) 186 if (lineNumber === -1)
187 continue; 187 continue;
188 oldDecorations.set(lineNumber, decoration); 188 oldDecorations.set(lineNumber, decoration);
189 } 189 }
190 190
191 /** @type {!Map<number, !{lineNumber: number, type: !Sources.SourceCodeDiff. GutterDecorationType}>} */ 191 /** @type {!Map<number, !{lineNumber: number, type: !SourceFrame.SourceCodeD iff.GutterDecorationType}>} */
192 var newDecorations = new Map(); 192 var newDecorations = new Map();
193 for (var i = 0; i < diff.length; ++i) { 193 for (var i = 0; i < diff.length; ++i) {
194 var diffEntry = diff[i]; 194 var diffEntry = diff[i];
195 for (var lineNumber = diffEntry.from; lineNumber < diffEntry.to; ++lineNum ber) 195 for (var lineNumber = diffEntry.from; lineNumber < diffEntry.to; ++lineNum ber)
196 newDecorations.set(lineNumber, {lineNumber: lineNumber, type: diffEntry. type}); 196 newDecorations.set(lineNumber, {lineNumber: lineNumber, type: diffEntry. type});
197 } 197 }
198 198
199 var decorationDiff = oldDecorations.diff(newDecorations, (e1, e2) => e1.type === e2.type); 199 var decorationDiff = oldDecorations.diff(newDecorations, (e1, e2) => e1.type === e2.type);
200 var addedDecorations = decorationDiff.added.map( 200 var addedDecorations = decorationDiff.added.map(
201 entry => new Sources.SourceCodeDiff.GutterDecoration(this._textEditor, e ntry.lineNumber, entry.type)); 201 entry => new SourceFrame.SourceCodeDiff.GutterDecoration(this._textEdito r, entry.lineNumber, entry.type));
202 202
203 this._decorations = decorationDiff.equal.concat(addedDecorations); 203 this._decorations = decorationDiff.equal.concat(addedDecorations);
204 this._updateDecorations(decorationDiff.removed, addedDecorations); 204 this._updateDecorations(decorationDiff.removed, addedDecorations);
205 this._decorationsSetForTest(newDecorations); 205 this._decorationsSetForTest(newDecorations);
206 } 206 }
207 207
208 /** 208 /**
209 * @param {!Map<number, !{lineNumber: number, type: !Sources.SourceCodeDiff.Gu tterDecorationType}>} decorations 209 * @param {!Map<number, !{lineNumber: number, type: !SourceFrame.SourceCodeDif f.GutterDecorationType}>} decorations
210 */ 210 */
211 _decorationsSetForTest(decorations) { 211 _decorationsSetForTest(decorations) {
212 } 212 }
213 }; 213 };
214 214
215 /** @type {number} */ 215 /** @type {number} */
216 Sources.SourceCodeDiff.UpdateTimeout = 200; 216 SourceFrame.SourceCodeDiff.UpdateTimeout = 200;
217 217
218 /** @type {string} */ 218 /** @type {string} */
219 Sources.SourceCodeDiff.DiffGutterType = 'CodeMirror-gutter-diff'; 219 SourceFrame.SourceCodeDiff.DiffGutterType = 'CodeMirror-gutter-diff';
220 220
221 /** @enum {symbol} */ 221 /** @enum {symbol} */
222 Sources.SourceCodeDiff.GutterDecorationType = { 222 SourceFrame.SourceCodeDiff.GutterDecorationType = {
223 Insert: Symbol('Insert'), 223 Insert: Symbol('Insert'),
224 Delete: Symbol('Delete'), 224 Delete: Symbol('Delete'),
225 Modify: Symbol('Modify'), 225 Modify: Symbol('Modify'),
226 }; 226 };
227 227
228 /** 228 /**
229 * @unrestricted 229 * @unrestricted
230 */ 230 */
231 Sources.SourceCodeDiff.GutterDecoration = class { 231 SourceFrame.SourceCodeDiff.GutterDecoration = class {
232 /** 232 /**
233 * @param {!TextEditor.CodeMirrorTextEditor} textEditor 233 * @param {!TextEditor.CodeMirrorTextEditor} textEditor
234 * @param {number} lineNumber 234 * @param {number} lineNumber
235 * @param {!Sources.SourceCodeDiff.GutterDecorationType} type 235 * @param {!SourceFrame.SourceCodeDiff.GutterDecorationType} type
236 */ 236 */
237 constructor(textEditor, lineNumber, type) { 237 constructor(textEditor, lineNumber, type) {
238 this._textEditor = textEditor; 238 this._textEditor = textEditor;
239 this._position = this._textEditor.textEditorPositionHandle(lineNumber, 0); 239 this._position = this._textEditor.textEditorPositionHandle(lineNumber, 0);
240 this._className = ''; 240 this._className = '';
241 if (type === Sources.SourceCodeDiff.GutterDecorationType.Insert) 241 if (type === SourceFrame.SourceCodeDiff.GutterDecorationType.Insert)
242 this._className = 'diff-entry-insert'; 242 this._className = 'diff-entry-insert';
243 else if (type === Sources.SourceCodeDiff.GutterDecorationType.Delete) 243 else if (type === SourceFrame.SourceCodeDiff.GutterDecorationType.Delete)
244 this._className = 'diff-entry-delete'; 244 this._className = 'diff-entry-delete';
245 else if (type === Sources.SourceCodeDiff.GutterDecorationType.Modify) 245 else if (type === SourceFrame.SourceCodeDiff.GutterDecorationType.Modify)
246 this._className = 'diff-entry-modify'; 246 this._className = 'diff-entry-modify';
247 this.type = type; 247 this.type = type;
248 } 248 }
249 249
250 /** 250 /**
251 * @return {number} 251 * @return {number}
252 */ 252 */
253 lineNumber() { 253 lineNumber() {
254 var location = this._position.resolve(); 254 var location = this._position.resolve();
255 if (!location) 255 if (!location)
256 return -1; 256 return -1;
257 return location.lineNumber; 257 return location.lineNumber;
258 } 258 }
259 259
260 install() { 260 install() {
261 var location = this._position.resolve(); 261 var location = this._position.resolve();
262 if (!location) 262 if (!location)
263 return; 263 return;
264 var element = createElementWithClass('div', 'diff-marker'); 264 var element = createElementWithClass('div', 'diff-marker');
265 element.textContent = '\u00A0'; 265 element.textContent = '\u00A0';
266 this._textEditor.setGutterDecoration(location.lineNumber, Sources.SourceCode Diff.DiffGutterType, element); 266 this._textEditor.setGutterDecoration(location.lineNumber, SourceFrame.Source CodeDiff.DiffGutterType, element);
267 this._textEditor.toggleLineClass(location.lineNumber, this._className, true) ; 267 this._textEditor.toggleLineClass(location.lineNumber, this._className, true) ;
268 } 268 }
269 269
270 remove() { 270 remove() {
271 var location = this._position.resolve(); 271 var location = this._position.resolve();
272 if (!location) 272 if (!location)
273 return; 273 return;
274 this._textEditor.setGutterDecoration(location.lineNumber, Sources.SourceCode Diff.DiffGutterType, null); 274 this._textEditor.setGutterDecoration(location.lineNumber, SourceFrame.Source CodeDiff.DiffGutterType, null);
275 this._textEditor.toggleLineClass(location.lineNumber, this._className, false ); 275 this._textEditor.toggleLineClass(location.lineNumber, this._className, false );
276 } 276 }
277 }; 277 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698