chrome-devtools-frontend 1.0.1706026 → 1.0.1709383

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.
Files changed (225) hide show
  1. package/.agents/skills/code-review/SKILL.md +121 -0
  2. package/AUTHORS +2 -0
  3. package/front_end/core/common/Color.ts +6 -0
  4. package/front_end/core/common/VersionController.ts +0 -53
  5. package/front_end/core/root/Runtime.ts +0 -41
  6. package/front_end/core/sdk/CSSModel.ts +57 -0
  7. package/front_end/core/sdk/CSSPropertyParser.ts +10 -17
  8. package/front_end/core/sdk/DOMModel.ts +13 -6
  9. package/front_end/core/sdk/DebuggerModel.ts +90 -56
  10. package/front_end/core/sdk/NetworkRequest.ts +70 -12
  11. package/front_end/core/sdk/OverlayModel.ts +47 -0
  12. package/front_end/core/sdk/PageResourceLoader.ts +26 -6
  13. package/front_end/core/sdk/SourceMap.ts +37 -9
  14. package/front_end/core/sdk/SourceMapScopesInfo.ts +223 -86
  15. package/front_end/core/text_utils/ContentData.ts +18 -1
  16. package/front_end/core/text_utils/TextUtils.ts +1 -1
  17. package/front_end/entrypoints/devtools_app/devtools_app.ts +1 -0
  18. package/front_end/entrypoints/heap_snapshot_worker/ContextAnalyzer.ts +102 -4
  19. package/front_end/entrypoints/main/MainImpl.ts +2 -21
  20. package/front_end/generated/InspectorBackendCommands.ts +9 -2
  21. package/front_end/generated/SupportedCSSProperties.ts +12 -3
  22. package/front_end/generated/protocol-mapping.d.ts +31 -0
  23. package/front_end/generated/protocol-proxy-api.d.ts +32 -0
  24. package/front_end/generated/protocol.ts +19 -3
  25. package/front_end/models/ai_assistance/AiAgent2.ts +127 -2
  26. package/front_end/models/ai_assistance/AiConversation.ts +2 -2
  27. package/front_end/models/ai_assistance/AiUtils.ts +4 -0
  28. package/front_end/models/ai_assistance/agents/AiAgent.ts +64 -13
  29. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +2 -2
  30. package/front_end/models/ai_assistance/agents/ExecuteJavascript.ts +4 -1
  31. package/front_end/models/ai_assistance/agents/PerformanceAgent.snapshot.txt +257 -2
  32. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +1 -1
  33. package/front_end/models/ai_assistance/ai_assistance.ts +2 -2
  34. package/front_end/models/ai_assistance/contexts/{AccessibilityContext.snapshot.txt → LighthouseContext.snapshot.txt} +23 -2
  35. package/front_end/models/ai_assistance/contexts/{AccessibilityContext.ts → LighthouseContext.ts} +24 -5
  36. package/front_end/models/ai_assistance/data_formatters/LighthouseFormatter.ts +26 -3
  37. package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +15 -16
  38. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.snapshot.txt +8 -18
  39. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +2 -2
  40. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +81 -103
  41. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +202 -15
  42. package/front_end/models/ai_assistance/skills/Skill.ts +1 -2
  43. package/front_end/models/ai_assistance/skills/SkillRegistry.ts +2 -0
  44. package/front_end/models/ai_assistance/skills/lighthouse.md +33 -0
  45. package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +6 -0
  46. package/front_end/models/ai_assistance/tools/GetCookieValues.ts +3 -0
  47. package/front_end/models/ai_assistance/tools/GetDetailedCallTree.ts +2 -0
  48. package/front_end/models/ai_assistance/tools/GetElementAccessibilityDetails.ts +2 -0
  49. package/front_end/models/ai_assistance/tools/GetInsightDetails.ts +2 -0
  50. package/front_end/models/ai_assistance/tools/GetLighthouseAudits.ts +8 -7
  51. package/front_end/models/ai_assistance/tools/GetNetworkRequestDetails.ts +2 -0
  52. package/front_end/models/ai_assistance/tools/GetSourceContent.ts +2 -0
  53. package/front_end/models/ai_assistance/tools/GetStorageBreakdown.ts +2 -0
  54. package/front_end/models/ai_assistance/tools/GetStorageValues.ts +3 -0
  55. package/front_end/models/ai_assistance/tools/GetStyles.ts +2 -0
  56. package/front_end/models/ai_assistance/tools/GetTraceEventByKey.ts +3 -1
  57. package/front_end/models/ai_assistance/tools/GetTraceFunctionCode.ts +2 -0
  58. package/front_end/models/ai_assistance/tools/GetTraceMainThreadSummary.ts +2 -0
  59. package/front_end/models/ai_assistance/tools/GetTraceNetworkSummary.ts +2 -0
  60. package/front_end/models/ai_assistance/tools/GetTraceResourceContent.ts +2 -0
  61. package/front_end/models/ai_assistance/tools/ListCookies.ts +2 -0
  62. package/front_end/models/ai_assistance/tools/ListNetworkRequests.ts +2 -0
  63. package/front_end/models/ai_assistance/tools/ListPageOrigins.ts +2 -0
  64. package/front_end/models/ai_assistance/tools/ListSources.ts +2 -0
  65. package/front_end/models/ai_assistance/tools/ListStorageKeys.ts +2 -0
  66. package/front_end/models/ai_assistance/tools/RecordPerformanceTrace.ts +2 -0
  67. package/front_end/models/ai_assistance/tools/ResolveDevtoolsNodePath.ts +2 -0
  68. package/front_end/models/ai_assistance/tools/RunLighthouse.ts +20 -12
  69. package/front_end/models/ai_assistance/tools/SelectTraceEventByKey.ts +2 -0
  70. package/front_end/models/ai_assistance/tools/Tool.ts +53 -0
  71. package/front_end/models/bindings/CompilerScriptMapping.ts +102 -45
  72. package/front_end/models/bindings/DebuggerLanguagePlugins.ts +25 -33
  73. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +70 -49
  74. package/front_end/models/bindings/SourceMapStepping.ts +50 -0
  75. package/front_end/models/bindings/StylesSourceMapping.ts +3 -0
  76. package/front_end/models/bindings/bindings.ts +2 -0
  77. package/front_end/models/emulation/DeviceModeModel.ts +85 -62
  78. package/front_end/models/extensions/ExtensionEndpoint.ts +27 -6
  79. package/front_end/models/extensions/LanguageExtensionEndpoint.ts +106 -21
  80. package/front_end/models/extensions/RecorderExtensionEndpoint.ts +4 -2
  81. package/front_end/models/har/Importer.ts +2 -3
  82. package/front_end/models/javascript_metadata/NativeFunctions.ts +6 -2
  83. package/front_end/models/lighthouse/LighthouseReporterTypes.ts +5 -1
  84. package/front_end/models/persistence/NetworkPersistenceManager.ts +4 -3
  85. package/front_end/models/source_map_scopes/NamesResolver.ts +30 -13
  86. package/front_end/models/stack_trace/StackTraceImpl.ts +138 -47
  87. package/front_end/models/stack_trace/StackTraceModel.ts +117 -84
  88. package/front_end/models/stack_trace/Trie.ts +27 -0
  89. package/front_end/models/trace/LanternComputationData.ts +8 -0
  90. package/front_end/models/trace/Processor.ts +2 -1
  91. package/front_end/models/trace/lantern/core/NetworkAnalyzer.ts +7 -2
  92. package/front_end/models/trace/lantern/graph/NetworkNode.ts +14 -0
  93. package/front_end/models/trace/lantern/graph/PageDependencyGraph.ts +1 -1
  94. package/front_end/models/trace/lantern/simulation/ConnectionPool.ts +4 -4
  95. package/front_end/models/trace/lantern/simulation/Simulator.ts +6 -2
  96. package/front_end/models/trace/lantern/simulation/TCPConnection.ts +12 -12
  97. package/front_end/models/trace/lantern/types/Lantern.ts +8 -0
  98. package/front_end/panels/accessibility/ARIAAttributesView.ts +6 -6
  99. package/front_end/panels/accessibility/AccessibilityAnnouncementRecordingView.ts +2 -2
  100. package/front_end/panels/accessibility/AccessibilityNodeView.ts +6 -9
  101. package/front_end/panels/accessibility/AccessibilitySidebarView.ts +83 -69
  102. package/front_end/panels/accessibility/AccessibilitySubPane.ts +24 -9
  103. package/front_end/panels/accessibility/SourceOrderView.ts +7 -3
  104. package/front_end/panels/accessibility/accessibilitySidebarView.css +5 -3
  105. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +14 -12
  106. package/front_end/panels/ai_assistance/components/ChatInput.ts +1 -1
  107. package/front_end/panels/ai_assistance/components/ChatMessage.ts +121 -13
  108. package/front_end/panels/ai_assistance/components/chatMessage.css +47 -0
  109. package/front_end/panels/application/BackgroundServiceView.ts +31 -33
  110. package/front_end/panels/application/IndexedDBModel.ts +8 -20
  111. package/front_end/panels/application/IndexedDBViews.ts +2 -6
  112. package/front_end/panels/application/ServiceWorkerUpdateCycleView.ts +8 -8
  113. package/front_end/panels/application/ServiceWorkersView.ts +44 -52
  114. package/front_end/panels/application/WebMCPView.ts +50 -50
  115. package/front_end/panels/application/serviceWorkersView.css +1 -1
  116. package/front_end/panels/comments/CommentsPane.ts +266 -0
  117. package/front_end/panels/comments/comments-meta.ts +47 -0
  118. package/front_end/panels/comments/comments.ts +9 -0
  119. package/front_end/panels/comments/commentsPane.css +206 -0
  120. package/front_end/panels/common/CommentThreadWidget.ts +30 -1
  121. package/front_end/panels/common/CommentsOverlayWidget.ts +42 -38
  122. package/front_end/panels/common/CommentsStatusBarPill.ts +3 -1
  123. package/front_end/panels/common/common-meta.ts +21 -9
  124. package/front_end/panels/console/ConsoleInsightTeaser.ts +25 -19
  125. package/front_end/panels/console/ConsoleViewMessage.ts +52 -23
  126. package/front_end/panels/console/ConsoleViewport.ts +1 -1
  127. package/front_end/panels/console/SymbolizedErrorWidget.ts +18 -9
  128. package/front_end/panels/console/console-meta.ts +1 -5
  129. package/front_end/panels/elements/CSSValueTraceView.ts +4 -4
  130. package/front_end/panels/elements/ComputedStyleWidget.ts +46 -42
  131. package/front_end/panels/elements/DOMPath.ts +11 -1
  132. package/front_end/panels/elements/DOMTreeContextMenu.ts +15 -0
  133. package/front_end/panels/elements/DOMTreeWidget.ts +237 -606
  134. package/front_end/panels/elements/ElementsPanel.ts +15 -16
  135. package/front_end/panels/elements/ElementsTreeElement.ts +24 -18
  136. package/front_end/panels/elements/EventListenersWidget.ts +5 -3
  137. package/front_end/panels/elements/InspectElementModeController.ts +6 -3
  138. package/front_end/panels/elements/LayoutPane.ts +3 -3
  139. package/front_end/panels/elements/PropertyRenderer.ts +132 -87
  140. package/front_end/panels/elements/StandaloneStylesContainer.ts +7 -3
  141. package/front_end/panels/elements/StylePropertiesSection.ts +49 -4
  142. package/front_end/panels/elements/StylePropertyTreeElement.ts +139 -36
  143. package/front_end/panels/elements/StylesContainer.ts +2 -1
  144. package/front_end/panels/elements/StylesSidebarPane.ts +75 -16
  145. package/front_end/panels/elements/components/CSSPropertyDocsView.ts +2 -1
  146. package/front_end/panels/elements/elements-meta.ts +24 -75
  147. package/front_end/panels/emulation/DeviceModeToolbar.ts +5 -2
  148. package/front_end/panels/emulation/DeviceModeView.ts +5 -2
  149. package/front_end/panels/emulation/emulation-meta.ts +3 -8
  150. package/front_end/panels/layer_viewer/Layers3DView.ts +8 -3
  151. package/front_end/panels/layer_viewer/layer_viewer-meta.ts +2 -5
  152. package/front_end/panels/lighthouse/LighthouseController.ts +9 -4
  153. package/front_end/panels/lighthouse/LighthouseReportRenderer.ts +13 -3
  154. package/front_end/panels/network/NetworkConfigView.ts +261 -190
  155. package/front_end/panels/network/NetworkLogView.ts +7 -5
  156. package/front_end/panels/network/NetworkPanel.ts +4 -3
  157. package/front_end/panels/network/NetworkWaterfallColumn.ts +7 -4
  158. package/front_end/panels/network/RequestPayloadView.ts +22 -14
  159. package/front_end/panels/network/network-meta.ts +23 -34
  160. package/front_end/panels/profiler/HeapDetachedElementsDataGrid.ts +0 -1
  161. package/front_end/panels/profiler/HeapProfileView.ts +20 -24
  162. package/front_end/panels/profiler/ProfilesPanel.ts +8 -3
  163. package/front_end/panels/recorder/RecordingView.ts +42 -47
  164. package/front_end/panels/recorder/StepEditor.ts +1 -0
  165. package/front_end/panels/recorder/recordingView.css +4 -4
  166. package/front_end/panels/screencast/ScreencastView.ts +6 -4
  167. package/front_end/panels/sources/CSSPlugin.ts +11 -0
  168. package/front_end/panels/sources/CoveragePlugin.ts +34 -23
  169. package/front_end/panels/sources/NavigatorView.ts +97 -52
  170. package/front_end/panels/sources/Plugin.ts +15 -1
  171. package/front_end/panels/sources/SourcesView.ts +47 -80
  172. package/front_end/panels/sources/TabbedEditorContainer.ts +63 -34
  173. package/front_end/panels/sources/UISourceCodeFrame.ts +11 -2
  174. package/front_end/panels/sources/navigatorTree.css +2 -2
  175. package/front_end/panels/timeline/TimelineHistoryManager.ts +2 -4
  176. package/front_end/panels/timeline/components/LiveMetricsView.ts +7 -20
  177. package/front_end/panels/timeline/components/MetricCard.ts +262 -315
  178. package/front_end/panels/timeline/components/liveMetricsView.css +4 -0
  179. package/front_end/panels/timeline/components/metricCard.css +2 -24
  180. package/front_end/panels/timeline/overlays/OverlaysImpl.ts +33 -17
  181. package/front_end/panels/timeline/overlays/components/TimeRangeOverlay.ts +182 -130
  182. package/front_end/panels/timeline/overlays/components/timeRangeOverlay.css +76 -74
  183. package/front_end/panels/whats_new/WhatsNewImpl.ts +2 -1
  184. package/front_end/panels/whats_new/whats_new-meta.ts +2 -5
  185. package/front_end/third_party/chromium/README.chromium +1 -1
  186. package/front_end/third_party/web-vitals/README.chromium +2 -2
  187. package/front_end/third_party/web-vitals/package/README.md +5 -3
  188. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onINP.js +1 -1
  189. package/front_end/third_party/web-vitals/package/dist/modules/attribution/onLCP.js +8 -5
  190. package/front_end/third_party/web-vitals/package/package.json +1 -1
  191. package/front_end/third_party/web-vitals/package/src/attribution/onINP.ts +1 -1
  192. package/front_end/third_party/web-vitals/package/src/attribution/onLCP.ts +9 -5
  193. package/front_end/third_party/web-vitals/rebuild.sh +2 -2
  194. package/front_end/ui/comments/CommentAnchorResolver.ts +17 -0
  195. package/front_end/ui/components/suggestion_input/SuggestionInput.ts +10 -1
  196. package/front_end/ui/components/text_editor/AiCodeCompletionTeaser.ts +1 -1
  197. package/front_end/ui/components/text_editor/AiCodeGenerationTeaser.ts +2 -2
  198. package/front_end/ui/components/text_editor/aiCodeCompletionTeaser.css +0 -11
  199. package/front_end/ui/components/text_editor/aiCodeGenerationTeaser.css +0 -11
  200. package/front_end/ui/components/text_editor/config.ts +2 -1
  201. package/front_end/ui/legacy/SoftDropDown.ts +17 -4
  202. package/front_end/ui/legacy/StackPane.ts +141 -0
  203. package/front_end/ui/legacy/TabbedPane.ts +67 -12
  204. package/front_end/ui/legacy/TextPrompt.ts +37 -7
  205. package/front_end/ui/legacy/Toolbar.ts +36 -14
  206. package/front_end/ui/legacy/Widget.ts +3 -3
  207. package/front_end/ui/legacy/components/inline_editor/PositionAreaEditor.ts +85 -0
  208. package/front_end/ui/legacy/components/inline_editor/positionAreaEditor.css +61 -0
  209. package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +93 -31
  210. package/front_end/ui/legacy/components/quick_open/FilteredListWidget.ts +15 -7
  211. package/front_end/ui/legacy/components/utils/Linkifier.ts +25 -45
  212. package/front_end/ui/legacy/inspectorCommon.css +11 -0
  213. package/front_end/ui/legacy/legacy.ts +2 -0
  214. package/front_end/ui/legacy/softContextMenu.css +2 -0
  215. package/front_end/ui/legacy/tabbedPane.css +12 -8
  216. package/front_end/ui/settings/ConsoleSettings.ts +7 -0
  217. package/front_end/ui/settings/ElementsSettings.ts +93 -0
  218. package/front_end/ui/settings/EmulationSettings.ts +17 -0
  219. package/front_end/ui/settings/LayerViewerSettings.ts +12 -0
  220. package/front_end/ui/settings/NetworkSettings.ts +26 -0
  221. package/front_end/ui/settings/WhatsNewSettings.ts +11 -0
  222. package/front_end/ui/settings/settings.ts +10 -0
  223. package/front_end/ui/visual_logging/KnownContextValues.ts +17 -0
  224. package/inspector_overlay/highlight_anchor.ts +1 -1
  225. package/package.json +1 -1
@@ -0,0 +1,121 @@
1
+ ---
2
+ name: code-review
3
+ description: Generic checklist for reviewing DevTools CLs (your own before upload, or someone else's on Gerrit). Covers test correctness (tautological/vacuous tests, cleanup, leaks), code clarity, CL hygiene, and points to the specialized skills to consult for imports, UI, testing, strings, models, and verification. Use when asked to review a CL, a diff, a patch, or to self-review before `git cl upload`.
4
+ ---
5
+
6
+ # Code Review
7
+
8
+ This checklist comes from recurring reviewer feedback on landed DevTools CLs.
9
+ Use it for self-review before upload and for reviewing other people's CLs.
10
+
11
+ ## 1. Gather context
12
+
13
+ - **Local change:** `git diff origin/main...HEAD` (or `git show HEAD` for a
14
+ single-commit branch). To learn about the branch and upload workflow, see the
15
+ `devtools-version-control` skill.
16
+ - **Gerrit CL:** strip the leading `)]}'` line from each response to get JSON:
17
+ - Diff: `git cl diff` (for the current branch), or fetch the patch set.
18
+ - Inline comments:
19
+ `curl -s https://chromium-review.googlesource.com/changes/devtools%2Fdevtools-frontend~<CL_NUMBER>/comments | tail -n +2`
20
+ - Messages:
21
+ `.../changes/devtools%2Fdevtools-frontend~<CL_NUMBER>/messages`
22
+ - Read the CL description first. Then check that the diff does what the
23
+ description says, and nothing else.
24
+
25
+ ## 2. Consult the specialized skills
26
+
27
+ Load the skill that matches what the diff touches, and apply its rules:
28
+
29
+ | If the diff touches… | Use skill |
30
+ | :--- | :--- |
31
+ | Any `import` statement, or a new cross-module dependency | `devtools-imports` |
32
+ | `UI.Widget`, lit-html views, components, CSS | `devtools-ui-widgets` |
33
+ | Migration of legacy imperative DOM to widgets or Lit | `ui-eng-vision-orchestrator` (and its sub-skills) |
34
+ | New or changed tests: choosing unit, API, or E2E | `devtools-testing-guidance` |
35
+ | Tests that use `describeWithEnvironment` or `describeWithMockConnection`, or foundation modules | `foundation-test-migration` |
36
+ | Ported Chromium web tests (`web_tests/http/tests/devtools`) | `migrate-chromium-test` |
37
+ | Flaky or disabled tests, or `it.skip` / `it.skipOnPlatforms` | `fix-tests` |
38
+ | `UIStrings` / user-facing text | `devtools-ux-writing-refactor` |
39
+ | Rendering user-controlled strings (URLs, names, console text) | `devtools-unicode-escaping` |
40
+ | `front_end/models/*`, `BUILD.gn`, `devtools_grd_files.gni`, entrypoints | `devtools-model-management` |
41
+ | Merging modules or consolidating `BUILD.gn` | `merging-devtools-module` |
42
+ | `Settings` registrations and descriptors | `devtools-setting-migration` |
43
+ | Stack traces, source maps, `DebuggerWorkspaceBinding` | `devtools-source-maps` |
44
+ | Building, running tests, or lint | `devtools-verification` |
45
+
46
+ ## 3. Test correctness (the most common review feedback)
47
+
48
+ - **Tautological tests:** A test must exercise real production code. If a
49
+ mock does the thing the test asserts (for example, a mocked `DOM.undo` that
50
+ calls `removeSection()` directly, followed by an assertion that the section
51
+ was removed), the test checks the mock and nothing else. Mock the *boundary*
52
+ instead (for example, have the CDP stub emit `CSSModel.Events.StyleSheetChanged`)
53
+ and let production code react to it.
54
+ - **Vacuous tests:** Look for local promises or data that are never connected
55
+ to DevTools logic, or stubs (like `initialize`) that skip the code path under
56
+ test. These tests pass because nothing happens.
57
+ - **Assertions that check the setup:** For example,
58
+ `assert.isNull(pane.node())` right after `pane.setNodeForTest(null)`. Each
59
+ assertion should verify the behavior that the test name describes.
60
+ - **Test lives where it belongs:** A test in `Foo.test.ts` should exercise
61
+ `Foo`. Move logic-only tests to the model's test file (for example,
62
+ `CSSMatchedStyles.test.ts`). Otherwise, render the UI and assert on the DOM.
63
+ - **Test covers the scenario it claims:** For example, an "iframe event
64
+ listeners" test must select a node *inside* the iframe. It is not enough
65
+ that it passes on `<body>` of the main frame.
66
+ - **Right suite:** Ask whether an E2E test could be a unit test, or whether the
67
+ E2E coverage is intentional for a user story. See `devtools-testing-guidance`.
68
+ - **E2E selectors match real UI:** Labels and `aria-label`s must match the
69
+ actual strings, for example "Show user agent shadow DOM" and not "User agent
70
+ shadow DOM". Check that the setting being toggled actually affects the
71
+ scenario.
72
+ - **Fail fast:** Throw or assert when a required value is missing. Don't let
73
+ the test time out later.
74
+
75
+ ## 4. Test hygiene and cleanup
76
+
77
+ - Pair every `beforeEach` singleton creation with a cleanup in `afterEach`
78
+ (for example, `CSSWorkspaceBinding.removeInstance()` or
79
+ `WorkspaceImpl.removeInstance()`) so that state does not leak between tests.
80
+ - Restore fake timers in `try { … } finally { clock.restore(); }`, or use the
81
+ sandbox or cleanup that the test runner provides. Keep the scope of fake
82
+ timers small.
83
+ - Don't stub the same method twice without calling `restore()` first. Sinon
84
+ throws `Attempted to wrap … which is already wrapped` when the object is the
85
+ same instance.
86
+ - Remove guards that were copied from helpers for no reason (for example,
87
+ `if (!stub.called) …` in a test that stubs the method only once).
88
+
89
+ ## 5. Code clarity
90
+
91
+ - Don't take detours to reach a value. If a module is imported, call
92
+ `TextUtils.TextRange.TextRange.fromObject(...)` directly instead of going
93
+ through `rule.style.range.constructor`.
94
+ - Look for dead code, leftover debug code, commented-out blocks, and unrelated
95
+ formatting churn.
96
+ - Check that the change stays in scope. Flag unrelated refactors that should be
97
+ split into a separate CL.
98
+ - Check for lifecycle issues: event listeners and observers that are added
99
+ without being removed, and async work that continues after a widget is
100
+ detached.
101
+
102
+ ## 6. CL hygiene
103
+
104
+ - The description explains *why*, including external dependencies (for
105
+ example, "V8 will stop emitting X; this must land first").
106
+ - Include a `Bug:` or `Fixed:` trailer, or `Bug: None`. Keep lines under 72
107
+ characters.
108
+ - For migrations and stacked series, list the legacy tests or files covered,
109
+ and number the series (for example, `(13/16)`).
110
+ - Disabled tests reference a bug.
111
+ - Presubmit, lint, and format pass. See `devtools-verification`.
112
+
113
+ ## 7. Writing review comments
114
+
115
+ - Be specific: cite file and line, explain the concrete failure mode (such as
116
+ a leak, a hang, or "passes vacuously"), and suggest a fix. Include a code
117
+ snippet when it helps.
118
+ - Separate blocking issues from nits and questions (for example, "Should we
119
+ move this to a unit test?").
120
+ - When a reviewer's concern is not an actual bug, reply with the rationale.
121
+ Don't make a silent change.
package/AUTHORS CHANGED
@@ -53,6 +53,7 @@ Han Xu <suyanhanx@gmail.com>
53
53
  Helmut Januschka <helmut@januschka.com>
54
54
  Henry Lim <henry@limhenry.xyz>
55
55
  Hojeong Park <parkhj062@gmail.com>
56
+ Ivan Akulov <gxoptg@gmail.com>
56
57
  Jacky Hu <flameddd@gmail.com>
57
58
  Jake Mulhern <mulherje@gmail.com>
58
59
  Jan Keitel <jan.keitel@gmail.com>
@@ -99,6 +100,7 @@ Ryuhei Shima <shimaryuhei@gmail.com>
99
100
  Samuel Maddock <samuelmaddock@electronjs.org>
100
101
  Satvic Dhawan <satvicdhawan14@gmail.com>
101
102
  Sebastian Markbåge <sebastian@calyptus.eu>
103
+ Sebeen Kwon <a856412@gmail.com>
102
104
  Semih Dogan <semih702do@gmail.com>
103
105
  Serg Kryvonos <sergeikrivonos@gmail.com>
104
106
  Sergio Avalos <sergio.avalos@gmail.com>
@@ -2458,6 +2458,12 @@ export const PageHighlight: Record<string, Legacy> = {
2458
2458
  GapBackground: Legacy.fromRGBA([...LAYOUT_LINES_HIGHLIGHT_COLOR, .3]),
2459
2459
  GapHatch: Legacy.fromRGBA([...LAYOUT_LINES_HIGHLIGHT_COLOR, .8]),
2460
2460
  GridAreaBorder: Legacy.fromRGBA([26, 115, 232, 1]),
2461
+ AnchorIMCB: Legacy.fromRGBA([127, 32, 210, 1]),
2462
+ AnchorIMCBBackground: Legacy.fromRGBA([127, 32, 210, 0.15]),
2463
+ AnchorInsetsBackground: Legacy.fromRGBA([246, 178, 107, 0.25]),
2464
+ AnchorInsetsHatch: Legacy.fromRGBA([246, 178, 107, 0.8]),
2465
+ AnchorTarget: Legacy.fromRGBA([26, 115, 232, 1]),
2466
+ AnchorTargetBackground: Legacy.fromRGBA([26, 115, 232, 0.15]),
2461
2467
  };
2462
2468
 
2463
2469
  export const SourceOrderHighlight: Record<string, Legacy> = {
@@ -3,7 +3,6 @@
3
3
  // found in the LICENSE file.
4
4
 
5
5
  import * as Platform from '../platform/platform.js';
6
- import * as Root from '../root/root.js';
7
6
 
8
7
  /* eslint @devtools/enforce-version-controller-methods: "error" */
9
8
 
@@ -834,67 +833,15 @@ export class VersionController {
834
833
  }
835
834
 
836
835
  updateVersionFrom42To43(): void {
837
- const timelineShowAllEventsExperimentEnabled =
838
- Root.Runtime.experiments.getValueFromStorage('timeline-show-all-events' as Root.ExperimentNames.ExperimentName);
839
- if (timelineShowAllEventsExperimentEnabled !== undefined) {
840
- if (this.#settings.syncedStorage.has('timeline-show-all-events')) {
841
- return; // Already migrated
842
- }
843
- try {
844
- const timelineShowAllEventsSetting = this.#settings.moduleSetting('timeline-show-all-events');
845
- timelineShowAllEventsSetting.set(timelineShowAllEventsExperimentEnabled);
846
- } catch {
847
- // If the setting is not registered yet (e.g. in tests), skip.
848
- }
849
- }
850
836
  }
851
837
 
852
838
  updateVersionFrom43To44(): void {
853
- const apcaExperimentEnabled =
854
- Root.Runtime.experiments.getValueFromStorage('apca' as Root.ExperimentNames.ExperimentName);
855
- if (apcaExperimentEnabled !== undefined) {
856
- if (this.#settings.syncedStorage.has('apca')) {
857
- return; // Already migrated
858
- }
859
- try {
860
- const apcaSetting = this.#settings.moduleSetting('apca');
861
- apcaSetting.set(apcaExperimentEnabled);
862
- } catch {
863
- // If the setting is not registered yet (e.g. in tests), skip.
864
- }
865
- }
866
839
  }
867
840
 
868
841
  updateVersionFrom44To45(): void {
869
- const timelineDebugModeExperimentEnabled =
870
- Root.Runtime.experiments.getValueFromStorage('timeline-debug-mode' as Root.ExperimentNames.ExperimentName);
871
- if (timelineDebugModeExperimentEnabled !== undefined) {
872
- if (this.#settings.syncedStorage.has('timeline-debug-mode')) {
873
- return; // Already migrated
874
- }
875
- try {
876
- const timelineDebugModeSetting = this.#settings.moduleSetting('timeline-debug-mode');
877
- timelineDebugModeSetting.set(timelineDebugModeExperimentEnabled);
878
- } catch {
879
- // If the setting is not registered yet (e.g. in tests), skip.
880
- }
881
- }
882
842
  }
883
843
 
884
844
  updateVersionFrom45To46(): void {
885
- const timelineInvalidationTrackingExperimentEnabled = Root.Runtime.experiments.getValueFromStorage(
886
- 'timeline-invalidation-tracking' as Root.ExperimentNames.ExperimentName);
887
- if (timelineInvalidationTrackingExperimentEnabled !== undefined) {
888
- if (this.#settings.syncedStorage.has('timeline-invalidation-tracking')) {
889
- return; // Already migrated
890
- }
891
- try {
892
- const timelineInvalidationTrackingSetting = this.#settings.moduleSetting('timeline-invalidation-tracking');
893
- timelineInvalidationTrackingSetting.set(timelineInvalidationTrackingExperimentEnabled);
894
- } catch {
895
- // If the setting is not registered yet (e.g. in tests), skip.
896
- }
897
- }
898
845
  }
899
846
 
900
847
  updateVersionFrom46To47(): void {
@@ -175,7 +175,6 @@ export interface Option {
175
175
  export class ExperimentsSupport {
176
176
  #experiments = new Map<ExperimentName, Experiment>();
177
177
  readonly #enabledForTests = new Set<ExperimentName>();
178
- readonly #storage = new ExperimentStorage();
179
178
 
180
179
  allConfigurableExperiments(): Experiment[] {
181
180
  return [...this.#experiments.values()];
@@ -205,10 +204,6 @@ export class ExperimentsSupport {
205
204
  throw new Error(`Unknown experiment '${experimentName}'`);
206
205
  }
207
206
 
208
- getValueFromStorage(experimentName: ExperimentName): boolean|undefined {
209
- return this.#storage.get(experimentName);
210
- }
211
-
212
207
  setEnabled(experimentName: ExperimentName, enabled: boolean): void {
213
208
  if (this.#isExperiment(experimentName)) {
214
209
  this.#experiments.get(experimentName)?.setEnabled(enabled);
@@ -240,47 +235,11 @@ export class ExperimentsSupport {
240
235
  this.#enabledForTests.clear();
241
236
  }
242
237
 
243
- // TODO(crbug.com/464173054) remove after M156
244
- removeAllExperimentsFromLocalStorage(): void {
245
- this.#storage.removeAllExperimentsFromLocalStorage();
246
- }
247
-
248
238
  #isExperiment(experimentName: ExperimentName): boolean {
249
239
  return this.#experiments.has(experimentName);
250
240
  }
251
241
  }
252
242
 
253
- // TODO(crbug.com/464173054) remove after M156
254
- /** Manages the 'experiments' dictionary in globalThis.localStorage */
255
- class ExperimentStorage {
256
- readonly #experiments: Record<string, boolean|undefined> = {};
257
-
258
- constructor() {
259
- try {
260
- const storedExperiments = Platform.HostRuntime.HOST_RUNTIME.getLocalStorage()?.getItem('experiments');
261
- if (storedExperiments) {
262
- this.#experiments = JSON.parse(storedExperiments);
263
- }
264
- } catch (err) {
265
- console.error('Failed to parse localStorage[\'experiments\']: ' + err.message);
266
- }
267
- }
268
-
269
- /**
270
- * Experiments are stored with a tri-state:
271
- * - true: Explicitly enabled.
272
- * - false: Explicitly disabled.
273
- * - undefined: Disabled.
274
- */
275
- get(experimentName: ExperimentName): boolean|undefined {
276
- return this.#experiments[experimentName];
277
- }
278
-
279
- removeAllExperimentsFromLocalStorage(): void {
280
- Platform.HostRuntime.HOST_RUNTIME.getLocalStorage()?.removeItem('experiments');
281
- }
282
- }
283
-
284
243
  export class Experiment {
285
244
  name: ExperimentName;
286
245
  title: string;
@@ -44,6 +44,60 @@ export interface LayoutProperties {
44
44
  isContents?: boolean;
45
45
  containerType?: string;
46
46
  hasScroll: boolean;
47
+ isAnchorPositioned?: boolean;
48
+ }
49
+
50
+ function isAnchorPositioned(computedStyle: Map<string, string>, matchedStyles?: CSSMatchedStyles|null): boolean {
51
+ const position = computedStyle.get('position');
52
+ if (position !== 'absolute' && position !== 'fixed') {
53
+ return false;
54
+ }
55
+ const positionAnchor = computedStyle.get('position-anchor');
56
+ if (positionAnchor && positionAnchor !== 'none') {
57
+ return true;
58
+ }
59
+ const positionArea = computedStyle.get('position-area');
60
+ if (positionArea && positionArea !== 'none') {
61
+ return true;
62
+ }
63
+ const anchorProperties = [
64
+ 'top',
65
+ 'right',
66
+ 'bottom',
67
+ 'left',
68
+ 'inset',
69
+ 'inset-block',
70
+ 'inset-inline',
71
+ 'inset-block-start',
72
+ 'inset-block-end',
73
+ 'inset-inline-start',
74
+ 'inset-inline-end',
75
+ 'width',
76
+ 'height',
77
+ 'min-width',
78
+ 'min-height',
79
+ 'max-width',
80
+ 'max-height',
81
+ ];
82
+ if (anchorProperties.some(prop => {
83
+ const val = computedStyle.get(prop);
84
+ return Boolean(val && (val.includes('anchor(') || val.includes('anchor-size(')));
85
+ })) {
86
+ return true;
87
+ }
88
+ if (matchedStyles) {
89
+ for (const style of matchedStyles.nodeStyles()) {
90
+ for (const property of style.allProperties()) {
91
+ if (!property.activeInStyle() || !matchedStyles.propertyState(property)) {
92
+ continue;
93
+ }
94
+ if (property.value.includes('anchor(') || property.value.includes('anchor-size(')) {
95
+ return true;
96
+ }
97
+ }
98
+ }
99
+ }
100
+ return false;
47
101
  }
48
102
 
49
103
  export class CSSModel extends SDKModel<EventTypes> {
@@ -408,6 +462,8 @@ export class CSSModel extends SDKModel<EventTypes> {
408
462
  const isContainer = Boolean(containerType) && containerType !== '' && containerType !== 'normal';
409
463
  const hasScroll = Boolean(styles.get('scroll-snap-type')) && styles.get('scroll-snap-type') !== 'none';
410
464
 
465
+ const isAnchored = isAnchorPositioned(styles);
466
+
411
467
  return {
412
468
  isFlex,
413
469
  isGrid,
@@ -416,6 +472,7 @@ export class CSSModel extends SDKModel<EventTypes> {
416
472
  isContents,
417
473
  containerType: isContainer ? containerType : undefined,
418
474
  hasScroll,
475
+ isAnchorPositioned: isAnchored,
419
476
  };
420
477
  }
421
478
 
@@ -87,9 +87,8 @@ export class SyntaxTree {
87
87
  readonly tree: CodeMirror.SyntaxNode;
88
88
  readonly trailingNodes: CodeMirror.SyntaxNode[];
89
89
  readonly propertyName: string|undefined;
90
- constructor(
91
- propertyValue: string, rule: string, tree: CodeMirror.SyntaxNode, propertyName?: string,
92
- trailingNodes: CodeMirror.SyntaxNode[] = []) {
90
+ constructor(propertyValue: string, rule: string, tree: CodeMirror.SyntaxNode, propertyName?: string,
91
+ trailingNodes: CodeMirror.SyntaxNode[] = []) {
93
92
  this.propertyName = propertyName;
94
93
  this.propertyValue = propertyValue;
95
94
  this.rule = rule;
@@ -135,8 +134,8 @@ export abstract class TreeWalker {
135
134
  }
136
135
  return instance;
137
136
  }
138
- static walk<T extends TreeWalker, ArgTs extends unknown[]>(
139
- this: {new(ast: SyntaxTree, ...args: ArgTs): T}, propertyValue: SyntaxTree, ...args: ArgTs): T {
137
+ static walk<T extends TreeWalker, ArgTs extends unknown[]>(this: {new(ast: SyntaxTree, ...args: ArgTs): T},
138
+ propertyValue: SyntaxTree, ...args: ArgTs): T {
140
139
  const instance = new this(propertyValue, ...args);
141
140
  if (propertyValue.tree.name === 'Declaration') {
142
141
  instance.iterateDeclaration(propertyValue.tree);
@@ -279,9 +278,8 @@ export class BottomUpTreeMatching extends TreeWalker {
279
278
  return this.getComputedTextRange(from ?? this.ast.tree, to ?? this.ast.tree, substitutionHook);
280
279
  }
281
280
 
282
- getComputedTextRange(
283
- from: CodeMirror.SyntaxNode|undefined, to: CodeMirror.SyntaxNode|undefined,
284
- substitutionHook?: (match: Match) => string | null): string {
281
+ getComputedTextRange(from: CodeMirror.SyntaxNode|undefined, to: CodeMirror.SyntaxNode|undefined,
282
+ substitutionHook?: (match: Match) => string | null): string {
285
283
  if (!from || !to) {
286
284
  return '';
287
285
  }
@@ -481,10 +479,9 @@ export class ComputedText {
481
479
 
482
480
  countTopLevelValues(begin: number, end: number): number {
483
481
  const pieces = Array.from(this.#getPieces(begin, end));
484
- const counts = pieces.map(
485
- chunk =>
486
- (chunk instanceof ComputedTextChunk ? chunk.topLevelValueCount :
487
- this.#countTopLevelValuesInStringPiece(chunk)));
482
+ const counts =
483
+ pieces.map(chunk => (chunk instanceof ComputedTextChunk ? chunk.topLevelValueCount :
484
+ this.#countTopLevelValuesInStringPiece(chunk)));
488
485
  const count = counts.reduce((sum, v) => sum + v, 0);
489
486
  return count;
490
487
  }
@@ -496,11 +493,7 @@ export class ComputedText {
496
493
  * sequences that make up the pieces of text may contain non-text nodes/trees. Any such element in between the texts is
497
494
  * ignored for the spacing requirement.
498
495
  **/
499
- export function requiresSpace(a: string, b: string): boolean;
500
- export function requiresSpace(a: Array<{textContent?: string | null}>,
501
- b: Array<{textContent?: string | null}>): boolean;
502
- export function requiresSpace(a: Array<{textContent?: string | null}>|string|undefined,
503
- b: Array<{textContent?: string | null}>|string|undefined): boolean {
496
+ export function requiresSpace(a: string, b: string): boolean {
504
497
  const tail = Array.isArray(a) ? a.findLast(node => node.textContent)?.textContent : a;
505
498
  const head = Array.isArray(b) ? b.find(node => node.textContent)?.textContent : b;
506
499
  const trailingChar = tail ? tail[tail.length - 1] : '';
@@ -1139,7 +1139,7 @@ export class DOMNode extends Common.ObjectWrapper.ObjectWrapper<DOMNodeEventType
1139
1139
  }
1140
1140
 
1141
1141
  isCustomElement(): boolean {
1142
- if (this.nodeType() !== NodeType.ELEMENT_NODE || this.isXMLNode()) {
1142
+ if (this.nodeType() !== NodeType.ELEMENT_NODE || this.isXMLNode() || Boolean(this.pseudoType())) {
1143
1143
  return false;
1144
1144
  }
1145
1145
  const localName = this.localName() || this.nodeName().toLowerCase();
@@ -1600,11 +1600,18 @@ export class DOMDocument extends DOMNode {
1600
1600
  this.#frameId = frameId ?? null;
1601
1601
 
1602
1602
  const resourceTreeModel = this.domModel().target().model(ResourceTreeModel);
1603
- const frame = this.#frameId ? resourceTreeModel?.frameForId(this.#frameId) : resourceTreeModel?.mainFrame;
1604
- // In production, DOMDocument should always resolve its security origin from an
1605
- // associated frame, but falls back to SecurityOrigin.create() as a last resort
1606
- // for test environments where no frame exists.
1607
- this.#securityOrigin = frame?.securityOrigin() ?? SecurityOrigin.create(this.#documentURL);
1603
+ const frame = this.#frameId ? resourceTreeModel?.frameForId(this.#frameId) : null;
1604
+ if (frame) {
1605
+ this.#securityOrigin = frame.securityOrigin();
1606
+ } else if (resourceTreeModel?.mainFrame) {
1607
+ // If the target has an active frame tree, a DOMDocument without a matching
1608
+ // frame is a detached document and must be isolated with an opaque origin.
1609
+ this.#securityOrigin = SecurityOrigin.createUniqueOpaque();
1610
+ } else {
1611
+ // TODO(b/567434846): Migrate synthetic unit tests to attach frames so this
1612
+ // fallback to parsing documentURL can be removed.
1613
+ this.#securityOrigin = SecurityOrigin.create(this.#documentURL);
1614
+ }
1608
1615
  }
1609
1616
 
1610
1617
  get documentURL(): Platform.DevToolsPath.UrlString {