chrome-devtools-frontend 1.0.1662289 → 1.0.1662965
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/.agents/skills/devtools-unicode-escaping/SKILL.md +64 -0
- package/.agents/skills/migrate-chromium-test/SKILL.md +29 -4
- package/front_end/core/common/SettingRegistration.ts +0 -5
- package/front_end/core/common/Settings.ts +69 -3
- package/front_end/core/platform/StringUtilities.ts +38 -6
- package/front_end/core/sdk/ServiceWorkerCacheModel.ts +0 -10
- package/front_end/core/sdk/StorageBucketsModel.ts +0 -10
- package/front_end/core/sdk/sdk-meta.ts +0 -1
- package/front_end/entrypoints/inspector_main/OutermostTargetSelector.ts +0 -13
- package/front_end/entrypoints/inspector_main/RenderingOptions.ts +8 -3
- package/front_end/entrypoints/inspector_main/inspector_main-meta.ts +3 -3
- package/front_end/entrypoints/main/MainImpl.ts +7 -2
- package/front_end/foundation/Universe.ts +16 -0
- package/front_end/generated/InspectorBackendCommands.ts +2 -14
- package/front_end/generated/protocol-mapping.d.ts +0 -53
- package/front_end/generated/protocol-proxy-api.d.ts +0 -46
- package/front_end/generated/protocol.ts +0 -148
- package/front_end/models/ai_assistance/AiAgent2.ts +3 -3
- package/front_end/models/ai_assistance/AiConversation.ts +21 -10
- package/front_end/models/ai_assistance/AiHistoryStorage.ts +21 -10
- package/front_end/models/ai_assistance/ChangeManager.ts +2 -2
- package/front_end/models/ai_assistance/ExtensionScope.ts +6 -2
- package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +1 -1
- package/front_end/models/ai_assistance/agents/AiAgent.ts +8 -1
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +1 -1
- package/front_end/models/badges/UserBadges.ts +31 -17
- package/front_end/models/bindings/NetworkProject.ts +16 -4
- package/front_end/models/emulation/DeviceModeModel.ts +67 -5
- package/front_end/models/extensions/RecorderPluginManager.ts +10 -6
- package/front_end/models/har/Log.snapshot.txt +193 -0
- package/front_end/models/har/Log.ts +3 -2
- package/front_end/models/source_map_scopes/FunctionCodeResolver.ts +7 -5
- package/front_end/models/source_map_scopes/NamesResolver.ts +36 -30
- package/front_end/models/stack_trace/StackTrace.ts +17 -0
- package/front_end/panels/application/IndexedDBModel.ts +0 -10
- package/front_end/panels/application/IndexedDBViews.ts +240 -164
- package/front_end/panels/application/SharedStorageModel.ts +0 -10
- package/front_end/panels/application/components/AdsView.ts +23 -0
- package/front_end/panels/application/components/SharedStorageAccessGrid.ts +1 -1
- package/front_end/panels/application/components/adsView.css +21 -1
- package/front_end/panels/application/indexedDBViews.css +1 -1
- package/front_end/panels/network/NetworkDataGridNode.ts +43 -1
- package/front_end/panels/network/RequestInitiatorView.ts +24 -2
- package/front_end/panels/network/networkLogView.css +5 -0
- package/front_end/panels/network/requestInitiatorViewTree.css +5 -0
- package/front_end/panels/profiler/HeapProfileView.ts +198 -79
- package/front_end/panels/recorder/README.md +1 -2
- package/front_end/panels/recorder/RecorderPanel.ts +1749 -17
- package/front_end/panels/recorder/recorder.ts +0 -2
- package/front_end/panels/settings/AISettingsTab.ts +13 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/components/spinners/Spinner.ts +29 -32
- package/front_end/ui/components/spinners/spinner.css +32 -84
- package/front_end/ui/legacy/Treeoutline.ts +14 -6
- package/front_end/ui/legacy/UIUtils.ts +25 -10
- package/front_end/ui/legacy/Widget.ts +17 -10
- package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +36 -7
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +63 -68
- package/front_end/ui/legacy/components/object_ui/RemoteObjectPreviewFormatter.ts +1 -1
- package/front_end/ui/legacy/components/object_ui/objectValue.css +2 -1
- package/front_end/ui/legacy/inspectorCommon.css +4 -4
- package/front_end/ui/lit/lit.ts +1 -0
- package/front_end/ui/lit/render.ts +44 -10
- package/front_end/ui/lit/strip-whitespace.ts +23 -2
- package/package.json +1 -1
- package/front_end/panels/recorder/RecorderController.ts +0 -1759
- /package/front_end/panels/recorder/{recorderController.css → recorderPanel.css} +0 -0
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import * as Common from '../../core/common/common.js';
|
|
6
6
|
import * as Host from '../../core/host/host.js';
|
|
7
|
+
import * as Root from '../../core/root/root.js';
|
|
7
8
|
|
|
8
9
|
import {AiExplorerBadge} from './AiExplorerBadge.js';
|
|
9
10
|
import type {Badge, BadgeAction, BadgeActionEvents, BadgeContext, TriggerOptions} from './Badge.js';
|
|
@@ -32,7 +33,6 @@ const SNOOZE_TIME_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
|
32
33
|
const MAX_SNOOZE_COUNT = 3;
|
|
33
34
|
const DELAY_BEFORE_TRIGGER = 1500;
|
|
34
35
|
|
|
35
|
-
let userBadgesInstance: UserBadges|undefined = undefined;
|
|
36
36
|
export class UserBadges extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
|
|
37
37
|
readonly #badgeActionEventTarget = new Common.ObjectWrapper.ObjectWrapper<BadgeActionEvents>();
|
|
38
38
|
|
|
@@ -43,6 +43,9 @@ export class UserBadges extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
|
|
|
43
43
|
#starterBadgeLastSnoozedTimestamp: Common.Settings.Setting<number>;
|
|
44
44
|
#starterBadgeDismissed: Common.Settings.Setting<boolean>;
|
|
45
45
|
|
|
46
|
+
readonly #settings: Common.Settings.Settings;
|
|
47
|
+
readonly #gdpClient: Host.GdpClient.GdpClient;
|
|
48
|
+
|
|
46
49
|
static readonly BADGE_REGISTRY: BadgeClass[] = [
|
|
47
50
|
StarterBadge,
|
|
48
51
|
SpeedsterBadge,
|
|
@@ -51,21 +54,27 @@ export class UserBadges extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
|
|
|
51
54
|
AiExplorerBadge,
|
|
52
55
|
];
|
|
53
56
|
|
|
54
|
-
|
|
57
|
+
constructor(
|
|
58
|
+
settings: Common.Settings.Settings,
|
|
59
|
+
gdpClient: Host.GdpClient.GdpClient,
|
|
60
|
+
) {
|
|
55
61
|
super();
|
|
56
62
|
|
|
57
|
-
this.#
|
|
63
|
+
this.#settings = settings;
|
|
64
|
+
this.#gdpClient = gdpClient;
|
|
65
|
+
|
|
66
|
+
this.#receiveBadgesSetting = this.#settings.moduleSetting('receive-gdp-badges');
|
|
58
67
|
if (!Host.GdpClient.isBadgesEnabled()) {
|
|
59
68
|
this.#receiveBadgesSetting.set(false);
|
|
60
69
|
}
|
|
61
70
|
this.#receiveBadgesSetting.addChangeListener(this.#reconcileBadges, this);
|
|
62
71
|
|
|
63
|
-
this.#starterBadgeSnoozeCount =
|
|
64
|
-
'starter-badge-snooze-count', 0, Common.Settings.SettingStorageType.SYNCED);
|
|
65
|
-
this.#starterBadgeLastSnoozedTimestamp =
|
|
66
|
-
|
|
67
|
-
this.#starterBadgeDismissed =
|
|
68
|
-
'starter-badge-dismissed', false, Common.Settings.SettingStorageType.SYNCED);
|
|
72
|
+
this.#starterBadgeSnoozeCount =
|
|
73
|
+
this.#settings.createSetting('starter-badge-snooze-count', 0, Common.Settings.SettingStorageType.SYNCED);
|
|
74
|
+
this.#starterBadgeLastSnoozedTimestamp = this.#settings.createSetting('starter-badge-last-snoozed-timestamp', 0,
|
|
75
|
+
Common.Settings.SettingStorageType.SYNCED);
|
|
76
|
+
this.#starterBadgeDismissed =
|
|
77
|
+
this.#settings.createSetting('starter-badge-dismissed', false, Common.Settings.SettingStorageType.SYNCED);
|
|
69
78
|
|
|
70
79
|
this.#allBadges = UserBadges.BADGE_REGISTRY.map(badgeCtor => new badgeCtor({
|
|
71
80
|
onTriggerBadge: this.#onTriggerBadge.bind(this),
|
|
@@ -74,10 +83,16 @@ export class UserBadges extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
|
|
|
74
83
|
}
|
|
75
84
|
|
|
76
85
|
static instance({forceNew}: {forceNew: boolean} = {forceNew: false}): UserBadges {
|
|
77
|
-
if (!
|
|
78
|
-
|
|
86
|
+
if (!Root.DevToolsContext.globalInstance().has(UserBadges) || forceNew) {
|
|
87
|
+
Root.DevToolsContext.globalInstance().set(
|
|
88
|
+
UserBadges,
|
|
89
|
+
new UserBadges(
|
|
90
|
+
Common.Settings.Settings.instance(),
|
|
91
|
+
Host.GdpClient.GdpClient.instance(),
|
|
92
|
+
),
|
|
93
|
+
);
|
|
79
94
|
}
|
|
80
|
-
return
|
|
95
|
+
return Root.DevToolsContext.globalInstance().get(UserBadges);
|
|
81
96
|
}
|
|
82
97
|
|
|
83
98
|
async initialize(): Promise<void> {
|
|
@@ -108,7 +123,7 @@ export class UserBadges extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
|
|
|
108
123
|
return BadgeTriggerReason.AWARD;
|
|
109
124
|
}
|
|
110
125
|
|
|
111
|
-
const getProfileResponse = await
|
|
126
|
+
const getProfileResponse = await this.#gdpClient.getProfile();
|
|
112
127
|
// The `getProfile` call failed and returned a `null`.
|
|
113
128
|
// For that case, we don't show anything.
|
|
114
129
|
if (!getProfileResponse) {
|
|
@@ -147,7 +162,7 @@ export class UserBadges extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
|
|
|
147
162
|
}
|
|
148
163
|
|
|
149
164
|
if (reason === BadgeTriggerReason.AWARD) {
|
|
150
|
-
const result = await
|
|
165
|
+
const result = await this.#gdpClient.createAward({name: badge.name});
|
|
151
166
|
if (!result) {
|
|
152
167
|
return;
|
|
153
168
|
}
|
|
@@ -192,7 +207,7 @@ export class UserBadges extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
|
|
|
192
207
|
return;
|
|
193
208
|
}
|
|
194
209
|
|
|
195
|
-
const getProfileResponse = await
|
|
210
|
+
const getProfileResponse = await this.#gdpClient.getProfile();
|
|
196
211
|
if (!getProfileResponse) {
|
|
197
212
|
this.#deactivateAllBadges();
|
|
198
213
|
return;
|
|
@@ -209,8 +224,7 @@ export class UserBadges extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
|
|
|
209
224
|
|
|
210
225
|
let awardedBadgeNames: Set<string>|null = null;
|
|
211
226
|
if (hasGdpProfile) {
|
|
212
|
-
awardedBadgeNames = await
|
|
213
|
-
{names: this.#allBadges.map(badge => badge.name)});
|
|
227
|
+
awardedBadgeNames = await this.#gdpClient.getAwardedBadgeNames({names: this.#allBadges.map(badge => badge.name)});
|
|
214
228
|
// This is a conservative approach. We bail out if `awardedBadgeNames` is null
|
|
215
229
|
// when there is a profile to prevent a negative user experience.
|
|
216
230
|
//
|
|
@@ -12,9 +12,9 @@ const uiSourceCodeToAttributionMap = new WeakMap<Workspace.UISourceCode.UISource
|
|
|
12
12
|
frame: SDK.ResourceTreeModel.ResourceTreeFrame,
|
|
13
13
|
count: number,
|
|
14
14
|
}>>();
|
|
15
|
-
const projectToTargetMap = new WeakMap<Workspace.Workspace.Project, SDK.Target.Target>();
|
|
16
15
|
|
|
17
16
|
export class NetworkProjectManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
|
|
17
|
+
readonly #projectToTargetMap = new WeakMap<Workspace.Workspace.Project, SDK.Target.Target>();
|
|
18
18
|
|
|
19
19
|
static instance({forceNew}: {
|
|
20
20
|
forceNew: boolean,
|
|
@@ -29,6 +29,18 @@ export class NetworkProjectManager extends Common.ObjectWrapper.ObjectWrapper<Ev
|
|
|
29
29
|
static removeInstance(): void {
|
|
30
30
|
Root.DevToolsContext.globalInstance().delete(NetworkProjectManager);
|
|
31
31
|
}
|
|
32
|
+
|
|
33
|
+
setTargetForProject(project: Workspace.Workspace.Project, target: SDK.Target.Target): void {
|
|
34
|
+
this.#projectToTargetMap.set(project, target);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
getTargetForProject(project: Workspace.Workspace.Project): SDK.Target.Target|null {
|
|
38
|
+
return this.#projectToTargetMap.get(project) ?? null;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
getTargetForUISourceCode(uiSourceCode: Workspace.UISourceCode.UISourceCode): SDK.Target.Target|null {
|
|
42
|
+
return this.#projectToTargetMap.get(uiSourceCode.project()) ?? null;
|
|
43
|
+
}
|
|
32
44
|
}
|
|
33
45
|
|
|
34
46
|
export const enum Events {
|
|
@@ -132,15 +144,15 @@ export class NetworkProject {
|
|
|
132
144
|
}
|
|
133
145
|
|
|
134
146
|
static targetForUISourceCode(uiSourceCode: Workspace.UISourceCode.UISourceCode): SDK.Target.Target|null {
|
|
135
|
-
return
|
|
147
|
+
return NetworkProjectManager.instance().getTargetForUISourceCode(uiSourceCode);
|
|
136
148
|
}
|
|
137
149
|
|
|
138
150
|
static setTargetForProject(project: Workspace.Workspace.Project, target: SDK.Target.Target): void {
|
|
139
|
-
|
|
151
|
+
NetworkProjectManager.instance().setTargetForProject(project, target);
|
|
140
152
|
}
|
|
141
153
|
|
|
142
154
|
static getTargetForProject(project: Workspace.Workspace.Project): SDK.Target.Target|null {
|
|
143
|
-
return
|
|
155
|
+
return NetworkProjectManager.instance().getTargetForProject(project);
|
|
144
156
|
}
|
|
145
157
|
|
|
146
158
|
static framesForUISourceCode(uiSourceCode: Workspace.UISourceCode.UISourceCode):
|
|
@@ -11,6 +11,8 @@ import * as Protocol from '../../generated/protocol.js';
|
|
|
11
11
|
import * as Geometry from '../geometry/geometry.js';
|
|
12
12
|
|
|
13
13
|
import {
|
|
14
|
+
type Cutout,
|
|
15
|
+
CutoutShape,
|
|
14
16
|
type EmulatedDevice,
|
|
15
17
|
Horizontal,
|
|
16
18
|
HorizontalSpanned,
|
|
@@ -85,6 +87,13 @@ const UIStrings = {
|
|
|
85
87
|
const str_ = i18n.i18n.registerUIStrings('models/emulation/DeviceModeModel.ts', UIStrings);
|
|
86
88
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
87
89
|
|
|
90
|
+
const CUTOUT_SHAPE_TO_PROTOCOL: Record<CutoutShape, Protocol.Overlay.DisplayCutoutShape> = {
|
|
91
|
+
[CutoutShape.PILL]: Protocol.Overlay.DisplayCutoutShape.Pill,
|
|
92
|
+
[CutoutShape.NOTCH]: Protocol.Overlay.DisplayCutoutShape.Notch,
|
|
93
|
+
[CutoutShape.CIRCLE]: Protocol.Overlay.DisplayCutoutShape.Circle,
|
|
94
|
+
[CutoutShape.RECTANGLE]: Protocol.Overlay.DisplayCutoutShape.Rectangle,
|
|
95
|
+
};
|
|
96
|
+
|
|
88
97
|
export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTypes> implements
|
|
89
98
|
SDK.TargetManager.SDKModelObserver<SDK.EmulationModel.EmulationModel> {
|
|
90
99
|
#screenRect: Rect;
|
|
@@ -506,7 +515,7 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
506
515
|
return;
|
|
507
516
|
}
|
|
508
517
|
|
|
509
|
-
this.
|
|
518
|
+
this.showDeviceOverlaysIfApplicable(overlayModel);
|
|
510
519
|
}
|
|
511
520
|
|
|
512
521
|
private onScreenOrientationLockChanged(
|
|
@@ -638,7 +647,7 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
638
647
|
const mobile = this.isMobile();
|
|
639
648
|
const overlayModel = this.#emulationModel ? this.#emulationModel.overlayModel() : null;
|
|
640
649
|
if (overlayModel) {
|
|
641
|
-
this.
|
|
650
|
+
this.showDeviceOverlaysIfApplicable(overlayModel);
|
|
642
651
|
}
|
|
643
652
|
if (this.#type === Type.Device && this.#device && this.#mode) {
|
|
644
653
|
const orientation = this.#device.orientationByName(this.#mode.orientation);
|
|
@@ -878,14 +887,67 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
878
887
|
}
|
|
879
888
|
}
|
|
880
889
|
|
|
881
|
-
private
|
|
890
|
+
private showDeviceOverlaysIfApplicable(overlayModel: SDK.OverlayModel.OverlayModel): void {
|
|
882
891
|
const orientation = (this.#device && this.#mode) ? this.#device.orientationByName(this.#mode.orientation) : null;
|
|
883
892
|
if (orientation?.hinge) {
|
|
884
893
|
overlayModel.showHingeForDualScreen(orientation.hinge);
|
|
885
|
-
|
|
894
|
+
} else {
|
|
895
|
+
overlayModel.showHingeForDualScreen(null);
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
overlayModel.showDisplayCutout(this.currentDisplayCutout());
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
private currentDisplayCutout(): SDK.OverlayModel.DisplayCutout|null {
|
|
902
|
+
const device = this.#device;
|
|
903
|
+
const mode = this.#mode;
|
|
904
|
+
if (!device || !mode || !device.modes.includes(mode)) {
|
|
905
|
+
return null;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
const cutout = mode.cutout;
|
|
909
|
+
if (cutout) {
|
|
910
|
+
return this.toDisplayCutout(cutout);
|
|
886
911
|
}
|
|
887
912
|
|
|
888
|
-
|
|
913
|
+
if (mode.orientation !== Horizontal) {
|
|
914
|
+
return null;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
const rotationPartner = device.getRotationPartner(mode);
|
|
918
|
+
const rotatedCutout = rotationPartner?.cutout;
|
|
919
|
+
if (rotationPartner?.orientation !== Vertical || !rotatedCutout) {
|
|
920
|
+
return null;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
const orientation = device.orientationByName(mode.orientation);
|
|
924
|
+
if (rotatedCutout.shape === CutoutShape.CIRCLE) {
|
|
925
|
+
return this.toDisplayCutout({
|
|
926
|
+
...rotatedCutout,
|
|
927
|
+
x: orientation.width - rotatedCutout.y - rotatedCutout.height,
|
|
928
|
+
y: rotatedCutout.x,
|
|
929
|
+
width: rotatedCutout.height,
|
|
930
|
+
height: rotatedCutout.width,
|
|
931
|
+
cx: orientation.width - rotatedCutout.cy,
|
|
932
|
+
cy: rotatedCutout.cx,
|
|
933
|
+
});
|
|
934
|
+
}
|
|
935
|
+
return this.toDisplayCutout({
|
|
936
|
+
...rotatedCutout,
|
|
937
|
+
x: orientation.width - rotatedCutout.y - rotatedCutout.height,
|
|
938
|
+
y: rotatedCutout.x,
|
|
939
|
+
width: rotatedCutout.height,
|
|
940
|
+
height: rotatedCutout.width,
|
|
941
|
+
});
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
private toDisplayCutout(cutout: Cutout): SDK.OverlayModel.DisplayCutout {
|
|
945
|
+
const {shape, ...rest} = cutout;
|
|
946
|
+
return {
|
|
947
|
+
...rest,
|
|
948
|
+
shape: CUTOUT_SHAPE_TO_PROTOCOL[shape],
|
|
949
|
+
contentColor: {r: 0, g: 0, b: 0, a: 1},
|
|
950
|
+
} as SDK.OverlayModel.DisplayCutout;
|
|
889
951
|
}
|
|
890
952
|
|
|
891
953
|
private getDisplayFeatureOrientation(): Protocol.Emulation.DisplayFeatureOrientation {
|
|
@@ -3,11 +3,10 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
5
|
import * as Common from '../../core/common/common.js';
|
|
6
|
+
import * as Root from '../../core/root/root.js';
|
|
6
7
|
|
|
7
8
|
import type {RecorderExtensionEndpoint} from './RecorderExtensionEndpoint.js';
|
|
8
9
|
|
|
9
|
-
let instance: RecorderPluginManager|null = null;
|
|
10
|
-
|
|
11
10
|
export interface ViewDescriptor {
|
|
12
11
|
id: string;
|
|
13
12
|
title: string;
|
|
@@ -21,11 +20,16 @@ export class RecorderPluginManager extends Common.ObjectWrapper.ObjectWrapper<Ev
|
|
|
21
20
|
#plugins = new Set<RecorderExtensionEndpoint>();
|
|
22
21
|
#views = new Map<string, ViewDescriptor>();
|
|
23
22
|
|
|
24
|
-
static instance(): RecorderPluginManager {
|
|
25
|
-
if (!
|
|
26
|
-
|
|
23
|
+
static instance(opts?: {forceNew: boolean}): RecorderPluginManager {
|
|
24
|
+
if (!Root.DevToolsContext.globalInstance().has(RecorderPluginManager) || opts?.forceNew) {
|
|
25
|
+
Root.DevToolsContext.globalInstance().set(RecorderPluginManager, new RecorderPluginManager());
|
|
27
26
|
}
|
|
28
|
-
|
|
27
|
+
|
|
28
|
+
return Root.DevToolsContext.globalInstance().get(RecorderPluginManager);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
static removeInstance(): void {
|
|
32
|
+
Root.DevToolsContext.globalInstance().delete(RecorderPluginManager);
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
addPlugin(plugin: RecorderExtensionEndpoint): void {
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
Title: HAR Log build converts network requests into a complete HAR log with pages and entries
|
|
2
|
+
Content:
|
|
3
|
+
{
|
|
4
|
+
"version": "1.2",
|
|
5
|
+
"creator": {
|
|
6
|
+
"name": "WebInspector",
|
|
7
|
+
"version": "VERSION"
|
|
8
|
+
},
|
|
9
|
+
"pages": [
|
|
10
|
+
{
|
|
11
|
+
"startedDateTime": "1970-01-01T00:00:01.000Z",
|
|
12
|
+
"id": "page_1",
|
|
13
|
+
"title": "http://127.0.0.1:8000/devtools/resources/inspected-page.html",
|
|
14
|
+
"pageTimings": {
|
|
15
|
+
"onContentLoad": 9000,
|
|
16
|
+
"onLoad": 14000
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"entries": [
|
|
21
|
+
{
|
|
22
|
+
"_initiator": null,
|
|
23
|
+
"_priority": null,
|
|
24
|
+
"_resourceType": "document",
|
|
25
|
+
"cache": {},
|
|
26
|
+
"request": {
|
|
27
|
+
"method": "GET",
|
|
28
|
+
"url": "http://127.0.0.1:8000/devtools/resources/inspected-page.html",
|
|
29
|
+
"httpVersion": "HTTP/1.1",
|
|
30
|
+
"headers": [
|
|
31
|
+
{
|
|
32
|
+
"name": "version",
|
|
33
|
+
"value": "HTTP/1.1"
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"queryString": [],
|
|
37
|
+
"cookies": [
|
|
38
|
+
{
|
|
39
|
+
"name": "a",
|
|
40
|
+
"value": "b",
|
|
41
|
+
"path": "/path",
|
|
42
|
+
"domain": "example.com",
|
|
43
|
+
"expires": null,
|
|
44
|
+
"httpOnly": false,
|
|
45
|
+
"secure": false
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "a1",
|
|
49
|
+
"value": "b1",
|
|
50
|
+
"expires": null,
|
|
51
|
+
"httpOnly": false,
|
|
52
|
+
"secure": false
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"name": "c1",
|
|
56
|
+
"value": "d1",
|
|
57
|
+
"expires": null,
|
|
58
|
+
"httpOnly": false,
|
|
59
|
+
"secure": false
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
"headersSize": -1,
|
|
63
|
+
"bodySize": 0
|
|
64
|
+
},
|
|
65
|
+
"response": {
|
|
66
|
+
"status": 0,
|
|
67
|
+
"statusText": "",
|
|
68
|
+
"httpVersion": "",
|
|
69
|
+
"headers": [
|
|
70
|
+
{
|
|
71
|
+
"name": "Set-Cookie",
|
|
72
|
+
"value": "x=y; Path=/path; Domain=example.com; httpOnly; Secure\nx1=y1; SameSite=Strict\nz2=y2; SameSite=Lax"
|
|
73
|
+
}
|
|
74
|
+
],
|
|
75
|
+
"cookies": [
|
|
76
|
+
{
|
|
77
|
+
"name": "x",
|
|
78
|
+
"value": "y",
|
|
79
|
+
"path": "/path",
|
|
80
|
+
"domain": "example.com",
|
|
81
|
+
"expires": null,
|
|
82
|
+
"httpOnly": true,
|
|
83
|
+
"secure": true
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"name": "x1",
|
|
87
|
+
"value": "y1",
|
|
88
|
+
"domain": "127.0.0.1",
|
|
89
|
+
"expires": null,
|
|
90
|
+
"httpOnly": false,
|
|
91
|
+
"secure": false,
|
|
92
|
+
"sameSite": "Strict"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"name": "z2",
|
|
96
|
+
"value": "y2",
|
|
97
|
+
"domain": "127.0.0.1",
|
|
98
|
+
"expires": null,
|
|
99
|
+
"httpOnly": false,
|
|
100
|
+
"secure": false,
|
|
101
|
+
"sameSite": "Lax"
|
|
102
|
+
}
|
|
103
|
+
],
|
|
104
|
+
"content": {
|
|
105
|
+
"size": 0,
|
|
106
|
+
"mimeType": "x-unknown"
|
|
107
|
+
},
|
|
108
|
+
"redirectURL": "",
|
|
109
|
+
"headersSize": -1,
|
|
110
|
+
"bodySize": -1,
|
|
111
|
+
"_transferSize": 0,
|
|
112
|
+
"_error": null,
|
|
113
|
+
"_fetchedViaServiceWorker": true,
|
|
114
|
+
"_responseCacheStorageCacheName": "v1",
|
|
115
|
+
"_serviceWorkerResponseSource": "cache-storage",
|
|
116
|
+
"_serviceWorkerRouterRuleIdMatched": 3,
|
|
117
|
+
"_serviceWorkerRouterMatchedSourceType": "cache",
|
|
118
|
+
"_serviceWorkerRouterActualSourceType": "cache"
|
|
119
|
+
},
|
|
120
|
+
"serverIPAddress": "",
|
|
121
|
+
"startedDateTime": "1969-12-31T23:59:59.000Z",
|
|
122
|
+
"time": 0,
|
|
123
|
+
"timings": {
|
|
124
|
+
"blocked": 0,
|
|
125
|
+
"dns": -1,
|
|
126
|
+
"ssl": -1,
|
|
127
|
+
"connect": -1,
|
|
128
|
+
"send": 0,
|
|
129
|
+
"wait": 0,
|
|
130
|
+
"receive": 0,
|
|
131
|
+
"_blocked_queueing": 2000
|
|
132
|
+
},
|
|
133
|
+
"pageref": "page_1"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"_initiator": null,
|
|
137
|
+
"_priority": null,
|
|
138
|
+
"_resourceType": "xhr",
|
|
139
|
+
"cache": {},
|
|
140
|
+
"request": {
|
|
141
|
+
"method": "POST",
|
|
142
|
+
"url": "http://127.0.0.1:8000/devtools/resources/post-target.cgi",
|
|
143
|
+
"httpVersion": "",
|
|
144
|
+
"headers": [
|
|
145
|
+
{
|
|
146
|
+
"name": "Content-Type",
|
|
147
|
+
"value": "text/xml"
|
|
148
|
+
}
|
|
149
|
+
],
|
|
150
|
+
"queryString": [],
|
|
151
|
+
"cookies": [],
|
|
152
|
+
"headersSize": -1,
|
|
153
|
+
"bodySize": 11,
|
|
154
|
+
"postData": {
|
|
155
|
+
"mimeType": "text/xml",
|
|
156
|
+
"text": "<xml></xml>"
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
"response": {
|
|
160
|
+
"status": 0,
|
|
161
|
+
"statusText": "",
|
|
162
|
+
"httpVersion": "",
|
|
163
|
+
"headers": [],
|
|
164
|
+
"cookies": [],
|
|
165
|
+
"content": {
|
|
166
|
+
"size": 0,
|
|
167
|
+
"mimeType": "application/xml"
|
|
168
|
+
},
|
|
169
|
+
"redirectURL": "",
|
|
170
|
+
"headersSize": -1,
|
|
171
|
+
"bodySize": -1,
|
|
172
|
+
"_transferSize": 0,
|
|
173
|
+
"_error": null,
|
|
174
|
+
"_fetchedViaServiceWorker": false
|
|
175
|
+
},
|
|
176
|
+
"serverIPAddress": "",
|
|
177
|
+
"startedDateTime": "1969-12-31T23:59:59.000Z",
|
|
178
|
+
"time": 0,
|
|
179
|
+
"timings": {
|
|
180
|
+
"blocked": 0,
|
|
181
|
+
"dns": -1,
|
|
182
|
+
"ssl": -1,
|
|
183
|
+
"connect": -1,
|
|
184
|
+
"send": 0,
|
|
185
|
+
"wait": 0,
|
|
186
|
+
"receive": 0,
|
|
187
|
+
"_blocked_queueing": -1
|
|
188
|
+
},
|
|
189
|
+
"pageref": "page_1"
|
|
190
|
+
}
|
|
191
|
+
]
|
|
192
|
+
}
|
|
193
|
+
=== end content
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// See https://bugs.webkit.org/show_bug.cgi?id=58127 for details.
|
|
10
10
|
|
|
11
11
|
import * as Common from '../../core/common/common.js';
|
|
12
|
-
import
|
|
12
|
+
import * as Platform from '../../core/platform/platform.js';
|
|
13
13
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
14
14
|
import type * as Protocol from '../../generated/protocol.js';
|
|
15
15
|
|
|
@@ -33,7 +33,8 @@ export class Log {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
private creator(): Creator {
|
|
36
|
-
const
|
|
36
|
+
const userAgent = Platform.HostRuntime.HOST_RUNTIME.getUserAgent();
|
|
37
|
+
const webKitVersion = /AppleWebKit\/([^ ]+)/.exec(userAgent);
|
|
37
38
|
|
|
38
39
|
return {name: 'WebInspector', version: webKitVersion ? webKitVersion[1] : 'n/a'};
|
|
39
40
|
}
|
|
@@ -216,14 +216,15 @@ function createFunctionCode(
|
|
|
216
216
|
*/
|
|
217
217
|
export async function getFunctionCodeFromLocation(
|
|
218
218
|
target: SDK.Target.Target, url: Platform.DevToolsPath.UrlString, line: number, column: number,
|
|
219
|
-
options?: CreateFunctionCodeOptions
|
|
219
|
+
options?: CreateFunctionCodeOptions,
|
|
220
|
+
debuggerWorkspaceBinding =
|
|
221
|
+
Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance()): Promise<FunctionCode|null> {
|
|
220
222
|
const debuggerModel = target.model(SDK.DebuggerModel.DebuggerModel);
|
|
221
223
|
if (!debuggerModel) {
|
|
222
224
|
throw new Error('missing debugger model');
|
|
223
225
|
}
|
|
224
226
|
|
|
225
227
|
let uiSourceCode: Workspace.UISourceCode.UISourceCode|null = null;
|
|
226
|
-
const debuggerWorkspaceBinding = Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance();
|
|
227
228
|
const projects = debuggerWorkspaceBinding.workspace.projectsForType(Workspace.Workspace.projectTypes.Network);
|
|
228
229
|
for (const project of projects) {
|
|
229
230
|
if (Bindings.NetworkProject.NetworkProject.getTargetForProject(project) !== target) {
|
|
@@ -245,7 +246,7 @@ export async function getFunctionCodeFromLocation(
|
|
|
245
246
|
return null;
|
|
246
247
|
}
|
|
247
248
|
|
|
248
|
-
return await getFunctionCodeFromRawLocation(rawLocation, options);
|
|
249
|
+
return await getFunctionCodeFromRawLocation(rawLocation, options, debuggerWorkspaceBinding);
|
|
249
250
|
}
|
|
250
251
|
|
|
251
252
|
async function format(uiSourceCode: Workspace.UISourceCode.UISourceCode, content: string,
|
|
@@ -264,8 +265,9 @@ async function format(uiSourceCode: Workspace.UISourceCode.UISourceCode, content
|
|
|
264
265
|
* Returns a {@link FunctionCode} for the given raw location.
|
|
265
266
|
*/
|
|
266
267
|
export async function getFunctionCodeFromRawLocation(
|
|
267
|
-
rawLocation: SDK.DebuggerModel.Location, options?: CreateFunctionCodeOptions
|
|
268
|
-
|
|
268
|
+
rawLocation: SDK.DebuggerModel.Location, options?: CreateFunctionCodeOptions,
|
|
269
|
+
debuggerWorkspaceBinding =
|
|
270
|
+
Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance()): Promise<FunctionCode|null> {
|
|
269
271
|
const functionBounds = await debuggerWorkspaceBinding.functionBoundsAtRawLocation(rawLocation);
|
|
270
272
|
if (!functionBounds) {
|
|
271
273
|
return null;
|