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

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

Issue 2772643002: DevTools: Changes View (Closed)
Patch Set: fix test 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/devtools/front_end/changes/ChangesView.js
diff --git a/third_party/WebKit/Source/devtools/front_end/changes/ChangesView.js b/third_party/WebKit/Source/devtools/front_end/changes/ChangesView.js
new file mode 100644
index 0000000000000000000000000000000000000000..b4078e735bfa45c160215ea02b0e0de998de165d
--- /dev/null
+++ b/third_party/WebKit/Source/devtools/front_end/changes/ChangesView.js
@@ -0,0 +1,296 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+Changes.ChangesView = class extends UI.VBox {
+ constructor() {
+ super(true);
+ this.registerRequiredCSS('changes/changesView.css');
+ var splitWidget = new UI.SplitWidget(true /* vertical */, false /* sidebar on left */);
+ var mainWidget = new UI.Widget();
+ splitWidget.setMainWidget(mainWidget);
+ splitWidget.show(this.contentElement);
+
+ this._emptyWidget = new UI.EmptyWidget(Common.UIString('No changes'));
+ this._emptyWidget.show(mainWidget.element);
+
+ this._workspaceDiff = WorkspaceDiff.workspaceDiff();
+ this._changesSidebar = new Changes.ChangesSidebar(this._workspaceDiff);
+ this._changesSidebar.addEventListener(
+ Changes.ChangesSidebar.Events.SelectedUISourceCodeChanged, this._selectedUISourceCodeChanged, this);
+ splitWidget.setSidebarWidget(this._changesSidebar);
+
+ /** @type {?Workspace.UISourceCode} */
+ this._selectedUISourceCode = null;
+
+ /** @type {!Array<!Changes.ChangesView.Row>} */
+ this._diffRows = [];
+
+ this._maxLineDigits = 1;
+
+ this._editor = new TextEditor.CodeMirrorTextEditor({
+ lineNumbers: true,
+ lineWrapping: false,
+ maxHighlightLength: Infinity // This is to avoid CodeMirror bailing out of highlighting big diffs.
+ });
+ this._editor.setReadOnly(true);
+ this._editor.show(mainWidget.element.createChild('div', 'editor-container'));
+ this._editor.hideWidget();
+
+ this._editor.element.addEventListener('click', this._click.bind(this), false);
+
+ this._toolbar = new UI.Toolbar('changes-toolbar', mainWidget.element);
+ var revertButton = new UI.ToolbarButton(Common.UIString('Revert all changes'), 'largeicon-undo');
+ revertButton.addEventListener(UI.ToolbarButton.Events.Click, this._revert.bind(this));
+ this._toolbar.appendToolbarItem(revertButton);
+ this._diffStats = new UI.ToolbarText('');
+ this._toolbar.appendToolbarItem(this._diffStats);
+ this._toolbar.setEnabled(false);
+
+ this._selectedUISourceCodeChanged();
+ }
+
+ _selectedUISourceCodeChanged() {
+ this._revealUISourceCode(this._changesSidebar.selectedUISourceCode());
+ }
+
+ _revert() {
+ var uiSourceCode = this._selectedUISourceCode;
+ if (!uiSourceCode)
+ return;
+ uiSourceCode.requestOriginalContent().then(original => uiSourceCode.addRevision(original || ''));
+ }
+
+ /**
+ * @param {!Event} event
+ */
+ _click(event) {
+ var selection = this._editor.selection();
+ if (!selection.isEmpty())
+ return;
+ var row = this._diffRows[selection.startLine];
+ Common.Revealer.reveal(
+ this._selectedUISourceCode.uiLocation(row.currentLineNumber - 1, selection.startColumn), false);
+ event.consume(true);
+ }
+
+ /**
+ * @param {?Workspace.UISourceCode} uiSourceCode
+ */
+ _revealUISourceCode(uiSourceCode) {
+ if (this._selectedUISourceCode === uiSourceCode)
+ return;
+
+ if (this._selectedUISourceCode)
+ this._workspaceDiff.unsubscribeFromDiffChange(this._selectedUISourceCode, this._refreshDiff, this);
+ if (uiSourceCode && this.isShowing())
+ this._workspaceDiff.subscribeToDiffChange(uiSourceCode, this._refreshDiff, this);
+
+ this._selectedUISourceCode = uiSourceCode;
+ this._refreshDiff();
+ }
+
+ /**
+ * @override
+ */
+ wasShown() {
+ this._refreshDiff();
+ }
+
+ _refreshDiff() {
+ if (!this.isShowing())
+ return;
+
+ if (!this._selectedUISourceCode) {
+ this._renderDiffRows(null);
+ return;
+ }
+ var uiSourceCode = this._selectedUISourceCode;
+ this._workspaceDiff.requestDiff(uiSourceCode).then(diff => {
+ if (this._selectedUISourceCode !== uiSourceCode)
+ return;
+ this._renderDiffRows(diff);
+ });
+ }
+
+ /**
+ * @param {?Diff.Diff.DiffArray} diff
+ */
+ _renderDiffRows(diff) {
+ this._diffRows = [];
+
+ if (!diff || (diff.length === 1 && diff[0][0] === Diff.Diff.Operation.Equal)) {
+ this._diffStats.setText('');
+ this._toolbar.setEnabled(false);
+ this._editor.hideWidget();
+ this._emptyWidget.showWidget();
+ return;
+ }
+
+ var insertions = 0;
+ var deletions = 0;
+ var currentLineNumber = 0;
+ var baselineLineNumber = 0;
+ var paddingLines = 3;
+
+ for (var i = 0; i < diff.length; ++i) {
+ var token = diff[i];
+ switch (token[0]) {
+ case Diff.Diff.Operation.Equal:
+ this._diffRows.pushAll(createEqualRows(token[1], i === 0, i === diff.length - 1));
+ break;
+ case Diff.Diff.Operation.Insert:
+ for (var line of token[1])
+ this._diffRows.push(createRow(line, Changes.ChangesView.RowType.Addition));
+ insertions += token[1].length;
+ break;
+ case Diff.Diff.Operation.Delete:
+ deletions += token[1].length;
+ if (diff[i + 1] && diff[i + 1][0] === Diff.Diff.Operation.Insert) {
+ i++;
+ this._diffRows.pushAll(createModifyRows(token[1].join('\n'), diff[i][1].join('\n')));
+ insertions += diff[i][1].length;
+ } else {
+ for (var line of token[1])
+ this._diffRows.push(createRow(line, Changes.ChangesView.RowType.Deletion));
+ }
+ break;
+ }
+ }
+
+ this._maxLineDigits = Math.ceil(Math.log10(Math.max(currentLineNumber, baselineLineNumber)));
+
+ this._diffStats.setText(Common.UIString(
+ '%d insertion%s (+), %d deletion%s (-)', insertions, insertions !== 1 ? 's' : '', deletions,
+ deletions !== 1 ? 's' : ''));
+ this._toolbar.setEnabled(true);
+ this._emptyWidget.hideWidget();
+
+ this._editor.operation(() => {
+ this._editor.showWidget();
+ this._editor.setHighlightMode({name: 'devtools-diff', rows: this._diffRows});
+ this._editor.setText(this._diffRows.map(row => row.content.map(t => t.text).join('')).join('\n'));
+ this._editor.setLineNumberFormatter(this._lineFormatter.bind(this));
+ });
+
+ /**
+ * @param {!Array<string>} lines
+ * @param {boolean} atStart
+ * @param {boolean} atEnd
+ * @return {!Array<!Changes.ChangesView.Row>}}
+ */
+ function createEqualRows(lines, atStart, atEnd) {
+ var equalRows = [];
+ if (!atStart) {
+ for (var i = 0; i < paddingLines && i < lines.length; i++)
+ equalRows.push(createRow(lines[i], Changes.ChangesView.RowType.Equal));
+ if (lines.length > paddingLines * 2 + 1 && !atEnd) {
+ equalRows.push(createRow(
+ Common.UIString('( \u2026 Skipping ') + (lines.length - paddingLines * 2) +
+ Common.UIString(' matching lines \u2026 )'),
+ Changes.ChangesView.RowType.Spacer));
+ }
+ }
+ if (!atEnd) {
+ var start = Math.max(lines.length - paddingLines - 1, atStart ? 0 : paddingLines);
+ var skip = lines.length - paddingLines - 1;
+ if (!atStart)
+ skip -= paddingLines;
+ if (skip > 0) {
+ baselineLineNumber += skip;
+ currentLineNumber += skip;
+ }
+
+ for (var i = start; i < lines.length; i++)
+ equalRows.push(createRow(lines[i], Changes.ChangesView.RowType.Equal));
+ }
+ return equalRows;
+ }
+
+ /**
+ * @param {string} before
+ * @param {string} after
+ * @return {!Array<!Changes.ChangesView.Row>}}
+ */
+ function createModifyRows(before, after) {
+ var internalDiff = Diff.Diff.charDiff(before, after, true /* cleanup diff */);
+ var deletionRows = [createRow('', Changes.ChangesView.RowType.Deletion)];
+ var insertionRows = [createRow('', Changes.ChangesView.RowType.Addition)];
+
+ for (var token of internalDiff) {
+ var text = token[1];
+ var type = token[0];
+ var className = type === Diff.Diff.Operation.Equal ? '' : 'inner-diff';
+ var lines = text.split('\n');
+ for (var i = 0; i < lines.length; i++) {
+ if (i > 0 && type !== Diff.Diff.Operation.Insert)
+ deletionRows.push(createRow('', Changes.ChangesView.RowType.Deletion));
+ if (i > 0 && type !== Diff.Diff.Operation.Delete)
+ insertionRows.push(createRow('', Changes.ChangesView.RowType.Addition));
+ if (!lines[i])
+ continue;
+ if (type !== Diff.Diff.Operation.Insert)
+ deletionRows[deletionRows.length - 1].content.push({text: lines[i], className});
+ if (type !== Diff.Diff.Operation.Delete)
+ insertionRows[insertionRows.length - 1].content.push({text: lines[i], className});
+ }
+ }
+ return deletionRows.concat(insertionRows);
+ }
+
+ /**
+ * @param {string} text
+ * @param {!Changes.ChangesView.RowType} type
+ * @return {!Changes.ChangesView.Row}
+ */
+ function createRow(text, type) {
+ if (type === Changes.ChangesView.RowType.Addition)
+ currentLineNumber++;
+ if (type === Changes.ChangesView.RowType.Deletion)
+ baselineLineNumber++;
+ if (type === Changes.ChangesView.RowType.Equal) {
+ baselineLineNumber++;
+ currentLineNumber++;
+ }
+
+ return {baselineLineNumber, currentLineNumber, content: text ? [{text, className: 'inner-diff'}] : [], type};
+ }
+ }
+
+ /**
+ * @param {number} lineNumber
+ * @return {string}
+ */
+ _lineFormatter(lineNumber) {
+ var row = this._diffRows[lineNumber - 1];
+ var showBaseNumber = row.type === Changes.ChangesView.RowType.Deletion;
+ var showCurrentNumber = row.type === Changes.ChangesView.RowType.Addition;
+ if (row.type === Changes.ChangesView.RowType.Equal) {
+ showBaseNumber = true;
+ showCurrentNumber = true;
+ }
+ var base = showBaseNumber ? numberToStringWithSpacesPadding(row.baselineLineNumber, this._maxLineDigits) :
+ spacesPadding(this._maxLineDigits);
+ var current = showCurrentNumber ? numberToStringWithSpacesPadding(row.currentLineNumber, this._maxLineDigits) :
+ spacesPadding(this._maxLineDigits);
+ return base + spacesPadding(1) + current;
+ }
+};
+
+/**
+ * @typedef {!{
+ * baselineLineNumber: number,
+ * currentLineNumber: number,
+ * content: !Array<!{text: string, className: string}>,
+ * type: !Changes.ChangesView.RowType
+ * }}
+ */
+Changes.ChangesView.Row;
+
+/** @enum {string} */
+Changes.ChangesView.RowType = {
+ Deletion: 'deletion',
+ Addition: 'addition',
+ Equal: 'equal',
+ Spacer: 'spacer'
+};

Powered by Google App Engine
This is Rietveld 408576698