chrome-devtools-frontend 1.0.930993 → 1.0.932348
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/gni/devtools_grd_files.gni +6 -2
- package/front_end/core/common/ParsedURL.ts +12 -10
- package/front_end/core/host/InspectorFrontendHostAPI.ts +8 -6
- package/front_end/core/i18n/locales/en-US.json +345 -12
- package/front_end/core/i18n/locales/en-XL.json +345 -12
- package/front_end/core/platform/DevToolsPath.ts +34 -0
- package/front_end/core/platform/platform.ts +2 -0
- package/front_end/core/protocol_client/NodeURL.ts +2 -1
- package/front_end/core/sdk/CSSStyleSheetHeader.ts +4 -2
- package/front_end/core/sdk/ChildTargetManager.ts +2 -0
- package/front_end/core/sdk/CompilerSourceMappingContentProvider.ts +4 -2
- package/front_end/core/sdk/DebuggerModel.ts +4 -3
- package/front_end/core/sdk/NetworkRequest.ts +3 -2
- package/front_end/core/sdk/Resource.ts +6 -5
- package/front_end/core/sdk/Script.ts +4 -2
- package/front_end/core/sdk/Target.ts +4 -0
- package/front_end/core/sdk/TracingModel.ts +8 -17
- package/front_end/entrypoint_template.html +1 -1
- package/front_end/entrypoints/formatter_worker/ESTreeWalker.ts +1 -1
- package/front_end/models/bindings/BreakpointManager.ts +6 -3
- package/front_end/models/bindings/ResourceMapping.ts +2 -1
- package/front_end/models/bindings/StylesSourceMapping.ts +2 -1
- package/front_end/models/emulation/DeviceModeModel.ts +1 -1
- package/front_end/models/persistence/IsolatedFileSystem.ts +9 -7
- package/front_end/models/persistence/IsolatedFileSystemManager.ts +8 -7
- package/front_end/models/persistence/PersistenceActions.ts +1 -1
- package/front_end/models/persistence/PlatformFileSystem.ts +4 -3
- package/front_end/models/text_utils/ContentProvider.ts +2 -1
- package/front_end/models/text_utils/StaticContentProvider.ts +4 -2
- package/front_end/models/workspace/UISourceCode.ts +3 -2
- package/front_end/panels/animation/AnimationGroupPreviewUI.ts +25 -25
- package/front_end/panels/animation/AnimationModel.ts +157 -156
- package/front_end/panels/animation/AnimationScreenshotPopover.ts +26 -26
- package/front_end/panels/animation/AnimationTimeline.ts +274 -260
- package/front_end/panels/animation/AnimationUI.ts +155 -145
- package/front_end/panels/application/BackForwardCacheStrings.ts +621 -0
- package/front_end/panels/application/BackForwardCacheView.ts +24 -8
- package/front_end/panels/application/ReportingApiReportsView.ts +3 -2
- package/front_end/panels/application/ReportingApiView.ts +1 -2
- package/front_end/panels/application/backForwardCacheView.css +10 -0
- package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +48 -40
- package/front_end/panels/browser_debugger/DOMBreakpointsSidebarPane.ts +37 -37
- package/front_end/panels/browser_debugger/ObjectEventListenersSidebarPane.ts +23 -19
- package/front_end/panels/browser_debugger/XHRBreakpointsSidebarPane.ts +56 -56
- package/front_end/panels/changes/ChangesView.ts +42 -225
- package/front_end/panels/changes/changes-legacy.ts +0 -2
- package/front_end/panels/changes/changes.ts +0 -6
- package/front_end/panels/changes/changesView.css +2 -69
- package/front_end/panels/changes/module.json +1 -1
- package/front_end/panels/console/ConsolePinPane.ts +80 -75
- package/front_end/panels/console/ConsoleView.ts +1 -9
- package/front_end/panels/console/consolePinPane.css +4 -1
- package/front_end/panels/elements/StylesSidebarPane.ts +2 -1
- package/front_end/panels/security/mainView.css +2 -1
- package/front_end/panels/snippets/ScriptSnippetFileSystem.ts +2 -1
- package/front_end/panels/sources/NavigatorView.ts +5 -2
- package/front_end/panels/sources/SourcesPanel.ts +28 -1
- package/front_end/panels/sources/sources-meta.ts +1 -4
- package/front_end/third_party/codemirror.next/bundle.ts +6 -4
- package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/markdown.js +1 -1
- package/front_end/third_party/codemirror.next/codemirror.next.d.ts +30 -1
- package/front_end/third_party/codemirror.next/codemirror.next.js +1 -1
- package/front_end/third_party/codemirror.next/package.json +4 -3
- package/front_end/ui/components/buttons/Button.ts +22 -6
- package/front_end/ui/components/buttons/button.css +50 -4
- package/front_end/ui/components/diff_view/DiffView.ts +288 -0
- package/front_end/ui/components/diff_view/diffView.css +73 -0
- package/front_end/ui/components/diff_view/diff_view.ts +5 -0
- package/front_end/ui/components/docs/button/basic.html +28 -0
- package/front_end/ui/components/docs/button/basic.ts +43 -2
- package/front_end/ui/components/report_view/report.css +1 -0
- package/front_end/ui/components/text_editor/config.ts +34 -1
- package/front_end/ui/legacy/ForwardedInputEventHandler.ts +5 -3
- package/front_end/ui/legacy/components/color_picker/spectrum.css +2 -4
- package/front_end/ui/legacy/themeColors.css +4 -0
- package/package.json +1 -1
- package/scripts/build/generate_css_js_files.js +1 -0
- package/scripts/migration/class-fields/migrate.js +1 -3
- package/front_end/panels/changes/ChangesHighlighter.ts +0 -179
- package/front_end/panels/changes/ChangesTextEditor.ts +0 -96
|
@@ -67,36 +67,36 @@ let xhrBreakpointsSidebarPaneInstance: XHRBreakpointsSidebarPane;
|
|
|
67
67
|
export class XHRBreakpointsSidebarPane extends UI.Widget.VBox implements UI.ContextFlavorListener.ContextFlavorListener,
|
|
68
68
|
UI.Toolbar.ItemsProvider,
|
|
69
69
|
UI.ListControl.ListDelegate<string> {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
70
|
+
readonly #breakpoints: UI.ListModel.ListModel<string>;
|
|
71
|
+
#list: UI.ListControl.ListControl<string>;
|
|
72
|
+
readonly #emptyElement: HTMLElement;
|
|
73
|
+
readonly #breakpointElements: Map<string, Element>;
|
|
74
|
+
readonly #addButton: UI.Toolbar.ToolbarButton;
|
|
75
75
|
// TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
|
|
76
76
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
77
|
-
|
|
77
|
+
#hitBreakpoint?: any;
|
|
78
78
|
|
|
79
79
|
private constructor() {
|
|
80
80
|
super(true);
|
|
81
81
|
|
|
82
|
-
this
|
|
83
|
-
this
|
|
84
|
-
this.contentElement.appendChild(this
|
|
85
|
-
this
|
|
86
|
-
UI.ARIAUtils.markAsList(this
|
|
87
|
-
UI.ARIAUtils.setAccessibleName(this
|
|
88
|
-
this
|
|
89
|
-
this
|
|
82
|
+
this.#breakpoints = new UI.ListModel.ListModel();
|
|
83
|
+
this.#list = new UI.ListControl.ListControl(this.#breakpoints, this, UI.ListControl.ListMode.NonViewport);
|
|
84
|
+
this.contentElement.appendChild(this.#list.element);
|
|
85
|
+
this.#list.element.classList.add('breakpoint-list', 'hidden');
|
|
86
|
+
UI.ARIAUtils.markAsList(this.#list.element);
|
|
87
|
+
UI.ARIAUtils.setAccessibleName(this.#list.element, i18nString(UIStrings.xhrfetchBreakpoints));
|
|
88
|
+
this.#emptyElement = this.contentElement.createChild('div', 'gray-info-message');
|
|
89
|
+
this.#emptyElement.textContent = i18nString(UIStrings.noBreakpoints);
|
|
90
90
|
|
|
91
|
-
this
|
|
91
|
+
this.#breakpointElements = new Map();
|
|
92
92
|
|
|
93
|
-
this
|
|
94
|
-
this
|
|
93
|
+
this.#addButton = new UI.Toolbar.ToolbarButton(i18nString(UIStrings.addXhrfetchBreakpoint), 'largeicon-add');
|
|
94
|
+
this.#addButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, () => {
|
|
95
95
|
this.addButtonClicked();
|
|
96
96
|
});
|
|
97
97
|
|
|
98
|
-
this
|
|
99
|
-
this
|
|
98
|
+
this.#emptyElement.addEventListener('contextmenu', this.emptyElementContextMenu.bind(this), true);
|
|
99
|
+
this.#emptyElement.tabIndex = -1;
|
|
100
100
|
this.restoreBreakpoints();
|
|
101
101
|
this.update();
|
|
102
102
|
}
|
|
@@ -109,7 +109,7 @@ export class XHRBreakpointsSidebarPane extends UI.Widget.VBox implements UI.Cont
|
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
toolbarItems(): UI.Toolbar.ToolbarItem[] {
|
|
112
|
-
return [this
|
|
112
|
+
return [this.#addButton];
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
private emptyElementContextMenu(event: Event): void {
|
|
@@ -127,7 +127,7 @@ export class XHRBreakpointsSidebarPane extends UI.Widget.VBox implements UI.Cont
|
|
|
127
127
|
|
|
128
128
|
const inputElement = inputElementContainer.createChild('span', 'breakpoint-condition-input');
|
|
129
129
|
UI.ARIAUtils.setAccessibleName(inputElement, i18nString(UIStrings.urlBreakpoint));
|
|
130
|
-
this.addListElement(inputElementContainer, this
|
|
130
|
+
this.addListElement(inputElementContainer, this.#list.element.firstChild as Element | null);
|
|
131
131
|
|
|
132
132
|
function finishEditing(this: XHRBreakpointsSidebarPane, accept: boolean, e: Element, text: string): void {
|
|
133
133
|
this.removeListElement(inputElementContainer);
|
|
@@ -153,10 +153,10 @@ export class XHRBreakpointsSidebarPane extends UI.Widget.VBox implements UI.Cont
|
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
private setBreakpoint(url: string): void {
|
|
156
|
-
if (this
|
|
157
|
-
this
|
|
156
|
+
if (this.#breakpoints.indexOf(url) !== -1) {
|
|
157
|
+
this.#list.refreshItem(url);
|
|
158
158
|
} else {
|
|
159
|
-
this
|
|
159
|
+
this.#breakpoints.insertWithComparator(url, (a, b) => {
|
|
160
160
|
if (a > b) {
|
|
161
161
|
return 1;
|
|
162
162
|
}
|
|
@@ -166,8 +166,8 @@ export class XHRBreakpointsSidebarPane extends UI.Widget.VBox implements UI.Cont
|
|
|
166
166
|
return 0;
|
|
167
167
|
});
|
|
168
168
|
}
|
|
169
|
-
if (!this
|
|
170
|
-
this
|
|
169
|
+
if (!this.#list.selectedItem() || !this.hasFocus()) {
|
|
170
|
+
this.#list.selectItem(this.#breakpoints.at(0));
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
|
|
@@ -195,7 +195,7 @@ export class XHRBreakpointsSidebarPane extends UI.Widget.VBox implements UI.Cont
|
|
|
195
195
|
breakpointEntryToCheckbox.set(element, label.checkboxElement);
|
|
196
196
|
label.checkboxElement.tabIndex = -1;
|
|
197
197
|
element.tabIndex = -1;
|
|
198
|
-
if (item === this
|
|
198
|
+
if (item === this.#list.selectedItem()) {
|
|
199
199
|
element.tabIndex = 0;
|
|
200
200
|
this.setDefaultFocusedElement(element);
|
|
201
201
|
}
|
|
@@ -214,14 +214,14 @@ export class XHRBreakpointsSidebarPane extends UI.Widget.VBox implements UI.Cont
|
|
|
214
214
|
}
|
|
215
215
|
});
|
|
216
216
|
|
|
217
|
-
if (item === this
|
|
217
|
+
if (item === this.#hitBreakpoint) {
|
|
218
218
|
element.classList.add('breakpoint-hit');
|
|
219
219
|
UI.ARIAUtils.setDescription(element, i18nString(UIStrings.breakpointHit));
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
label.classList.add('cursor-auto');
|
|
223
223
|
label.textElement.addEventListener('dblclick', this.labelClicked.bind(this, item), false);
|
|
224
|
-
this
|
|
224
|
+
this.#breakpointElements.set(item, listItemElement);
|
|
225
225
|
return listItemElement;
|
|
226
226
|
}
|
|
227
227
|
|
|
@@ -252,25 +252,25 @@ export class XHRBreakpointsSidebarPane extends UI.Widget.VBox implements UI.Cont
|
|
|
252
252
|
}
|
|
253
253
|
|
|
254
254
|
private removeBreakpoint(url: string): void {
|
|
255
|
-
const index = this
|
|
255
|
+
const index = this.#breakpoints.indexOf(url);
|
|
256
256
|
if (index >= 0) {
|
|
257
|
-
this
|
|
257
|
+
this.#breakpoints.remove(index);
|
|
258
258
|
}
|
|
259
|
-
this
|
|
259
|
+
this.#breakpointElements.delete(url);
|
|
260
260
|
this.update();
|
|
261
261
|
}
|
|
262
262
|
|
|
263
263
|
private addListElement(element: Element, beforeNode: Node|null): void {
|
|
264
|
-
this
|
|
265
|
-
this
|
|
266
|
-
this
|
|
264
|
+
this.#list.element.insertBefore(element, beforeNode);
|
|
265
|
+
this.#emptyElement.classList.add('hidden');
|
|
266
|
+
this.#list.element.classList.remove('hidden');
|
|
267
267
|
}
|
|
268
268
|
|
|
269
269
|
private removeListElement(element: Element): void {
|
|
270
|
-
this
|
|
271
|
-
if (!this
|
|
272
|
-
this
|
|
273
|
-
this
|
|
270
|
+
this.#list.element.removeChild(element);
|
|
271
|
+
if (!this.#list.element.firstElementChild) {
|
|
272
|
+
this.#emptyElement.classList.remove('hidden');
|
|
273
|
+
this.#list.element.classList.add('hidden');
|
|
274
274
|
}
|
|
275
275
|
}
|
|
276
276
|
|
|
@@ -283,7 +283,7 @@ export class XHRBreakpointsSidebarPane extends UI.Widget.VBox implements UI.Cont
|
|
|
283
283
|
}
|
|
284
284
|
|
|
285
285
|
function removeAllBreakpoints(this: XHRBreakpointsSidebarPane): void {
|
|
286
|
-
for (const url of this
|
|
286
|
+
for (const url of this.#breakpointElements.keys()) {
|
|
287
287
|
SDK.DOMDebuggerModel.DOMDebuggerManager.instance().removeXHRBreakpoint(url);
|
|
288
288
|
this.removeBreakpoint(url);
|
|
289
289
|
}
|
|
@@ -300,20 +300,20 @@ export class XHRBreakpointsSidebarPane extends UI.Widget.VBox implements UI.Cont
|
|
|
300
300
|
private checkboxClicked(url: string, checked: boolean): void {
|
|
301
301
|
const hadFocus = this.hasFocus();
|
|
302
302
|
SDK.DOMDebuggerModel.DOMDebuggerManager.instance().toggleXHRBreakpoint(url, !checked);
|
|
303
|
-
this
|
|
304
|
-
this
|
|
303
|
+
this.#list.refreshItem(url);
|
|
304
|
+
this.#list.selectItem(url);
|
|
305
305
|
if (hadFocus) {
|
|
306
306
|
this.focus();
|
|
307
307
|
}
|
|
308
308
|
}
|
|
309
309
|
|
|
310
310
|
private labelClicked(url: string): void {
|
|
311
|
-
const element = this
|
|
311
|
+
const element = this.#breakpointElements.get(url);
|
|
312
312
|
const inputElement = document.createElement('span');
|
|
313
313
|
inputElement.classList.add('breakpoint-condition');
|
|
314
314
|
inputElement.textContent = url;
|
|
315
315
|
if (element) {
|
|
316
|
-
this
|
|
316
|
+
this.#list.element.insertBefore(inputElement, element);
|
|
317
317
|
element.classList.add('hidden');
|
|
318
318
|
}
|
|
319
319
|
|
|
@@ -333,7 +333,7 @@ export class XHRBreakpointsSidebarPane extends UI.Widget.VBox implements UI.Cont
|
|
|
333
333
|
}
|
|
334
334
|
SDK.DOMDebuggerModel.DOMDebuggerManager.instance().addXHRBreakpoint(text, enabled);
|
|
335
335
|
this.setBreakpoint(text);
|
|
336
|
-
this
|
|
336
|
+
this.#list.selectItem(text);
|
|
337
337
|
} else if (element) {
|
|
338
338
|
element.classList.remove('hidden');
|
|
339
339
|
}
|
|
@@ -351,27 +351,27 @@ export class XHRBreakpointsSidebarPane extends UI.Widget.VBox implements UI.Cont
|
|
|
351
351
|
}
|
|
352
352
|
|
|
353
353
|
private update(): void {
|
|
354
|
-
const isEmpty = this
|
|
355
|
-
this
|
|
356
|
-
this
|
|
354
|
+
const isEmpty = this.#breakpoints.length === 0;
|
|
355
|
+
this.#list.element.classList.toggle('hidden', isEmpty);
|
|
356
|
+
this.#emptyElement.classList.toggle('hidden', !isEmpty);
|
|
357
357
|
|
|
358
358
|
const details = UI.Context.Context.instance().flavor(SDK.DebuggerModel.DebuggerPausedDetails);
|
|
359
359
|
if (!details || details.reason !== Protocol.Debugger.PausedEventReason.XHR) {
|
|
360
|
-
if (this
|
|
361
|
-
const oldHitBreakpoint = this
|
|
362
|
-
|
|
363
|
-
if (this
|
|
364
|
-
this
|
|
360
|
+
if (this.#hitBreakpoint) {
|
|
361
|
+
const oldHitBreakpoint = this.#hitBreakpoint;
|
|
362
|
+
this.#hitBreakpoint = undefined;
|
|
363
|
+
if (this.#breakpoints.indexOf(oldHitBreakpoint) >= 0) {
|
|
364
|
+
this.#list.refreshItem(oldHitBreakpoint);
|
|
365
365
|
}
|
|
366
366
|
}
|
|
367
367
|
return;
|
|
368
368
|
}
|
|
369
369
|
const url = details.auxData && details.auxData['breakpointURL'];
|
|
370
|
-
this
|
|
371
|
-
if (this
|
|
370
|
+
this.#hitBreakpoint = url;
|
|
371
|
+
if (this.#breakpoints.indexOf(url) < 0) {
|
|
372
372
|
return;
|
|
373
373
|
}
|
|
374
|
-
this
|
|
374
|
+
this.#list.refreshItem(url);
|
|
375
375
|
UI.ViewManager.ViewManager.instance().showView('sources.xhrBreakpoints');
|
|
376
376
|
}
|
|
377
377
|
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import * as Common from '../../core/common/common.js';
|
|
6
6
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
7
7
|
import * as Diff from '../../third_party/diff/diff.js';
|
|
8
|
+
import * as DiffView from '../../ui/components/diff_view/diff_view.js';
|
|
8
9
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
9
10
|
|
|
10
11
|
import changesViewStyles from './changesView.css.js';
|
|
@@ -13,13 +14,8 @@ import type * as Workspace from '../../models/workspace/workspace.js';
|
|
|
13
14
|
import * as WorkspaceDiff from '../../models/workspace_diff/workspace_diff.js';
|
|
14
15
|
|
|
15
16
|
import {ChangesSidebar, Events} from './ChangesSidebar.js';
|
|
16
|
-
import {ChangesTextEditor} from './ChangesTextEditor.js';
|
|
17
17
|
|
|
18
18
|
const UIStrings = {
|
|
19
|
-
/**
|
|
20
|
-
*@description Screen-reader accessible name for the code editor in the Changes tool showing the user's changes.
|
|
21
|
-
*/
|
|
22
|
-
changesDiffViewer: 'Changes diff viewer',
|
|
23
19
|
/**
|
|
24
20
|
*@description Screen reader/tooltip label for a button in the Changes tool that reverts all changes to the currently open file.
|
|
25
21
|
*/
|
|
@@ -44,15 +40,20 @@ const UIStrings = {
|
|
|
44
40
|
* lines were removed (not translatable).
|
|
45
41
|
*/
|
|
46
42
|
sDeletions: '{n, plural, =1 {# deletion (-)} other {# deletions (-)}}',
|
|
47
|
-
/**
|
|
48
|
-
*@description Text in Changes View of the Changes tab
|
|
49
|
-
*@example {2} PH1
|
|
50
|
-
*/
|
|
51
|
-
SkippingDMatchingLines: '( … Skipping {PH1} matching lines … )',
|
|
52
43
|
};
|
|
53
44
|
const str_ = i18n.i18n.registerUIStrings('panels/changes/ChangesView.ts', UIStrings);
|
|
54
45
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
55
46
|
|
|
47
|
+
function diffStats(diff: Diff.Diff.DiffArray): string {
|
|
48
|
+
const insertions =
|
|
49
|
+
diff.reduce((ins, token) => ins + (token[0] === Diff.Diff.Operation.Insert ? token[1].length : 0), 0);
|
|
50
|
+
const deletions =
|
|
51
|
+
diff.reduce((ins, token) => ins + (token[0] === Diff.Diff.Operation.Delete ? token[1].length : 0), 0);
|
|
52
|
+
const deletionText = i18nString(UIStrings.sDeletions, {n: deletions});
|
|
53
|
+
const insertionText = i18nString(UIStrings.sInsertions, {n: insertions});
|
|
54
|
+
return `${insertionText}, ${deletionText}`;
|
|
55
|
+
}
|
|
56
|
+
|
|
56
57
|
let changesViewInstance: ChangesView;
|
|
57
58
|
|
|
58
59
|
export class ChangesView extends UI.Widget.VBox {
|
|
@@ -60,11 +61,10 @@ export class ChangesView extends UI.Widget.VBox {
|
|
|
60
61
|
private readonly workspaceDiff: WorkspaceDiff.WorkspaceDiff.WorkspaceDiffImpl;
|
|
61
62
|
readonly changesSidebar: ChangesSidebar;
|
|
62
63
|
private selectedUISourceCode: Workspace.UISourceCode.UISourceCode|null;
|
|
63
|
-
private
|
|
64
|
-
private maxLineDigits: number;
|
|
65
|
-
private readonly editor: ChangesTextEditor;
|
|
64
|
+
private readonly diffContainer: HTMLElement;
|
|
66
65
|
private readonly toolbar: UI.Toolbar.Toolbar;
|
|
67
66
|
private readonly diffStats: UI.Toolbar.ToolbarText;
|
|
67
|
+
private readonly diffView: DiffView.DiffView.DiffView;
|
|
68
68
|
|
|
69
69
|
private constructor() {
|
|
70
70
|
super(true);
|
|
@@ -84,30 +84,11 @@ export class ChangesView extends UI.Widget.VBox {
|
|
|
84
84
|
|
|
85
85
|
this.selectedUISourceCode = null;
|
|
86
86
|
|
|
87
|
-
this.
|
|
88
|
-
|
|
89
|
-
this.
|
|
90
|
-
|
|
91
|
-
this.editor = new ChangesTextEditor({
|
|
92
|
-
bracketMatchingSetting: undefined,
|
|
93
|
-
devtoolsAccessibleName: i18nString(UIStrings.changesDiffViewer),
|
|
94
|
-
lineNumbers: true,
|
|
95
|
-
lineWrapping: false,
|
|
96
|
-
mimeType: undefined,
|
|
97
|
-
autoHeight: undefined,
|
|
98
|
-
padBottom: undefined,
|
|
99
|
-
maxHighlightLength: Infinity, // Avoid CodeMirror bailing out of highlighting big diffs.
|
|
100
|
-
placeholder: undefined,
|
|
101
|
-
lineWiseCopyCut: undefined,
|
|
102
|
-
inputStyle: undefined,
|
|
103
|
-
});
|
|
104
|
-
this.editor.setReadOnly(true);
|
|
105
|
-
const editorContainer = mainWidget.element.createChild('div', 'editor-container');
|
|
106
|
-
UI.ARIAUtils.markAsTabpanel(editorContainer);
|
|
107
|
-
this.editor.show(editorContainer);
|
|
108
|
-
this.editor.hideWidget();
|
|
87
|
+
this.diffContainer = mainWidget.element.createChild('div', 'diff-container');
|
|
88
|
+
UI.ARIAUtils.markAsTabpanel(this.diffContainer);
|
|
89
|
+
this.diffContainer.addEventListener('click', event => this.click(event));
|
|
109
90
|
|
|
110
|
-
|
|
91
|
+
this.diffView = this.diffContainer.appendChild(new DiffView.DiffView.DiffView());
|
|
111
92
|
|
|
112
93
|
this.toolbar = new UI.Toolbar.Toolbar('changes-toolbar', mainWidget.element);
|
|
113
94
|
const revertButton =
|
|
@@ -143,15 +124,25 @@ export class ChangesView extends UI.Widget.VBox {
|
|
|
143
124
|
this.workspaceDiff.revertToOriginal(uiSourceCode);
|
|
144
125
|
}
|
|
145
126
|
|
|
146
|
-
private click(event:
|
|
147
|
-
|
|
148
|
-
if (!selection.isEmpty() || !this.selectedUISourceCode) {
|
|
127
|
+
private click(event: MouseEvent): void {
|
|
128
|
+
if (!this.selectedUISourceCode) {
|
|
149
129
|
return;
|
|
150
130
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
131
|
+
for (let target: HTMLElement|null = event.target as HTMLElement; target; target = target.parentElement) {
|
|
132
|
+
if (target.classList.contains('diff-line-content')) {
|
|
133
|
+
const number = target.getAttribute('data-line-number');
|
|
134
|
+
if (number) {
|
|
135
|
+
// Unfortunately, caretRangeFromPoint is broken in shadow
|
|
136
|
+
// roots, which makes determining the character offset more
|
|
137
|
+
// work than justified here.
|
|
138
|
+
Common.Revealer.reveal(this.selectedUISourceCode.uiLocation(Number(number) - 1, 0), false);
|
|
139
|
+
event.consume(true);
|
|
140
|
+
}
|
|
141
|
+
break;
|
|
142
|
+
} else if (target.classList.contains('diff-listing')) {
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
155
146
|
}
|
|
156
147
|
|
|
157
148
|
private revealUISourceCode(uiSourceCode: Workspace.UISourceCode.UISourceCode|null): void {
|
|
@@ -200,188 +191,25 @@ export class ChangesView extends UI.Widget.VBox {
|
|
|
200
191
|
private hideDiff(message: string): void {
|
|
201
192
|
this.diffStats.setText('');
|
|
202
193
|
this.toolbar.setEnabled(false);
|
|
203
|
-
this.
|
|
194
|
+
this.diffContainer.style.display = 'none';
|
|
204
195
|
this.emptyWidget.text = message;
|
|
205
196
|
this.emptyWidget.showWidget();
|
|
206
197
|
}
|
|
207
198
|
|
|
208
199
|
private renderDiffRows(diff: Diff.Diff.DiffArray|null): void {
|
|
209
|
-
this.diffRows = [];
|
|
210
|
-
|
|
211
200
|
if (!diff || (diff.length === 1 && diff[0][0] === Diff.Diff.Operation.Equal)) {
|
|
212
201
|
this.hideDiff(i18nString(UIStrings.noChanges));
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
const paddingLines = 3;
|
|
221
|
-
|
|
222
|
-
const originalLines: string[] = [];
|
|
223
|
-
const currentLines: string[] = [];
|
|
224
|
-
|
|
225
|
-
for (let i = 0; i < diff.length; ++i) {
|
|
226
|
-
const token = diff[i];
|
|
227
|
-
switch (token[0]) {
|
|
228
|
-
case Diff.Diff.Operation.Equal:
|
|
229
|
-
this.diffRows.push(...createEqualRows(token[1], i === 0, i === diff.length - 1));
|
|
230
|
-
originalLines.push(...token[1]);
|
|
231
|
-
currentLines.push(...token[1]);
|
|
232
|
-
break;
|
|
233
|
-
case Diff.Diff.Operation.Insert:
|
|
234
|
-
for (const line of token[1]) {
|
|
235
|
-
this.diffRows.push(createRow(line, RowType.Addition));
|
|
236
|
-
}
|
|
237
|
-
insertions += token[1].length;
|
|
238
|
-
currentLines.push(...token[1]);
|
|
239
|
-
break;
|
|
240
|
-
case Diff.Diff.Operation.Delete:
|
|
241
|
-
deletions += token[1].length;
|
|
242
|
-
originalLines.push(...token[1]);
|
|
243
|
-
if (diff[i + 1] && diff[i + 1][0] === Diff.Diff.Operation.Insert) {
|
|
244
|
-
i++;
|
|
245
|
-
this.diffRows.push(...createModifyRows(token[1].join('\n'), diff[i][1].join('\n')));
|
|
246
|
-
insertions += diff[i][1].length;
|
|
247
|
-
currentLines.push(...diff[i][1]);
|
|
248
|
-
} else {
|
|
249
|
-
for (const line of token[1]) {
|
|
250
|
-
this.diffRows.push(createRow(line, RowType.Deletion));
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
break;
|
|
254
|
-
}
|
|
202
|
+
} else {
|
|
203
|
+
this.diffStats.setText(diffStats(diff));
|
|
204
|
+
this.toolbar.setEnabled(true);
|
|
205
|
+
this.emptyWidget.hideWidget();
|
|
206
|
+
const mimeType = (this.selectedUISourceCode as Workspace.UISourceCode.UISourceCode).mimeType();
|
|
207
|
+
this.diffContainer.style.display = 'block';
|
|
208
|
+
this.diffView.data = {diff, mimeType};
|
|
255
209
|
}
|
|
256
|
-
|
|
257
|
-
this.maxLineDigits = Math.ceil(Math.log10(Math.max(currentLineNumber, baselineLineNumber)));
|
|
258
|
-
|
|
259
|
-
const insertionText = i18nString(UIStrings.sInsertions, {n: insertions});
|
|
260
|
-
const deletionText = i18nString(UIStrings.sDeletions, {n: deletions});
|
|
261
|
-
|
|
262
|
-
this.diffStats.setText(`${insertionText}, ${deletionText}`);
|
|
263
|
-
this.toolbar.setEnabled(true);
|
|
264
|
-
this.emptyWidget.hideWidget();
|
|
265
|
-
|
|
266
|
-
this.editor.operation((): void => {
|
|
267
|
-
this.editor.showWidget();
|
|
268
|
-
this.editor.setHighlightMode({
|
|
269
|
-
name: 'devtools-diff',
|
|
270
|
-
diffRows: this.diffRows,
|
|
271
|
-
mimeType: /** @type {!Workspace.UISourceCode.UISourceCode} */ (
|
|
272
|
-
this.selectedUISourceCode as Workspace.UISourceCode.UISourceCode)
|
|
273
|
-
.mimeType(),
|
|
274
|
-
baselineLines: originalLines,
|
|
275
|
-
currentLines: currentLines,
|
|
276
|
-
});
|
|
277
|
-
this.editor.setText(this.diffRows
|
|
278
|
-
.map(
|
|
279
|
-
(row: Row): string =>
|
|
280
|
-
row.tokens.map((t: {text: string, className: string}): string => t.text).join(''))
|
|
281
|
-
.join('\n'));
|
|
282
|
-
this.editor.setLineNumberFormatter(this.lineFormatter.bind(this));
|
|
283
|
-
this.editor.updateDiffGutter(this.diffRows);
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
function createEqualRows(lines: string[], atStart: boolean, atEnd: boolean): Row[] {
|
|
287
|
-
const equalRows = [];
|
|
288
|
-
if (!atStart) {
|
|
289
|
-
for (let i = 0; i < paddingLines && i < lines.length; i++) {
|
|
290
|
-
equalRows.push(createRow(lines[i], RowType.Equal));
|
|
291
|
-
}
|
|
292
|
-
if (lines.length > paddingLines * 2 + 1 && !atEnd) {
|
|
293
|
-
equalRows.push(createRow(
|
|
294
|
-
i18nString(UIStrings.SkippingDMatchingLines, {PH1: (lines.length - paddingLines * 2)}), RowType.Spacer));
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
if (!atEnd) {
|
|
298
|
-
const start = Math.max(lines.length - paddingLines - 1, atStart ? 0 : paddingLines);
|
|
299
|
-
let skip = lines.length - paddingLines - 1;
|
|
300
|
-
if (!atStart) {
|
|
301
|
-
skip -= paddingLines;
|
|
302
|
-
}
|
|
303
|
-
if (skip > 0) {
|
|
304
|
-
baselineLineNumber += skip;
|
|
305
|
-
currentLineNumber += skip;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
for (let i = start; i < lines.length; i++) {
|
|
309
|
-
equalRows.push(createRow(lines[i], RowType.Equal));
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
return equalRows;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
function createModifyRows(before: string, after: string): Row[] {
|
|
316
|
-
const internalDiff = Diff.Diff.DiffWrapper.charDiff(before, after, true /* cleanup diff */);
|
|
317
|
-
const deletionRows = [createRow('', RowType.Deletion)];
|
|
318
|
-
const insertionRows = [createRow('', RowType.Addition)];
|
|
319
|
-
|
|
320
|
-
for (const token of internalDiff) {
|
|
321
|
-
const text = token[1];
|
|
322
|
-
const type = token[0];
|
|
323
|
-
const className = type === Diff.Diff.Operation.Equal ? '' : 'inner-diff';
|
|
324
|
-
const lines = text.split('\n');
|
|
325
|
-
for (let i = 0; i < lines.length; i++) {
|
|
326
|
-
if (i > 0 && type !== Diff.Diff.Operation.Insert) {
|
|
327
|
-
deletionRows.push(createRow('', RowType.Deletion));
|
|
328
|
-
}
|
|
329
|
-
if (i > 0 && type !== Diff.Diff.Operation.Delete) {
|
|
330
|
-
insertionRows.push(createRow('', RowType.Addition));
|
|
331
|
-
}
|
|
332
|
-
if (!lines[i]) {
|
|
333
|
-
continue;
|
|
334
|
-
}
|
|
335
|
-
if (type !== Diff.Diff.Operation.Insert) {
|
|
336
|
-
deletionRows[deletionRows.length - 1].tokens.push({text: lines[i], className});
|
|
337
|
-
}
|
|
338
|
-
if (type !== Diff.Diff.Operation.Delete) {
|
|
339
|
-
insertionRows[insertionRows.length - 1].tokens.push({text: lines[i], className});
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
return deletionRows.concat(insertionRows);
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
function createRow(text: string, type: RowType): Row {
|
|
347
|
-
if (type === RowType.Addition) {
|
|
348
|
-
currentLineNumber++;
|
|
349
|
-
}
|
|
350
|
-
if (type === RowType.Deletion) {
|
|
351
|
-
baselineLineNumber++;
|
|
352
|
-
}
|
|
353
|
-
if (type === RowType.Equal) {
|
|
354
|
-
baselineLineNumber++;
|
|
355
|
-
currentLineNumber++;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
return {baselineLineNumber, currentLineNumber, tokens: text ? [{text, className: 'inner-diff'}] : [], type};
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
private lineFormatter(lineNumber: number): string {
|
|
363
|
-
const row = this.diffRows[lineNumber - 1];
|
|
364
|
-
let showBaseNumber = row.type === RowType.Deletion;
|
|
365
|
-
let showCurrentNumber = row.type === RowType.Addition;
|
|
366
|
-
if (row.type === RowType.Equal) {
|
|
367
|
-
showBaseNumber = true;
|
|
368
|
-
showCurrentNumber = true;
|
|
369
|
-
}
|
|
370
|
-
const baseText = showBaseNumber ? String(row.baselineLineNumber) : '';
|
|
371
|
-
const base = baseText.padStart(this.maxLineDigits, '\xA0');
|
|
372
|
-
const currentText = showCurrentNumber ? String(row.currentLineNumber) : '';
|
|
373
|
-
const current = currentText.padStart(this.maxLineDigits, '\xA0');
|
|
374
|
-
return base + '\xA0' + current;
|
|
375
210
|
}
|
|
376
211
|
}
|
|
377
212
|
|
|
378
|
-
export const enum RowType {
|
|
379
|
-
Deletion = 'deletion',
|
|
380
|
-
Addition = 'addition',
|
|
381
|
-
Equal = 'equal',
|
|
382
|
-
Spacer = 'spacer',
|
|
383
|
-
}
|
|
384
|
-
|
|
385
213
|
let diffUILocationRevealerInstance: DiffUILocationRevealer;
|
|
386
214
|
export class DiffUILocationRevealer implements Common.Revealer.Revealer {
|
|
387
215
|
static instance(opts: {forceNew: boolean} = {forceNew: false}): DiffUILocationRevealer {
|
|
@@ -401,14 +229,3 @@ export class DiffUILocationRevealer implements Common.Revealer.Revealer {
|
|
|
401
229
|
ChangesView.instance().changesSidebar.selectUISourceCode(diffUILocation.uiSourceCode, omitFocus);
|
|
402
230
|
}
|
|
403
231
|
}
|
|
404
|
-
|
|
405
|
-
export interface Token {
|
|
406
|
-
text: string;
|
|
407
|
-
className: string;
|
|
408
|
-
}
|
|
409
|
-
export interface Row {
|
|
410
|
-
baselineLineNumber: number;
|
|
411
|
-
currentLineNumber: number;
|
|
412
|
-
tokens: Token[];
|
|
413
|
-
type: RowType;
|
|
414
|
-
}
|
|
@@ -2,19 +2,13 @@
|
|
|
2
2
|
// Use of this source code is governed by a BSD-style license that can be
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
|
-
import './ChangesHighlighter.js';
|
|
6
5
|
import './ChangesView.js';
|
|
7
6
|
import './ChangesSidebar.js';
|
|
8
|
-
import './ChangesTextEditor.js';
|
|
9
7
|
|
|
10
|
-
import * as ChangesHighlighter from './ChangesHighlighter.js';
|
|
11
8
|
import * as ChangesSidebar from './ChangesSidebar.js';
|
|
12
|
-
import * as ChangesTextEditor from './ChangesTextEditor.js';
|
|
13
9
|
import * as ChangesView from './ChangesView.js';
|
|
14
10
|
|
|
15
11
|
export {
|
|
16
|
-
ChangesHighlighter,
|
|
17
12
|
ChangesSidebar,
|
|
18
|
-
ChangesTextEditor,
|
|
19
13
|
ChangesView,
|
|
20
14
|
};
|