chrome-devtools-frontend 1.0.968818 → 1.0.970391
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 +64 -0
- package/front_end/core/i18n/locales/en-US.json +18 -0
- package/front_end/core/i18n/locales/en-XL.json +18 -0
- package/front_end/core/sdk/ChildTargetManager.ts +2 -2
- package/front_end/core/sdk/Connections.ts +6 -1
- package/front_end/core/sdk/NetworkManager.ts +4 -3
- package/front_end/entrypoints/lighthouse_worker/LighthouseService.ts +84 -13
- package/front_end/models/persistence/NetworkPersistenceManager.ts +205 -41
- package/front_end/models/timeline_model/TimelineFrameModel.ts +21 -7
- package/front_end/panels/animation/animationTimeline.css +0 -3
- package/front_end/panels/application/components/ReportsGrid.ts +19 -4
- package/front_end/panels/application/components/trustTokensViewDeleteButton.css +0 -1
- package/front_end/panels/console/consolePinPane.css +0 -17
- package/front_end/panels/css_overview/cssOverviewCompletedView.css +0 -1
- package/front_end/panels/elements/components/adornerSettingsPane.css +0 -1
- package/front_end/panels/elements/components/computedStyleTrace.css +1 -1
- package/front_end/panels/elements/components/elementsBreadcrumbs.css +0 -1
- package/front_end/panels/elements/computedStyleWidgetTree.css +2 -2
- package/front_end/panels/elements/elementsTreeOutline.css +0 -2
- package/front_end/panels/emulation/deviceModeView.css +0 -1
- package/front_end/panels/event_listeners/eventListenersView.css +0 -1
- package/front_end/panels/issues/components/hideIssuesMenu.css +0 -1
- package/front_end/panels/lighthouse/LighthouseController.ts +25 -1
- package/front_end/panels/lighthouse/LighthouseProtocolService.ts +37 -5
- package/front_end/panels/lighthouse/LighthouseStartView.ts +1 -0
- package/front_end/panels/lighthouse/LighthouseStatusView.ts +5 -5
- package/front_end/panels/media/playerListView.css +0 -1
- package/front_end/panels/network/networkLogView.css +0 -4
- package/front_end/panels/network/requestPayloadTree.css +0 -2
- package/front_end/panels/network/signedExchangeInfoTree.css +0 -1
- package/front_end/panels/settings/emulation/components/userAgentClientHintsForm.css +0 -4
- package/front_end/panels/settings/emulation/devicesSettingsTab.css +0 -1
- package/front_end/panels/sources/CSSPlugin.ts +2 -0
- package/front_end/panels/sources/watchExpressionsSidebarPane.css +0 -1
- package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +75 -3
- package/front_end/panels/webauthn/webauthnPane.css +0 -12
- package/front_end/services/puppeteer/PuppeteerConnection.ts +107 -0
- package/front_end/services/puppeteer/puppeteer.ts +9 -0
- package/front_end/third_party/codemirror/package/addon/fold/foldgutter.css +1 -5
- package/front_end/third_party/codemirror.next/README.chromium +10 -0
- package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/cpp.js +2 -1
- package/front_end/third_party/codemirror.next/chunk/markdown.js +2 -2
- package/front_end/third_party/codemirror.next/chunk/python.js +2 -1
- package/front_end/third_party/codemirror.next/codemirror.next.d.ts +574 -553
- package/front_end/third_party/codemirror.next/package.json +11 -11
- package/front_end/ui/components/adorners/adorner.css +0 -4
- package/front_end/ui/components/buttons/button.css +0 -4
- package/front_end/ui/components/data_grid/dataGrid.css +0 -4
- package/front_end/ui/components/icon_button/iconButton.css +0 -1
- package/front_end/ui/components/markdown_view/MarkdownLinksMap.ts +2 -2
- package/front_end/ui/legacy/TabbedPane.ts +1 -1
- package/front_end/ui/legacy/components/perf_ui/TimelineOverviewPane.ts +2 -2
- package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +4 -2
- package/front_end/ui/legacy/tabbedPane.css +0 -4
- package/front_end/ui/legacy/textButton.css +0 -1
- package/front_end/ui/legacy/toolbar.css +0 -1
- package/package.json +2 -2
- package/scripts/hosted_mode/server.js +5 -0
@@ -125,6 +125,14 @@ const UIStrings = {
|
|
125
125
|
*@description Text of checkbox to reset storage features prior to running audits in Lighthouse
|
126
126
|
*/
|
127
127
|
clearStorage: 'Clear storage',
|
128
|
+
/**
|
129
|
+
* @description Text of checkbox to use the legacy Lighthouse navigation mode
|
130
|
+
*/
|
131
|
+
legacyNavigation: 'Legacy navigation',
|
132
|
+
/**
|
133
|
+
* @description Tooltip text that appears when hovering over the 'Legacy navigation' checkbox in the settings pane opened by clicking the setting cog in the start view of the audits panel
|
134
|
+
*/
|
135
|
+
useLegacyNavigation: 'Audit the page using classic Lighthouse when in navigation mode.',
|
128
136
|
/**
|
129
137
|
* @description Tooltip text of checkbox to reset storage features prior to running audits in
|
130
138
|
* Lighthouse. Resetting the storage clears/empties it to a neutral state.
|
@@ -277,7 +285,11 @@ export class LighthouseController extends Common.ObjectWrapper.ObjectWrapper<Eve
|
|
277
285
|
return navigationEntry.url;
|
278
286
|
}
|
279
287
|
|
280
|
-
getFlags(): {
|
288
|
+
getFlags(): {
|
289
|
+
internalDisableDeviceScreenEmulation: boolean,
|
290
|
+
emulatedFormFactor: (string|undefined),
|
291
|
+
legacyNavigation: boolean,
|
292
|
+
} {
|
281
293
|
const flags = {
|
282
294
|
// DevTools handles all the emulation. This tells Lighthouse to not bother with emulation.
|
283
295
|
internalDisableDeviceScreenEmulation: true,
|
@@ -288,6 +300,7 @@ export class LighthouseController extends Common.ObjectWrapper.ObjectWrapper<Eve
|
|
288
300
|
return flags as {
|
289
301
|
internalDisableDeviceScreenEmulation: boolean,
|
290
302
|
emulatedFormFactor: (string | undefined),
|
303
|
+
legacyNavigation: boolean,
|
291
304
|
};
|
292
305
|
}
|
293
306
|
|
@@ -433,6 +446,17 @@ export const RuntimeSettings: RuntimeSetting[] = [
|
|
433
446
|
options: undefined,
|
434
447
|
learnMore: undefined,
|
435
448
|
},
|
449
|
+
{
|
450
|
+
setting: Common.Settings.Settings.instance().createSetting(
|
451
|
+
'lighthouse.legacy_navigation', true, Common.Settings.SettingStorageType.Synced),
|
452
|
+
title: i18nLazyString(UIStrings.legacyNavigation),
|
453
|
+
description: i18nLazyString(UIStrings.useLegacyNavigation),
|
454
|
+
setFlags: (flags: Flags, value: string|boolean): void => {
|
455
|
+
flags.legacyNavigation = value;
|
456
|
+
},
|
457
|
+
options: undefined,
|
458
|
+
learnMore: undefined,
|
459
|
+
},
|
436
460
|
];
|
437
461
|
|
438
462
|
// TODO(crbug.com/1167717): Make this a const enum again
|
@@ -11,6 +11,11 @@ import type * as ReportRenderer from './LighthouseReporterTypes.js';
|
|
11
11
|
let lastId = 1;
|
12
12
|
|
13
13
|
export class ProtocolService {
|
14
|
+
private targetInfo?: {
|
15
|
+
mainSessionId: string,
|
16
|
+
mainTargetId: string,
|
17
|
+
mainFrameId: string,
|
18
|
+
};
|
14
19
|
private rawConnection?: ProtocolClient.InspectorBackend.Connection;
|
15
20
|
private lighthouseWorkerPromise?: Promise<Worker>;
|
16
21
|
private lighthouseMessageUpdateCallback?: ((arg0: string) => void);
|
@@ -19,26 +24,53 @@ export class ProtocolService {
|
|
19
24
|
await SDK.TargetManager.TargetManager.instance().suspendAllTargets();
|
20
25
|
const mainTarget = SDK.TargetManager.TargetManager.instance().mainTarget();
|
21
26
|
if (!mainTarget) {
|
22
|
-
throw new Error('Unable to find main target required for
|
27
|
+
throw new Error('Unable to find main target required for Lighthouse');
|
23
28
|
}
|
24
29
|
const childTargetManager = mainTarget.model(SDK.ChildTargetManager.ChildTargetManager);
|
25
30
|
if (!childTargetManager) {
|
26
|
-
throw new Error('Unable to find child target manager required for
|
31
|
+
throw new Error('Unable to find child target manager required for Lighthouse');
|
27
32
|
}
|
28
|
-
|
33
|
+
const resourceTreeModel = mainTarget.model(SDK.ResourceTreeModel.ResourceTreeModel);
|
34
|
+
if (!resourceTreeModel) {
|
35
|
+
throw new Error('Unable to find resource tree model required for Lighthouse');
|
36
|
+
}
|
37
|
+
const mainFrame = resourceTreeModel.mainFrame;
|
38
|
+
if (!mainFrame) {
|
39
|
+
throw new Error('Unable to find main frame required for Lighthouse');
|
40
|
+
}
|
41
|
+
|
42
|
+
const {connection, sessionId} = await childTargetManager.createParallelConnection(message => {
|
29
43
|
if (typeof message === 'string') {
|
30
44
|
message = JSON.parse(message);
|
31
45
|
}
|
32
46
|
this.dispatchProtocolMessage(message);
|
33
47
|
});
|
48
|
+
|
49
|
+
this.rawConnection = connection;
|
50
|
+
this.targetInfo = {
|
51
|
+
mainTargetId: await childTargetManager.getParentTargetId(),
|
52
|
+
mainFrameId: mainFrame.id,
|
53
|
+
mainSessionId: sessionId,
|
54
|
+
};
|
34
55
|
}
|
35
56
|
|
36
57
|
getLocales(): readonly string[] {
|
37
58
|
return [i18n.DevToolsLocale.DevToolsLocale.instance().locale];
|
38
59
|
}
|
39
60
|
|
40
|
-
startLighthouse(auditURL: string, categoryIDs: string[], flags: Object):
|
41
|
-
|
61
|
+
async startLighthouse(auditURL: string, categoryIDs: string[], flags: Record<string, Object|undefined>):
|
62
|
+
Promise<ReportRenderer.RunnerResult> {
|
63
|
+
if (!this.targetInfo) {
|
64
|
+
throw new Error('Unable to get target info required for Lighthouse');
|
65
|
+
}
|
66
|
+
const mode = flags.legacyNavigation ? 'start' : 'navigate';
|
67
|
+
return this.sendWithResponse(mode, {
|
68
|
+
url: auditURL,
|
69
|
+
categoryIDs,
|
70
|
+
flags,
|
71
|
+
locales: this.getLocales(),
|
72
|
+
target: this.targetInfo,
|
73
|
+
});
|
42
74
|
}
|
43
75
|
|
44
76
|
async detach(): Promise<void> {
|
@@ -113,6 +113,7 @@ export class StartView extends UI.Widget.Widget {
|
|
113
113
|
}
|
114
114
|
|
115
115
|
private render(): void {
|
116
|
+
this.populateRuntimeSettingAsToolbarCheckbox('lighthouse.legacy_navigation', this.settingsToolbarInternal);
|
116
117
|
this.populateRuntimeSettingAsToolbarCheckbox('lighthouse.clear_storage', this.settingsToolbarInternal);
|
117
118
|
this.populateRuntimeSettingAsToolbarCheckbox('lighthouse.throttling', this.settingsToolbarInternal);
|
118
119
|
|
@@ -321,7 +321,7 @@ export class StatusView {
|
|
321
321
|
}
|
322
322
|
|
323
323
|
private getPhaseForMessage(message: string): StatusPhase|null {
|
324
|
-
return StatusPhases.find(phase =>
|
324
|
+
return StatusPhases.find(phase => phase.statusMessageRegex.test(message)) || null;
|
325
325
|
}
|
326
326
|
|
327
327
|
private resetProgressBarClasses(): void {
|
@@ -457,7 +457,7 @@ export interface StatusPhase {
|
|
457
457
|
id: string;
|
458
458
|
progressBarClass: string;
|
459
459
|
message: () => Common.UIString.LocalizedString;
|
460
|
-
|
460
|
+
statusMessageRegex: RegExp;
|
461
461
|
}
|
462
462
|
|
463
463
|
export const StatusPhases: StatusPhase[] = [
|
@@ -465,19 +465,19 @@ export const StatusPhases: StatusPhase[] = [
|
|
465
465
|
id: 'loading',
|
466
466
|
progressBarClass: 'loading',
|
467
467
|
message: i18nLazyString(UIStrings.lighthouseIsLoadingThePage),
|
468
|
-
|
468
|
+
statusMessageRegex: /^(Loading page|Navigating to)/,
|
469
469
|
},
|
470
470
|
{
|
471
471
|
id: 'gathering',
|
472
472
|
progressBarClass: 'gathering',
|
473
473
|
message: i18nLazyString(UIStrings.lighthouseIsGatheringInformation),
|
474
|
-
|
474
|
+
statusMessageRegex: /^(Gathering|Computing artifact)/,
|
475
475
|
},
|
476
476
|
{
|
477
477
|
id: 'auditing',
|
478
478
|
progressBarClass: 'auditing',
|
479
479
|
message: i18nLazyString(UIStrings.almostThereLighthouseIsNow),
|
480
|
-
|
480
|
+
statusMessageRegex: /^Auditing/,
|
481
481
|
},
|
482
482
|
];
|
483
483
|
|
@@ -71,7 +71,6 @@
|
|
71
71
|
|
72
72
|
.tree-outline li .header-toggle:hover {
|
73
73
|
color: var(--color-text-secondary);
|
74
|
-
cursor: pointer;
|
75
74
|
}
|
76
75
|
|
77
76
|
.tree-outline .payload-name {
|
@@ -105,7 +104,6 @@
|
|
105
104
|
display: inline-block;
|
106
105
|
font-size: 12px;
|
107
106
|
font-family: sans-serif;
|
108
|
-
cursor: pointer;
|
109
107
|
margin: 0 4px;
|
110
108
|
padding: 2px 4px;
|
111
109
|
}
|
@@ -238,12 +238,14 @@ function createCSSTooltip(active: ActiveTooltip): CodeMirror.Tooltip {
|
|
238
238
|
changes: text === active.text ? undefined :
|
239
239
|
{from: active.pos, to: active.pos + text.length, insert: active.text},
|
240
240
|
});
|
241
|
+
widget.hideWidget();
|
241
242
|
view.focus();
|
242
243
|
}
|
243
244
|
});
|
244
245
|
widget.element.addEventListener('focusout', event => {
|
245
246
|
if (event.relatedTarget && !widget.element.contains(event.relatedTarget as Node)) {
|
246
247
|
view.dispatch({effects: setTooltip.of(null)});
|
248
|
+
widget.hideWidget();
|
247
249
|
}
|
248
250
|
}, false);
|
249
251
|
widget.element.addEventListener('mousedown', event => event.consume());
|
@@ -144,6 +144,10 @@ const UIStrings = {
|
|
144
144
|
*/
|
145
145
|
droppedFrame: 'Dropped Frame',
|
146
146
|
/**
|
147
|
+
*@description Text in Timeline Frame Chart Data Provider of the Performance panel
|
148
|
+
*/
|
149
|
+
partiallyPresentedFrame: 'Partially Presented Frame',
|
150
|
+
/**
|
147
151
|
*@description Text for a rendering frame
|
148
152
|
*/
|
149
153
|
frame: 'Frame',
|
@@ -164,6 +168,8 @@ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
164
168
|
export class TimelineFlameChartDataProvider extends Common.ObjectWrapper.ObjectWrapper<EventTypes> implements
|
165
169
|
PerfUI.FlameChart.FlameChartDataProvider {
|
166
170
|
private readonly font: string;
|
171
|
+
private droppedFramePatternCanvas: HTMLCanvasElement;
|
172
|
+
private partialFramePatternCanvas: HTMLCanvasElement;
|
167
173
|
private timelineDataInternal: PerfUI.FlameChart.TimelineData|null;
|
168
174
|
private currentLevel: number;
|
169
175
|
private performanceModel: PerformanceModel|null;
|
@@ -206,6 +212,9 @@ export class TimelineFlameChartDataProvider extends Common.ObjectWrapper.ObjectW
|
|
206
212
|
super();
|
207
213
|
this.reset();
|
208
214
|
this.font = '11px ' + Host.Platform.fontFamily();
|
215
|
+
this.droppedFramePatternCanvas = document.createElement('canvas');
|
216
|
+
this.partialFramePatternCanvas = document.createElement('canvas');
|
217
|
+
this.preparePatternCanvas();
|
209
218
|
this.timelineDataInternal = null;
|
210
219
|
this.currentLevel = 0;
|
211
220
|
this.performanceModel = null;
|
@@ -1002,7 +1011,11 @@ export class TimelineFlameChartDataProvider extends Common.ObjectWrapper.ObjectW
|
|
1002
1011
|
if (frame.idle) {
|
1003
1012
|
title = i18nString(UIStrings.idleFrame);
|
1004
1013
|
} else if (frame.dropped) {
|
1005
|
-
|
1014
|
+
if (frame.isPartial) {
|
1015
|
+
title = i18nString(UIStrings.partiallyPresentedFrame);
|
1016
|
+
} else {
|
1017
|
+
title = i18nString(UIStrings.droppedFrame);
|
1018
|
+
}
|
1006
1019
|
nameSpanTimelineInfoTime = 'timeline-info-warning';
|
1007
1020
|
} else {
|
1008
1021
|
title = i18nString(UIStrings.frame);
|
@@ -1093,6 +1106,42 @@ export class TimelineFlameChartDataProvider extends Common.ObjectWrapper.ObjectW
|
|
1093
1106
|
return key ? `hsl(${Platform.StringUtilities.hashCode(key) % 300 + 30}, 40%, 70%)` : '#ccc';
|
1094
1107
|
}
|
1095
1108
|
|
1109
|
+
private preparePatternCanvas(): void {
|
1110
|
+
// Set the candy stripe pattern to 17px so it repeats well.
|
1111
|
+
const size = 17;
|
1112
|
+
this.droppedFramePatternCanvas.width = size;
|
1113
|
+
this.droppedFramePatternCanvas.height = size;
|
1114
|
+
|
1115
|
+
this.partialFramePatternCanvas.width = size;
|
1116
|
+
this.partialFramePatternCanvas.height = size;
|
1117
|
+
|
1118
|
+
const ctx = this.droppedFramePatternCanvas.getContext('2d');
|
1119
|
+
if (ctx) {
|
1120
|
+
// Make a dense solid-line pattern.
|
1121
|
+
ctx.translate(size * 0.5, size * 0.5);
|
1122
|
+
ctx.rotate(Math.PI * 0.25);
|
1123
|
+
ctx.translate(-size * 0.5, -size * 0.5);
|
1124
|
+
|
1125
|
+
ctx.fillStyle = 'rgb(255, 255, 255)';
|
1126
|
+
for (let x = -size; x < size * 2; x += 3) {
|
1127
|
+
ctx.fillRect(x, -size, 1, size * 3);
|
1128
|
+
}
|
1129
|
+
}
|
1130
|
+
|
1131
|
+
const ctx2 = this.partialFramePatternCanvas.getContext('2d');
|
1132
|
+
if (ctx2) {
|
1133
|
+
// Make a sparse dashed-line pattern.
|
1134
|
+
ctx2.strokeStyle = 'rgb(255, 255, 255)';
|
1135
|
+
ctx2.lineWidth = 2;
|
1136
|
+
ctx2.beginPath();
|
1137
|
+
ctx2.moveTo(17, 0);
|
1138
|
+
ctx2.lineTo(10, 7);
|
1139
|
+
ctx2.moveTo(8, 9);
|
1140
|
+
ctx2.lineTo(2, 15);
|
1141
|
+
ctx2.stroke();
|
1142
|
+
}
|
1143
|
+
}
|
1144
|
+
|
1096
1145
|
private drawFrame(
|
1097
1146
|
entryIndex: number, context: CanvasRenderingContext2D, text: string|null, barX: number, barY: number,
|
1098
1147
|
barWidth: number, barHeight: number): void {
|
@@ -1100,8 +1149,31 @@ export class TimelineFlameChartDataProvider extends Common.ObjectWrapper.ObjectW
|
|
1100
1149
|
const frame = (this.entryData[entryIndex] as TimelineModel.TimelineFrameModel.TimelineFrame);
|
1101
1150
|
barX += hPadding;
|
1102
1151
|
barWidth -= 2 * hPadding;
|
1103
|
-
|
1104
|
-
|
1152
|
+
if (frame.idle) {
|
1153
|
+
context.fillStyle = 'white';
|
1154
|
+
} else if (frame.dropped) {
|
1155
|
+
if (frame.isPartial) {
|
1156
|
+
// For partially presented frame boxes, paint a yellow background with
|
1157
|
+
// a sparse white dashed-line pattern overlay.
|
1158
|
+
context.fillStyle = '#f0e442';
|
1159
|
+
context.fillRect(barX, barY, barWidth, barHeight);
|
1160
|
+
|
1161
|
+
const overlay = context.createPattern(this.partialFramePatternCanvas, 'repeat');
|
1162
|
+
context.fillStyle = overlay || context.fillStyle;
|
1163
|
+
} else {
|
1164
|
+
// For dropped frame boxes, paint a red background with a dense white
|
1165
|
+
// solid-line pattern overlay.
|
1166
|
+
context.fillStyle = '#f08080';
|
1167
|
+
context.fillRect(barX, barY, barWidth, barHeight);
|
1168
|
+
|
1169
|
+
const overlay = context.createPattern(this.droppedFramePatternCanvas, 'repeat');
|
1170
|
+
context.fillStyle = overlay || context.fillStyle;
|
1171
|
+
}
|
1172
|
+
} else if (frame.hasWarnings()) {
|
1173
|
+
context.fillStyle = '#fad1d1';
|
1174
|
+
} else {
|
1175
|
+
context.fillStyle = '#d7f0d1';
|
1176
|
+
}
|
1105
1177
|
context.fillRect(barX, barY, barWidth, barHeight);
|
1106
1178
|
|
1107
1179
|
const frameDurationText = i18n.TimeUtilities.preciseMillisToString(frame.duration, 1);
|
@@ -120,18 +120,6 @@
|
|
120
120
|
padding: 5px 10px 0 0;
|
121
121
|
}
|
122
122
|
|
123
|
-
.text-button {
|
124
|
-
float: right;
|
125
|
-
white-space: nowrap;
|
126
|
-
overflow: hidden;
|
127
|
-
min-width: 28px;
|
128
|
-
background: transparent;
|
129
|
-
border: none;
|
130
|
-
color: var(--color-link);
|
131
|
-
text-decoration: underline;
|
132
|
-
cursor: pointer;
|
133
|
-
}
|
134
|
-
|
135
123
|
td .text-button {
|
136
124
|
min-width: 20px;
|
137
125
|
margin: auto;
|
@@ -0,0 +1,107 @@
|
|
1
|
+
// Copyright (c) 2022 The Chromium Authors. All rights reserved.
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
3
|
+
// found in the LICENSE file.
|
4
|
+
|
5
|
+
import * as puppeteer from '../../third_party/puppeteer/puppeteer.js';
|
6
|
+
import type * as Protocol from '../../generated/protocol.js';
|
7
|
+
import type * as SDK from '../../core/sdk/sdk.js';
|
8
|
+
|
9
|
+
export class Transport implements puppeteer.ConnectionTransport {
|
10
|
+
#connection: SDK.Connections.ParallelConnectionInterface;
|
11
|
+
#knownIds = new Set<number>();
|
12
|
+
|
13
|
+
constructor(connection: SDK.Connections.ParallelConnectionInterface) {
|
14
|
+
this.#connection = connection;
|
15
|
+
}
|
16
|
+
|
17
|
+
send(message: string): void {
|
18
|
+
const data = JSON.parse(message);
|
19
|
+
this.#knownIds.add(data.id);
|
20
|
+
this.#connection.sendRawMessage(JSON.stringify(data));
|
21
|
+
}
|
22
|
+
|
23
|
+
close(): void {
|
24
|
+
void this.#connection.disconnect();
|
25
|
+
}
|
26
|
+
|
27
|
+
set onmessage(cb: (message: string) => void) {
|
28
|
+
this.#connection.setOnMessage((message: Object) => {
|
29
|
+
if (!cb) {
|
30
|
+
return;
|
31
|
+
}
|
32
|
+
const data = (message) as {id: number, method: string, params: unknown, sessionId?: string};
|
33
|
+
if (data.id && !this.#knownIds.has(data.id)) {
|
34
|
+
return;
|
35
|
+
}
|
36
|
+
this.#knownIds.delete(data.id);
|
37
|
+
if (!data.sessionId) {
|
38
|
+
return;
|
39
|
+
}
|
40
|
+
return cb(JSON.stringify({
|
41
|
+
...data,
|
42
|
+
// Puppeteer is expecting to use the default session, but we give it a non-default session in #connection.
|
43
|
+
// Replace that sessionId with undefined so Puppeteer treats it as default.
|
44
|
+
sessionId: data.sessionId === this.#connection.getSessionId() ? undefined : data.sessionId,
|
45
|
+
}));
|
46
|
+
});
|
47
|
+
}
|
48
|
+
|
49
|
+
set onclose(cb: () => void) {
|
50
|
+
const prev = this.#connection.getOnDisconnect();
|
51
|
+
this.#connection.setOnDisconnect(reason => {
|
52
|
+
if (prev) {
|
53
|
+
prev(reason);
|
54
|
+
}
|
55
|
+
if (cb) {
|
56
|
+
cb();
|
57
|
+
}
|
58
|
+
});
|
59
|
+
}
|
60
|
+
}
|
61
|
+
|
62
|
+
export class PuppeteerConnection extends puppeteer.Connection {
|
63
|
+
// Overriding Puppeteer's API here.
|
64
|
+
// eslint-disable-next-line rulesdir/no_underscored_properties
|
65
|
+
async _onMessage(message: string): Promise<void> {
|
66
|
+
const msgObj = JSON.parse(message) as {id: number, method: string, params: unknown, sessionId?: string};
|
67
|
+
if (msgObj.sessionId && !this._sessions.has(msgObj.sessionId)) {
|
68
|
+
return;
|
69
|
+
}
|
70
|
+
void super._onMessage(message);
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
export async function getPuppeteerConnection(
|
75
|
+
rawConnection: SDK.Connections.ParallelConnectionInterface,
|
76
|
+
mainFrameId: string,
|
77
|
+
mainTargetId: string,
|
78
|
+
): Promise<{page: puppeteer.Page | null, browser: puppeteer.Browser}> {
|
79
|
+
const transport = new Transport(rawConnection);
|
80
|
+
|
81
|
+
// url is an empty string in this case parallel to:
|
82
|
+
// https://github.com/puppeteer/puppeteer/blob/f63a123ecef86693e6457b07437a96f108f3e3c5/src/common/BrowserConnector.ts#L72
|
83
|
+
const connection = new PuppeteerConnection('', transport);
|
84
|
+
|
85
|
+
const targetFilterCallback = (targetInfo: Protocol.Target.TargetInfo): boolean => {
|
86
|
+
if (targetInfo.type !== 'page' && targetInfo.type !== 'iframe') {
|
87
|
+
return false;
|
88
|
+
}
|
89
|
+
// TODO only connect to iframes that are related to the main target. This requires refactoring in Puppeteer: https://github.com/puppeteer/puppeteer/issues/3667.
|
90
|
+
return targetInfo.targetId === mainTargetId || targetInfo.openerId === mainTargetId || targetInfo.type === 'iframe';
|
91
|
+
};
|
92
|
+
|
93
|
+
const browser = await puppeteer.Browser.create(
|
94
|
+
connection,
|
95
|
+
[] /* contextIds */,
|
96
|
+
false /* ignoreHTTPSErrors */,
|
97
|
+
undefined /* defaultViewport */,
|
98
|
+
undefined /* process */,
|
99
|
+
undefined /* closeCallback */,
|
100
|
+
targetFilterCallback,
|
101
|
+
);
|
102
|
+
|
103
|
+
const pages = await browser.pages();
|
104
|
+
const page = pages.find(p => p.mainFrame()._id === mainFrameId) || null;
|
105
|
+
|
106
|
+
return {page, browser};
|
107
|
+
}
|
@@ -0,0 +1,9 @@
|
|
1
|
+
// Copyright (c) 2022 The Chromium Authors. All rights reserved.
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
3
|
+
// found in the LICENSE file.
|
4
|
+
|
5
|
+
import * as PuppeteerConnection from './PuppeteerConnection.js';
|
6
|
+
|
7
|
+
export {
|
8
|
+
PuppeteerConnection,
|
9
|
+
};
|
@@ -3,15 +3,11 @@
|
|
3
3
|
text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px;
|
4
4
|
font-family: arial;
|
5
5
|
line-height: .3;
|
6
|
-
cursor: pointer;
|
7
6
|
}
|
8
7
|
.CodeMirror-foldgutter {
|
9
8
|
width: .7em;
|
10
9
|
}
|
11
|
-
|
12
|
-
.CodeMirror-foldgutter-folded {
|
13
|
-
cursor: pointer;
|
14
|
-
}
|
10
|
+
|
15
11
|
.CodeMirror-foldgutter-open:after {
|
16
12
|
content: "\25BE";
|
17
13
|
}
|
@@ -16,3 +16,13 @@ To update this package, adjust the version ranges in package.json if necessary,
|
|
16
16
|
```
|
17
17
|
|
18
18
|
It will use npm to locally install the necessary packages and their dependencies, and bundle them into a single file (codemirror.js and codemirror.d.ts) with rollup.
|
19
|
+
|
20
|
+
If you want to easily obtain all the latest versions of the packages, run the following:
|
21
|
+
|
22
|
+
```
|
23
|
+
npm i
|
24
|
+
npm outdated
|
25
|
+
```
|
26
|
+
|
27
|
+
This will show you a table with all the latest versions of each package.
|
28
|
+
You will need to manually update the versions in the `package.json` file.
|