chrome-devtools-frontend 1.0.1535712 → 1.0.1536371
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/docs/contributing/images/issues-nearestslo.png +0 -0
- package/docs/contributing/issues.md +17 -21
- package/front_end/core/common/Console.ts +1 -8
- package/front_end/core/common/ParsedURL.ts +10 -20
- package/front_end/core/common/SegmentedRange.ts +1 -2
- package/front_end/core/common/StringOutputStream.ts +1 -4
- package/front_end/core/i18n/i18nImpl.ts +0 -24
- package/front_end/core/sdk/AnimationModel.ts +1 -2
- package/front_end/core/sdk/CSSMatchedStyles.ts +2 -2
- package/front_end/core/sdk/CSSModel.ts +1 -1
- package/front_end/core/sdk/CSSProperty.ts +3 -6
- package/front_end/core/sdk/CSSStyleDeclaration.ts +4 -4
- package/front_end/core/sdk/DebuggerModel.ts +1 -2
- package/front_end/core/sdk/EnhancedTracesParser.ts +4 -0
- package/front_end/core/sdk/SourceMap.ts +2 -3
- package/front_end/entrypoints/node_app/NodeConnectionsPanel.ts +2 -1
- package/front_end/generated/InspectorBackendCommands.js +1 -2
- package/front_end/generated/SupportedCSSProperties.js +19 -0
- package/front_end/generated/protocol.ts +0 -27
- package/front_end/panels/accessibility/AccessibilityNodeView.ts +18 -17
- package/front_end/panels/accessibility/AccessibilitySidebarView.ts +9 -12
- package/front_end/panels/ai_assistance/components/ChatView.ts +5 -4
- package/front_end/panels/application/AppManifestView.ts +7 -6
- package/front_end/panels/application/ApplicationPanelSidebar.ts +4 -4
- package/front_end/panels/application/OpenedWindowDetailsView.ts +6 -6
- package/front_end/panels/application/StorageView.ts +9 -8
- package/front_end/panels/application/components/BackForwardCacheView.ts +333 -314
- package/front_end/panels/application/components/ProtocolHandlersView.ts +3 -2
- package/front_end/panels/application/preloading/components/PreloadingDisabledInfobar.ts +2 -1
- package/front_end/panels/browser_debugger/ObjectEventListenersSidebarPane.ts +8 -8
- package/front_end/panels/common/BadgeNotification.ts +2 -1
- package/front_end/panels/common/GdpSignUpDialog.ts +2 -1
- package/front_end/panels/console/ConsoleInsightTeaser.ts +8 -2
- package/front_end/panels/console/ConsolePinPane.ts +12 -7
- package/front_end/panels/developer_resources/DeveloperResourcesView.ts +9 -9
- package/front_end/panels/elements/ComputedStyleWidget.ts +7 -7
- package/front_end/panels/elements/EventListenersWidget.ts +9 -9
- package/front_end/panels/elements/NodeStackTraceWidget.ts +6 -6
- package/front_end/panels/elements/PlatformFontsWidget.ts +5 -5
- package/front_end/panels/elements/PropertiesWidget.ts +8 -8
- package/front_end/panels/layer_viewer/Layers3DView.ts +2 -1
- package/front_end/panels/layer_viewer/PaintProfilerView.ts +3 -3
- package/front_end/panels/network/RequestCookiesView.ts +2 -1
- package/front_end/panels/network/RequestTimingView.ts +2 -1
- package/front_end/panels/recorder/RecorderController.ts +34 -23
- package/front_end/panels/recorder/components/CreateRecordingView.ts +249 -240
- package/front_end/panels/security/CookieControlsView.ts +2 -1
- package/front_end/panels/security/CookieReportView.ts +3 -2
- package/front_end/panels/settings/AISettingsTab.ts +2 -1
- package/front_end/panels/settings/KeybindsSettingsTab.ts +6 -0
- package/front_end/panels/settings/components/SyncSection.ts +2 -1
- package/front_end/panels/sources/DebuggerPausedMessage.ts +4 -3
- package/front_end/panels/sources/ResourceOriginPlugin.ts +3 -2
- package/front_end/panels/sources/SourcesNavigator.ts +2 -1
- package/front_end/panels/sources/TabbedEditorContainer.ts +3 -2
- package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +9 -9
- package/front_end/panels/timeline/TimelineUIUtils.ts +3 -2
- package/front_end/panels/timeline/components/DetailsView.ts +5 -4
- package/front_end/panels/timeline/components/FieldSettingsDialog.ts +2 -1
- package/front_end/panels/timeline/components/LiveMetricsView.ts +5 -4
- package/front_end/panels/timeline/components/MetricCompareStrings.ts +25 -24
- package/front_end/panels/timeline/components/insights/LCPDiscovery.ts +2 -1
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/components/docs/tooltip/basic.ts +1 -1
- package/front_end/ui/components/tooltips/Tooltip.ts +32 -17
- package/front_end/ui/i18n/i18n.ts +31 -0
- package/front_end/ui/legacy/SoftDropDown.ts +1 -12
- package/front_end/ui/legacy/ViewManager.ts +2 -4
- package/front_end/ui/legacy/Widget.ts +33 -17
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +2 -1
- package/front_end/ui/legacy/legacy.ts +0 -2
- package/front_end/ui/visual_logging/KnownContextValues.ts +3 -0
- package/mcp/mcp.ts +1 -0
- package/package.json +1 -1
- package/front_end/ui/components/docs/recorder_create_recording_view/basic.html +0 -20
- package/front_end/ui/components/docs/recorder_create_recording_view/basic.ts +0 -27
- package/front_end/ui/legacy/ThrottledWidget.ts +0 -48
|
@@ -154,10 +154,322 @@ const enum ScreenStatusType {
|
|
|
154
154
|
RESULT = 'Result',
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
function renderMainFrameInformation(
|
|
158
|
+
frame: SDK.ResourceTreeModel.ResourceTreeFrame|null,
|
|
159
|
+
frameTreeData: {node: FrameTreeNodeData, frameCount: number, issueCount: number}|undefined,
|
|
160
|
+
reasonToFramesMap: Map<Protocol.Page.BackForwardCacheNotRestoredReason, string[]>, screenStatus: ScreenStatusType,
|
|
161
|
+
navigateAwayAndBack: () => Promise<void>): Lit.TemplateResult {
|
|
162
|
+
if (!frame) {
|
|
163
|
+
// clang-format of
|
|
164
|
+
return html`
|
|
165
|
+
<devtools-report-key>
|
|
166
|
+
${i18nString(UIStrings.mainFrame)}
|
|
167
|
+
</devtools-report-key>
|
|
168
|
+
<devtools-report-value>
|
|
169
|
+
${i18nString(UIStrings.unavailable)}
|
|
170
|
+
</devtools-report-value>`;
|
|
171
|
+
// clang-format on
|
|
172
|
+
}
|
|
173
|
+
const isTestRunning = (screenStatus === ScreenStatusType.RUNNING);
|
|
174
|
+
// Prevent running BFCache test on the DevTools window itself via DevTools on DevTools
|
|
175
|
+
const isTestingForbidden = Common.ParsedURL.schemeIs(frame.url, 'devtools:');
|
|
176
|
+
// clang-format off
|
|
177
|
+
return html`
|
|
178
|
+
${renderBackForwardCacheStatus(frame.backForwardCacheDetails.restoredFromCache)}
|
|
179
|
+
<devtools-report-key>${i18nString(UIStrings.url)}</devtools-report-key>
|
|
180
|
+
<devtools-report-value>${frame.url}</devtools-report-value>
|
|
181
|
+
${maybeRenderFrameTree(frameTreeData)}
|
|
182
|
+
<devtools-report-section>
|
|
183
|
+
<devtools-button
|
|
184
|
+
aria-label=${i18nString(UIStrings.runTest)}
|
|
185
|
+
.disabled=${isTestRunning || isTestingForbidden}
|
|
186
|
+
.spinner=${isTestRunning}
|
|
187
|
+
.variant=${Buttons.Button.Variant.PRIMARY}
|
|
188
|
+
@click=${navigateAwayAndBack}
|
|
189
|
+
jslog=${VisualLogging.action('back-forward-cache.run-test').track({click: true})}>
|
|
190
|
+
${isTestRunning ? html`
|
|
191
|
+
${i18nString(UIStrings.runningTest)}`:`
|
|
192
|
+
${i18nString(UIStrings.runTest)}
|
|
193
|
+
`}
|
|
194
|
+
</devtools-button>
|
|
195
|
+
</devtools-report-section>
|
|
196
|
+
<devtools-report-divider>
|
|
197
|
+
</devtools-report-divider>
|
|
198
|
+
${maybeRenderExplanations(frame.backForwardCacheDetails.explanations,
|
|
199
|
+
frame.backForwardCacheDetails.explanationsTree,
|
|
200
|
+
reasonToFramesMap)}
|
|
201
|
+
<devtools-report-section>
|
|
202
|
+
<x-link href="https://web.dev/bfcache/" class="link"
|
|
203
|
+
jslog=${VisualLogging.action('learn-more.eligibility').track({click: true})}>
|
|
204
|
+
${i18nString(UIStrings.learnMore)}
|
|
205
|
+
</x-link>
|
|
206
|
+
</devtools-report-section>`;
|
|
207
|
+
// clang-format on
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function maybeRenderFrameTree(
|
|
211
|
+
frameTreeData: {node: FrameTreeNodeData, frameCount: number, issueCount: number}|undefined): Lit.LitTemplate {
|
|
212
|
+
if (!frameTreeData || (frameTreeData.frameCount === 0 && frameTreeData.issueCount === 0)) {
|
|
213
|
+
return Lit.nothing;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
function treeNodeRenderer(node: TreeOutline.TreeOutlineUtils.TreeNode<FrameTreeNodeData>): Lit.TemplateResult {
|
|
217
|
+
// clang-format off
|
|
218
|
+
return html`
|
|
219
|
+
<div class="text-ellipsis">
|
|
220
|
+
${node.treeNodeData.iconName ? html`
|
|
221
|
+
<devtools-icon class="inline-icon extra-large" .name=${node.treeNodeData.iconName} style="margin-bottom: -3px;">
|
|
222
|
+
</devtools-icon>
|
|
223
|
+
` : Lit.nothing}
|
|
224
|
+
${node.treeNodeData.text}
|
|
225
|
+
</div>`;
|
|
226
|
+
// clang-format on
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const frameTreeNode = buildFrameTree(frameTreeData.node);
|
|
230
|
+
// Override the icon for the outermost frame.
|
|
231
|
+
frameTreeNode.treeNodeData.iconName = 'frame';
|
|
232
|
+
let title = '';
|
|
233
|
+
// The translation pipeline does not support nested plurals. We avoid this
|
|
234
|
+
// here by pulling out the logic for one of the plurals into code instead.
|
|
235
|
+
if (frameTreeData.frameCount === 1) {
|
|
236
|
+
title = i18nString(UIStrings.issuesInSingleFrame, {n: frameTreeData.issueCount});
|
|
237
|
+
} else {
|
|
238
|
+
title = i18nString(UIStrings.issuesInMultipleFrames, {n: frameTreeData.issueCount, m: frameTreeData.frameCount});
|
|
239
|
+
}
|
|
240
|
+
const root: TreeOutline.TreeOutlineUtils.TreeNode<FrameTreeNodeData> = {
|
|
241
|
+
treeNodeData: {
|
|
242
|
+
text: title,
|
|
243
|
+
},
|
|
244
|
+
id: 'root',
|
|
245
|
+
children: () => Promise.resolve([frameTreeNode]),
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
// clang-format off
|
|
249
|
+
return html`
|
|
250
|
+
<devtools-report-key jslog=${VisualLogging.section('frames')}>${i18nString(UIStrings.framesTitle)}</devtools-report-key>
|
|
251
|
+
<devtools-report-value>
|
|
252
|
+
<devtools-tree-outline .data=${{
|
|
253
|
+
tree: [root],
|
|
254
|
+
defaultRenderer: treeNodeRenderer,
|
|
255
|
+
compact: true,
|
|
256
|
+
} as TreeOutline.TreeOutline.TreeOutlineData<FrameTreeNodeData>}>
|
|
257
|
+
</devtools-tree-outline>
|
|
258
|
+
</devtools-report-value>`;
|
|
259
|
+
// clang-format on
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
let nextNodeId = 0;
|
|
263
|
+
|
|
264
|
+
function buildFrameTree(data: FrameTreeNodeData): TreeOutline.TreeOutlineUtils.TreeNode<FrameTreeNodeData> {
|
|
265
|
+
const children = data.children;
|
|
266
|
+
const node = {
|
|
267
|
+
treeNodeData: {
|
|
268
|
+
text: data.text,
|
|
269
|
+
...(data.iconName ? {iconName: data.iconName} : {}),
|
|
270
|
+
},
|
|
271
|
+
...(children?.length ? {children: () => Promise.resolve(children.map(child => buildFrameTree(child)))} : {}),
|
|
272
|
+
id: String(nextNodeId++),
|
|
273
|
+
};
|
|
274
|
+
return node;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function renderBackForwardCacheStatus(status: boolean|undefined): Lit.TemplateResult {
|
|
278
|
+
switch (status) {
|
|
279
|
+
case true:
|
|
280
|
+
// clang-format off
|
|
281
|
+
return html`
|
|
282
|
+
<devtools-report-section>
|
|
283
|
+
<div class="status extra-large">
|
|
284
|
+
<devtools-icon class="inline-icon extra-large" name="check-circle" style="color: var(--icon-checkmark-green);">
|
|
285
|
+
</devtools-icon>
|
|
286
|
+
</div>
|
|
287
|
+
${i18nString(UIStrings.restoredFromBFCache)}
|
|
288
|
+
</devtools-report-section>`;
|
|
289
|
+
// clang-format on
|
|
290
|
+
case false:
|
|
291
|
+
// clang-format off
|
|
292
|
+
return html`
|
|
293
|
+
<devtools-report-section>
|
|
294
|
+
<div class="status">
|
|
295
|
+
<devtools-icon class="inline-icon extra-large" name="clear">
|
|
296
|
+
</devtools-icon>
|
|
297
|
+
</div>
|
|
298
|
+
${i18nString(UIStrings.normalNavigation)}
|
|
299
|
+
</devtools-report-section>`;
|
|
300
|
+
// clang-format on
|
|
301
|
+
}
|
|
302
|
+
// clang-format off
|
|
303
|
+
return html`
|
|
304
|
+
<devtools-report-section>
|
|
305
|
+
${i18nString(UIStrings.unknown)}
|
|
306
|
+
</devtools-report-section>`;
|
|
307
|
+
// clang-format on
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
function maybeRenderExplanations(
|
|
311
|
+
explanations: Protocol.Page.BackForwardCacheNotRestoredExplanation[],
|
|
312
|
+
explanationTree: Protocol.Page.BackForwardCacheNotRestoredExplanationTree|undefined,
|
|
313
|
+
reasonToFramesMap: Map<Protocol.Page.BackForwardCacheNotRestoredReason, string[]>): Lit.LitTemplate {
|
|
314
|
+
if (explanations.length === 0) {
|
|
315
|
+
return Lit.nothing;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const pageSupportNeeded = explanations.filter(
|
|
319
|
+
explanation => explanation.type === Protocol.Page.BackForwardCacheNotRestoredReasonType.PageSupportNeeded);
|
|
320
|
+
const supportPending = explanations.filter(
|
|
321
|
+
explanation => explanation.type === Protocol.Page.BackForwardCacheNotRestoredReasonType.SupportPending);
|
|
322
|
+
const circumstantial = explanations.filter(
|
|
323
|
+
explanation => explanation.type === Protocol.Page.BackForwardCacheNotRestoredReasonType.Circumstantial);
|
|
324
|
+
|
|
325
|
+
// Disabled until https://crbug.com/1079231 is fixed.
|
|
326
|
+
// clang-format off
|
|
327
|
+
return html`
|
|
328
|
+
${renderExplanations(i18nString(UIStrings.pageSupportNeeded), i18nString(UIStrings.pageSupportNeededExplanation), pageSupportNeeded, reasonToFramesMap)}
|
|
329
|
+
${renderExplanations(i18nString(UIStrings.supportPending), i18nString(UIStrings.supportPendingExplanation), supportPending, reasonToFramesMap)}
|
|
330
|
+
${renderExplanations(i18nString(UIStrings.circumstantial), i18nString(UIStrings.circumstantialExplanation), circumstantial, reasonToFramesMap)}`;
|
|
331
|
+
// clang-format on
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function renderExplanations(
|
|
335
|
+
category: Platform.UIString.LocalizedString, explainerText: Platform.UIString.LocalizedString,
|
|
336
|
+
explanations: Protocol.Page.BackForwardCacheNotRestoredExplanation[],
|
|
337
|
+
reasonToFramesMap: Map<Protocol.Page.BackForwardCacheNotRestoredReason, string[]>): Lit.TemplateResult {
|
|
338
|
+
// Disabled until https://crbug.com/1079231 is fixed.
|
|
339
|
+
// clang-format off
|
|
340
|
+
return html`
|
|
341
|
+
${explanations.length > 0 ? html`
|
|
342
|
+
<devtools-report-section-header>
|
|
343
|
+
${category}
|
|
344
|
+
<div class="help-outline-icon">
|
|
345
|
+
<devtools-icon class="inline-icon medium" name="help" title=${explainerText}>
|
|
346
|
+
</devtools-icon>
|
|
347
|
+
</div>
|
|
348
|
+
</devtools-report-section-header>
|
|
349
|
+
${explanations.map(explanation => renderReason(explanation, reasonToFramesMap.get(explanation.reason)))}
|
|
350
|
+
` : Lit.nothing}`;
|
|
351
|
+
// clang-format on
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
function maybeRenderReasonContext(explanation: Protocol.Page.BackForwardCacheNotRestoredExplanation): Lit.LitTemplate {
|
|
355
|
+
if (explanation.reason ===
|
|
356
|
+
Protocol.Page.BackForwardCacheNotRestoredReason.EmbedderExtensionSentMessageToCachedFrame &&
|
|
357
|
+
explanation.context) {
|
|
358
|
+
const link = 'chrome://extensions/?id=' + explanation.context as Platform.DevToolsPath.UrlString;
|
|
359
|
+
// clang-format off
|
|
360
|
+
return html`${i18nString(UIStrings.blockingExtensionId)}
|
|
361
|
+
<devtools-chrome-link .href=${link}>${explanation.context}</devtools-chrome-link>`;
|
|
362
|
+
// clang-format on
|
|
363
|
+
}
|
|
364
|
+
return Lit.nothing;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function renderFramesPerReason(frames: string[]|undefined): Lit.LitTemplate {
|
|
368
|
+
if (frames === undefined || frames.length === 0) {
|
|
369
|
+
return Lit.nothing;
|
|
370
|
+
}
|
|
371
|
+
const rows = [html`<div>${i18nString(UIStrings.framesPerIssue, {n: frames.length})}</div>`];
|
|
372
|
+
rows.push(...frames.map(url => html`<div class="text-ellipsis" title=${url}
|
|
373
|
+
jslog=${VisualLogging.treeItem()}>${url}</div>`));
|
|
374
|
+
return html`
|
|
375
|
+
<div class="details-list"
|
|
376
|
+
jslog=${VisualLogging.tree('frames-per-issue')}>
|
|
377
|
+
<devtools-expandable-list .data=${{
|
|
378
|
+
rows,
|
|
379
|
+
title: i18nString(UIStrings.framesPerIssue, {n: frames.length}),
|
|
380
|
+
} as ExpandableList.ExpandableList.ExpandableListData}
|
|
381
|
+
jslog=${VisualLogging.treeItem()}></devtools-expandable-list>
|
|
382
|
+
</div>
|
|
383
|
+
`;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function maybeRenderDeepLinkToUnload(explanation: Protocol.Page.BackForwardCacheNotRestoredExplanation):
|
|
387
|
+
Lit.LitTemplate {
|
|
388
|
+
if (explanation.reason === Protocol.Page.BackForwardCacheNotRestoredReason.UnloadHandlerExistsInMainFrame ||
|
|
389
|
+
explanation.reason === Protocol.Page.BackForwardCacheNotRestoredReason.UnloadHandlerExistsInSubFrame) {
|
|
390
|
+
return html`
|
|
391
|
+
<x-link href="https://web.dev/bfcache/#never-use-the-unload-event" class="link"
|
|
392
|
+
jslog=${VisualLogging.action('learn-more.never-use-unload').track({
|
|
393
|
+
click: true,
|
|
394
|
+
})}>
|
|
395
|
+
${i18nString(UIStrings.neverUseUnload)}
|
|
396
|
+
</x-link>`;
|
|
397
|
+
}
|
|
398
|
+
return Lit.nothing;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
function maybeRenderJavaScriptDetails(details: Protocol.Page.BackForwardCacheBlockingDetails[]|undefined):
|
|
402
|
+
Lit.LitTemplate {
|
|
403
|
+
if (details === undefined || details.length === 0) {
|
|
404
|
+
return Lit.nothing;
|
|
405
|
+
}
|
|
406
|
+
const maxLengthForDisplayedURLs = 50;
|
|
407
|
+
const linkifier = new Components.Linkifier.Linkifier(maxLengthForDisplayedURLs);
|
|
408
|
+
const rows = [html`<div>${i18nString(UIStrings.filesPerIssue, {n: details.length})}</div>`];
|
|
409
|
+
rows.push(...details.map(
|
|
410
|
+
detail => html`${
|
|
411
|
+
linkifier.linkifyScriptLocation(
|
|
412
|
+
null, null, detail.url as Platform.DevToolsPath.UrlString, detail.lineNumber, {
|
|
413
|
+
columnNumber: detail.columnNumber,
|
|
414
|
+
showColumnNumber: true,
|
|
415
|
+
inlineFrameIndex: 0,
|
|
416
|
+
})}`));
|
|
417
|
+
return html`
|
|
418
|
+
<div class="details-list">
|
|
419
|
+
<devtools-expandable-list .data=${
|
|
420
|
+
{rows} as ExpandableList.ExpandableList.ExpandableListData}></devtools-expandable-list>
|
|
421
|
+
</div>
|
|
422
|
+
`;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function renderReason(
|
|
426
|
+
explanation: Protocol.Page.BackForwardCacheNotRestoredExplanation, frames: string[]|undefined): Lit.TemplateResult {
|
|
427
|
+
// clang-format off
|
|
428
|
+
return html`
|
|
429
|
+
<devtools-report-section>
|
|
430
|
+
${(explanation.reason in NotRestoredReasonDescription) ?
|
|
431
|
+
html`
|
|
432
|
+
<div class="circled-exclamation-icon">
|
|
433
|
+
<devtools-icon class="inline-icon medium" style="color: var(--icon-warning)" name="warning">
|
|
434
|
+
</devtools-icon>
|
|
435
|
+
</div>
|
|
436
|
+
<div>
|
|
437
|
+
${NotRestoredReasonDescription[explanation.reason].name()}
|
|
438
|
+
${maybeRenderDeepLinkToUnload(explanation)}
|
|
439
|
+
${maybeRenderReasonContext(explanation)}
|
|
440
|
+
</div>` :
|
|
441
|
+
Lit.nothing}
|
|
442
|
+
</devtools-report-section>
|
|
443
|
+
<div class="gray-text">
|
|
444
|
+
${explanation.reason}
|
|
445
|
+
</div>
|
|
446
|
+
${maybeRenderJavaScriptDetails(explanation.details)}
|
|
447
|
+
${renderFramesPerReason(frames)}`;
|
|
448
|
+
// clang-format on
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
function renderBackForwardCacheView(
|
|
452
|
+
frame: SDK.ResourceTreeModel.ResourceTreeFrame|null,
|
|
453
|
+
frameTreeData: {node: FrameTreeNodeData, frameCount: number, issueCount: number}|undefined,
|
|
454
|
+
reasonToFramesMap: Map<Protocol.Page.BackForwardCacheNotRestoredReason, string[]>, screenStatus: ScreenStatusType,
|
|
455
|
+
navigateAwayAndBack: () => Promise<void>, target: ShadowRoot): void {
|
|
456
|
+
// Disabled until https://crbug.com/1079231 is fixed.
|
|
457
|
+
// clang-format off
|
|
458
|
+
Lit.render(html`
|
|
459
|
+
<style>${backForwardCacheViewStyles}</style>
|
|
460
|
+
<devtools-report .data=${
|
|
461
|
+
{reportTitle: i18nString(UIStrings.backForwardCacheTitle)} as ReportView.ReportView.ReportData
|
|
462
|
+
} jslog=${VisualLogging.pane('back-forward-cache')}>
|
|
463
|
+
|
|
464
|
+
${renderMainFrameInformation(frame, frameTreeData, reasonToFramesMap, screenStatus, navigateAwayAndBack)}
|
|
465
|
+
</devtools-report>
|
|
466
|
+
`, target);
|
|
467
|
+
// clang-format on
|
|
468
|
+
}
|
|
469
|
+
|
|
157
470
|
export class BackForwardCacheView extends LegacyWrapper.LegacyWrapper.WrappableComponent {
|
|
158
471
|
readonly #shadow = this.attachShadow({mode: 'open'});
|
|
159
472
|
#screenStatus = ScreenStatusType.RESULT;
|
|
160
|
-
#nextNodeId = 0;
|
|
161
473
|
#historyIndex = 0;
|
|
162
474
|
|
|
163
475
|
constructor() {
|
|
@@ -182,18 +494,14 @@ export class BackForwardCacheView extends LegacyWrapper.LegacyWrapper.WrappableC
|
|
|
182
494
|
|
|
183
495
|
override async render(): Promise<void> {
|
|
184
496
|
await RenderCoordinator.write('BackForwardCacheView render', () => {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
${this.#renderMainFrameInformation()}
|
|
194
|
-
</devtools-report>
|
|
195
|
-
`, this.#shadow, {host: this});
|
|
196
|
-
// clang-format on
|
|
497
|
+
const reasonToFramesMap = new Map<Protocol.Page.BackForwardCacheNotRestoredReason, string[]>();
|
|
498
|
+
const explanationTree = this.#getMainFrame()?.backForwardCacheDetails?.explanationsTree;
|
|
499
|
+
if (explanationTree) {
|
|
500
|
+
this.#buildReasonToFramesMap(explanationTree, {blankCount: 1}, reasonToFramesMap);
|
|
501
|
+
}
|
|
502
|
+
renderBackForwardCacheView(
|
|
503
|
+
this.#getMainFrame(), this.#buildFrameTreeDataRecursive(explanationTree, {blankCount: 1}), reasonToFramesMap,
|
|
504
|
+
this.#screenStatus, this.#navigateAwayAndBack.bind(this), this.#shadow);
|
|
197
505
|
});
|
|
198
506
|
}
|
|
199
507
|
|
|
@@ -258,120 +566,17 @@ export class BackForwardCacheView extends LegacyWrapper.LegacyWrapper.WrappableC
|
|
|
258
566
|
void resourceTreeModel.navigate('chrome://terms' as Platform.DevToolsPath.UrlString);
|
|
259
567
|
}
|
|
260
568
|
|
|
261
|
-
#renderMainFrameInformation(): Lit.TemplateResult {
|
|
262
|
-
const frame = this.#getMainFrame();
|
|
263
|
-
if (!frame) {
|
|
264
|
-
// clang-format off
|
|
265
|
-
return html`
|
|
266
|
-
<devtools-report-key>
|
|
267
|
-
${i18nString(UIStrings.mainFrame)}
|
|
268
|
-
</devtools-report-key>
|
|
269
|
-
<devtools-report-value>
|
|
270
|
-
${i18nString(UIStrings.unavailable)}
|
|
271
|
-
</devtools-report-value>
|
|
272
|
-
`;
|
|
273
|
-
// clang-format on
|
|
274
|
-
}
|
|
275
|
-
const isTestRunning = (this.#screenStatus === ScreenStatusType.RUNNING);
|
|
276
|
-
// Prevent running BFCache test on the DevTools window itself via DevTools on DevTools
|
|
277
|
-
const isTestingForbidden = Common.ParsedURL.schemeIs(frame.url, 'devtools:');
|
|
278
|
-
// clang-format off
|
|
279
|
-
return html`
|
|
280
|
-
${this.#renderBackForwardCacheStatus(frame.backForwardCacheDetails.restoredFromCache)}
|
|
281
|
-
<devtools-report-key>${i18nString(UIStrings.url)}</devtools-report-key>
|
|
282
|
-
<devtools-report-value>${frame.url}</devtools-report-value>
|
|
283
|
-
${this.#maybeRenderFrameTree(frame.backForwardCacheDetails.explanationsTree)}
|
|
284
|
-
<devtools-report-section>
|
|
285
|
-
<devtools-button
|
|
286
|
-
aria-label=${i18nString(UIStrings.runTest)}
|
|
287
|
-
.disabled=${isTestRunning || isTestingForbidden}
|
|
288
|
-
.spinner=${isTestRunning}
|
|
289
|
-
.variant=${Buttons.Button.Variant.PRIMARY}
|
|
290
|
-
@click=${this.#navigateAwayAndBack}
|
|
291
|
-
jslog=${VisualLogging.action('back-forward-cache.run-test').track({click: true})}>
|
|
292
|
-
${isTestRunning ? html`
|
|
293
|
-
${i18nString(UIStrings.runningTest)}`:`
|
|
294
|
-
${i18nString(UIStrings.runTest)}
|
|
295
|
-
`}
|
|
296
|
-
</devtools-button>
|
|
297
|
-
</devtools-report-section>
|
|
298
|
-
<devtools-report-divider>
|
|
299
|
-
</devtools-report-divider>
|
|
300
|
-
${this.#maybeRenderExplanations(frame.backForwardCacheDetails.explanations,
|
|
301
|
-
frame.backForwardCacheDetails.explanationsTree)}
|
|
302
|
-
<devtools-report-section>
|
|
303
|
-
<x-link href="https://web.dev/bfcache/" class="link"
|
|
304
|
-
jslog=${VisualLogging.action('learn-more.eligibility').track({click: true})}>
|
|
305
|
-
${i18nString(UIStrings.learnMore)}
|
|
306
|
-
</x-link>
|
|
307
|
-
</devtools-report-section>
|
|
308
|
-
`;
|
|
309
|
-
// clang-format on
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
#maybeRenderFrameTree(explanationTree: Protocol.Page.BackForwardCacheNotRestoredExplanationTree|undefined):
|
|
313
|
-
Lit.LitTemplate {
|
|
314
|
-
if (!explanationTree || (explanationTree.explanations.length === 0 && explanationTree.children.length === 0)) {
|
|
315
|
-
return Lit.nothing;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
function treeNodeRenderer(node: TreeOutline.TreeOutlineUtils.TreeNode<FrameTreeNodeData>): Lit.TemplateResult {
|
|
319
|
-
// clang-format off
|
|
320
|
-
return html`
|
|
321
|
-
<div class="text-ellipsis">
|
|
322
|
-
${node.treeNodeData.iconName ? html`
|
|
323
|
-
<devtools-icon class="inline-icon extra-large" .name=${node.treeNodeData.iconName} style="margin-bottom: -3px;">
|
|
324
|
-
</devtools-icon>
|
|
325
|
-
` : Lit.nothing}
|
|
326
|
-
${node.treeNodeData.text}
|
|
327
|
-
</div>
|
|
328
|
-
`;
|
|
329
|
-
// clang-format on
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
const frameTreeData = this.#buildFrameTreeDataRecursive(explanationTree, {blankCount: 1});
|
|
333
|
-
// Override the icon for the outermost frame.
|
|
334
|
-
frameTreeData.node.treeNodeData.iconName = 'frame';
|
|
335
|
-
let title = '';
|
|
336
|
-
// The translation pipeline does not support nested plurals. We avoid this
|
|
337
|
-
// here by pulling out the logic for one of the plurals into code instead.
|
|
338
|
-
if (frameTreeData.frameCount === 1) {
|
|
339
|
-
title = i18nString(UIStrings.issuesInSingleFrame, {n: frameTreeData.issueCount});
|
|
340
|
-
} else {
|
|
341
|
-
title = i18nString(UIStrings.issuesInMultipleFrames, {n: frameTreeData.issueCount, m: frameTreeData.frameCount});
|
|
342
|
-
}
|
|
343
|
-
const root: TreeOutline.TreeOutlineUtils.TreeNode<FrameTreeNodeData> = {
|
|
344
|
-
treeNodeData: {
|
|
345
|
-
text: title,
|
|
346
|
-
},
|
|
347
|
-
id: 'root',
|
|
348
|
-
children: () => Promise.resolve([frameTreeData.node]),
|
|
349
|
-
};
|
|
350
|
-
|
|
351
|
-
// clang-format off
|
|
352
|
-
return html`
|
|
353
|
-
<devtools-report-key jslog=${VisualLogging.section('frames')}>${i18nString(UIStrings.framesTitle)}</devtools-report-key>
|
|
354
|
-
<devtools-report-value>
|
|
355
|
-
<devtools-tree-outline .data=${{
|
|
356
|
-
tree: [root],
|
|
357
|
-
defaultRenderer: treeNodeRenderer,
|
|
358
|
-
compact: true,
|
|
359
|
-
} as TreeOutline.TreeOutline.TreeOutlineData<FrameTreeNodeData>}>
|
|
360
|
-
</devtools-tree-outline>
|
|
361
|
-
</devtools-report-value>
|
|
362
|
-
`;
|
|
363
|
-
// clang-format on
|
|
364
|
-
}
|
|
365
|
-
|
|
366
569
|
// Builds a subtree of the frame tree, conaining only frames with BFCache issues and their ancestors.
|
|
367
570
|
// Returns the root node, the number of frames in the subtree, and the number of issues in the subtree.
|
|
368
571
|
#buildFrameTreeDataRecursive(
|
|
369
|
-
explanationTree: Protocol.Page.BackForwardCacheNotRestoredExplanationTree,
|
|
370
|
-
nextBlankURLCount: {blankCount: number}):
|
|
371
|
-
|
|
572
|
+
explanationTree: Protocol.Page.BackForwardCacheNotRestoredExplanationTree|undefined,
|
|
573
|
+
nextBlankURLCount: {blankCount: number}): {node: FrameTreeNodeData, frameCount: number, issueCount: number} {
|
|
574
|
+
if (!explanationTree) {
|
|
575
|
+
return {node: {text: ''}, frameCount: 0, issueCount: 0};
|
|
576
|
+
}
|
|
372
577
|
let frameCount = 1;
|
|
373
578
|
let issueCount = 0;
|
|
374
|
-
const children:
|
|
579
|
+
const children: FrameTreeNodeData[] = [];
|
|
375
580
|
|
|
376
581
|
let nodeUrlText = '';
|
|
377
582
|
if (explanationTree.url.length) {
|
|
@@ -382,7 +587,7 @@ export class BackForwardCacheView extends LegacyWrapper.LegacyWrapper.WrappableC
|
|
|
382
587
|
}
|
|
383
588
|
|
|
384
589
|
for (const explanation of explanationTree.explanations) {
|
|
385
|
-
const child = {
|
|
590
|
+
const child = {text: explanation.reason};
|
|
386
591
|
issueCount += 1;
|
|
387
592
|
children.push(child);
|
|
388
593
|
}
|
|
@@ -395,18 +600,12 @@ export class BackForwardCacheView extends LegacyWrapper.LegacyWrapper.WrappableC
|
|
|
395
600
|
}
|
|
396
601
|
}
|
|
397
602
|
|
|
398
|
-
let node:
|
|
399
|
-
|
|
400
|
-
text: `(${issueCount}) ${nodeUrlText}`,
|
|
401
|
-
},
|
|
402
|
-
id: String(this.#nextNodeId++),
|
|
603
|
+
let node: FrameTreeNodeData = {
|
|
604
|
+
text: `(${issueCount}) ${nodeUrlText}`,
|
|
403
605
|
};
|
|
404
606
|
if (children.length) {
|
|
405
|
-
node = {
|
|
406
|
-
|
|
407
|
-
children: () => Promise.resolve(children),
|
|
408
|
-
};
|
|
409
|
-
node.treeNodeData.iconName = 'iframe';
|
|
607
|
+
node = {...node, children};
|
|
608
|
+
node.iconName = 'iframe';
|
|
410
609
|
} else if (!explanationTree.url.length) {
|
|
411
610
|
// If the current node increased the blank count, but it has no children and
|
|
412
611
|
// is therefore not shown, decrement the blank count again.
|
|
@@ -415,42 +614,6 @@ export class BackForwardCacheView extends LegacyWrapper.LegacyWrapper.WrappableC
|
|
|
415
614
|
return {node, frameCount, issueCount};
|
|
416
615
|
}
|
|
417
616
|
|
|
418
|
-
#renderBackForwardCacheStatus(status: boolean|undefined): Lit.TemplateResult {
|
|
419
|
-
switch (status) {
|
|
420
|
-
case true:
|
|
421
|
-
// clang-format off
|
|
422
|
-
return html`
|
|
423
|
-
<devtools-report-section>
|
|
424
|
-
<div class="status extra-large">
|
|
425
|
-
<devtools-icon class="inline-icon extra-large" name="check-circle" style="color: var(--icon-checkmark-green);">
|
|
426
|
-
</devtools-icon>
|
|
427
|
-
</div>
|
|
428
|
-
${i18nString(UIStrings.restoredFromBFCache)}
|
|
429
|
-
</devtools-report-section>
|
|
430
|
-
`;
|
|
431
|
-
// clang-format on
|
|
432
|
-
case false:
|
|
433
|
-
// clang-format off
|
|
434
|
-
return html`
|
|
435
|
-
<devtools-report-section>
|
|
436
|
-
<div class="status">
|
|
437
|
-
<devtools-icon class="inline-icon extra-large" name="clear">
|
|
438
|
-
</devtools-icon>
|
|
439
|
-
</div>
|
|
440
|
-
${i18nString(UIStrings.normalNavigation)}
|
|
441
|
-
</devtools-report-section>
|
|
442
|
-
`;
|
|
443
|
-
// clang-format on
|
|
444
|
-
}
|
|
445
|
-
// clang-format off
|
|
446
|
-
return html`
|
|
447
|
-
<devtools-report-section>
|
|
448
|
-
${i18nString(UIStrings.unknown)}
|
|
449
|
-
</devtools-report-section>
|
|
450
|
-
`;
|
|
451
|
-
// clang-format on
|
|
452
|
-
}
|
|
453
|
-
|
|
454
617
|
#buildReasonToFramesMap(
|
|
455
618
|
explanationTree: Protocol.Page.BackForwardCacheNotRestoredExplanationTree,
|
|
456
619
|
nextBlankURLCount: {blankCount: number},
|
|
@@ -473,156 +636,12 @@ export class BackForwardCacheView extends LegacyWrapper.LegacyWrapper.WrappableC
|
|
|
473
636
|
this.#buildReasonToFramesMap(child, nextBlankURLCount, outputMap);
|
|
474
637
|
});
|
|
475
638
|
}
|
|
476
|
-
|
|
477
|
-
#maybeRenderExplanations(
|
|
478
|
-
explanations: Protocol.Page.BackForwardCacheNotRestoredExplanation[],
|
|
479
|
-
explanationTree: Protocol.Page.BackForwardCacheNotRestoredExplanationTree|undefined): Lit.LitTemplate {
|
|
480
|
-
if (explanations.length === 0) {
|
|
481
|
-
return Lit.nothing;
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
const pageSupportNeeded = explanations.filter(
|
|
485
|
-
explanation => explanation.type === Protocol.Page.BackForwardCacheNotRestoredReasonType.PageSupportNeeded);
|
|
486
|
-
const supportPending = explanations.filter(
|
|
487
|
-
explanation => explanation.type === Protocol.Page.BackForwardCacheNotRestoredReasonType.SupportPending);
|
|
488
|
-
const circumstantial = explanations.filter(
|
|
489
|
-
explanation => explanation.type === Protocol.Page.BackForwardCacheNotRestoredReasonType.Circumstantial);
|
|
490
|
-
|
|
491
|
-
const reasonToFramesMap = new Map<Protocol.Page.BackForwardCacheNotRestoredReason, string[]>();
|
|
492
|
-
if (explanationTree) {
|
|
493
|
-
this.#buildReasonToFramesMap(explanationTree, {blankCount: 1}, reasonToFramesMap);
|
|
494
|
-
}
|
|
495
|
-
// Disabled until https://crbug.com/1079231 is fixed.
|
|
496
|
-
// clang-format off
|
|
497
|
-
return html`
|
|
498
|
-
${this.#renderExplanations(i18nString(UIStrings.pageSupportNeeded), i18nString(UIStrings.pageSupportNeededExplanation), pageSupportNeeded, reasonToFramesMap)}
|
|
499
|
-
${this.#renderExplanations(i18nString(UIStrings.supportPending), i18nString(UIStrings.supportPendingExplanation), supportPending, reasonToFramesMap)}
|
|
500
|
-
${this.#renderExplanations(i18nString(UIStrings.circumstantial), i18nString(UIStrings.circumstantialExplanation), circumstantial, reasonToFramesMap)}
|
|
501
|
-
`;
|
|
502
|
-
// clang-format on
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
#renderExplanations(
|
|
506
|
-
category: Platform.UIString.LocalizedString, explainerText: Platform.UIString.LocalizedString,
|
|
507
|
-
explanations: Protocol.Page.BackForwardCacheNotRestoredExplanation[],
|
|
508
|
-
reasonToFramesMap: Map<Protocol.Page.BackForwardCacheNotRestoredReason, string[]>): Lit.TemplateResult {
|
|
509
|
-
// Disabled until https://crbug.com/1079231 is fixed.
|
|
510
|
-
// clang-format off
|
|
511
|
-
return html`
|
|
512
|
-
${explanations.length > 0 ? html`
|
|
513
|
-
<devtools-report-section-header>
|
|
514
|
-
${category}
|
|
515
|
-
<div class="help-outline-icon">
|
|
516
|
-
<devtools-icon class="inline-icon medium" name="help" title=${explainerText}>
|
|
517
|
-
</devtools-icon>
|
|
518
|
-
</div>
|
|
519
|
-
</devtools-report-section-header>
|
|
520
|
-
${explanations.map(explanation => this.#renderReason(explanation, reasonToFramesMap.get(explanation.reason)))}
|
|
521
|
-
` : Lit.nothing}
|
|
522
|
-
`;
|
|
523
|
-
// clang-format on
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
#maybeRenderReasonContext(explanation: Protocol.Page.BackForwardCacheNotRestoredExplanation): Lit.LitTemplate {
|
|
527
|
-
if (explanation.reason ===
|
|
528
|
-
Protocol.Page.BackForwardCacheNotRestoredReason.EmbedderExtensionSentMessageToCachedFrame &&
|
|
529
|
-
explanation.context) {
|
|
530
|
-
const link = 'chrome://extensions/?id=' + explanation.context as Platform.DevToolsPath.UrlString;
|
|
531
|
-
// clang-format off
|
|
532
|
-
return html`${i18nString(UIStrings.blockingExtensionId)}
|
|
533
|
-
<devtools-chrome-link .href=${link}>${explanation.context}</devtools-chrome-link>`;
|
|
534
|
-
// clang-format on
|
|
535
|
-
}
|
|
536
|
-
return Lit.nothing;
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
#renderFramesPerReason(frames: string[]|undefined): Lit.LitTemplate {
|
|
540
|
-
if (frames === undefined || frames.length === 0) {
|
|
541
|
-
return Lit.nothing;
|
|
542
|
-
}
|
|
543
|
-
const rows = [html`<div>${i18nString(UIStrings.framesPerIssue, {n: frames.length})}</div>`];
|
|
544
|
-
rows.push(...frames.map(url => html`<div class="text-ellipsis" title=${url}
|
|
545
|
-
jslog=${VisualLogging.treeItem()}>${url}</div>`));
|
|
546
|
-
return html`
|
|
547
|
-
<div class="details-list"
|
|
548
|
-
jslog=${VisualLogging.tree('frames-per-issue')}>
|
|
549
|
-
<devtools-expandable-list .data=${{
|
|
550
|
-
rows,
|
|
551
|
-
title: i18nString(UIStrings.framesPerIssue, {n: frames.length}),
|
|
552
|
-
} as ExpandableList.ExpandableList.ExpandableListData}
|
|
553
|
-
jslog=${VisualLogging.treeItem()}></devtools-expandable-list>
|
|
554
|
-
</div>
|
|
555
|
-
`;
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
#maybeRenderDeepLinkToUnload(explanation: Protocol.Page.BackForwardCacheNotRestoredExplanation): Lit.LitTemplate {
|
|
559
|
-
if (explanation.reason === Protocol.Page.BackForwardCacheNotRestoredReason.UnloadHandlerExistsInMainFrame ||
|
|
560
|
-
explanation.reason === Protocol.Page.BackForwardCacheNotRestoredReason.UnloadHandlerExistsInSubFrame) {
|
|
561
|
-
return html`
|
|
562
|
-
<x-link href="https://web.dev/bfcache/#never-use-the-unload-event" class="link"
|
|
563
|
-
jslog=${VisualLogging.action('learn-more.never-use-unload').track({
|
|
564
|
-
click: true,
|
|
565
|
-
})}>
|
|
566
|
-
${i18nString(UIStrings.neverUseUnload)}
|
|
567
|
-
</x-link>`;
|
|
568
|
-
}
|
|
569
|
-
return Lit.nothing;
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
#maybeRenderJavaScriptDetails(details: Protocol.Page.BackForwardCacheBlockingDetails[]|undefined): Lit.LitTemplate {
|
|
573
|
-
if (details === undefined || details.length === 0) {
|
|
574
|
-
return Lit.nothing;
|
|
575
|
-
}
|
|
576
|
-
const maxLengthForDisplayedURLs = 50;
|
|
577
|
-
const linkifier = new Components.Linkifier.Linkifier(maxLengthForDisplayedURLs);
|
|
578
|
-
const rows = [html`<div>${i18nString(UIStrings.filesPerIssue, {n: details.length})}</div>`];
|
|
579
|
-
rows.push(...details.map(
|
|
580
|
-
detail => html`${
|
|
581
|
-
linkifier.linkifyScriptLocation(
|
|
582
|
-
null, null, detail.url as Platform.DevToolsPath.UrlString, detail.lineNumber, {
|
|
583
|
-
columnNumber: detail.columnNumber,
|
|
584
|
-
showColumnNumber: true,
|
|
585
|
-
inlineFrameIndex: 0,
|
|
586
|
-
})}`));
|
|
587
|
-
return html`
|
|
588
|
-
<div class="details-list">
|
|
589
|
-
<devtools-expandable-list .data=${
|
|
590
|
-
{rows} as ExpandableList.ExpandableList.ExpandableListData}></devtools-expandable-list>
|
|
591
|
-
</div>
|
|
592
|
-
`;
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
#renderReason(explanation: Protocol.Page.BackForwardCacheNotRestoredExplanation, frames: string[]|undefined):
|
|
596
|
-
Lit.TemplateResult {
|
|
597
|
-
// clang-format off
|
|
598
|
-
return html`
|
|
599
|
-
<devtools-report-section>
|
|
600
|
-
${(explanation.reason in NotRestoredReasonDescription) ?
|
|
601
|
-
html`
|
|
602
|
-
<div class="circled-exclamation-icon">
|
|
603
|
-
<devtools-icon class="inline-icon medium" style="color: var(--icon-warning)" name="warning">
|
|
604
|
-
</devtools-icon>
|
|
605
|
-
</div>
|
|
606
|
-
<div>
|
|
607
|
-
${NotRestoredReasonDescription[explanation.reason].name()}
|
|
608
|
-
${this.#maybeRenderDeepLinkToUnload(explanation)}
|
|
609
|
-
${this.#maybeRenderReasonContext(explanation)}
|
|
610
|
-
</div>` :
|
|
611
|
-
Lit.nothing}
|
|
612
|
-
</devtools-report-section>
|
|
613
|
-
<div class="gray-text">
|
|
614
|
-
${explanation.reason}
|
|
615
|
-
</div>
|
|
616
|
-
${this.#maybeRenderJavaScriptDetails(explanation.details)}
|
|
617
|
-
${this.#renderFramesPerReason(frames)}
|
|
618
|
-
`;
|
|
619
|
-
// clang-format on
|
|
620
|
-
}
|
|
621
639
|
}
|
|
622
640
|
|
|
623
641
|
interface FrameTreeNodeData {
|
|
624
642
|
text: string;
|
|
625
643
|
iconName?: string;
|
|
644
|
+
children?: FrameTreeNodeData[];
|
|
626
645
|
}
|
|
627
646
|
|
|
628
647
|
customElements.define('devtools-resources-back-forward-cache-view', BackForwardCacheView);
|