chrome-devtools-frontend 1.0.961797 → 1.0.963960

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 (53) hide show
  1. package/.eslintignore +5 -4
  2. package/AUTHORS +1 -0
  3. package/config/gni/devtools_grd_files.gni +1 -1
  4. package/docs/resource_management.md +119 -0
  5. package/front_end/core/common/ParsedURL.ts +12 -10
  6. package/front_end/core/host/UserMetrics.ts +2 -1
  7. package/front_end/core/i18n/locales/en-US.json +2 -2
  8. package/front_end/core/i18n/locales/en-XL.json +2 -2
  9. package/front_end/core/protocol_client/InspectorBackend.ts +7 -7
  10. package/front_end/core/root/Runtime.ts +2 -0
  11. package/front_end/core/sdk/CSSProperty.ts +22 -110
  12. package/front_end/core/sdk/DOMModel.ts +2 -2
  13. package/front_end/core/sdk/DebuggerModel.ts +1 -1
  14. package/front_end/entrypoints/main/MainImpl.ts +7 -2
  15. package/front_end/generated/InspectorBackendCommands.js +8 -4
  16. package/front_end/generated/protocol-mapping.d.ts +12 -1
  17. package/front_end/generated/protocol-proxy-api.d.ts +11 -1
  18. package/front_end/generated/protocol-tsconfig.json +2 -2
  19. package/front_end/generated/protocol.ts +16787 -0
  20. package/front_end/models/emulation/EmulatedDevices.ts +3 -3
  21. package/front_end/models/persistence/IsolatedFileSystem.ts +3 -2
  22. package/front_end/models/persistence/PersistenceActions.ts +2 -2
  23. package/front_end/models/text_utils/text_utils-legacy.ts +0 -5
  24. package/front_end/models/text_utils/text_utils.ts +0 -2
  25. package/front_end/panels/animation/AnimationUI.ts +2 -1
  26. package/front_end/panels/application/AppManifestView.ts +7 -1
  27. package/front_end/panels/application/components/BackForwardCacheStrings.ts +1 -1
  28. package/front_end/panels/application/components/FrameDetailsView.ts +1 -0
  29. package/front_end/panels/elements/StylePropertyTreeElement.ts +13 -0
  30. package/front_end/panels/elements/StylesSidebarPane.ts +73 -4
  31. package/front_end/panels/elements/stylesSectionTree.css +28 -0
  32. package/front_end/panels/media/PlayerListView.ts +2 -0
  33. package/front_end/panels/media/playerListView.css +3 -0
  34. package/front_end/panels/sensors/sensors-meta.ts +2 -2
  35. package/front_end/panels/sources/NavigatorView.ts +1 -1
  36. package/front_end/ui/components/diff_view/DiffView.ts +2 -2
  37. package/front_end/ui/components/docs/icon_button/basic.ts +1 -1
  38. package/front_end/ui/components/icon_button/IconButton.ts +1 -1
  39. package/front_end/ui/components/text_editor/TextEditor.ts +8 -1
  40. package/front_end/ui/components/text_editor/config.ts +3 -2
  41. package/front_end/ui/legacy/GlassPane.ts +2 -0
  42. package/front_end/ui/legacy/UIUtils.ts +1 -1
  43. package/front_end/ui/legacy/softDropDownButton.css +2 -0
  44. package/front_end/ui/legacy/themeColors.css +2 -0
  45. package/front_end/ui/legacy/toolbar.css +6 -0
  46. package/package.json +1 -1
  47. package/scripts/build/ninja/devtools_entrypoint.gni +25 -17
  48. package/scripts/devtools_paths.js +3 -2
  49. package/scripts/devtools_paths.py +4 -0
  50. package/scripts/protocol_typescript/protocol_dts_generator.ts +4 -9
  51. package/scripts/whitespaces.txt +1 -0
  52. package/front_end/generated/protocol.d.ts +0 -16771
  53. package/front_end/models/text_utils/CodeMirrorUtils.ts +0 -77
package/.eslintignore CHANGED
@@ -5,13 +5,14 @@
5
5
  // clang-format check also ignores that file
6
6
  front_end/.eslintrc.js
7
7
  front_end/diff/diff_match_patch.js
8
+ front_end/generated/protocol.ts
8
9
  front_end/javascript_metadata/NativeFunctions.js
9
10
  front_end/third_party/
11
+ node_modules
12
+ scripts/migration/**/*.js
13
+ scripts/protocol_typescript/*.js
14
+ test/**/fixtures/
10
15
  test/e2e/**/*.js
11
16
  test/shared/**/*.js
12
- test/**/fixtures/
13
- scripts/protocol_typescript/*.js
14
- scripts/migration/**/*.js
15
- node_modules
16
17
 
17
18
  *.d.ts
package/AUTHORS CHANGED
@@ -39,6 +39,7 @@ Luke Swiderski <luke.swiderski@gmail.com>
39
39
  Marijn Haverbeke <marijnh@gmail.com>
40
40
  Michael Brüning <michael.bruning@qt.io>
41
41
  Michael Rienstra <mrienstra@gmail.com>
42
+ Paul Fisher <paul@pfish.zone>
42
43
  Per-Olov Jernberg <possan@possan.se>
43
44
  PhistucK <phistuck@gmail.com>
44
45
  Pradhuman Singh Baid <pradhumansinghbaid@gmail.com>
@@ -659,6 +659,7 @@ grd_files_debug_sources = [
659
659
  "front_end/generated/ARIAProperties.js",
660
660
  "front_end/generated/InspectorBackendCommands.js",
661
661
  "front_end/generated/SupportedCSSProperties.js",
662
+ "front_end/generated/protocol.js",
662
663
  "front_end/legacy_test_runner/test_runner/TestRunner.js",
663
664
  "front_end/models/bindings/BreakpointManager.js",
664
665
  "front_end/models/bindings/CSSWorkspaceBinding.js",
@@ -735,7 +736,6 @@ grd_files_debug_sources = [
735
736
  "front_end/models/persistence/WorkspaceSettingsTab.js",
736
737
  "front_end/models/persistence/editFileSystemView.css.js",
737
738
  "front_end/models/persistence/workspaceSettingsTab.css.js",
738
- "front_end/models/text_utils/CodeMirrorUtils.js",
739
739
  "front_end/models/text_utils/ContentProvider.js",
740
740
  "front_end/models/text_utils/StaticContentProvider.js",
741
741
  "front_end/models/text_utils/Text.js",
@@ -0,0 +1,119 @@
1
+ # Resource management in DevTools
2
+
3
+ This document outlines how DevTools keeps track of resources like scripts and
4
+ HTML files, and how they interact with other features such as the Debugger.
5
+ The source code lives in the bindings/, persistence/ and workspace/ directories.
6
+
7
+ ## Core concepts and classes
8
+
9
+ * **Project:** Interface to a collection of resources. DevTools supports
10
+ different project **types**. For example “filesystem”, for resources
11
+ originating from the developers local machine, and “network”, for actual page
12
+ resources. The **Project** interface abstracts away rudimentary file
13
+ operations. Depending on the **type**, a **Project** may be able to create,
14
+ rename or delete resources, or change the contents.
15
+
16
+ * **Workspace**: A collection of all the **Projects** currently in use.
17
+ Implemented as a singleton in WorkspaceImpl.ts.
18
+
19
+ * **UISourceCode:** An actual resource identified by its URL. Scripts and
20
+ stylesheets are prominent examples, but DevTools also uses more esoteric
21
+ **ResourceTypes** such as XHR, WebSocket or EventSource.
22
+
23
+ ## Project types
24
+
25
+ A short overview over the different Project types and what **kind of resources**
26
+ they contain.
27
+
28
+ * **Network:** All resources loaded from the network are stored in network
29
+ projects. Different targets and/or **Resource** **types** may use different
30
+ projects. E.g. Each target has their own project containing only JavaScript
31
+ source maps.
32
+
33
+ * **Filesystem:** Resources stored on the developers local machine.
34
+ * Snippets are managed with a single Project just for snippets.
35
+ * Each local directory mapped into DevTools with the “Workspaces” feature has
36
+ its own project.
37
+ * Each directory used for the “Overrides” feature has a corresponding project
38
+ to manage the local files.
39
+
40
+ * **Formatter:** A single project of this type manages the formatted version of
41
+ script resources. That is the “pretty-print” feature for minified JS files.
42
+
43
+ * **ContentScripts**: Scripts from extensions running in the context of the page
44
+ itself. One project per target. Source maps for content scripts are managed by
45
+ separate, per target, projects. The source map projects also have the
46
+ **ContentScripts** type.
47
+
48
+ * **Service:** One project of this type per target. It holds placeholder
49
+ UISourceCodes for source maps while they are loaded. Once a source map
50
+ finishes loading, the placeholder is removed from the **Service** project.
51
+
52
+ * **Debugger:** One project of this type per target. Debugger projects store
53
+ parsed JS scripts (see next section).
54
+
55
+ ## The “Debugger” project type
56
+
57
+ When V8 parses scripts, it sends out a
58
+ [“Debugger.ScriptParsed”](https://chromedevtools.github.io/devtools-protocol/tot/Debugger/#event-scriptParsed)
59
+ event with some details, including a unique script ID and the URL of the script.
60
+ For each “Debugger.ScriptParsed” event, DevTools creates a **Script** object and
61
+ an associated **UISourceCode** in the “debugger” project. It is important to
62
+ note that the URL of this “debugger” UISourceCode contains both the script ID as
63
+ well as the script name (not URL!) to uniquely identify it. This is because:
64
+
65
+ _The relationship between network/filesystem UISourceCodes and **Script**
66
+ **objects**/debugger UISourceCodes is 1:n._
67
+
68
+ For example if the same script is included twice on a page with &lt;script>
69
+ elements, it will result in a single UISourceCode in the **Network** project but
70
+ **two Script** **objects** and two UISourceCodes in the **Debugger** project.
71
+ Similarly, every invocation of a Snippet will result in a separate **Script**
72
+ object per invocation while the Snippet itself is stored in a **Filesystem**
73
+ project.
74
+
75
+ ## Mappings and bindings
76
+
77
+ As can be seen above, UISourceCodes in different projects can potentially be
78
+ related to one another. A minified script resource in a **scripts Network project**
79
+ might have a pretty-printed version in the **Formatter project** while the
80
+ source map for the minified script is stored in the **source map Network project**.
81
+ Once the minified script is parsed/executed by V8, it also has a corresponding
82
+ **Script object** and a UISourceCode in the **Debugger project**.
83
+
84
+ This brings us to mappings and bindings. The terminology is roughly:
85
+
86
+ * _A **binding** ties different UISourceCodes together and determines which
87
+ UISourceCodes relate to one another._
88
+ * _A **mapping** translates source positions between bound UISourceCodes._
89
+
90
+ ## Binding implementations
91
+
92
+ There are a couple of classes tasked with establishing bindings between
93
+ UISourceCodes:
94
+
95
+ * **DebuggerWorkspaceBinding:** Responsible for scripts and source maps.
96
+ It ties together network/filesystem UISourceCodes with **Script** objects and
97
+ the debugger USourceCodes. Script source maps are also partially implemented
98
+ by this class.
99
+
100
+ * **CSSWorkspaceBinding:** Responsible for CSS and CSS source maps. DevTools can
101
+ handle source mapped CSS when it was authored in SASS and this class is
102
+ responsible for binding the corresponding UISourceCodes.
103
+
104
+ * **PersistenceBinding/PersistenceImpl/Automapping**: Responsible for the
105
+ [“Workspaces”](https://developer.chrome.com/docs/devtools/workspaces/)
106
+ feature. When a developer adds a local directory to DevTools that corresponds
107
+ to the pages sources, these classes establish and manage the binding between
108
+ the corresponding **Filesystem** and **Network** resources.
109
+
110
+ * **NetworkPersistenceManager**: Responsible for the
111
+ [“Local Overrides”](https://developer.chrome.com/blog/new-in-devtools-65/#overrides)
112
+ feature. It connects the **Network** resources with the corresponding
113
+ overwritten version in a **Filesystem** project. This class also handles
114
+ network request interceptions and determines whether to serve the original or
115
+ the overwritten UISourceCode.
116
+
117
+ Please keep in mind that many of these classes have gathered additional
118
+ responsibilities over the years, so the concepts presented above might not
119
+ always cleanly apply or be apparent in code.
@@ -168,16 +168,17 @@ export class ParsedURL {
168
168
  }
169
169
 
170
170
  static rawPathToUrlString(fileSystemPath: Platform.DevToolsPath.RawPathString): Platform.DevToolsPath.UrlString {
171
- let rawPath: string = fileSystemPath;
172
- rawPath = rawPath.replace(/\\/g, '/');
173
- if (!rawPath.startsWith('file://')) {
174
- if (rawPath.startsWith('/')) {
175
- rawPath = 'file://' + rawPath;
171
+ let preEncodedPath: string = ParsedURL.preEncodeSpecialCharactersInPath(
172
+ fileSystemPath.replace(/\\/g, '/') as Platform.DevToolsPath.RawPathString);
173
+ preEncodedPath = preEncodedPath.replace(/\\/g, '/');
174
+ if (!preEncodedPath.startsWith('file://')) {
175
+ if (preEncodedPath.startsWith('/')) {
176
+ preEncodedPath = 'file://' + preEncodedPath;
176
177
  } else {
177
- rawPath = 'file:///' + rawPath;
178
+ preEncodedPath = 'file:///' + preEncodedPath;
178
179
  }
179
180
  }
180
- return rawPath as Platform.DevToolsPath.UrlString;
181
+ return new URL(preEncodedPath).toString() as Platform.DevToolsPath.UrlString;
181
182
  }
182
183
 
183
184
  static relativePathToUrlString(relativePath: string, baseURL: Platform.DevToolsPath.UrlString):
@@ -187,13 +188,14 @@ export class ParsedURL {
187
188
  return new URL(preEncodedPath, baseURL).toString() as Platform.DevToolsPath.UrlString;
188
189
  }
189
190
 
190
- static capFilePrefix(fileURL: Platform.DevToolsPath.UrlString, isWindows?: boolean):
191
+ static urlToRawPathString(fileURL: Platform.DevToolsPath.UrlString, isWindows?: boolean):
191
192
  Platform.DevToolsPath.RawPathString {
192
193
  console.assert(fileURL.startsWith('file://'), 'This must be a file URL.');
194
+ const decodedFileURL = decodeURIComponent(fileURL);
193
195
  if (isWindows) {
194
- return fileURL.substr('file:///'.length).replace(/\//g, '\\') as Platform.DevToolsPath.RawPathString;
196
+ return decodedFileURL.substr('file:///'.length).replace(/\//g, '\\') as Platform.DevToolsPath.RawPathString;
195
197
  }
196
- return fileURL.substr('file://'.length) as Platform.DevToolsPath.RawPathString;
198
+ return decodedFileURL.substr('file://'.length) as Platform.DevToolsPath.RawPathString;
197
199
  }
198
200
 
199
201
  static urlWithoutHash(url: string): string {
@@ -584,7 +584,8 @@ export enum DevtoolsExperiments {
584
584
  'cssTypeComponentLength' = 52,
585
585
  'preciseChanges' = 53,
586
586
  'bfcacheDisplayTree' = 54,
587
- 'MaxValue' = 55,
587
+ 'stylesPaneCSSChanges' = 55,
588
+ 'MaxValue' = 56,
588
589
  }
589
590
  /* eslint-enable @typescript-eslint/naming-convention */
590
591
 
@@ -4809,10 +4809,10 @@
4809
4809
  "message": "Copy selector"
4810
4810
  },
4811
4811
  "panels/elements/StylesSidebarPane.ts | cssPropertyName": {
4812
- "message": "CSS property name"
4812
+ "message": "CSS property name: {PH1}"
4813
4813
  },
4814
4814
  "panels/elements/StylesSidebarPane.ts | cssPropertyValue": {
4815
- "message": "CSS property value"
4815
+ "message": "CSS property value: {PH1}"
4816
4816
  },
4817
4817
  "panels/elements/StylesSidebarPane.ts | cssSelector": {
4818
4818
  "message": "CSS selector"
@@ -4809,10 +4809,10 @@
4809
4809
  "message": "Ĉóp̂ý selector"
4810
4810
  },
4811
4811
  "panels/elements/StylesSidebarPane.ts | cssPropertyName": {
4812
- "message": "CSS p̂ŕôṕêŕt̂ý n̂ám̂é"
4812
+ "message": "CSS p̂ŕôṕêŕt̂ý n̂ám̂é: {PH1}"
4813
4813
  },
4814
4814
  "panels/elements/StylesSidebarPane.ts | cssPropertyValue": {
4815
- "message": "CSS p̂ŕôṕêŕt̂ý v̂ál̂úê"
4815
+ "message": "CSS p̂ŕôṕêŕt̂ý v̂ál̂úê: {PH1}"
4816
4816
  },
4817
4817
  "panels/elements/StylesSidebarPane.ts | cssSelector": {
4818
4818
  "message": "CSS ŝél̂éĉt́ôŕ"
@@ -30,7 +30,7 @@
30
30
 
31
31
  import {NodeURL} from './NodeURL.js';
32
32
  import type * as ProtocolProxyApi from '../../generated/protocol-proxy-api.js';
33
- import * as Protocol from '../../generated/protocol.js';
33
+ import type * as Protocol from '../../generated/protocol.js';
34
34
 
35
35
  export const DevToolsStubErrorCode = -32015;
36
36
  // TODO(dgozman): we are not reporting generic errors in tests, but we should
@@ -147,14 +147,14 @@ export class InspectorBackend {
147
147
 
148
148
  registerEnum(type: QualifiedName, values: Object): void {
149
149
  const [domain, name] = splitQualifiedName(type);
150
- // @ts-ignore Protocol global namespace pollution
151
- if (!Protocol[domain]) {
152
- // @ts-ignore Protocol global namespace pollution
153
- Protocol[domain] = {};
150
+ // @ts-ignore globalThis global namespace pollution
151
+ if (!globalThis.Protocol[domain]) {
152
+ // @ts-ignore globalThis global namespace pollution
153
+ globalThis.Protocol[domain] = {};
154
154
  }
155
155
 
156
- // @ts-ignore Protocol global namespace pollution
157
- Protocol[domain][name] = values;
156
+ // @ts-ignore globalThis global namespace pollution
157
+ globalThis.Protocol[domain][name] = values;
158
158
  this.#initialized = true;
159
159
  }
160
160
 
@@ -272,6 +272,8 @@ export enum ExperimentName {
272
272
  WEBAUTHN_PANE = 'webauthnPane',
273
273
  SYNC_SETTINGS = 'syncSettings',
274
274
  FULL_ACCESSIBILITY_TREE = 'fullAccessibilityTree',
275
+ PRECISE_CHANGES = 'preciseChanges',
276
+ STYLES_PANE_CSS_CHANGES = 'stylesPaneCSSChanges',
275
277
  }
276
278
 
277
279
  // TODO(crbug.com/1167717): Make this a const enum again
@@ -3,13 +3,10 @@
3
3
  // found in the LICENSE file.
4
4
 
5
5
  import * as TextUtils from '../../models/text_utils/text_utils.js';
6
- import * as Common from '../common/common.js';
6
+ import type * as Common from '../common/common.js';
7
7
  import * as HostModule from '../host/host.js';
8
- import * as Platform from '../platform/platform.js';
9
- import * as Root from '../root/root.js';
10
8
  import type * as Protocol from '../../generated/protocol.js';
11
9
 
12
- import {cssMetadata, GridAreaRowRegex} from './CSSMetadata.js';
13
10
  import type {Edit} from './CSSModel.js';
14
11
  import type {CSSStyleDeclaration} from './CSSStyleDeclaration.js';
15
12
 
@@ -163,113 +160,17 @@ export class CSSProperty {
163
160
  }
164
161
 
165
162
  const range = this.range.relativeTo(this.ownerStyle.range.startLine, this.ownerStyle.range.startColumn);
166
- const indentation = this.ownerStyle.cssText ?
167
- this.detectIndentation(this.ownerStyle.cssText) :
168
- Common.Settings.Settings.instance().moduleSetting('textEditorIndent').get();
169
- const endIndentation = this.ownerStyle.cssText ? indentation.substring(0, this.ownerStyle.range.endColumn) : '';
170
163
  const text = new TextUtils.Text.Text(this.ownerStyle.cssText || '');
171
- const newStyleText = text.replaceRange(range, Platform.StringUtilities.sprintf(';%s;', propertyText));
172
- const tokenizerFactory = TextUtils.CodeMirrorUtils.TokenizerFactory.instance();
173
- const styleText = CSSProperty.formatStyle(newStyleText, indentation, endIndentation, tokenizerFactory);
174
- return this.ownerStyle.setText(styleText, majorChange);
175
- }
176
-
177
- static formatStyle(
178
- styleText: string, indentation: string, endIndentation: string,
179
- tokenizerFactory: TextUtils.TextUtils.TokenizerFactory): string {
180
- const doubleIndent = indentation.substring(endIndentation.length) + indentation;
181
- if (indentation) {
182
- indentation = '\n' + indentation;
183
- }
184
- let result = '';
185
- let propertyName = '';
186
- let propertyText = '';
187
- let insideProperty = false;
188
- let needsSemi = false;
189
- const tokenize = tokenizerFactory.createTokenizer('text/css');
190
-
191
- tokenize('*{' + styleText + '}', processToken);
192
- if (insideProperty) {
193
- result += propertyText;
194
- }
195
- result = result.substring(2, result.length - 1).trimRight();
196
- return result + (indentation ? '\n' + endIndentation : '');
197
-
198
- function processToken(token: string, tokenType: string|null, _column: number, _newColumn: number): void {
199
- if (!insideProperty) {
200
- const disabledProperty = tokenType && tokenType.includes('comment') && isDisabledProperty(token);
201
- const isPropertyStart = tokenType &&
202
- (tokenType.includes('string') || tokenType.includes('meta') || tokenType.includes('property') ||
203
- tokenType.includes('variable-2'));
204
- if (disabledProperty) {
205
- result = result.trimRight() + indentation + token;
206
- } else if (isPropertyStart) {
207
- insideProperty = true;
208
- propertyText = token;
209
- } else if (token !== ';' || needsSemi) {
210
- result += token;
211
- if (token.trim() && !(tokenType && tokenType.includes('comment'))) {
212
- needsSemi = token !== ';';
213
- }
214
- }
215
- if (token === '{' && !tokenType) {
216
- needsSemi = false;
217
- }
218
- return;
219
- }
220
-
221
- if (token === '}' || token === ';') {
222
- // While `propertyText` can generally be trimmed, doing so
223
- // breaks valid CSS declarations such as `--foo: ;` which would
224
- // then produce invalid CSS of the form `--foo:;`. This
225
- // implementation takes special care to restore a single
226
- // whitespace token in this edge case. https://crbug.com/1071296
227
- const trimmedPropertyText = propertyText.trim();
228
- result =
229
- result.trimRight() + indentation + trimmedPropertyText + (trimmedPropertyText.endsWith(':') ? ' ' : '');
230
- needsSemi = false;
231
- insideProperty = false;
232
- propertyName = '';
233
- if (Root.Runtime.experiments.isEnabled('preciseChanges')) {
234
- result += token;
235
- return;
236
- }
237
- // We preserve the legacy behavior to always add semicolon to
238
- // declarations regardless of its original text.
239
- result += ';';
240
- if (token === '}') {
241
- result += '}';
242
- }
243
- } else {
244
- if (cssMetadata().isGridAreaDefiningProperty(propertyName)) {
245
- const rowResult = GridAreaRowRegex.exec(token);
246
- if (rowResult && rowResult.index === 0 && !propertyText.trimRight().endsWith(']')) {
247
- propertyText = propertyText.trimRight() + '\n' + doubleIndent;
248
- }
249
- }
250
- if (!propertyName && token === ':') {
251
- propertyName = propertyText;
252
- }
253
- propertyText += token;
254
- }
164
+ const textBeforeInsertion =
165
+ text.extract(new TextUtils.TextRange.TextRange(0, 0, range.startLine, range.startColumn));
166
+ // If we are appending after the last property and that property doesn't have a semicolon at the end
167
+ // (which is only legal in the last position), then add the semicolon in front of the new text to avoid
168
+ // CSS parsing errors. However, we shouldn't prepend semicolons on the first line or after a comment.
169
+ if (textBeforeInsertion.trim().length && !/[;{\/]\s*$/.test(textBeforeInsertion)) {
170
+ propertyText = ';' + propertyText;
255
171
  }
256
-
257
- function isDisabledProperty(text: string): boolean {
258
- const colon = text.indexOf(':');
259
- if (colon === -1) {
260
- return false;
261
- }
262
- const propertyName = text.substring(2, colon).trim();
263
- return cssMetadata().isCSSPropertyName(propertyName);
264
- }
265
- }
266
-
267
- private detectIndentation(text: string): string {
268
- const lines = text.split('\n');
269
- if (lines.length < 2) {
270
- return '';
271
- }
272
- return TextUtils.TextUtils.Utils.lineIndent(lines[1]);
172
+ const newStyleText = text.replaceRange(range, propertyText);
173
+ return this.ownerStyle.setText(newStyleText, majorChange);
273
174
  }
274
175
 
275
176
  setValue(newValue: string, majorChange: boolean, overwrite: boolean, userCallback?: ((arg0: boolean) => void)): void {
@@ -288,7 +189,18 @@ export class CSSProperty {
288
189
  return Promise.resolve(true);
289
190
  }
290
191
  const propertyText = this.text.trim();
291
- const text = disabled ? '/* ' + propertyText + ' */' : this.text.substring(2, propertyText.length - 2).trim();
192
+ // Ensure that if we try to enable/disable a property that has no semicolon (which is only legal
193
+ // in the last position of a css rule), we add it. This ensures that if we then later try
194
+ // to re-enable/-disable the rule, we end up with legal syntax (if the user adds more properties
195
+ // after the disabled rule).
196
+ const appendSemicolonIfMissing = (propertyText: string): string =>
197
+ propertyText + (propertyText.endsWith(';') ? '' : ';');
198
+ let text: string;
199
+ if (disabled) {
200
+ text = '/* ' + appendSemicolonIfMissing(propertyText) + ' */';
201
+ } else {
202
+ text = appendSemicolonIfMissing(this.text.substring(2, propertyText.length - 2).trim());
203
+ }
292
204
  return this.setText(text, true, true);
293
205
  }
294
206
 
@@ -1038,7 +1038,7 @@ export class DOMModel extends SDKModel<EventTypes> {
1038
1038
  this.#pendingDocumentRequestPromise = null;
1039
1039
 
1040
1040
  if (!target.suspended()) {
1041
- void this.agent.invoke_enable();
1041
+ void this.agent.invoke_enable({});
1042
1042
  }
1043
1043
 
1044
1044
  if (Root.Runtime.experiments.isEnabled('captureNodeCreationStacks')) {
@@ -1497,7 +1497,7 @@ export class DOMModel extends SDKModel<EventTypes> {
1497
1497
  }
1498
1498
 
1499
1499
  async resumeModel(): Promise<void> {
1500
- await this.agent.invoke_enable();
1500
+ await this.agent.invoke_enable({});
1501
1501
  }
1502
1502
 
1503
1503
  dispose(): void {
@@ -425,7 +425,7 @@ export class DebuggerModel extends SDKModel<EventTypes> {
425
425
  if (this.target().type() === Type.Node && url.startsWith('file://')) {
426
426
  // TODO(crbug.com/1253323): Cast to UrlString will be removed when migration to branded types is complete.
427
427
  const platformPath =
428
- Common.ParsedURL.ParsedURL.capFilePrefix(url as Platform.DevToolsPath.UrlString, Host.Platform.isWin());
428
+ Common.ParsedURL.ParsedURL.urlToRawPathString(url as Platform.DevToolsPath.UrlString, Host.Platform.isWin());
429
429
  urlRegex =
430
430
  `${Platform.StringUtilities.escapeForRegExp(platformPath)}|${Platform.StringUtilities.escapeForRegExp(url)}`;
431
431
  }
@@ -365,13 +365,18 @@ export class MainImpl {
365
365
  'https://developer.chrome.com/blog/new-in-devtools-96/#length');
366
366
 
367
367
  // Display precise changes in the Changes tab.
368
- Root.Runtime.experiments.register('preciseChanges', 'Display more precise changes in the Changes tab');
368
+ Root.Runtime.experiments.register(
369
+ Root.Runtime.ExperimentName.PRECISE_CHANGES, 'Display more precise changes in the Changes tab');
370
+
371
+ // Integrate CSS changes in the Styles pane.
372
+ Root.Runtime.experiments.register(
373
+ Root.Runtime.ExperimentName.STYLES_PANE_CSS_CHANGES, 'Sync CSS changes in the Styles pane');
369
374
 
370
375
  Root.Runtime.experiments.enableExperimentsByDefault([
371
376
  'sourceOrderViewer',
372
377
  'hideIssuesFeature',
373
378
  'cssTypeComponentLength',
374
- 'preciseChanges',
379
+ Root.Runtime.ExperimentName.PRECISE_CHANGES,
375
380
  'reportingApiDebugging',
376
381
  Root.Runtime.ExperimentName.SYNC_SETTINGS,
377
382
  ]);
@@ -295,7 +295,6 @@ export function registerCommands(inspectorBackend) {
295
295
  AttributionReportingIssue: 'AttributionReportingIssue',
296
296
  QuirksModeIssue: 'QuirksModeIssue',
297
297
  NavigatorUserAgentIssue: 'NavigatorUserAgentIssue',
298
- WasmCrossOriginModuleSharingIssue: 'WasmCrossOriginModuleSharingIssue',
299
298
  GenericIssue: 'GenericIssue',
300
299
  DeprecationIssue: 'DeprecationIssue',
301
300
  ClientHintIssue: 'ClientHintIssue'
@@ -681,7 +680,9 @@ export function registerCommands(inspectorBackend) {
681
680
  inspectorBackend.registerCommand('DOM.disable', [], []);
682
681
  inspectorBackend.registerCommand(
683
682
  'DOM.discardSearchResults', [{'name': 'searchId', 'type': 'string', 'optional': false}], []);
684
- inspectorBackend.registerCommand('DOM.enable', [], []);
683
+ inspectorBackend.registerEnum('DOM.EnableRequestIncludeWhitespace', {None: 'none', All: 'all'});
684
+ inspectorBackend.registerCommand(
685
+ 'DOM.enable', [{'name': 'includeWhitespace', 'type': 'string', 'optional': true}], []);
685
686
  inspectorBackend.registerCommand(
686
687
  'DOM.focus',
687
688
  [
@@ -2114,7 +2115,7 @@ export function registerCommands(inspectorBackend) {
2114
2115
  inspectorBackend.registerEnum(
2115
2116
  'Page.NavigationType', {Navigation: 'Navigation', BackForwardCacheRestore: 'BackForwardCacheRestore'});
2116
2117
  inspectorBackend.registerEnum('Page.BackForwardCacheNotRestoredReason', {
2117
- NotMainFrame: 'NotMainFrame',
2118
+ NotPrimaryMainFrame: 'NotPrimaryMainFrame',
2118
2119
  BackForwardCacheDisabled: 'BackForwardCacheDisabled',
2119
2120
  RelatedActiveContentsExist: 'RelatedActiveContentsExist',
2120
2121
  HTTPStatusNotOK: 'HTTPStatusNotOK',
@@ -2637,7 +2638,7 @@ export function registerCommands(inspectorBackend) {
2637
2638
  inspectorBackend.registerEvent('Storage.cacheStorageListUpdated', ['origin']);
2638
2639
  inspectorBackend.registerEvent('Storage.indexedDBContentUpdated', ['origin', 'databaseName', 'objectStoreName']);
2639
2640
  inspectorBackend.registerEvent('Storage.indexedDBListUpdated', ['origin']);
2640
- inspectorBackend.registerEvent('Storage.interestGroupAccessed', ['type', 'ownerOrigin', 'name']);
2641
+ inspectorBackend.registerEvent('Storage.interestGroupAccessed', ['accessTime', 'type', 'ownerOrigin', 'name']);
2641
2642
  inspectorBackend.registerCommand(
2642
2643
  'Storage.clearDataForOrigin',
2643
2644
  [
@@ -3488,6 +3489,9 @@ export function registerCommands(inspectorBackend) {
3488
3489
  []);
3489
3490
  inspectorBackend.registerCommand(
3490
3491
  'Runtime.removeBinding', [{'name': 'name', 'type': 'string', 'optional': false}], []);
3492
+ inspectorBackend.registerCommand(
3493
+ 'Runtime.getExceptionDetails', [{'name': 'errorObjectId', 'type': 'string', 'optional': false}],
3494
+ ['exceptionDetails']);
3491
3495
 
3492
3496
  // Schema.
3493
3497
  inspectorBackend.registerCommand('Schema.getDomains', [], ['domains']);
@@ -1138,7 +1138,7 @@ export namespace ProtocolMapping {
1138
1138
  /**
1139
1139
  * Enables DOM agent for the given page.
1140
1140
  */
1141
- 'DOM.enable': {paramsType: []; returnType: void;};
1141
+ 'DOM.enable': {paramsType: [Protocol.DOM.EnableRequest?]; returnType: void;};
1142
1142
  /**
1143
1143
  * Focuses the given element.
1144
1144
  */
@@ -3115,6 +3115,17 @@ export namespace ProtocolMapping {
3115
3115
  * unsubscribes current runtime agent from Runtime.bindingCalled notifications.
3116
3116
  */
3117
3117
  'Runtime.removeBinding': {paramsType: [Protocol.Runtime.RemoveBindingRequest]; returnType: void;};
3118
+ /**
3119
+ * This method tries to lookup and populate exception details for a
3120
+ * JavaScript Error object.
3121
+ * Note that the stackTrace portion of the resulting exceptionDetails will
3122
+ * only be populated if the Runtime domain was enabled at the time when the
3123
+ * Error was thrown.
3124
+ */
3125
+ 'Runtime.getExceptionDetails': {
3126
+ paramsType: [Protocol.Runtime.GetExceptionDetailsRequest];
3127
+ returnType: Protocol.Runtime.GetExceptionDetailsResponse;
3128
+ };
3118
3129
  /**
3119
3130
  * Returns supported domains.
3120
3131
  */
@@ -824,7 +824,7 @@ declare namespace ProtocolProxyApi {
824
824
  /**
825
825
  * Enables DOM agent for the given page.
826
826
  */
827
- invoke_enable(): Promise<Protocol.ProtocolResponseWithError>;
827
+ invoke_enable(params: Protocol.DOM.EnableRequest): Promise<Protocol.ProtocolResponseWithError>;
828
828
 
829
829
  /**
830
830
  * Focuses the given element.
@@ -4050,6 +4050,16 @@ declare namespace ProtocolProxyApi {
4050
4050
  * unsubscribes current runtime agent from Runtime.bindingCalled notifications.
4051
4051
  */
4052
4052
  invoke_removeBinding(params: Protocol.Runtime.RemoveBindingRequest): Promise<Protocol.ProtocolResponseWithError>;
4053
+
4054
+ /**
4055
+ * This method tries to lookup and populate exception details for a
4056
+ * JavaScript Error object.
4057
+ * Note that the stackTrace portion of the resulting exceptionDetails will
4058
+ * only be populated if the Runtime domain was enabled at the time when the
4059
+ * Error was thrown.
4060
+ */
4061
+ invoke_getExceptionDetails(params: Protocol.Runtime.GetExceptionDetailsRequest):
4062
+ Promise<Protocol.Runtime.GetExceptionDetailsResponse>;
4053
4063
  }
4054
4064
  export interface RuntimeDispatcher {
4055
4065
  /**
@@ -3,8 +3,8 @@
3
3
  "composite": true
4
4
  },
5
5
  "files": [
6
- "protocol.d.ts",
6
+ "protocol.ts",
7
7
  "protocol-mapping.d.ts",
8
8
  "protocol-proxy-api.d.ts"
9
9
  ]
10
- }
10
+ }