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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/changes/ChangesView.js

Issue 2772643002: DevTools: Changes View (Closed)
Patch Set: merge Created 3 years, 8 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
(Empty)
1 // Copyright 2017 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 Changes.ChangesView = class extends UI.VBox {
6 constructor() {
7 super(true);
8 this.registerRequiredCSS('changes/changesView.css');
9 var splitWidget = new UI.SplitWidget(true /* vertical */, false /* sidebar o n left */);
10 var mainWidget = new UI.Widget();
11 splitWidget.setMainWidget(mainWidget);
12 splitWidget.show(this.contentElement);
13
14 this._emptyWidget = new UI.EmptyWidget(Common.UIString('No changes'));
15 this._emptyWidget.show(mainWidget.element);
16
17 this._workspaceDiff = WorkspaceDiff.workspaceDiff();
18 this._changesSidebar = new Changes.ChangesSidebar(this._workspaceDiff);
19 this._changesSidebar.addEventListener(
20 Changes.ChangesSidebar.Events.SelectedUISourceCodeChanged, this._selecte dUISourceCodeChanged, this);
21 splitWidget.setSidebarWidget(this._changesSidebar);
22
23 /** @type {?Workspace.UISourceCode} */
24 this._selectedUISourceCode = null;
25
26 /** @type {!Array<!Changes.ChangesView.Row>} */
27 this._rows = [];
lushnikov 2017/03/29 18:26:17 this._diffRows = [];
einbinder 2017/03/29 19:06:40 Done.
28
29 this._maxLineDigits = 1;
30
31 this._editor = new TextEditor.CodeMirrorTextEditor({
32 lineNumbers: true,
33 lineWrapping: false,
34 maxHighlightLength: Infinity // This is to avoid CodeMirror bailing out o f highlighting big diffs.
35 });
36 this._editor.setReadOnly(true);
37 this._editor.show(mainWidget.element.createChild('div', 'editor-container')) ;
38 this._editor.hideWidget();
39
40 this._editor.element.addEventListener('click', this._click.bind(this), false );
41
42 this._toolbar = new UI.Toolbar('changes-toolbar', mainWidget.element);
43 var revertButton = new UI.ToolbarButton(Common.UIString('Revert all changes' ), 'largeicon-undo');
44 revertButton.addEventListener(UI.ToolbarButton.Events.Click, this._revert.bi nd(this));
45 this._toolbar.appendToolbarItem(revertButton);
46 this._diffStats = new UI.ToolbarText('');
47 this._toolbar.appendToolbarItem(this._diffStats);
48 this._toolbar.setEnabled(false);
49
50 this._selectedUISourceCodeChanged();
51 }
52
53 _selectedUISourceCodeChanged() {
54 this._revealUISourceCode(this._changesSidebar.selectedUISourceCode());
55 }
56
57 _revert() {
58 var uiSourceCode = this._selectedUISourceCode;
59 if (!uiSourceCode)
60 return;
61 uiSourceCode.requestOriginalContent().then(original => uiSourceCode.addRevis ion(original || ''));
62 }
63
64 /**
65 * @param {!Event} event
66 */
67 _click(event) {
68 var selection = this._editor.selection();
69 if (!selection.isEmpty())
70 return;
71 var row = this._rows[selection.startLine];
72 Common.Revealer.reveal(
73 this._selectedUISourceCode.uiLocation(row.currentLineNumber - 1, selecti on.startColumn), false);
74 event.consume(true);
75 }
76
77 /**
78 * @param {?Workspace.UISourceCode} uiSourceCode
79 */
80 _revealUISourceCode(uiSourceCode) {
81 if (this._selectedUISourceCode === uiSourceCode)
82 return;
83
84 if (this._selectedUISourceCode)
85 this._workspaceDiff.unsubscribeFromDiffChange(this._selectedUISourceCode, this._refreshDiff, this);
86 if (uiSourceCode && this.isShowing())
87 this._workspaceDiff.subscribeToDiffChange(uiSourceCode, this._refreshDiff, this);
88
89 this._selectedUISourceCode = uiSourceCode;
90 this._refreshDiff();
91 }
92
93 /**
94 * @override
95 */
96 wasShown() {
97 this._refreshDiff();
98 }
99
100 _refreshDiff() {
101 if (!this.isShowing())
102 return;
103
104 if (!this._selectedUISourceCode) {
105 this._renderRows(null);
lushnikov 2017/03/29 18:26:17 _renderDiffRows
einbinder 2017/03/29 19:06:40 Done.
106 return;
107 }
108 var uiSourceCode = this._selectedUISourceCode;
109 this._workspaceDiff.requestDiff(uiSourceCode).then(diff => {
110 if (this._selectedUISourceCode !== uiSourceCode)
111 return;
112 this._renderRows(diff);
113 });
114 }
115
116 /**
117 * @param {?Diff.Diff.DiffArray} diff
118 */
119 _renderRows(diff) {
120 this._rows = [];
121
122 if (!diff || (diff.length === 1 && diff[0][0] === Diff.Diff.Operation.Equal) ) {
123 this._diffStats.setText('');
124 this._toolbar.setEnabled(false);
125 this._editor.hideWidget();
126 this._emptyWidget.showWidget();
127 return;
128 }
129
130 var insertions = 0;
131 var deletions = 0;
132 var currentLineNumber = 0;
133 var baselineLineNumber = 0;
134 var paddingLines = 3;
135
136 for (var i = 0; i < diff.length; ++i) {
137 var token = diff[i];
138 switch (token[0]) {
139 case Diff.Diff.Operation.Equal:
140 this._rows.pushAll(createEqualRows(token[1], i === 0, i === diff.lengt h - 1));
141 break;
142 case Diff.Diff.Operation.Insert:
143 for (var line of token[1])
144 this._rows.push(createRow(line, Changes.ChangesView.RowType.Addition ));
145 insertions += token[1].length;
146 break;
147 case Diff.Diff.Operation.Delete:
148 deletions += token[1].length;
149 if (diff[i + 1] && diff[i + 1][0] === Diff.Diff.Operation.Insert) {
150 i++;
151 this._rows.pushAll(createModifyRows(token[1].join('\n'), diff[i][1]. join('\n')));
152 insertions += diff[i][1].length;
153 } else {
154 for (var line of token[1])
155 this._rows.push(createRow(line, Changes.ChangesView.RowType.Deleti on));
156 }
157 break;
158 }
159 }
160
161 this._maxLineDigits = Math.ceil(Math.log10(Math.max(currentLineNumber, basel ineLineNumber)));
162
163 this._diffStats.setText(Common.UIString(
164 '%d insertion%s (+), %d deletion%s (-)', insertions, insertions !== 1 ? 's' : '', deletions,
165 deletions !== 1 ? 's' : ''));
166 this._toolbar.setEnabled(true);
167 this._emptyWidget.hideWidget();
168
169 this._editor.operation(() => {
170 this._editor.showWidget();
171 this._editor.setHighlightMode({name: 'devtools-diff', rows: this._rows});
172 this._editor.setText(this._rows.map(row => row.content.map(t => t.text).jo in('')).join('\n'));
173 this._editor.setLineNumberFormatter(this._lineFormatter.bind(this));
174 });
175
176 /**
177 * @param {!Array<string>} lines
178 * @param {boolean} atStart
179 * @param {boolean} atEnd
180 * @return {!Array<!Changes.ChangesView.Row>}}
181 */
182 function createEqualRows(lines, atStart, atEnd) {
183 var equalRows = [];
184 if (!atStart) {
185 for (var i = 0; i < paddingLines && i < lines.length; i++)
186 equalRows.push(createRow(lines[i], Changes.ChangesView.RowType.Equal)) ;
187 if (lines.length > paddingLines * 2 + 1 && !atEnd) {
188 equalRows.push(createRow(
189 Common.UIString('( \u2026 Skipping ') + (lines.length - paddingLin es * 2) +
190 Common.UIString(' matching lines \u2026 )'),
191 Changes.ChangesView.RowType.Spacer));
192 }
193 }
194 if (!atEnd) {
195 var start = Math.max(lines.length - paddingLines - 1, atStart ? 0 : padd ingLines);
196 var skip = lines.length - paddingLines - 1;
197 if (!atStart)
198 skip -= paddingLines;
199 if (skip > 0) {
200 baselineLineNumber += skip;
201 currentLineNumber += skip;
202 }
203
204 for (var i = start; i < lines.length; i++)
205 equalRows.push(createRow(lines[i], Changes.ChangesView.RowType.Equal)) ;
206 }
207 return equalRows;
208 }
209
210 /**
211 * @param {string} before
212 * @param {string} after
213 * @return {!Array<!Changes.ChangesView.Row>}}
214 */
215 function createModifyRows(before, after) {
216 var internalDiff = Diff.Diff.charDiff(before, after, true /* cleanup diff */);
217 var deletionRows = [createRow('', Changes.ChangesView.RowType.Deletion)];
218 var insertionRows = [createRow('', Changes.ChangesView.RowType.Addition)];
219
220 for (var token of internalDiff) {
221 var text = token[1];
222 var type = token[0];
223 var className = type === Diff.Diff.Operation.Equal ? '' : 'inner-diff';
224 var lines = text.split('\n');
225 for (var i = 0; i < lines.length; i++) {
226 if (i > 0 && type !== Diff.Diff.Operation.Insert)
227 deletionRows.push(createRow('', Changes.ChangesView.RowType.Deletion ));
228 if (i > 0 && type !== Diff.Diff.Operation.Delete)
229 insertionRows.push(createRow('', Changes.ChangesView.RowType.Additio n));
230 if (!lines[i])
231 continue;
232 if (type !== Diff.Diff.Operation.Insert)
233 deletionRows[deletionRows.length - 1].content.push({text: lines[i], className: className});
234 if (type !== Diff.Diff.Operation.Delete)
235 insertionRows[insertionRows.length - 1].content.push({text: lines[i] , className: className});
236 }
237 }
238 return deletionRows.concat(insertionRows);
239 }
240
241 /**
242 * @param {string} text
243 * @param {!Changes.ChangesView.RowType} type
244 * @return {!Changes.ChangesView.Row}
245 */
246 function createRow(text, type) {
247 if (type === Changes.ChangesView.RowType.Addition)
248 currentLineNumber++;
249 if (type === Changes.ChangesView.RowType.Deletion)
250 baselineLineNumber++;
251 if (type === Changes.ChangesView.RowType.Equal) {
252 baselineLineNumber++;
253 currentLineNumber++;
254 }
255
256 return {baselineLineNumber, currentLineNumber, content: text ? [{text, cla ssName: 'inner-diff'}] : [], type};
luoe 2017/03/29 18:25:42 Object property shorthand! Is this a convention w
einbinder 2017/03/29 19:06:40 Done.
257 }
258 }
259
260 /**
261 * @param {number} lineNumber
262 * @return {string}
263 */
264 _lineFormatter(lineNumber) {
265 var row = this._rows[lineNumber - 1];
266 var showBaseNumber = row.type === Changes.ChangesView.RowType.Deletion;
267 var showCurrentNumber = row.type === Changes.ChangesView.RowType.Addition;
268 if (row.type === Changes.ChangesView.RowType.Equal) {
269 showBaseNumber = true;
270 showCurrentNumber = true;
271 }
272 var base = showBaseNumber ? numberToStringWithSpacesPadding(row.baselineLine Number, this._maxLineDigits) :
273 spacesPadding(this._maxLineDigits);
274 var current = showCurrentNumber ? numberToStringWithSpacesPadding(row.curren tLineNumber, this._maxLineDigits) :
275 spacesPadding(this._maxLineDigits);
276 return base + spacesPadding(1) + current;
luoe 2017/03/29 18:25:42 Where is spacesPadding() defined? Is this still n
einbinder 2017/03/29 19:06:40 Spaces padding is in utilities.js
277 }
278 };
279
280 /**
281 * @typedef {!{
282 * baselineLineNumber: number,
283 * currentLineNumber: number,
284 * content: !Array<!{text: string, className: string}>,
285 * type: !Changes.ChangesView.RowType
286 * }}
287 */
288 Changes.ChangesView.Row;
289
290 /** @enum {string} */
291 Changes.ChangesView.RowType = {
292 Deletion: 'deletion',
293 Addition: 'addition',
294 Equal: 'equal',
295 Spacer: 'spacer'
296 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698