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

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

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

Powered by Google App Engine
This is Rietveld 408576698