chrome-devtools-frontend 1.0.1040337 → 1.0.1040857
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 +0 -1
- package/front_end/core/i18n/locales/en-US.json +10 -4
- package/front_end/core/i18n/locales/en-XL.json +10 -4
- package/front_end/core/sdk/ScreenCaptureModel.ts +32 -3
- package/front_end/entrypoints/inspector_main/inspector_main-meta.ts +35 -0
- package/front_end/models/emulation/DeviceModeModel.ts +15 -3
- package/front_end/models/issues_manager/DeprecationIssue.ts +1 -1
- package/front_end/models/workspace/UISourceCode.ts +12 -6
- package/front_end/panels/application/components/OriginTrialTreeView.ts +0 -5
- package/front_end/panels/sources/BreakpointsSidebarPane.ts +193 -14
- package/front_end/panels/sources/components/breakpointsView.css +1 -1
- package/front_end/panels/sources/sources-meta.ts +1 -1
- package/front_end/ui/legacy/SearchableView.ts +4 -0
- package/package.json +1 -1
- package/front_end/panels/application/components/originTrialTreeView.css +0 -9
@@ -870,7 +870,6 @@ grd_files_debug_sources = [
|
|
870
870
|
"front_end/panels/application/components/frameDetailsReportView.css.js",
|
871
871
|
"front_end/panels/application/components/interestGroupAccessGrid.css.js",
|
872
872
|
"front_end/panels/application/components/originTrialTokenRows.css.js",
|
873
|
-
"front_end/panels/application/components/originTrialTreeView.css.js",
|
874
873
|
"front_end/panels/application/components/permissionsPolicySection.css.js",
|
875
874
|
"front_end/panels/application/components/protocolHandlersView.css.js",
|
876
875
|
"front_end/panels/application/components/reportingApiGrid.css.js",
|
@@ -896,6 +896,15 @@
|
|
896
896
|
"entrypoints/inspector_main/inspector_main-meta.ts | rendering": {
|
897
897
|
"message": "Rendering"
|
898
898
|
},
|
899
|
+
"entrypoints/inspector_main/inspector_main-meta.ts | searchAsYouTypeCommand": {
|
900
|
+
"message": "Enable search as you type"
|
901
|
+
},
|
902
|
+
"entrypoints/inspector_main/inspector_main-meta.ts | searchAsYouTypeSetting": {
|
903
|
+
"message": "Search as you type"
|
904
|
+
},
|
905
|
+
"entrypoints/inspector_main/inspector_main-meta.ts | searchOnEnterCommand": {
|
906
|
+
"message": "Disable search as you type (press Enter to search)"
|
907
|
+
},
|
899
908
|
"entrypoints/inspector_main/inspector_main-meta.ts | showAds": {
|
900
909
|
"message": "Show ads on this site, if allowed"
|
901
910
|
},
|
@@ -1449,7 +1458,7 @@
|
|
1449
1458
|
"message": "Your partner is negotiating an obsolete (D)TLS version. Please check with your partner to have this fixed."
|
1450
1459
|
},
|
1451
1460
|
"models/issues_manager/DeprecationIssue.ts | openWebDatabaseInsecureContext": {
|
1452
|
-
"message": "WebSQL in non-secure contexts is deprecated and will be removed
|
1461
|
+
"message": "WebSQL in non-secure contexts is deprecated and will be removed soon. Please use Web Storage or Indexed Database."
|
1453
1462
|
},
|
1454
1463
|
"models/issues_manager/DeprecationIssue.ts | persistentQuotaType": {
|
1455
1464
|
"message": "StorageType.persistent is deprecated. Please use standardized navigator.storage instead."
|
@@ -9791,9 +9800,6 @@
|
|
9791
9800
|
"panels/sources/BreakpointEditDialog.ts | pauseOnlyWhenTheConditionIsTrue": {
|
9792
9801
|
"message": "Pause only when the condition is true"
|
9793
9802
|
},
|
9794
|
-
"panels/sources/BreakpointsSidebarPane.ts | noBreakpoints": {
|
9795
|
-
"message": "No breakpoints"
|
9796
|
-
},
|
9797
9803
|
"panels/sources/CallStackSidebarPane.ts | addAllContentScriptsToIgnoreList": {
|
9798
9804
|
"message": "Add all content scripts to ignore list"
|
9799
9805
|
},
|
@@ -896,6 +896,15 @@
|
|
896
896
|
"entrypoints/inspector_main/inspector_main-meta.ts | rendering": {
|
897
897
|
"message": "R̂én̂d́êŕîńĝ"
|
898
898
|
},
|
899
|
+
"entrypoints/inspector_main/inspector_main-meta.ts | searchAsYouTypeCommand": {
|
900
|
+
"message": "Êńâb́l̂é ŝéâŕĉh́ âś ŷóû t́ŷṕê"
|
901
|
+
},
|
902
|
+
"entrypoints/inspector_main/inspector_main-meta.ts | searchAsYouTypeSetting": {
|
903
|
+
"message": "Ŝéâŕĉh́ âś ŷóû t́ŷṕê"
|
904
|
+
},
|
905
|
+
"entrypoints/inspector_main/inspector_main-meta.ts | searchOnEnterCommand": {
|
906
|
+
"message": "D̂íŝáb̂ĺê śêár̂ćĥ áŝ ýôú t̂ýp̂é (p̂ŕêśŝ Én̂t́êŕ t̂ó ŝéâŕĉh́)"
|
907
|
+
},
|
899
908
|
"entrypoints/inspector_main/inspector_main-meta.ts | showAds": {
|
900
909
|
"message": "Ŝh́ôẃ âd́ŝ ón̂ t́ĥíŝ śît́ê, íf̂ ál̂ĺôẃêd́"
|
901
910
|
},
|
@@ -1449,7 +1458,7 @@
|
|
1449
1458
|
"message": "Ŷóûŕ p̂ár̂t́n̂ér̂ íŝ ńêǵôt́îát̂ín̂ǵ âń ôb́ŝól̂ét̂é (D̂)T́L̂Ś v̂ér̂śîón̂. Ṕl̂éâśê ćĥéĉḱ ŵít̂h́ ŷóûŕ p̂ár̂t́n̂ér̂ t́ô h́âv́ê t́ĥíŝ f́îx́êd́."
|
1450
1459
|
},
|
1451
1460
|
"models/issues_manager/DeprecationIssue.ts | openWebDatabaseInsecureContext": {
|
1452
|
-
"message": "Ŵéb̂ŚQ̂Ĺ îń n̂ón̂-śêćûŕê ćôńt̂éx̂t́ŝ íŝ d́êṕr̂éĉát̂éd̂ án̂d́ ŵíl̂ĺ b̂é r̂ém̂óv̂éd̂
|
1461
|
+
"message": "Ŵéb̂ŚQ̂Ĺ îń n̂ón̂-śêćûŕê ćôńt̂éx̂t́ŝ íŝ d́êṕr̂éĉát̂éd̂ án̂d́ ŵíl̂ĺ b̂é r̂ém̂óv̂éd̂ śôón̂. Ṕl̂éâśê úŝé Ŵéb̂ Śt̂ór̂áĝé ôŕ Îńd̂éx̂éd̂ D́ât́âb́âśê."
|
1453
1462
|
},
|
1454
1463
|
"models/issues_manager/DeprecationIssue.ts | persistentQuotaType": {
|
1455
1464
|
"message": "StorageType.persistent îś d̂ép̂ŕêćât́êd́. P̂ĺêáŝé ûśê śt̂án̂d́âŕd̂íẑéd̂ navigator.storage ín̂śt̂éâd́."
|
@@ -9791,9 +9800,6 @@
|
|
9791
9800
|
"panels/sources/BreakpointEditDialog.ts | pauseOnlyWhenTheConditionIsTrue": {
|
9792
9801
|
"message": "P̂áûśê ón̂ĺŷ ẃĥén̂ t́ĥé ĉón̂d́ît́îón̂ íŝ t́r̂úê"
|
9793
9802
|
},
|
9794
|
-
"panels/sources/BreakpointsSidebarPane.ts | noBreakpoints": {
|
9795
|
-
"message": "N̂ó b̂ŕêák̂ṕôín̂t́ŝ"
|
9796
|
-
},
|
9797
9803
|
"panels/sources/CallStackSidebarPane.ts | addAllContentScriptsToIgnoreList": {
|
9798
9804
|
"message": "Âd́d̂ ál̂ĺ ĉón̂t́êńt̂ śĉŕîṕt̂ś t̂ó îǵn̂ór̂é l̂íŝt́"
|
9799
9805
|
},
|
@@ -10,6 +10,11 @@ import {OverlayModel} from './OverlayModel.js';
|
|
10
10
|
import {Capability, type Target} from './Target.js';
|
11
11
|
import {SDKModel} from './SDKModel.js';
|
12
12
|
|
13
|
+
export const enum ScreenshotMode {
|
14
|
+
FROM_VIEWPORT = 'fromViewport',
|
15
|
+
FROM_CLIP = 'fromClip',
|
16
|
+
FULLPAGE = 'fullpage',
|
17
|
+
}
|
13
18
|
export class ScreenCaptureModel extends SDKModel<void> implements ProtocolProxyApi.PageDispatcher {
|
14
19
|
readonly #agent: ProtocolProxyApi.PageApi;
|
15
20
|
#onScreencastFrame: ((arg0: Protocol.binary, arg1: Protocol.Page.ScreencastFrameMetadata) => void)|null;
|
@@ -39,11 +44,35 @@ export class ScreenCaptureModel extends SDKModel<void> implements ProtocolProxyA
|
|
39
44
|
}
|
40
45
|
|
41
46
|
async captureScreenshot(
|
42
|
-
format: Protocol.Page.CaptureScreenshotRequestFormat, quality: number,
|
47
|
+
format: Protocol.Page.CaptureScreenshotRequestFormat, quality: number, mode: ScreenshotMode,
|
43
48
|
clip?: Protocol.Page.Viewport): Promise<string|null> {
|
49
|
+
const properties: Protocol.Page.CaptureScreenshotRequest = {
|
50
|
+
format: format,
|
51
|
+
quality: quality,
|
52
|
+
fromSurface: true,
|
53
|
+
};
|
54
|
+
switch (mode) {
|
55
|
+
case 'fromClip':
|
56
|
+
properties.captureBeyondViewport = true;
|
57
|
+
properties.clip = clip;
|
58
|
+
break;
|
59
|
+
case 'fullpage':
|
60
|
+
properties.captureBeyondViewport = true;
|
61
|
+
// TODO(crbug/1357584): Delete this after the upstream CDP change lands.
|
62
|
+
properties.clip = clip;
|
63
|
+
// TODO(crbug/1357584): Uncoment this after the upstream CDP change lands.
|
64
|
+
// properties.clip = undefined;
|
65
|
+
break;
|
66
|
+
case 'fromViewport':
|
67
|
+
properties.captureBeyondViewport = false;
|
68
|
+
properties.clip = undefined;
|
69
|
+
break;
|
70
|
+
default:
|
71
|
+
throw new Error('Unexpected or unspecified screnshotMode');
|
72
|
+
}
|
73
|
+
|
44
74
|
await OverlayModel.muteHighlight();
|
45
|
-
const result = await this.#agent.invoke_captureScreenshot(
|
46
|
-
{format, quality, clip, fromSurface: true, captureBeyondViewport: true});
|
75
|
+
const result = await this.#agent.invoke_captureScreenshot(properties);
|
47
76
|
await OverlayModel.unmuteHighlight();
|
48
77
|
return result.data;
|
49
78
|
}
|
@@ -93,6 +93,21 @@ const UIStrings = {
|
|
93
93
|
*/
|
94
94
|
doNotAutoOpen: 'Do not auto-open DevTools for popups',
|
95
95
|
/**
|
96
|
+
* @description A command available in the command menu to perform searches, for example in the
|
97
|
+
* elements panel, as user types, rather than only when they press Enter.
|
98
|
+
*/
|
99
|
+
searchAsYouTypeSetting: 'Search as you type',
|
100
|
+
/**
|
101
|
+
* @description A command available in the command menu to perform searches, for example in the
|
102
|
+
* elements panel, as user types, rather than only when they press Enter.
|
103
|
+
*/
|
104
|
+
searchAsYouTypeCommand: 'Enable search as you type',
|
105
|
+
/**
|
106
|
+
* @description A command available in the command menu to perform searches, for example in the
|
107
|
+
* elements panel, only when the user presses Enter.
|
108
|
+
*/
|
109
|
+
searchOnEnterCommand: 'Disable search as you type (press Enter to search)',
|
110
|
+
/**
|
96
111
|
* @description Title of a setting under the Appearance category in Settings. When the webpage is
|
97
112
|
* paused by devtools, an overlay is shown on top of the page to indicate that it is paused. The
|
98
113
|
* overlay is a pause/unpause button and some text, which appears on top of the paused page. This
|
@@ -245,6 +260,26 @@ Common.Settings.registerSettingExtension({
|
|
245
260
|
],
|
246
261
|
});
|
247
262
|
|
263
|
+
Common.Settings.registerSettingExtension({
|
264
|
+
category: Common.Settings.SettingCategory.GLOBAL,
|
265
|
+
storageType: Common.Settings.SettingStorageType.Local,
|
266
|
+
title: i18nLazyString(UIStrings.searchAsYouTypeSetting),
|
267
|
+
settingName: 'searchAsYouType',
|
268
|
+
settingType: Common.Settings.SettingType.BOOLEAN,
|
269
|
+
order: 3,
|
270
|
+
defaultValue: true,
|
271
|
+
options: [
|
272
|
+
{
|
273
|
+
value: true,
|
274
|
+
title: i18nLazyString(UIStrings.searchAsYouTypeCommand),
|
275
|
+
},
|
276
|
+
{
|
277
|
+
value: false,
|
278
|
+
title: i18nLazyString(UIStrings.searchOnEnterCommand),
|
279
|
+
},
|
280
|
+
],
|
281
|
+
});
|
282
|
+
|
248
283
|
Common.Settings.registerSettingExtension({
|
249
284
|
category: Common.Settings.SettingCategory.APPEARANCE,
|
250
285
|
storageType: Common.Settings.SettingStorageType.Synced,
|
@@ -722,13 +722,23 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
722
722
|
return null;
|
723
723
|
}
|
724
724
|
|
725
|
+
let screenshotMode;
|
726
|
+
if (clip) {
|
727
|
+
screenshotMode = SDK.ScreenCaptureModel.ScreenshotMode.FROM_CLIP;
|
728
|
+
} else if (fullSize) {
|
729
|
+
screenshotMode = SDK.ScreenCaptureModel.ScreenshotMode.FULLPAGE;
|
730
|
+
} else {
|
731
|
+
screenshotMode = SDK.ScreenCaptureModel.ScreenshotMode.FROM_VIEWPORT;
|
732
|
+
}
|
733
|
+
|
725
734
|
const overlayModel = this.#emulationModel ? this.#emulationModel.overlayModel() : null;
|
726
735
|
if (overlayModel) {
|
727
736
|
overlayModel.setShowViewportSizeOnResize(false);
|
728
737
|
}
|
729
738
|
|
739
|
+
// TODO(crbug/1357584): Delete this after the upstream CDP change lands.
|
730
740
|
// Define the right clipping area for fullsize screenshots.
|
731
|
-
if (
|
741
|
+
if (!clip) {
|
732
742
|
const metrics = await screenCaptureModel.fetchLayoutMetrics();
|
733
743
|
if (!metrics) {
|
734
744
|
return null;
|
@@ -738,8 +748,10 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
738
748
|
const contentHeight = Math.min((1 << 14), metrics.contentHeight);
|
739
749
|
clip = {x: 0, y: 0, width: Math.floor(metrics.contentWidth), height: Math.floor(contentHeight), scale: 1};
|
740
750
|
}
|
741
|
-
|
742
|
-
|
751
|
+
// TODO(crbug/1357584): Delete till here.
|
752
|
+
|
753
|
+
const screenshot = await screenCaptureModel.captureScreenshot(
|
754
|
+
Protocol.Page.CaptureScreenshotRequestFormat.Png, 100, screenshotMode, clip);
|
743
755
|
|
744
756
|
const deviceMetrics: Protocol.Page.SetDeviceMetricsOverrideRequest = {
|
745
757
|
width: 0,
|
@@ -185,7 +185,7 @@ const UIStrings = {
|
|
185
185
|
* @description Warning displayed to developers when `window.openDatabase` is used in non-secure contexts to notify that the API is deprecated and will be removed.
|
186
186
|
*/
|
187
187
|
openWebDatabaseInsecureContext:
|
188
|
-
'WebSQL in non-secure contexts is deprecated and will be removed
|
188
|
+
'WebSQL in non-secure contexts is deprecated and will be removed soon. Please use Web Storage or Indexed Database.',
|
189
189
|
/**
|
190
190
|
* @description Warning displayed to developers when persistent storage type is used to notify that storage type is deprecated.
|
191
191
|
*/
|
@@ -528,21 +528,27 @@ export class UILocation {
|
|
528
528
|
this.columnNumber = columnNumber;
|
529
529
|
}
|
530
530
|
|
531
|
-
linkText(skipTrim
|
532
|
-
|
531
|
+
linkText(skipTrim: boolean = false, showColumnNumber: boolean = false): string {
|
532
|
+
const displayName = this.uiSourceCode.displayName(skipTrim);
|
533
|
+
const lineAndColumnText = this.lineAndColumnText(showColumnNumber);
|
534
|
+
return lineAndColumnText ? displayName + ':' + lineAndColumnText : displayName;
|
535
|
+
}
|
536
|
+
|
537
|
+
lineAndColumnText(showColumnNumber: boolean = false): string|undefined {
|
538
|
+
let lineAndColumnText;
|
533
539
|
if (this.uiSourceCode.mimeType() === 'application/wasm') {
|
534
540
|
// For WebAssembly locations, we follow the conventions described in
|
535
541
|
// github.com/WebAssembly/design/blob/master/Web.md#developer-facing-display-conventions
|
536
542
|
if (typeof this.columnNumber === 'number') {
|
537
|
-
|
543
|
+
lineAndColumnText = `0x${this.columnNumber.toString(16)}`;
|
538
544
|
}
|
539
545
|
} else {
|
540
|
-
|
546
|
+
lineAndColumnText = `${this.lineNumber + 1}`;
|
541
547
|
if (showColumnNumber && typeof this.columnNumber === 'number') {
|
542
|
-
|
548
|
+
lineAndColumnText += ':' + (this.columnNumber + 1);
|
543
549
|
}
|
544
550
|
}
|
545
|
-
return
|
551
|
+
return lineAndColumnText;
|
546
552
|
}
|
547
553
|
|
548
554
|
id(): string {
|
@@ -11,7 +11,6 @@ import * as LitHtml from '../../../ui/lit-html/lit-html.js';
|
|
11
11
|
|
12
12
|
import badgeStyles from './badge.css.js';
|
13
13
|
import originTrialTokenRowsStyles from './originTrialTokenRows.css.js';
|
14
|
-
import originTrialTreeViewStyles from './originTrialTreeView.css.js';
|
15
14
|
|
16
15
|
const UIStrings = {
|
17
16
|
/**
|
@@ -323,10 +322,6 @@ export class OriginTrialTreeView extends HTMLElement {
|
|
323
322
|
this.#render(data.trials);
|
324
323
|
}
|
325
324
|
|
326
|
-
connectedCallback(): void {
|
327
|
-
this.#shadow.adoptedStyleSheets = [originTrialTreeViewStyles];
|
328
|
-
}
|
329
|
-
|
330
325
|
#render(trials: Protocol.Page.OriginTrial[]): void {
|
331
326
|
if (!trials.length) {
|
332
327
|
return;
|
@@ -2,23 +2,20 @@
|
|
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 * as
|
5
|
+
import * as Platform from '../../core/platform/platform.js';
|
6
|
+
import * as SDK from '../../core/sdk/sdk.js';
|
7
|
+
import * as Bindings from '../../models/bindings/bindings.js';
|
8
|
+
import * as TextUtils from '../../models/text_utils/text_utils.js';
|
9
|
+
import * as Workspace from '../../models/workspace/workspace.js';
|
6
10
|
import * as UI from '../../ui/legacy/legacy.js';
|
7
11
|
|
8
|
-
|
9
|
-
/**
|
10
|
-
*@description Text to indicate that there are no breakpoints
|
11
|
-
*/
|
12
|
-
noBreakpoints: 'No breakpoints',
|
13
|
-
};
|
14
|
-
|
15
|
-
const str_ = i18n.i18n.registerUIStrings('panels/sources/BreakpointsSidebarPane.ts', UIStrings);
|
16
|
-
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
12
|
+
import * as SourcesComponents from './components/components.js';
|
17
13
|
|
18
14
|
let breakpointsSidebarPaneInstance: BreakpointsSidebarPane;
|
15
|
+
let breakpointsViewControllerInstance: BreakpointsSidebarController;
|
19
16
|
|
20
17
|
export class BreakpointsSidebarPane extends UI.ThrottledWidget.ThrottledWidget {
|
21
|
-
readonly #
|
18
|
+
readonly #breakpointsView: SourcesComponents.BreakpointsView.BreakpointsView;
|
22
19
|
|
23
20
|
static instance(): BreakpointsSidebarPane {
|
24
21
|
if (!breakpointsSidebarPaneInstance) {
|
@@ -30,8 +27,190 @@ export class BreakpointsSidebarPane extends UI.ThrottledWidget.ThrottledWidget {
|
|
30
27
|
constructor() {
|
31
28
|
super(true);
|
32
29
|
|
33
|
-
this.#
|
34
|
-
this
|
35
|
-
this
|
30
|
+
this.#breakpointsView = new SourcesComponents.BreakpointsView.BreakpointsView();
|
31
|
+
this.contentElement.appendChild(this.#breakpointsView);
|
32
|
+
this.update();
|
33
|
+
}
|
34
|
+
|
35
|
+
async doUpdate(): Promise<void> {
|
36
|
+
await BreakpointsSidebarController.instance().update();
|
37
|
+
}
|
38
|
+
|
39
|
+
set data(data: SourcesComponents.BreakpointsView.BreakpointsViewData) {
|
40
|
+
this.#breakpointsView.data = data;
|
41
|
+
}
|
42
|
+
}
|
43
|
+
export class BreakpointsSidebarController implements UI.ContextFlavorListener.ContextFlavorListener {
|
44
|
+
readonly #breakpointManager: Bindings.BreakpointManager.BreakpointManager;
|
45
|
+
|
46
|
+
constructor() {
|
47
|
+
this.#breakpointManager = Bindings.BreakpointManager.BreakpointManager.instance();
|
48
|
+
this.#breakpointManager.addEventListener(Bindings.BreakpointManager.Events.BreakpointAdded, this.update, this);
|
49
|
+
this.#breakpointManager.addEventListener(Bindings.BreakpointManager.Events.BreakpointRemoved, this.update, this);
|
50
|
+
}
|
51
|
+
|
52
|
+
static instance(opts: {forceNew: boolean|null} = {forceNew: null}): BreakpointsSidebarController {
|
53
|
+
if (!breakpointsViewControllerInstance || opts.forceNew) {
|
54
|
+
breakpointsViewControllerInstance = new BreakpointsSidebarController();
|
55
|
+
}
|
56
|
+
return breakpointsViewControllerInstance;
|
57
|
+
}
|
58
|
+
|
59
|
+
flavorChanged(_object: Object|null): void {
|
60
|
+
void this.update();
|
61
|
+
}
|
62
|
+
|
63
|
+
async update(): Promise<void> {
|
64
|
+
const data = await this.getUpdatedBreakpointViewData();
|
65
|
+
BreakpointsSidebarPane.instance().data = data;
|
66
|
+
}
|
67
|
+
|
68
|
+
async getUpdatedBreakpointViewData(): Promise<SourcesComponents.BreakpointsView.BreakpointsViewData> {
|
69
|
+
const breakpointLocations = this.#getBreakpointLocations();
|
70
|
+
if (!breakpointLocations.length) {
|
71
|
+
return {groups: []};
|
72
|
+
}
|
73
|
+
|
74
|
+
const locationsGroupedById = this.#groupBreakpointLocationsById(breakpointLocations);
|
75
|
+
const locationIdsByLineId = this.#getLocationIdsByLineId(breakpointLocations);
|
76
|
+
|
77
|
+
const content = await this.#getContent(locationsGroupedById);
|
78
|
+
const selectedUILocation = await this.#getHitUILocation();
|
79
|
+
|
80
|
+
const urlToGroup = new Map<Platform.DevToolsPath.UrlString, SourcesComponents.BreakpointsView.BreakpointGroup>();
|
81
|
+
|
82
|
+
for (let idx = 0; idx < locationsGroupedById.length; idx++) {
|
83
|
+
const locations = locationsGroupedById[idx];
|
84
|
+
const fstLocation = locations[0];
|
85
|
+
const sourceURL = fstLocation.uiLocation.uiSourceCode.url();
|
86
|
+
const uiLocation = fstLocation.uiLocation;
|
87
|
+
|
88
|
+
const isHit = selectedUILocation !== null &&
|
89
|
+
locations.some(location => location.uiLocation.id() === selectedUILocation.id());
|
90
|
+
|
91
|
+
const numBreakpointsOnLine = locationIdsByLineId.get(uiLocation.lineId()).size;
|
92
|
+
const showColumn = numBreakpointsOnLine > 1;
|
93
|
+
const locationText = uiLocation.lineAndColumnText(showColumn);
|
94
|
+
|
95
|
+
const text = (content[idx] as TextUtils.Text.Text);
|
96
|
+
const codeSnippet = text.lineAt(uiLocation.lineNumber);
|
97
|
+
|
98
|
+
const status: SourcesComponents.BreakpointsView.BreakpointStatus = this.#getBreakpointState(locations);
|
99
|
+
const item = {location: locationText, codeSnippet, isHit, status} as
|
100
|
+
SourcesComponents.BreakpointsView.BreakpointItem;
|
101
|
+
|
102
|
+
let group = urlToGroup.get(sourceURL);
|
103
|
+
if (group) {
|
104
|
+
group.breakpointItems.push(item);
|
105
|
+
} else {
|
106
|
+
group =
|
107
|
+
{url: sourceURL, name: uiLocation.uiSourceCode.displayName(), expanded: true, breakpointItems: [item]} as
|
108
|
+
SourcesComponents.BreakpointsView.BreakpointGroup;
|
109
|
+
urlToGroup.set(sourceURL, group);
|
110
|
+
}
|
111
|
+
}
|
112
|
+
return {groups: Array.from(urlToGroup.values())};
|
113
|
+
}
|
114
|
+
|
115
|
+
async #getHitUILocation(): Promise<Workspace.UISourceCode.UILocation|null> {
|
116
|
+
const details = UI.Context.Context.instance().flavor(SDK.DebuggerModel.DebuggerPausedDetails);
|
117
|
+
if (details && details.callFrames.length) {
|
118
|
+
return await Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance().rawLocationToUILocation(
|
119
|
+
details.callFrames[0].location());
|
120
|
+
}
|
121
|
+
return null;
|
122
|
+
}
|
123
|
+
|
124
|
+
#getBreakpointLocations(): Bindings.BreakpointManager.BreakpointLocation[] {
|
125
|
+
const locations = this.#breakpointManager.allBreakpointLocations().filter(
|
126
|
+
breakpointLocation =>
|
127
|
+
breakpointLocation.uiLocation.uiSourceCode.project().type() !== Workspace.Workspace.projectTypes.Debugger);
|
128
|
+
|
129
|
+
locations.sort((item1, item2) => item1.uiLocation.compareTo(item2.uiLocation));
|
130
|
+
|
131
|
+
const result = [];
|
132
|
+
let lastBreakpoint: Bindings.BreakpointManager.Breakpoint|null = null;
|
133
|
+
let lastLocation: Workspace.UISourceCode.UILocation|null = null;
|
134
|
+
for (const location of locations) {
|
135
|
+
if (location.breakpoint !== lastBreakpoint || (lastLocation && location.uiLocation.compareTo(lastLocation))) {
|
136
|
+
result.push(location);
|
137
|
+
lastBreakpoint = location.breakpoint;
|
138
|
+
lastLocation = location.uiLocation;
|
139
|
+
}
|
140
|
+
}
|
141
|
+
return result;
|
142
|
+
}
|
143
|
+
|
144
|
+
#groupBreakpointLocationsById(breakpointLocations: Bindings.BreakpointManager.BreakpointLocation[]):
|
145
|
+
Bindings.BreakpointManager.BreakpointLocation[][] {
|
146
|
+
const map = new Platform.MapUtilities.Multimap<string, Bindings.BreakpointManager.BreakpointLocation>();
|
147
|
+
for (const breakpointLocation of breakpointLocations) {
|
148
|
+
const uiLocation = breakpointLocation.uiLocation;
|
149
|
+
map.set(uiLocation.id(), breakpointLocation);
|
150
|
+
}
|
151
|
+
const arr: Bindings.BreakpointManager.BreakpointLocation[][] = [];
|
152
|
+
for (const id of map.keysArray()) {
|
153
|
+
const locations = Array.from(map.get(id));
|
154
|
+
if (locations.length) {
|
155
|
+
arr.push(locations);
|
156
|
+
}
|
157
|
+
}
|
158
|
+
return arr;
|
159
|
+
}
|
160
|
+
|
161
|
+
#getLocationIdsByLineId(breakpointLocations: Bindings.BreakpointManager.BreakpointLocation[]):
|
162
|
+
Platform.MapUtilities.Multimap<string, string> {
|
163
|
+
const result = new Platform.MapUtilities.Multimap<string, string>();
|
164
|
+
|
165
|
+
for (const breakpointLocation of breakpointLocations) {
|
166
|
+
const uiLocation = breakpointLocation.uiLocation;
|
167
|
+
result.set(uiLocation.lineId(), uiLocation.id());
|
168
|
+
}
|
169
|
+
|
170
|
+
return result;
|
171
|
+
}
|
172
|
+
|
173
|
+
#getBreakpointState(locations: Bindings.BreakpointManager.BreakpointLocation[]):
|
174
|
+
SourcesComponents.BreakpointsView.BreakpointStatus {
|
175
|
+
const hasEnabled = locations.some(location => location.breakpoint.enabled());
|
176
|
+
const hasDisabled = locations.some(location => !location.breakpoint.enabled());
|
177
|
+
let status: SourcesComponents.BreakpointsView.BreakpointStatus;
|
178
|
+
if (hasEnabled) {
|
179
|
+
status = hasDisabled ? SourcesComponents.BreakpointsView.BreakpointStatus.INDETERMINATE :
|
180
|
+
SourcesComponents.BreakpointsView.BreakpointStatus.ENABLED;
|
181
|
+
} else {
|
182
|
+
status = SourcesComponents.BreakpointsView.BreakpointStatus.DISABLED;
|
183
|
+
}
|
184
|
+
return status;
|
185
|
+
}
|
186
|
+
|
187
|
+
#getContent(locations: Bindings.BreakpointManager.BreakpointLocation[][]): Promise<TextUtils.Text.Text[]> {
|
188
|
+
// Use a cache to share the Text objects between all breakpoints. This way
|
189
|
+
// we share the cached line ending information that Text calculates. This
|
190
|
+
// was very slow to calculate with a lot of breakpoints in the same very
|
191
|
+
// large source file.
|
192
|
+
const contentToTextMap = new Map<string, TextUtils.Text.Text>();
|
193
|
+
|
194
|
+
return Promise.all(locations.map(async ([{uiLocation: {uiSourceCode}}]) => {
|
195
|
+
if (uiSourceCode.mimeType() === 'application/wasm') {
|
196
|
+
// We could mirror the logic from `SourceFrame._ensureContentLoaded()` here
|
197
|
+
// (and if so, ideally share that code somewhere), but that's quite heavy
|
198
|
+
// logic just to display a single Wasm instruction. Also not really clear
|
199
|
+
// how much value this would add. So let's keep it simple for now and don't
|
200
|
+
// display anything additional for Wasm breakpoints, and if there's demand
|
201
|
+
// to display some text preview, we could look into selectively disassemb-
|
202
|
+
// ling the part of the text that we need here.
|
203
|
+
// Relevant crbug: https://crbug.com/1090256
|
204
|
+
return new TextUtils.Text.Text('');
|
205
|
+
}
|
206
|
+
const {content} = await uiSourceCode.requestContent();
|
207
|
+
const contentText = content || '';
|
208
|
+
if (contentToTextMap.has(contentText)) {
|
209
|
+
return contentToTextMap.get(contentText) as TextUtils.Text.Text;
|
210
|
+
}
|
211
|
+
const text = new TextUtils.Text.Text(contentText);
|
212
|
+
contentToTextMap.set(contentText, text);
|
213
|
+
return text;
|
214
|
+
}));
|
36
215
|
}
|
37
216
|
}
|
@@ -1730,7 +1730,7 @@ UI.Context.registerListener({
|
|
1730
1730
|
},
|
1731
1731
|
async loadListener() {
|
1732
1732
|
const Sources = await loadSourcesModule();
|
1733
|
-
return Sources.
|
1733
|
+
return Sources.BreakpointsSidebarPane.BreakpointsSidebarController.instance();
|
1734
1734
|
},
|
1735
1735
|
});
|
1736
1736
|
|
@@ -561,6 +561,10 @@ export class SearchableView extends VBox {
|
|
561
561
|
}
|
562
562
|
|
563
563
|
private onInput(_event: Event): void {
|
564
|
+
if (!Common.Settings.Settings.instance().moduleSetting('searchAsYouType').get()) {
|
565
|
+
return;
|
566
|
+
}
|
567
|
+
|
564
568
|
if (this.valueChangedTimeoutId) {
|
565
569
|
clearTimeout(this.valueChangedTimeoutId);
|
566
570
|
}
|
package/package.json
CHANGED