chrome-devtools-frontend 1.0.1715126 → 1.0.1716465
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/eslint.config.mjs +1 -0
- package/front_end/core/host/Platform.ts +37 -0
- package/front_end/core/host/UserMetricsEnums.ts +5 -2
- package/front_end/core/platform/browser/HostRuntime.ts +3 -3
- package/front_end/core/sdk/CSSProperty.ts +2 -1
- package/front_end/core/sdk/DebuggerModel.ts +7 -1
- package/front_end/core/sdk/ResourceTreeModel.ts +9 -0
- package/front_end/core/sdk/RuntimeModel.ts +6 -3
- package/front_end/core/sdk/SDKSettings.ts +7 -0
- package/front_end/core/sdk/SourceMapFunctionRanges.ts +4 -1
- package/front_end/core/sdk/SourceMapScopesInfo.ts +8 -7
- package/front_end/devtools_compatibility.js +5 -2
- package/front_end/entrypoints/formatter_worker/CSSFormatter.ts +56 -6
- package/front_end/entrypoints/formatter_worker/HTMLFormatter.ts +29 -6
- package/front_end/entrypoints/main/MainImpl.ts +6 -14
- package/front_end/generated/Deprecation.ts +0 -7
- package/front_end/generated/InspectorBackendCommands.ts +2 -2
- package/front_end/generated/protocol.ts +5 -2
- package/front_end/models/ai_assistance/AiAgent2.ts +0 -1
- package/front_end/models/ai_assistance/README.md +2 -2
- package/front_end/models/ai_assistance/skills/Skill.ts +1 -1
- package/front_end/models/ai_assistance/skills/SkillRegistry.ts +0 -2
- package/front_end/models/ai_assistance/skills/lighthouse.md +28 -10
- package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +0 -3
- package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +21 -11
- package/front_end/models/bindings/DefaultScriptMapping.ts +8 -2
- package/front_end/models/bindings/SourceMapStepping.ts +23 -3
- package/front_end/models/emulation/DeviceModeModel.ts +4 -19
- package/front_end/models/formatter/ScriptFormatter.ts +6 -7
- package/front_end/models/javascript_metadata/NativeFunctions.ts +0 -44
- package/front_end/models/source_map_scopes/FunctionCodeResolver.ts +9 -12
- package/front_end/models/trace/LanternComputationData.ts +6 -14
- package/front_end/models/trace/extras/TraceTree.ts +44 -13
- package/front_end/models/trace/helpers/SamplesIntegrator.ts +70 -58
- package/front_end/models/trace/insights/Common.ts +3 -2
- package/front_end/models/trace/insights/RenderBlocking.ts +28 -6
- package/front_end/models/trace/lantern/core/NetworkAnalyzer.ts +12 -20
- package/front_end/models/trace/lantern/simulation/Simulator.ts +5 -2
- package/front_end/models/trace/lantern/simulation/TCPConnection.ts +1 -1
- package/front_end/models/trace/types/Overlays.ts +4 -3
- package/front_end/models/workspace_diff/WorkspaceDiff.ts +5 -3
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +1 -2
- package/front_end/panels/application/DeviceBoundSessionsTreeElement.ts +0 -8
- package/front_end/panels/application/FrameDetailsView.ts +84 -0
- package/front_end/panels/application/WebMCPView.ts +3 -3
- package/front_end/panels/application/preloading/PreloadingView.ts +4 -1
- package/front_end/panels/application/preloading/components/RuleSetDetailsView.ts +5 -2
- package/front_end/panels/common/ExtensionServer.ts +84 -26
- package/front_end/panels/console/PromptBuilder.ts +5 -2
- package/front_end/panels/elements/AdoptedStyleSheetTreeElement.ts +1 -118
- package/front_end/panels/elements/DOMPath.ts +38 -5
- package/front_end/panels/elements/DOMTreeContextMenu.ts +13 -8
- package/front_end/panels/elements/{ElementsTreeElement.ts → DOMTreeElementWidget.ts} +104 -469
- package/front_end/panels/elements/DOMTreeWidget.ts +74 -1253
- package/front_end/panels/elements/StylePropertiesSection.ts +3 -3
- package/front_end/panels/elements/StylePropertyTreeElement.ts +2 -2
- package/front_end/panels/elements/StylesSidebarPane.ts +3 -1
- package/front_end/panels/elements/{elementsTreeOutline.css → domTreeWidget.css} +3 -178
- package/front_end/panels/elements/elements.ts +3 -6
- package/front_end/panels/emulation/DeviceModeToolbar.ts +0 -8
- package/front_end/panels/media/PlayerPropertiesView.ts +4 -4
- package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +4 -4
- package/front_end/panels/recorder/RecorderPanel.ts +2 -1
- package/front_end/panels/security/SecurityPanel.ts +163 -100
- package/front_end/panels/sources/DebuggerPlugin.ts +125 -81
- package/front_end/panels/sources/SourcesPanel.ts +10 -4
- package/front_end/panels/sources/TabbedEditorContainer.ts +2 -1
- package/front_end/panels/sources/UISourceCodeFrame.ts +4 -2
- package/front_end/panels/sources/sources-meta.ts +20 -34
- package/front_end/panels/timeline/README.md +3 -1
- package/front_end/panels/timeline/TimelineUIUtils.ts +2 -1
- package/front_end/panels/timeline/components/LiveMetricsView.ts +2 -2
- package/front_end/panels/timeline/overlays/OverlaysImpl.ts +14 -32
- package/front_end/panels/timeline/timelineFlameChartView.css +1 -42
- package/front_end/panels/whats_new/ReleaseNoteText.ts +8 -8
- package/front_end/panels/whats_new/resources/WNDT.md +5 -5
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/puppeteer/README.chromium +2 -2
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +77 -0
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +474 -358
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.d.ts +15 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.js +27 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPResponse.d.ts +13 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPResponse.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPResponse.js +38 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPResponse.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts +20 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Browser.js +9 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BrowserContext.js +6 -5
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BrowserContext.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Connection.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Connection.js +2 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Connection.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/ExposedFunction.js +2 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/ExposedFunction.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Frame.js +2 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Frame.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Input.js +4 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Input.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.js +9 -8
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Realm.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Realm.js +9 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Realm.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Request.js +3 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Request.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/UserPrompt.js +3 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/UserPrompt.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/util.d.ts +2 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/util.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/util.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/util.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js +11 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.js +9 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.js +7 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/WebWorker.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/WebWorker.js +9 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/WebWorker.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/utils.d.ts +3 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/utils.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/utils.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/utils.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.js +9 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConnectOptions.d.ts +8 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConnectOptions.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConsoleMessage.d.ts +24 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConsoleMessage.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConsoleMessage.js +30 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConsoleMessage.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/CustomQueryHandler.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/CustomQueryHandler.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/util.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/util.js +5 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/util.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.js +7 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.d.ts +10 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.js +7 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.d.ts +3 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/types.d.ts +77 -0
- package/front_end/third_party/puppeteer/package/package.json +7 -7
- package/front_end/third_party/puppeteer/package/src/api/HTTPRequest.ts +30 -0
- package/front_end/third_party/puppeteer/package/src/api/HTTPResponse.ts +41 -0
- package/front_end/third_party/puppeteer/package/src/api/Page.ts +20 -0
- package/front_end/third_party/puppeteer/package/src/bidi/Browser.ts +6 -0
- package/front_end/third_party/puppeteer/package/src/bidi/Connection.ts +2 -1
- package/front_end/third_party/puppeteer/package/src/bidi/Realm.ts +1 -0
- package/front_end/third_party/puppeteer/package/src/bidi/util.ts +3 -0
- package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +9 -2
- package/front_end/third_party/puppeteer/package/src/cdp/EmulationManager.ts +10 -3
- package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +11 -2
- package/front_end/third_party/puppeteer/package/src/cdp/WebWorker.ts +19 -2
- package/front_end/third_party/puppeteer/package/src/cdp/utils.ts +6 -1
- package/front_end/third_party/puppeteer/package/src/common/BrowserConnector.ts +10 -2
- package/front_end/third_party/puppeteer/package/src/common/ConnectOptions.ts +9 -0
- package/front_end/third_party/puppeteer/package/src/common/ConsoleMessage.ts +35 -0
- package/front_end/third_party/puppeteer/package/src/common/CustomQueryHandler.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/generated/injected.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/injected/util.ts +6 -2
- package/front_end/third_party/puppeteer/package/src/node/BrowserLauncher.ts +7 -2
- package/front_end/third_party/puppeteer/package/src/node/NodeWebSocketTransport.ts +12 -1
- package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
- package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
- package/front_end/ui/components/text_editor/config.ts +6 -3
- package/front_end/ui/legacy/InspectorView.ts +13 -12
- package/front_end/ui/legacy/ProgressIndicator.ts +18 -0
- package/front_end/ui/legacy/SearchableView.ts +348 -269
- package/front_end/ui/legacy/TabbedPane.ts +19 -3
- package/front_end/ui/legacy/UIUtils.ts +1 -46
- package/front_end/ui/legacy/components/data_grid/DataGrid.ts +4 -0
- package/front_end/ui/legacy/components/source_frame/ResourceSourceFrame.ts +3 -3
- package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +66 -30
- package/front_end/ui/legacy/components/source_frame/source_frame-meta.ts +3 -5
- package/front_end/ui/settings/SourcesSettings.ts +21 -0
- package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
- package/package.json +1 -1
- package/front_end/models/ai_assistance/skills/accessibility.md +0 -33
- package/front_end/panels/elements/ShortcutTreeElement.ts +0 -172
- package/front_end/panels/elements/TopLayerContainer.ts +0 -54
|
@@ -1,35 +1,53 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lighthouse
|
|
3
|
-
description:
|
|
3
|
+
description: Analyzing an active Lighthouse report context, running Lighthouse reports and audits (performance, accessibility, best practices, Search Engine Optimization (SEO)), accessibility audits, ARIA properties, accessible tree inspection, color contrast, and screen reader semantics. Not for general page performance measurement without a Lighthouse report; use the performance skill for that.
|
|
4
4
|
allowed-tools:
|
|
5
5
|
- runLighthouse
|
|
6
6
|
- getLighthouseAudits
|
|
7
7
|
- resolveDevtoolsNodePath
|
|
8
|
+
- getStyles
|
|
9
|
+
- getElementAccessibilityDetails
|
|
10
|
+
- executeJavaScript
|
|
8
11
|
---
|
|
9
|
-
You are an expert web quality
|
|
10
|
-
Your role is to evaluate websites using Lighthouse audits across performance, accessibility, best practices, and SEO.
|
|
12
|
+
You are an expert web quality, Lighthouse audit, and accessibility debugging assistant integrated into Chrome DevTools.
|
|
13
|
+
Your role is to evaluate websites using Lighthouse audits across performance, accessibility, best practices, and SEO, and to inspect live DOM elements for accessibility and styling fixes.
|
|
11
14
|
|
|
12
15
|
# Tools & Workflow
|
|
13
16
|
|
|
14
17
|
1. **Lighthouse Audits (`runLighthouse` & `getLighthouseAudits`)**:
|
|
15
|
-
- The Lighthouse report context contains only category scores and failing audit titles. To answer
|
|
18
|
+
- The Lighthouse report context contains only category scores and failing audit titles. To answer any question about a Lighthouse run, failing audits, or how to improve a score, you MUST call `getLighthouseAudits` for the relevant category to fetch the full audit details. Never reply using only the initial summary.
|
|
16
19
|
- If an active Lighthouse report context already exists and no fresh audit is requested:
|
|
17
|
-
- To inspect the entire report
|
|
20
|
+
- To inspect the entire report, multiple categories, or general opportunities to improve the score, call `getLighthouseAudits` with `categoryId: 'all'`.
|
|
18
21
|
- For a specific category, call `getLighthouseAudits` with the corresponding category ID (e.g. `'performance'`, `'accessibility'`, `'best-practices'`, `'seo'`).
|
|
19
22
|
- If no active report exists or a fresh audit is requested, call `runLighthouse`:
|
|
20
23
|
- If the user asks for a general report or multiple categories, use `categoryId: 'all'`.
|
|
21
|
-
- For a single category, pass that category ID.
|
|
24
|
+
- For a single category, pass that category ID (e.g. `'accessibility'`).
|
|
22
25
|
- Execution mode:
|
|
23
26
|
- Use `"navigation"` mode for full page-load audits (default for full site reviews).
|
|
24
27
|
- Use `"snapshot"` mode to re-evaluate live in-page DOM/CSS modifications without reloading.
|
|
25
28
|
- Use `"timespan"` mode for user interaction flows.
|
|
26
29
|
- Always honor explicit mode requests from the user.
|
|
30
|
+
- **CRITICAL**: `runLighthouse` only records the report and returns `"Lighthouse audit completed"` without audit details. Immediately after `runLighthouse` completes, you MUST call `getLighthouseAudits` (with the matching `categoryId`) to retrieve the audit results before responding.
|
|
27
31
|
|
|
28
|
-
2. **Resolving
|
|
29
|
-
-
|
|
32
|
+
2. **Resolving & Inspecting Failing Audit Elements (`resolveDevtoolsNodePath`, `getStyles`, `getElementAccessibilityDetails`)**:
|
|
33
|
+
- `getLighthouseAudits` only returns static HTML snippets and DevTools `node path` strings (e.g. `"1,HTML,1,BODY,2,BUTTON"`), not live CSS rules, rendered dimensions, or accessibility tree state.
|
|
34
|
+
- Whenever failing audits reference specific page elements by `node path` (excluding document-level `"1,HTML"` landmark checks) and those elements have not yet been resolved and inspected in the conversation:
|
|
35
|
+
1. Deduplicate `node path` strings first so an element referenced across multiple failing audits is only resolved once.
|
|
36
|
+
2. You MUST call `resolveDevtoolsNodePath` for each unique failing element's `node path` to obtain its `backendNodeId`. Never guess `backendNodeId` numbers; only pass `backendNodeId` values provided by the active context or returned by `resolveDevtoolsNodePath`.
|
|
37
|
+
3. You MUST then inspect those `backendNodeId`s using dedicated tools before answering:
|
|
38
|
+
- Call `getStyles` on the `backendNodeId` for sizing/layout audits (such as `unsized-images` to find the actual rendered CSS `width` and `height`), color contrast, or link styling (`link-in-text-block`).
|
|
39
|
+
- Call `getElementAccessibilityDetails` on the `backendNodeId` for accessibility, ARIA, role, or accessible name audits (such as `button-name`).
|
|
40
|
+
- Never guess CSS dimensions, styles, or ARIA properties from the static HTML snippet alone, and never use `executeJavaScript` (`document.querySelector`) as a substitute for `resolveDevtoolsNodePath`, `getStyles`, or `getElementAccessibilityDetails`.
|
|
41
|
+
|
|
42
|
+
3. **Direct Element Accessibility Inspection (`getElementAccessibilityDetails` & `getStyles`)**:
|
|
43
|
+
- When inspecting a selected DOM element for accessibility, ALWAYS call `getElementAccessibilityDetails` on its `backendNodeId` to retrieve the computed role, accessible name, name source, ARIA attributes, ignored state, and accessibility properties directly from the accessibility tree.
|
|
44
|
+
- Call `getStyles` on the `backendNodeId` to inspect layout, color contrast, or font properties when relevant.
|
|
45
|
+
|
|
46
|
+
4. **Supplementary DOM & Dynamic Interaction Checks (`executeJavaScript`)**:
|
|
47
|
+
- Only after calling `resolveDevtoolsNodePath`, `getStyles`, and `getElementAccessibilityDetails` on failing elements with a `node path`, you may use `executeJavaScript` if you need supplementary DOM state not available from single-node tools (such as `<head>` `<meta>` tags, `document.body.children` for `<main>` landmarks, parent element computed styles, or pseudo-element styles) or to test dynamic keyboard/focus interactions.
|
|
30
48
|
|
|
31
49
|
# Considerations
|
|
32
50
|
|
|
33
|
-
- Base all analysis on empirical Lighthouse audit data. Never fabricate audit scores or results.
|
|
34
|
-
- For performance-only questions (e.g. loading speed, Core Web Vitals), do not run Lighthouse unless the user mentions Lighthouse or a Lighthouse score. Record a performance trace with the performance skill instead.
|
|
51
|
+
- Base all analysis on empirical Lighthouse audit data and live element inspection. Never fabricate audit scores or results.
|
|
52
|
+
- For performance-only questions (e.g. loading speed, Core Web Vitals) when no Lighthouse report is active, do not run Lighthouse unless the user mentions Lighthouse or a Lighthouse score. Record a performance trace with the performance skill instead.
|
|
35
53
|
- When summarizing a full Lighthouse run, highlight overall category scores first, then detail failing audits (score < 90).
|
|
@@ -2,7 +2,6 @@
|
|
|
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 Common from '../../../core/common/common.js';
|
|
6
5
|
import * as Host from '../../../core/host/host.js';
|
|
7
6
|
import * as i18n from '../../../core/i18n/i18n.js';
|
|
8
7
|
import * as Root from '../../../core/root/root.js';
|
|
@@ -48,8 +47,6 @@ export class ExecuteJavaScriptTool implements
|
|
|
48
47
|
static async validateAndFormatCode(code: string): Promise<{formattedCode?: string, error?: string}> {
|
|
49
48
|
try {
|
|
50
49
|
const formatted = await Formatter.ScriptFormatter.formatScriptContent(
|
|
51
|
-
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
52
|
-
Common.Settings.Settings.instance(),
|
|
53
50
|
'text/javascript',
|
|
54
51
|
code,
|
|
55
52
|
' ',
|
|
@@ -2,7 +2,7 @@
|
|
|
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
|
|
5
|
+
import * as Common from '../../core/common/common.js';
|
|
6
6
|
import * as Platform from '../../core/platform/platform.js';
|
|
7
7
|
import * as Root from '../../core/root/root.js';
|
|
8
8
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
@@ -28,6 +28,13 @@ import {
|
|
|
28
28
|
UnparsableError,
|
|
29
29
|
} from './SymbolizedError.js';
|
|
30
30
|
|
|
31
|
+
export const wasmAutoSteppingSettingDescriptor: Common.Settings.SettingDescriptor<boolean> = {
|
|
32
|
+
name: 'wasm-auto-stepping',
|
|
33
|
+
type: Common.Settings.SettingType.BOOLEAN,
|
|
34
|
+
defaultValue: true,
|
|
35
|
+
storageType: Common.Settings.SettingStorageType.LOCAL,
|
|
36
|
+
};
|
|
37
|
+
|
|
31
38
|
export class DebuggerWorkspaceBinding implements SDK.TargetManager.SDKModelObserver<SDK.DebuggerModel.DebuggerModel>,
|
|
32
39
|
DebuggerLocationUpdater {
|
|
33
40
|
readonly resourceMapping: ResourceMapping;
|
|
@@ -474,6 +481,10 @@ export class DebuggerWorkspaceBinding implements SDK.TargetManager.SDKModelObser
|
|
|
474
481
|
const scripts = new Set<SDK.Script.Script>();
|
|
475
482
|
this.pluginManager.scriptsForUISourceCode(uiSourceCode).forEach(script => scripts.add(script));
|
|
476
483
|
for (const modelData of this.#debuggerModelToData.values()) {
|
|
484
|
+
const defaultScript = modelData.defaultMapping.scriptForUISourceCode(uiSourceCode);
|
|
485
|
+
if (defaultScript) {
|
|
486
|
+
scripts.add(defaultScript);
|
|
487
|
+
}
|
|
477
488
|
const resourceScriptFile = modelData.getResourceScriptMapping().scriptFile(uiSourceCode);
|
|
478
489
|
if (resourceScriptFile?.script) {
|
|
479
490
|
scripts.add(resourceScriptFile.script);
|
|
@@ -536,7 +547,7 @@ export class DebuggerWorkspaceBinding implements SDK.TargetManager.SDKModelObser
|
|
|
536
547
|
const {callFrames: [frame]} = debuggerPausedDetails;
|
|
537
548
|
const functionLocation = frame.functionLocation();
|
|
538
549
|
if (!autoSteppingContext || debuggerPausedDetails.reason !== Protocol.Debugger.PausedEventReason.Step ||
|
|
539
|
-
!functionLocation || !this.#settings.
|
|
550
|
+
!functionLocation || !this.#settings.resolve(wasmAutoSteppingSettingDescriptor).get() ||
|
|
540
551
|
!this.pluginManager.hasPluginForScript(frame.script)) {
|
|
541
552
|
return true;
|
|
542
553
|
}
|
|
@@ -581,7 +592,7 @@ export class DebuggerWorkspaceBinding implements SDK.TargetManager.SDKModelObser
|
|
|
581
592
|
class ModelData {
|
|
582
593
|
readonly #debuggerModel: SDK.DebuggerModel.DebuggerModel;
|
|
583
594
|
readonly #debuggerWorkspaceBinding: DebuggerWorkspaceBinding;
|
|
584
|
-
|
|
595
|
+
readonly defaultMapping: DefaultScriptMapping;
|
|
585
596
|
readonly #resourceMapping: ResourceMapping;
|
|
586
597
|
#resourceScriptMapping: ResourceScriptMapping;
|
|
587
598
|
readonly compilerMapping: CompilerScriptMapping;
|
|
@@ -592,7 +603,7 @@ class ModelData {
|
|
|
592
603
|
this.#debuggerWorkspaceBinding = debuggerWorkspaceBinding;
|
|
593
604
|
|
|
594
605
|
const {workspace} = debuggerWorkspaceBinding.resourceMapping;
|
|
595
|
-
this
|
|
606
|
+
this.defaultMapping = new DefaultScriptMapping(debuggerModel, workspace, debuggerWorkspaceBinding);
|
|
596
607
|
this.#resourceMapping = debuggerWorkspaceBinding.resourceMapping;
|
|
597
608
|
this.#resourceScriptMapping = new ResourceScriptMapping(debuggerModel, workspace, debuggerWorkspaceBinding);
|
|
598
609
|
this.compilerMapping = new CompilerScriptMapping(debuggerModel, workspace, debuggerWorkspaceBinding);
|
|
@@ -631,7 +642,7 @@ class ModelData {
|
|
|
631
642
|
#nonCompilerRawLocationToUILocation(rawLocation: SDK.DebuggerModel.Location): Workspace.UISourceCode.UILocation|null {
|
|
632
643
|
let uiLocation = this.#resourceScriptMapping.rawLocationToUILocation(rawLocation);
|
|
633
644
|
uiLocation = uiLocation || this.#resourceMapping.jsLocationToUILocation(rawLocation);
|
|
634
|
-
uiLocation = uiLocation || this
|
|
645
|
+
uiLocation = uiLocation || this.defaultMapping.rawLocationToUILocation(rawLocation);
|
|
635
646
|
return uiLocation;
|
|
636
647
|
}
|
|
637
648
|
|
|
@@ -639,7 +650,7 @@ class ModelData {
|
|
|
639
650
|
let uiSourceCode: Workspace.UISourceCode.UISourceCode|null = null;
|
|
640
651
|
uiSourceCode = uiSourceCode || this.#resourceScriptMapping.uiSourceCodeForScript(script);
|
|
641
652
|
uiSourceCode = uiSourceCode || this.#resourceMapping.uiSourceCodeForScript(script);
|
|
642
|
-
uiSourceCode = uiSourceCode || this
|
|
653
|
+
uiSourceCode = uiSourceCode || this.defaultMapping.uiSourceCodeForScript(script);
|
|
643
654
|
return uiSourceCode;
|
|
644
655
|
}
|
|
645
656
|
|
|
@@ -654,9 +665,8 @@ class ModelData {
|
|
|
654
665
|
locations = locations.length ?
|
|
655
666
|
locations :
|
|
656
667
|
this.#resourceMapping.uiLocationToJSLocations(uiSourceCode, lineNumber, columnNumber);
|
|
657
|
-
locations = locations.length ?
|
|
658
|
-
|
|
659
|
-
this.#defaultMapping.uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber);
|
|
668
|
+
locations = locations.length ? locations :
|
|
669
|
+
this.defaultMapping.uiLocationToRawLocations(uiSourceCode, lineNumber, columnNumber);
|
|
660
670
|
return locations;
|
|
661
671
|
}
|
|
662
672
|
|
|
@@ -666,7 +676,7 @@ class ModelData {
|
|
|
666
676
|
let ranges = this.compilerMapping.uiLocationRangeToRawLocationRanges(uiSourceCode, textRange);
|
|
667
677
|
ranges ??= this.#resourceScriptMapping.uiLocationRangeToRawLocationRanges(uiSourceCode, textRange);
|
|
668
678
|
ranges ??= this.#resourceMapping.uiLocationRangeToJSLocationRanges(uiSourceCode, textRange);
|
|
669
|
-
ranges ??= this
|
|
679
|
+
ranges ??= this.defaultMapping.uiLocationRangeToRawLocationRanges(uiSourceCode, textRange);
|
|
670
680
|
return ranges;
|
|
671
681
|
}
|
|
672
682
|
|
|
@@ -720,7 +730,7 @@ class ModelData {
|
|
|
720
730
|
this.#debuggerModel.setBeforePausedCallback(null);
|
|
721
731
|
this.compilerMapping.dispose();
|
|
722
732
|
this.#resourceScriptMapping.dispose();
|
|
723
|
-
this
|
|
733
|
+
this.defaultMapping.dispose();
|
|
724
734
|
}
|
|
725
735
|
|
|
726
736
|
getResourceScriptMapping(): ResourceScriptMapping {
|
|
@@ -10,6 +10,7 @@ import * as Workspace from '../workspace/workspace.js';
|
|
|
10
10
|
|
|
11
11
|
import {ContentProviderBasedProject} from './ContentProviderBasedProject.js';
|
|
12
12
|
import type {DebuggerSourceMapping, DebuggerWorkspaceBinding} from './DebuggerWorkspaceBinding.js';
|
|
13
|
+
import {NetworkProject} from './NetworkProject.js';
|
|
13
14
|
|
|
14
15
|
export class DefaultScriptMapping implements DebuggerSourceMapping {
|
|
15
16
|
readonly #debuggerWorkspaceBinding: DebuggerWorkspaceBinding;
|
|
@@ -26,6 +27,7 @@ export class DefaultScriptMapping implements DebuggerSourceMapping {
|
|
|
26
27
|
this.#project =
|
|
27
28
|
new ContentProviderBasedProject(workspace, 'debugger:' + debuggerModel.target().id(),
|
|
28
29
|
Workspace.Workspace.projectTypes.Debugger, '', true /* isServiceProject */);
|
|
30
|
+
NetworkProject.setTargetForProject(this.#project, debuggerModel.target());
|
|
29
31
|
this.#eventListeners = [
|
|
30
32
|
debuggerModel.addEventListener(SDK.DebuggerModel.Events.GlobalObjectCleared, this.globalObjectCleared, this),
|
|
31
33
|
debuggerModel.addEventListener(SDK.DebuggerModel.Events.ParsedScriptSource, this.parsedScriptSource, this),
|
|
@@ -44,14 +46,18 @@ export class DefaultScriptMapping implements DebuggerSourceMapping {
|
|
|
44
46
|
|
|
45
47
|
static scriptForUISourceCode(uiSourceCode: Workspace.UISourceCode.UISourceCode): SDK.Script.Script|null {
|
|
46
48
|
for (const defaultScriptMapping of defaultScriptMappings) {
|
|
47
|
-
const script = defaultScriptMapping
|
|
48
|
-
if (script !==
|
|
49
|
+
const script = defaultScriptMapping.scriptForUISourceCode(uiSourceCode);
|
|
50
|
+
if (script !== null) {
|
|
49
51
|
return script;
|
|
50
52
|
}
|
|
51
53
|
}
|
|
52
54
|
return null;
|
|
53
55
|
}
|
|
54
56
|
|
|
57
|
+
scriptForUISourceCode(uiSourceCode: Workspace.UISourceCode.UISourceCode): SDK.Script.Script|null {
|
|
58
|
+
return this.#uiSourceCodeToScript.get(uiSourceCode) ?? null;
|
|
59
|
+
}
|
|
60
|
+
|
|
55
61
|
uiSourceCodeForScript(script: SDK.Script.Script): Workspace.UISourceCode.UISourceCode|null {
|
|
56
62
|
return this.#scriptToUISourceCode.get(script) ?? null;
|
|
57
63
|
}
|
|
@@ -104,6 +104,24 @@ export function inlinedFunctionRanges(frame: SDK.DebuggerModel.CallFrame): SDK.D
|
|
|
104
104
|
return position && range ? toLocationRanges(position, [range]) : [];
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
+
/**
|
|
108
|
+
* @returns true iff both frames are paused in the same call of an inlined function (or both aren't in any). Separate
|
|
109
|
+
* calls of the same function are inlined into separate generated ranges.
|
|
110
|
+
*/
|
|
111
|
+
function isSameInlinedCall(a: SDK.DebuggerModel.CallFrame, b: SDK.DebuggerModel.CallFrame): boolean {
|
|
112
|
+
const range = (frame: SDK.DebuggerModel.CallFrame): SDK.SourceMapScopesInfo.PositionRange|null => {
|
|
113
|
+
const position = scopedPosition(frame);
|
|
114
|
+
return position?.sourceMap.inlinedFunctionRange(position.line, position.column) ?? null;
|
|
115
|
+
};
|
|
116
|
+
const rangeA = range(a);
|
|
117
|
+
const rangeB = range(b);
|
|
118
|
+
if (!rangeA || !rangeB) {
|
|
119
|
+
return rangeA === rangeB;
|
|
120
|
+
}
|
|
121
|
+
return a.script === b.script && SDK.SourceMapScopesInfo.comparePositions(rangeA.start, rangeB.start) === 0 &&
|
|
122
|
+
SDK.SourceMapScopesInfo.comparePositions(rangeA.end, rangeB.end) === 0;
|
|
123
|
+
}
|
|
124
|
+
|
|
107
125
|
/** @returns the bodies of the functions inlined into the logical function that {@link frame} is paused in. */
|
|
108
126
|
export function inlinedCalleeRanges(frame: SDK.DebuggerModel.CallFrame): SDK.DebuggerModel.LocationRange[] {
|
|
109
127
|
const position = scopedPosition(frame);
|
|
@@ -157,9 +175,11 @@ export async function nextAutoStep(
|
|
|
157
175
|
case SDK.DebuggerModel.StepMode.STEP_OVER: {
|
|
158
176
|
const startDepth = logicalDepth(start);
|
|
159
177
|
const depth = logicalDepth(frames);
|
|
160
|
-
if (isUnmapped(frames[0]) ||
|
|
161
|
-
|
|
162
|
-
|
|
178
|
+
if (isUnmapped(frames[0]) ||
|
|
179
|
+
(depth === startDepth && isSameOriginalLocation(frames[0], start[0]) &&
|
|
180
|
+
isSameInlinedCall(frames[0], start[0]))) {
|
|
181
|
+
// Unmapped code, or still on the same original location in the same (inlined) call (the skip list only covers
|
|
182
|
+
// the generated ranges that contain the start position): keep stepping over.
|
|
163
183
|
return await computeAutoStep(SDK.DebuggerModel.StepMode.STEP_OVER, frames);
|
|
164
184
|
}
|
|
165
185
|
return null;
|
|
@@ -778,25 +778,10 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
778
778
|
}
|
|
779
779
|
|
|
780
780
|
private calculateFitScale(screenWidth: number, screenHeight: number): number {
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
scale = Math.
|
|
784
|
-
|
|
785
|
-
let sharpScale = scale;
|
|
786
|
-
while (sharpScale > scale * 0.7) {
|
|
787
|
-
let sharp = true;
|
|
788
|
-
if (screenWidth) {
|
|
789
|
-
sharp = sharp && Number.isInteger(screenWidth * sharpScale / 100);
|
|
790
|
-
}
|
|
791
|
-
if (screenHeight) {
|
|
792
|
-
sharp = sharp && Number.isInteger(screenHeight * sharpScale / 100);
|
|
793
|
-
}
|
|
794
|
-
if (sharp) {
|
|
795
|
-
return sharpScale / 100;
|
|
796
|
-
}
|
|
797
|
-
sharpScale -= 1;
|
|
798
|
-
}
|
|
799
|
-
return scale / 100;
|
|
781
|
+
const scaleW = screenWidth ? Math.floor(this.#preferredSize.width * 100 / screenWidth) : 100;
|
|
782
|
+
const scaleH = screenHeight ? Math.floor(this.#preferredSize.height * 100 / screenHeight) : 100;
|
|
783
|
+
const scale = Math.min(scaleW, scaleH, 100);
|
|
784
|
+
return Math.max(scale, 1) / 100;
|
|
800
785
|
}
|
|
801
786
|
|
|
802
787
|
setSizeAndScaleToFit(width: number, height: number): void {
|
|
@@ -30,25 +30,24 @@ export interface FormattedContent {
|
|
|
30
30
|
formattedMapping: FormatterSourceMapping;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
export async function format(
|
|
34
|
-
|
|
33
|
+
export async function format(contentType: Common.ResourceType.ResourceType, mimeType: string, content: string,
|
|
34
|
+
indent: string): Promise<FormattedContent> {
|
|
35
35
|
if (contentType.isDocumentOrScriptOrStyleSheet()) {
|
|
36
|
-
return await formatScriptContent(
|
|
36
|
+
return await formatScriptContent(mimeType, content, indent);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
return {formattedContent: content, formattedMapping: new IdentityFormatterSourceMapping()};
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
export async function formatScriptContent(
|
|
43
|
-
indent
|
|
44
|
-
const indentString = indent ?? settings.moduleSetting('text-editor-indent').get();
|
|
42
|
+
export async function formatScriptContent(mimeType: string, content: string,
|
|
43
|
+
indent: string): Promise<FormattedContent> {
|
|
45
44
|
const originalContent = content.replace(/\r\n?|[\n\u2028\u2029]/g, '\n').replace(/^\uFEFF/, '');
|
|
46
45
|
|
|
47
46
|
const pool = formatterWorkerPool();
|
|
48
47
|
|
|
49
48
|
let formatResult: FormatterActions.FormatResult = {content: originalContent, mapping: {original: [], formatted: []}};
|
|
50
49
|
try {
|
|
51
|
-
formatResult = await pool.format(mimeType, originalContent,
|
|
50
|
+
formatResult = await pool.format(mimeType, originalContent, indent);
|
|
52
51
|
} catch {
|
|
53
52
|
}
|
|
54
53
|
const originalContentLineEndings = Platform.StringUtilities.findLineEndingIndexes(originalContent);
|
|
@@ -6735,10 +6735,6 @@ export const NativeFunctions: readonly NativeFunctionValue[] = [
|
|
|
6735
6735
|
name: "setImmediates",
|
|
6736
6736
|
signatures: [["rangeOffset","data","?dataOffset","?size"]]
|
|
6737
6737
|
},
|
|
6738
|
-
{
|
|
6739
|
-
name: "copyElementImageToTexture",
|
|
6740
|
-
signatures: [["source","destination"]]
|
|
6741
|
-
},
|
|
6742
6738
|
{
|
|
6743
6739
|
name: "drawElementImageToTexture",
|
|
6744
6740
|
signatures: [["source","destination"]]
|
|
@@ -6831,10 +6827,6 @@ export const NativeFunctions: readonly NativeFunctionValue[] = [
|
|
|
6831
6827
|
name: "drawingBufferToneMapping",
|
|
6832
6828
|
signatures: [["?toneMapping"]]
|
|
6833
6829
|
},
|
|
6834
|
-
{
|
|
6835
|
-
name: "texElementImage2D",
|
|
6836
|
-
signatures: [["target","internalformat","element","?config"]]
|
|
6837
|
-
},
|
|
6838
6830
|
{
|
|
6839
6831
|
name: "texElementSubImage2D",
|
|
6840
6832
|
signatures: [["target","level","xoffset","yoffset","element","?config"]]
|
|
@@ -7131,38 +7123,6 @@ export const NativeFunctions: readonly NativeFunctionValue[] = [
|
|
|
7131
7123
|
name: "SmartCardError",
|
|
7132
7124
|
signatures: [["message","options"]]
|
|
7133
7125
|
},
|
|
7134
|
-
{
|
|
7135
|
-
name: "contributeToHistogram",
|
|
7136
|
-
signatures: [["contribution"]]
|
|
7137
|
-
},
|
|
7138
|
-
{
|
|
7139
|
-
name: "enableDebugMode",
|
|
7140
|
-
signatures: [["?options"]]
|
|
7141
|
-
},
|
|
7142
|
-
{
|
|
7143
|
-
name: "SharedStorageAppendMethod",
|
|
7144
|
-
signatures: [["key","value","?options"]]
|
|
7145
|
-
},
|
|
7146
|
-
{
|
|
7147
|
-
name: "SharedStorageClearMethod",
|
|
7148
|
-
signatures: [["?options"]]
|
|
7149
|
-
},
|
|
7150
|
-
{
|
|
7151
|
-
name: "SharedStorageDeleteMethod",
|
|
7152
|
-
signatures: [["key","?options"]]
|
|
7153
|
-
},
|
|
7154
|
-
{
|
|
7155
|
-
name: "SharedStorageSetMethod",
|
|
7156
|
-
signatures: [["key","value","?options"]]
|
|
7157
|
-
},
|
|
7158
|
-
{
|
|
7159
|
-
name: "selectURL",
|
|
7160
|
-
signatures: [["name","urls","?options"]]
|
|
7161
|
-
},
|
|
7162
|
-
{
|
|
7163
|
-
name: "run",
|
|
7164
|
-
signatures: [["name","?options"]]
|
|
7165
|
-
},
|
|
7166
7126
|
{
|
|
7167
7127
|
name: "BarcodeDetector",
|
|
7168
7128
|
signatures: [["?barcodeDetectorOptions"]]
|
|
@@ -8739,10 +8699,6 @@ export const NativeFunctions: readonly NativeFunctionValue[] = [
|
|
|
8739
8699
|
name: "setReportEventDataForAutomaticBeacons",
|
|
8740
8700
|
signatures: [["event"]]
|
|
8741
8701
|
},
|
|
8742
|
-
{
|
|
8743
|
-
name: "setSharedStorageContext",
|
|
8744
|
-
signatures: [["contextString"]]
|
|
8745
|
-
},
|
|
8746
8702
|
{
|
|
8747
8703
|
name: "CloseWatcher",
|
|
8748
8704
|
signatures: [["?options"]]
|
|
@@ -2,7 +2,6 @@
|
|
|
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 type * as Common from '../../core/common/common.js';
|
|
6
5
|
import type * as Platform from '../../core/platform/platform.js';
|
|
7
6
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
8
7
|
import * as TextUtils from '../../core/text_utils/text_utils.js';
|
|
@@ -42,9 +41,8 @@ interface InputData {
|
|
|
42
41
|
|
|
43
42
|
const inputCache = new WeakMap<Workspace.UISourceCode.UISourceCode, Promise<InputData>>();
|
|
44
43
|
|
|
45
|
-
async function prepareInput(uiSourceCode: Workspace.UISourceCode.UISourceCode, content: string
|
|
46
|
-
|
|
47
|
-
const formattedContent = await format(uiSourceCode, content, settings);
|
|
44
|
+
async function prepareInput(uiSourceCode: Workspace.UISourceCode.UISourceCode, content: string): Promise<InputData> {
|
|
45
|
+
const formattedContent = await format(uiSourceCode, content);
|
|
48
46
|
const text = new TextUtils.Text.Text(formattedContent ? formattedContent.formattedContent : content);
|
|
49
47
|
let performanceData = uiSourceCode.getDecorationData(Workspace.UISourceCode.DecoratorType.PERFORMANCE) as
|
|
50
48
|
Workspace.UISourceCode.LineColumnProfileMap |
|
|
@@ -61,14 +59,14 @@ async function prepareInput(uiSourceCode: Workspace.UISourceCode.UISourceCode, c
|
|
|
61
59
|
}
|
|
62
60
|
|
|
63
61
|
/** Formatting and parsing line endings for Text is expensive, so cache it. */
|
|
64
|
-
async function prepareInputAndCache(uiSourceCode: Workspace.UISourceCode.UISourceCode,
|
|
65
|
-
|
|
62
|
+
async function prepareInputAndCache(uiSourceCode: Workspace.UISourceCode.UISourceCode,
|
|
63
|
+
content: string): Promise<InputData> {
|
|
66
64
|
let cachedPromise = inputCache.get(uiSourceCode);
|
|
67
65
|
if (cachedPromise) {
|
|
68
66
|
return await cachedPromise;
|
|
69
67
|
}
|
|
70
68
|
|
|
71
|
-
cachedPromise = prepareInput(uiSourceCode, content
|
|
69
|
+
cachedPromise = prepareInput(uiSourceCode, content);
|
|
72
70
|
inputCache.set(uiSourceCode, cachedPromise);
|
|
73
71
|
return await cachedPromise;
|
|
74
72
|
}
|
|
@@ -248,8 +246,8 @@ export async function getFunctionCodeFromLocation(
|
|
|
248
246
|
return await getFunctionCodeFromRawLocation(rawLocation, debuggerWorkspaceBinding, options);
|
|
249
247
|
}
|
|
250
248
|
|
|
251
|
-
async function format(uiSourceCode: Workspace.UISourceCode.UISourceCode,
|
|
252
|
-
|
|
249
|
+
async function format(uiSourceCode: Workspace.UISourceCode.UISourceCode,
|
|
250
|
+
content: string): Promise<Formatter.ScriptFormatter.FormattedContent|null> {
|
|
253
251
|
const contentType = uiSourceCode.contentType();
|
|
254
252
|
const shouldFormat = !contentType.isFromSourceMap() && (contentType.isDocument() || contentType.isScript()) &&
|
|
255
253
|
TextUtils.TextUtils.isMinified(content);
|
|
@@ -257,7 +255,7 @@ async function format(uiSourceCode: Workspace.UISourceCode.UISourceCode, content
|
|
|
257
255
|
return null;
|
|
258
256
|
}
|
|
259
257
|
|
|
260
|
-
return await Formatter.ScriptFormatter.formatScriptContent(
|
|
258
|
+
return await Formatter.ScriptFormatter.formatScriptContent(contentType.canonicalMimeType(), content, '\t');
|
|
261
259
|
}
|
|
262
260
|
|
|
263
261
|
/**
|
|
@@ -278,7 +276,6 @@ export async function getFunctionCodeFromRawLocation(
|
|
|
278
276
|
return null;
|
|
279
277
|
}
|
|
280
278
|
|
|
281
|
-
const
|
|
282
|
-
const inputData = await prepareInputAndCache(functionBounds.uiSourceCode, content, settings);
|
|
279
|
+
const inputData = await prepareInputAndCache(functionBounds.uiSourceCode, content);
|
|
283
280
|
return createFunctionCode(inputData, functionBounds, options);
|
|
284
281
|
}
|
|
@@ -157,17 +157,6 @@ function createLanternRequest(
|
|
|
157
157
|
resourceType = 'Fetch';
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
// TODO: set decodedBodyLength for data urls in Trace Engine.
|
|
161
|
-
let resourceSize = request.args.data.decodedBodyLength ?? 0;
|
|
162
|
-
if (url.protocol === 'data:' && resourceSize === 0) {
|
|
163
|
-
const commaIndex = url.pathname.indexOf(',');
|
|
164
|
-
if (url.pathname.substring(0, commaIndex).includes(';base64')) {
|
|
165
|
-
resourceSize = atob(url.pathname.substring(commaIndex + 1)).length;
|
|
166
|
-
} else {
|
|
167
|
-
resourceSize = url.pathname.length - commaIndex - 1;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
160
|
// NetworkRequestsHandler defaults missing `renderBlocking` to 'non_blocking',
|
|
172
161
|
// so only populate `renderBlocking` when it was explicitly set on the raw
|
|
173
162
|
// ResourceSendRequest event or updated via PreloadRenderBlockingStatusChange.
|
|
@@ -189,7 +178,7 @@ function createLanternRequest(
|
|
|
189
178
|
responseHeadersEndTime: request.args.data.syntheticData.downloadStart / 1000,
|
|
190
179
|
networkEndTime: request.args.data.syntheticData.finishTime / 1000,
|
|
191
180
|
transferSize: request.args.data.encodedDataLength,
|
|
192
|
-
resourceSize,
|
|
181
|
+
resourceSize: request.args.data.decodedBodyLength ?? 0,
|
|
193
182
|
fromDiskCache: request.args.data.syntheticData.isDiskCached,
|
|
194
183
|
fromMemoryCache: request.args.data.syntheticData.isMemoryCached,
|
|
195
184
|
isLinkPreload: request.args.data.isLinkPreload,
|
|
@@ -321,8 +310,8 @@ function createNetworkRequests(trace: Lantern.Types.Trace, data: Handlers.Types.
|
|
|
321
310
|
|
|
322
311
|
redirectedRequest.timing = {
|
|
323
312
|
requestTime: redirectedRequest.networkRequestTime / 1000,
|
|
324
|
-
receiveHeadersStart: redirectedRequest.responseHeadersEndTime,
|
|
325
|
-
receiveHeadersEnd: redirectedRequest.responseHeadersEndTime,
|
|
313
|
+
receiveHeadersStart: redirectedRequest.responseHeadersEndTime - redirectedRequest.networkRequestTime,
|
|
314
|
+
receiveHeadersEnd: redirectedRequest.responseHeadersEndTime - redirectedRequest.networkRequestTime,
|
|
326
315
|
proxyStart: -1,
|
|
327
316
|
proxyEnd: -1,
|
|
328
317
|
dnsStart: -1,
|
|
@@ -351,6 +340,9 @@ function createNetworkRequests(trace: Lantern.Types.Trace, data: Handlers.Types.
|
|
|
351
340
|
requestChain.push(redirectedRequest);
|
|
352
341
|
lanternRequests.push(redirectedRequest);
|
|
353
342
|
}
|
|
343
|
+
if (requestChain.length) {
|
|
344
|
+
request.rendererStartTime = requestChain[requestChain.length - 1].networkEndTime;
|
|
345
|
+
}
|
|
354
346
|
requestChain.push(request);
|
|
355
347
|
lanternRequests.push(request);
|
|
356
348
|
|
|
@@ -408,23 +408,57 @@ export class BottomUpRootNode extends Node {
|
|
|
408
408
|
const forceGroupIdCallback = this.forceGroupIdCallback;
|
|
409
409
|
|
|
410
410
|
const idToIsCacheHit = new Map<string, boolean>();
|
|
411
|
+
|
|
412
|
+
// Node IDs are cached so that every event with the same ID reuses one
|
|
413
|
+
// string. Building a new ID string per event, and hashing it again on
|
|
414
|
+
// each Map lookup, is a large part of the cost of this loop on big
|
|
415
|
+
// traces.
|
|
416
|
+
const profileCallIdByCallFrame = new Map<Protocol.Runtime.CallFrame, string>();
|
|
417
|
+
// Grouped IDs are looked up by ID and then by group ID, because keying a
|
|
418
|
+
// flat Map by `${id}-${groupId}` would build a new string per event.
|
|
419
|
+
const groupedIdsByEventId = new Map<string, Map<string, string>>();
|
|
420
|
+
const nodeIdForEvent = (e: Types.Events.Event): string => {
|
|
421
|
+
let id: string;
|
|
422
|
+
if (Types.Events.isProfileCall(e)) {
|
|
423
|
+
// Profile calls for the same frame share one callFrame object, and
|
|
424
|
+
// their ID only depends on its fields.
|
|
425
|
+
const cachedId = profileCallIdByCallFrame.get(e.callFrame);
|
|
426
|
+
if (cachedId === undefined) {
|
|
427
|
+
id = generateEventID(e);
|
|
428
|
+
profileCallIdByCallFrame.set(e.callFrame, id);
|
|
429
|
+
} else {
|
|
430
|
+
id = cachedId;
|
|
431
|
+
}
|
|
432
|
+
} else {
|
|
433
|
+
id = generateEventID(e);
|
|
434
|
+
}
|
|
435
|
+
if (!forceGroupIdCallback || !eventGroupIdCallback) {
|
|
436
|
+
return id;
|
|
437
|
+
}
|
|
438
|
+
const groupId = eventGroupIdCallback(e);
|
|
439
|
+
let groupedIds = groupedIdsByEventId.get(id);
|
|
440
|
+
if (!groupedIds) {
|
|
441
|
+
groupedIds = new Map();
|
|
442
|
+
groupedIdsByEventId.set(id, groupedIds);
|
|
443
|
+
}
|
|
444
|
+
let groupedId = groupedIds.get(groupId);
|
|
445
|
+
if (groupedId === undefined) {
|
|
446
|
+
groupedId = `${id}-${groupId}`;
|
|
447
|
+
groupedIds.set(groupId, groupedId);
|
|
448
|
+
}
|
|
449
|
+
return groupedId;
|
|
450
|
+
};
|
|
451
|
+
|
|
411
452
|
for (const e of this.events) {
|
|
412
453
|
if (Types.Events.isReceivedDataEvent(e) && e.name === 'ResourceReceiveResponse') {
|
|
413
|
-
|
|
414
|
-
if (this.forceGroupIdCallback && this.eventGroupIdCallback) {
|
|
415
|
-
id = `${id}-${this.eventGroupIdCallback(e)}`;
|
|
416
|
-
}
|
|
417
|
-
idToIsCacheHit.set(id, e.args.data.fromCache || false);
|
|
454
|
+
idToIsCacheHit.set(nodeIdForEvent(e), e.args.data.fromCache || false);
|
|
418
455
|
}
|
|
419
456
|
}
|
|
420
457
|
|
|
421
458
|
// encodedDataLength is provided solely on instant events.
|
|
422
459
|
const sumTransferSizeOfInstantEvent = (e: Types.Events.Event): void => {
|
|
423
460
|
if (Types.Events.isReceivedDataEvent(e)) {
|
|
424
|
-
|
|
425
|
-
if (this.forceGroupIdCallback && this.eventGroupIdCallback) {
|
|
426
|
-
id = `${id}-${this.eventGroupIdCallback(e)}`;
|
|
427
|
-
}
|
|
461
|
+
const id = nodeIdForEvent(e);
|
|
428
462
|
let node = nodeById.get(id);
|
|
429
463
|
if (!node) {
|
|
430
464
|
node = new BottomUpNode(root, id, e, false, root);
|
|
@@ -477,10 +511,7 @@ export class BottomUpRootNode extends Node {
|
|
|
477
511
|
const duration = actualEndTime - Math.max(currentStartTime, startTime);
|
|
478
512
|
selfTimeStack[selfTimeStack.length - 1] -= duration;
|
|
479
513
|
selfTimeStack.push(duration);
|
|
480
|
-
|
|
481
|
-
if (forceGroupIdCallback && eventGroupIdCallback) {
|
|
482
|
-
id = `${id}-${eventGroupIdCallback(e)}`;
|
|
483
|
-
}
|
|
514
|
+
const id = nodeIdForEvent(e);
|
|
484
515
|
|
|
485
516
|
idStack.push(id);
|
|
486
517
|
|