chrome-devtools-frontend 1.0.947377 → 1.0.948916

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 (124) hide show
  1. package/config/gni/all_devtools_files.gni +1 -6
  2. package/config/gni/devtools_grd_files.gni +5 -12
  3. package/config/gni/devtools_image_files.gni +1 -0
  4. package/front_end/.eslintrc.js +1 -0
  5. package/front_end/Images/src/circled_backslash_icon.svg +3 -0
  6. package/front_end/core/host/UserMetrics.ts +1 -1
  7. package/front_end/core/i18n/locales/en-US.json +32 -44
  8. package/front_end/core/i18n/locales/en-XL.json +32 -44
  9. package/front_end/core/platform/platform.ts +0 -2
  10. package/front_end/core/platform/string-utilities.ts +14 -1
  11. package/front_end/core/platform/utilities.ts +0 -29
  12. package/front_end/core/root/Runtime.ts +4 -207
  13. package/front_end/core/sdk/Cookie.ts +0 -21
  14. package/front_end/core/sdk/RemoteObject.ts +15 -1
  15. package/front_end/core/sdk/sdk-legacy.ts +0 -3
  16. package/front_end/entrypoints/devtools_app/{devtools_app-meta-files.ts → devtools_app.ts} +9 -3
  17. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +2 -1
  18. package/front_end/entrypoints/js_app/{JsMain.ts → js_app.ts} +5 -1
  19. package/front_end/entrypoints/main/MainImpl.ts +0 -1
  20. package/front_end/entrypoints/ndb_app/{ndb_app.js → ndb_app.ts} +0 -2
  21. package/front_end/entrypoints/node_app/node_app.ts +1 -3
  22. package/front_end/entrypoints/shell/{shell.js → shell.ts} +0 -2
  23. package/front_end/entrypoints/visibility.gni +3 -1
  24. package/front_end/entrypoints/worker_app/worker_app.ts +1 -4
  25. package/front_end/generated/InspectorBackendCommands.js +8 -1
  26. package/front_end/generated/protocol-mapping.d.ts +4 -0
  27. package/front_end/generated/protocol-proxy-api.d.ts +6 -0
  28. package/front_end/generated/protocol.d.ts +9 -0
  29. package/front_end/legacy/legacy-defs.d.ts +0 -4
  30. package/front_end/legacy_test_runner/test_runner/TestRunner.js +35 -59
  31. package/front_end/models/issues_manager/AttributionReportingIssue.ts +27 -2
  32. package/front_end/models/issues_manager/CorsIssue.ts +15 -15
  33. package/front_end/models/issues_manager/descriptions/{corsInsecurePrivateNetworkPreflight.md → corsPreflightAllowPrivateNetworkError.md} +1 -1
  34. package/front_end/panels/accessibility/AccessibilitySidebarView.ts +3 -1
  35. package/front_end/panels/application/BackForwardCacheStrings.ts +1 -5
  36. package/front_end/panels/application/BackForwardCacheView.ts +150 -58
  37. package/front_end/panels/application/ResourcesPanel.ts +0 -42
  38. package/front_end/panels/application/application-legacy.ts +0 -3
  39. package/front_end/panels/application/application-meta.ts +0 -13
  40. package/front_end/panels/application/backForwardCacheView.css +44 -6
  41. package/front_end/panels/application/components/FrameDetailsView.ts +3 -3
  42. package/front_end/panels/application/components/OriginTrialTreeView.ts +3 -3
  43. package/front_end/panels/application/components/StackTrace.ts +1 -1
  44. package/front_end/panels/console/ConsolePrompt.ts +0 -4
  45. package/front_end/panels/coverage/CoverageView.ts +1 -1
  46. package/front_end/panels/css_overview/components/cssOverviewStartView.css +1 -0
  47. package/front_end/panels/css_overview/cssOverviewCompletedView.css +1 -1
  48. package/front_end/panels/developer_resources/DeveloperResourcesView.ts +2 -1
  49. package/front_end/panels/elements/AccessibilityTreeUtils.ts +1 -7
  50. package/front_end/panels/elements/ElementsPanel.ts +9 -1
  51. package/front_end/panels/elements/ElementsTreeElement.ts +1 -1
  52. package/front_end/panels/elements/PropertiesWidget.ts +109 -4
  53. package/front_end/panels/elements/components/ElementsBreadcrumbs.ts +1 -1
  54. package/front_end/panels/elements/propertiesWidget.css +34 -0
  55. package/front_end/panels/emulation/DeviceModeToolbar.ts +5 -1
  56. package/front_end/panels/issues/CorsIssueDetailsView.ts +20 -8
  57. package/front_end/panels/network/NetworkWaterfallColumn.ts +2 -0
  58. package/front_end/panels/profiler/CPUProfileFlameChart.ts +3 -1
  59. package/front_end/panels/profiler/ProfileDataGrid.ts +2 -1
  60. package/front_end/panels/settings/components/SyncSection.ts +2 -2
  61. package/front_end/panels/settings/emulation/components/UserAgentClientHintsForm.ts +46 -46
  62. package/front_end/panels/timeline/TimelineTreeView.ts +2 -1
  63. package/front_end/ui/components/diff_view/DiffView.ts +4 -4
  64. package/front_end/ui/components/helpers/component-server-setup.ts +1 -12
  65. package/front_end/ui/components/helpers/helpers.ts +0 -2
  66. package/front_end/ui/components/icon_button/IconButton.ts +1 -1
  67. package/front_end/ui/components/issue_counter/IssueCounter.ts +2 -2
  68. package/front_end/ui/components/linear_memory_inspector/LinearMemoryViewer.ts +3 -3
  69. package/front_end/ui/components/markdown_view/MarkdownView.ts +4 -4
  70. package/front_end/ui/components/panel_feedback/PreviewToggle.ts +98 -0
  71. package/front_end/ui/components/panel_feedback/panel_feedback.ts +1 -0
  72. package/front_end/ui/components/panel_feedback/previewToggle.css +24 -0
  73. package/front_end/ui/components/report_view/ReportView.ts +22 -0
  74. package/front_end/ui/components/report_view/reportSection.css +20 -0
  75. package/front_end/ui/components/request_link_icon/RequestLinkIcon.ts +1 -1
  76. package/front_end/ui/components/settings/SettingCheckbox.ts +2 -2
  77. package/front_end/ui/components/text_editor/config.ts +4 -3
  78. package/front_end/ui/components/text_editor/javascript.ts +8 -4
  79. package/front_end/ui/components/text_prompt/TextPrompt.ts +2 -2
  80. package/front_end/ui/legacy/GlassPane.ts +1 -1
  81. package/front_end/ui/legacy/SearchableView.ts +2 -1
  82. package/front_end/ui/legacy/Treeoutline.ts +1 -1
  83. package/front_end/ui/legacy/Widget.ts +1 -1
  84. package/front_end/ui/legacy/XWidget.ts +0 -5
  85. package/front_end/ui/legacy/components/inline_editor/CSSVarSwatch.ts +2 -2
  86. package/front_end/ui/legacy/components/inline_editor/ColorSwatch.ts +1 -1
  87. package/front_end/ui/legacy/utils/append-style.ts +2 -13
  88. package/front_end/ui/legacy/utils/create-shadow-root-with-core-styles.ts +7 -5
  89. package/package.json +2 -4
  90. package/scripts/build/build_inspector_overlay.py +15 -1
  91. package/scripts/build/rjsmin.py +84 -115
  92. package/scripts/eslint_rules/lib/ban_a_tags_in_lit_html.js +2 -11
  93. package/scripts/eslint_rules/lib/ban_literal_devtools_component_tag_names.js +2 -11
  94. package/scripts/eslint_rules/lib/ban_self_closing_custom_element_tagnames.js +2 -11
  95. package/scripts/eslint_rules/lib/ban_style_tags_in_lit_html.js +2 -11
  96. package/scripts/eslint_rules/lib/lit_html_data_as_type.js +2 -11
  97. package/scripts/eslint_rules/lib/lit_html_no_attribute_quotes.js +89 -0
  98. package/scripts/eslint_rules/lib/lit_no_style_interpolation.js +2 -11
  99. package/scripts/eslint_rules/lib/no_only_eslint_tests.js +53 -0
  100. package/scripts/eslint_rules/lib/static_tag_must_be_static_property.js +2 -11
  101. package/scripts/eslint_rules/lib/utils.js +29 -0
  102. package/scripts/eslint_rules/tests/.eslintrc.js +18 -0
  103. package/scripts/eslint_rules/tests/lit_html_no_attribute_quotes_test.js +45 -0
  104. package/scripts/eslint_rules/tests/no_only_eslint_tests_test.js +94 -0
  105. package/scripts/eslint_rules/tests/utils_test.js +40 -0
  106. package/front_end/entrypoints/devtools_app/devtools_app.js +0 -11
  107. package/front_end/entrypoints/devtools_app/devtools_app.json +0 -4
  108. package/front_end/entrypoints/js_app/js_app.js +0 -12
  109. package/front_end/entrypoints/js_app/js_app.json +0 -3
  110. package/front_end/entrypoints/ndb_app/ndb_app.json +0 -4
  111. package/front_end/entrypoints/startup/RuntimeInstantiator.ts +0 -95
  112. package/front_end/entrypoints/startup/startup.ts +0 -9
  113. package/front_end/panels/help/HelpImpl.ts +0 -141
  114. package/front_end/panels/help/ReleaseNoteText.ts +0 -1496
  115. package/front_end/panels/help/ReleaseNoteView.ts +0 -107
  116. package/front_end/panels/help/help-meta.ts +0 -145
  117. package/front_end/panels/help/help.ts +0 -13
  118. package/front_end/panels/help/releaseNote.css +0 -115
  119. package/front_end/ui/components/helpers/get-stylesheet.ts +0 -45
  120. package/scripts/build/build_release_applications.py +0 -216
  121. package/scripts/build/modular_build.py +0 -184
  122. package/scripts/check_gn.js +0 -119
  123. package/scripts/json_validator/module.schema.json +0 -19
  124. package/scripts/json_validator/validate_module_json.js +0 -44
@@ -9,7 +9,6 @@ import * as UI from '../../ui/legacy/legacy.js';
9
9
 
10
10
  import resourcesPanelStyles from './resourcesPanel.css.js';
11
11
 
12
- import type {CookieTreeElement} from './ApplicationPanelSidebar.js';
13
12
  import {ApplicationPanelSidebar, StorageCategoryView} from './ApplicationPanelSidebar.js';
14
13
  import {CookieItemsView} from './CookieItemsView.js';
15
14
  import {DatabaseQueryView} from './DatabaseQueryView.js';
@@ -215,47 +214,6 @@ export class ResourceRevealer implements Common.Revealer.Revealer {
215
214
  }
216
215
  }
217
216
 
218
- let cookieReferenceRevealerInstance: CookieReferenceRevealer;
219
-
220
- export class CookieReferenceRevealer implements Common.Revealer.Revealer {
221
- static instance(opts: {
222
- forceNew: boolean|null,
223
- } = {forceNew: null}): CookieReferenceRevealer {
224
- const {forceNew} = opts;
225
- if (!cookieReferenceRevealerInstance || forceNew) {
226
- cookieReferenceRevealerInstance = new CookieReferenceRevealer();
227
- }
228
-
229
- return cookieReferenceRevealerInstance;
230
- }
231
- async reveal(cookie: Object): Promise<void> {
232
- if (!(cookie instanceof SDK.Cookie.CookieReference)) {
233
- throw new Error('Internal error: not a cookie reference');
234
- }
235
-
236
- const sidebar = await ResourcesPanel.showAndGetSidebar();
237
- await sidebar.cookieListTreeElement.select();
238
-
239
- const contextUrl = cookie.contextUrl();
240
- if (contextUrl && await this.revealByDomain(sidebar, contextUrl)) {
241
- return;
242
- }
243
- // Fallback: try to reveal the cookie using its domain as context, which may not work, because the
244
- // Application Panel shows cookies grouped by context, see crbug.com/1060563.
245
- this.revealByDomain(sidebar, cookie.domain());
246
- }
247
-
248
- private async revealByDomain(sidebar: ApplicationPanelSidebar, domain: string): Promise<boolean> {
249
- const item = sidebar.cookieListTreeElement.children().find(
250
- c => /** @type {!CookieTreeElement} */ (c as CookieTreeElement).cookieDomain().endsWith(domain));
251
- if (item) {
252
- await item.revealAndSelect();
253
- return true;
254
- }
255
- return false;
256
- }
257
- }
258
-
259
217
  let frameDetailsRevealerInstance: FrameDetailsRevealer;
260
218
 
261
219
  export class FrameDetailsRevealer implements Common.Revealer.Revealer {
@@ -95,9 +95,6 @@ Resources.ResourcesPanel = ResourcesModule.ResourcesPanel.ResourcesPanel;
95
95
  /** @constructor */
96
96
  Resources.ResourcesPanel.ResourceRevealer = ResourcesModule.ResourcesPanel.ResourceRevealer;
97
97
 
98
- /** @constructor */
99
- Resources.ResourcesPanel.CookieReferenceRevealer = ResourcesModule.ResourcesPanel.CookieReferenceRevealer;
100
-
101
98
  /** @constructor */
102
99
  Resources.ResourcesPanel.FrameDetailsRevealer = ResourcesModule.ResourcesPanel.FrameDetailsRevealer;
103
100
 
@@ -139,19 +139,6 @@ Common.Revealer.registerRevealer({
139
139
  },
140
140
  });
141
141
 
142
- Common.Revealer.registerRevealer({
143
- contextTypes() {
144
- return [
145
- SDK.Cookie.CookieReference,
146
- ];
147
- },
148
- destination: Common.Revealer.RevealerDestination.APPLICATION_PANEL,
149
- async loadRevealer() {
150
- const Resources = await loadResourcesModule();
151
- return Resources.ResourcesPanel.CookieReferenceRevealer.instance();
152
- },
153
- });
154
-
155
142
  Common.Revealer.registerRevealer({
156
143
  contextTypes() {
157
144
  return [
@@ -3,12 +3,50 @@
3
3
  * Use of this source code is governed by a BSD-style license that can be
4
4
  * found in the LICENSE file.
5
5
  */
6
- .not-restored-reason-list {
7
- margin: 0;
8
- list-style-type: none;
9
- padding-inline-start: 0;
10
- }
11
-
12
6
  .inline-icon {
13
7
  vertical-align: sub;
14
8
  }
9
+
10
+ .gray-text {
11
+ color: var(--color-text-secondary);
12
+ margin: 0 0 15px 56px;
13
+ display: flex;
14
+ flex-direction: row;
15
+ align-items: center;
16
+ flex: auto;
17
+ overflow-wrap: break-word;
18
+ overflow: hidden;
19
+ }
20
+
21
+ .help-outline-icon {
22
+ margin: 0 2px;
23
+ }
24
+
25
+ .circled-exclamation-icon {
26
+ margin-right: 10px;
27
+ flex-shrink: 0;
28
+ }
29
+
30
+ .status {
31
+ margin-right: 15px;
32
+ flex-shrink: 0;
33
+ }
34
+
35
+ .url {
36
+ grid-column-start: span 2;
37
+ display: flex;
38
+ align-items: center;
39
+ margin: 0 30px;
40
+ line-height: 28px;
41
+ }
42
+
43
+ .url-key {
44
+ color: var(--color-text-secondary);
45
+ min-width: auto;
46
+ overflow-wrap: break-word;
47
+ }
48
+
49
+ .url-value {
50
+ padding: 0 6px;
51
+ overflow-wrap: break-word;
52
+ }
@@ -318,7 +318,7 @@ export class FrameDetailsReportView extends HTMLElement {
318
318
  return LitHtml.html`
319
319
  <${ReportView.ReportView.ReportSectionHeader.litTagName}>
320
320
  ${i18n.i18n.lockedString('Origin Trials')}
321
- <${IconButton.IconButton.IconButton.litTagName} class="inline-button" .data="${{
321
+ <${IconButton.IconButton.IconButton.litTagName} class="inline-button" .data=${{
322
322
  clickHandler: refreshOriginTrials,
323
323
  groups: [
324
324
  {
@@ -326,7 +326,7 @@ export class FrameDetailsReportView extends HTMLElement {
326
326
  text: 'Refresh',
327
327
  } as IconButton.IconButton.IconWithTextData,
328
328
  ],
329
- } as IconButton.IconButton.IconButtonData}">
329
+ } as IconButton.IconButton.IconButtonData}>
330
330
  </${IconButton.IconButton.IconButton.litTagName}>
331
331
  </${ReportView.ReportView.ReportSectionHeader.litTagName}>
332
332
  ${this.originTrialTreeView}
@@ -541,7 +541,7 @@ export class FrameDetailsReportView extends HTMLElement {
541
541
  return LitHtml.nothing;
542
542
  }
543
543
  const typeStrings = this.getAdFrameTypeStrings(adFrameType);
544
- const rows = [LitHtml.html`<div title="${typeStrings.description}">${typeStrings.value}</div>`];
544
+ const rows = [LitHtml.html`<div title=${typeStrings.description}>${typeStrings.value}</div>`];
545
545
  for (const explanation of this.frame.adFrameStatus()?.explanations || []) {
546
546
  rows.push(LitHtml.html`<div>${this.getAdFrameExplanationString(explanation)}</div>`);
547
547
  }
@@ -229,7 +229,7 @@ export class OriginTrialTokenRows extends HTMLElement {
229
229
  }
230
230
 
231
231
  private renderTokenField = (fieldValue: string, hasError?: boolean): LitHtml.TemplateResult => LitHtml.html`
232
- <div class="${LitHtml.Directives.ifDefined(hasError ? 'error-text' : undefined)}">
232
+ <div class=${LitHtml.Directives.ifDefined(hasError ? 'error-text' : undefined)}>
233
233
  ${fieldValue}
234
234
  </div>`;
235
235
 
@@ -334,10 +334,10 @@ export class OriginTrialTreeView extends HTMLElement {
334
334
 
335
335
  LitHtml.render(
336
336
  LitHtml.html`
337
- <${TreeOutline.TreeOutline.TreeOutline.litTagName} .data="${{
337
+ <${TreeOutline.TreeOutline.TreeOutline.litTagName} .data=${{
338
338
  tree: trials.map(constructOriginTrialTree),
339
339
  defaultRenderer,
340
- } as TreeOutline.TreeOutline.TreeOutlineData<OriginTrialTreeNodeData>}">
340
+ } as TreeOutline.TreeOutline.TreeOutlineData<OriginTrialTreeNodeData>}>
341
341
  </${TreeOutline.TreeOutline.TreeOutline.litTagName}>
342
342
  `,
343
343
  this.shadow, {host: this});
@@ -64,7 +64,7 @@ export class StackTraceRow extends HTMLElement {
64
64
  LitHtml.render(
65
65
  LitHtml.html`
66
66
  <div class="stack-trace-row">
67
- <div class="stack-trace-function-name text-ellipsis" title="${this.stackTraceRowItem.functionName}">
67
+ <div class="stack-trace-function-name text-ellipsis" title=${this.stackTraceRowItem.functionName}>
68
68
  ${this.stackTraceRowItem.functionName}
69
69
  </div>
70
70
  <div class="stack-trace-source-location">
@@ -259,7 +259,6 @@ export class ConsolePrompt extends Common.ObjectWrapper.eventMixin<EventTypes, t
259
259
  } else {
260
260
  this.editor.dispatch({scrollIntoView: true});
261
261
  }
262
- this.enterProcessedForTest();
263
262
  return true;
264
263
  }
265
264
 
@@ -283,9 +282,6 @@ export class ConsolePrompt extends Common.ObjectWrapper.eventMixin<EventTypes, t
283
282
  }
284
283
  }
285
284
 
286
- private enterProcessedForTest(): void {
287
- }
288
-
289
285
  private editorUpdate(update: CodeMirror.ViewUpdate): void {
290
286
  if (update.docChanged ||
291
287
  CodeMirror.selectedCompletion(update.state) !== CodeMirror.selectedCompletion(update.startState)) {
@@ -470,7 +470,7 @@ export class CoverageView extends UI.Widget.VBox {
470
470
  return;
471
471
  }
472
472
  const text = this.filterInput.value();
473
- this.textFilterRegExp = text ? createPlainTextSearchRegex(text, 'i') : null;
473
+ this.textFilterRegExp = text ? Platform.StringUtilities.createPlainTextSearchRegex(text, 'i') : null;
474
474
  this.listView.updateFilterAndHighlight(this.textFilterRegExp);
475
475
  this.updateStats();
476
476
  }
@@ -14,6 +14,7 @@ h1 {
14
14
  display: flex;
15
15
  flex-direction: column;
16
16
  background-color: var(--color-background);
17
+ overflow: auto;
17
18
  }
18
19
 
19
20
  .summary-header {
@@ -249,7 +249,7 @@
249
249
 
250
250
  .overview-completed-view .font-info .font-metric {
251
251
  display: grid;
252
- grid-template-columns: 1fr 1fr 1fr;
252
+ grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
253
253
  grid-gap: 12px;
254
254
  }
255
255
 
@@ -4,6 +4,7 @@
4
4
 
5
5
  import * as Common from '../../core/common/common.js';
6
6
  import * as i18n from '../../core/i18n/i18n.js';
7
+ import * as Platform from '../../core/platform/platform.js';
7
8
  import * as SDK from '../../core/sdk/sdk.js';
8
9
  import * as UI from '../../ui/legacy/legacy.js';
9
10
 
@@ -125,7 +126,7 @@ export class DeveloperResourcesView extends UI.Widget.VBox {
125
126
  }
126
127
 
127
128
  const text = this.filterInput.value();
128
- this.textFilterRegExp = text ? createPlainTextSearchRegex(text, 'i') : null;
129
+ this.textFilterRegExp = text ? Platform.StringUtilities.createPlainTextSearchRegex(text, 'i') : null;
129
130
  this.listView.updateFilterAndHighlight(this.textFilterRegExp);
130
131
  this.updateStats();
131
132
  }
@@ -86,13 +86,7 @@ async function getChildren(node: SDK.AccessibilityModel.AccessibilityNode):
86
86
  const localRoot = await getRootNode(frameId);
87
87
  return [localRoot];
88
88
  }
89
- if (node.hasUnloadedChildren()) {
90
- await node.accessibilityModel().requestAXChildren(node.id(), node.getFrameId() || undefined);
91
- if (node.numChildren() !== node.children().length) {
92
- throw new Error('Once loaded, number of children and length of children must match.');
93
- }
94
- }
95
- return node.children();
89
+ return node.accessibilityModel().requestAXChildren(node.id(), node.getFrameId() || undefined);
96
90
  }
97
91
 
98
92
  export async function sdkNodeToAXTreeNodes(sdkNode: SDK.AccessibilityModel.AccessibilityNode): Promise<AXTreeNode[]> {
@@ -291,8 +291,16 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
291
291
  }
292
292
 
293
293
  private showDOMTree(): void {
294
- // TODO(meredithl): Scroll to inspected DOM node.
295
294
  this.splitWidget.setMainWidget(this.searchableViewInternal);
295
+ const selectedNode = this.selectedDOMNode();
296
+ if (!selectedNode) {
297
+ return;
298
+ }
299
+ const treeElement = this.treeElementForNode(selectedNode);
300
+ if (!treeElement) {
301
+ return;
302
+ }
303
+ treeElement.select();
296
304
  }
297
305
 
298
306
  static instance(opts: {
@@ -1899,7 +1899,7 @@ export class ElementsTreeElement extends UI.TreeOutline.TreeElement {
1899
1899
  this.hideSearchHighlight();
1900
1900
 
1901
1901
  const text = this.listItemElement.textContent || '';
1902
- const regexObject = createPlainTextSearchRegex(this.searchQuery, 'gi');
1902
+ const regexObject = Platform.StringUtilities.createPlainTextSearchRegex(this.searchQuery, 'gi');
1903
1903
 
1904
1904
  let match = regexObject.exec(text);
1905
1905
  const matchRanges = [];
@@ -31,25 +31,67 @@
31
31
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
32
  */
33
33
 
34
- import propertiesWidgetStyles from './propertiesWidget.css.js';
35
- import type * as Common from '../../core/common/common.js';
34
+ import * as Common from '../../core/common/common.js';
36
35
  import * as Host from '../../core/host/host.js';
36
+ import * as i18n from '../../core/i18n/i18n.js';
37
37
  import * as SDK from '../../core/sdk/sdk.js';
38
+ import * as Protocol from '../../generated/protocol.js';
38
39
  import * as ObjectUI from '../../ui/legacy/components/object_ui/object_ui.js';
39
40
  import * as UI from '../../ui/legacy/legacy.js';
40
41
 
42
+ import propertiesWidgetStyles from './propertiesWidget.css.js';
43
+ import {StylesSidebarPane} from './StylesSidebarPane.js';
44
+
41
45
  const OBJECT_GROUP_NAME = 'properties-sidebar-pane';
42
46
 
47
+ const UIStrings = {
48
+ /**
49
+ * @description Placeholder text for a text input used to filter which DOM element properties show up in
50
+ * the Properties tab of the Elements panel.
51
+ */
52
+ filter: 'Filter',
53
+ /**
54
+ * @description ARIA accessible name for the text input used to filter which DOM element properties show up
55
+ * in the Properties tab of the Elements panel.
56
+ */
57
+ filterProperties: 'Filter Properties',
58
+ /**
59
+ * @description Text on the checkbox in the Properties tab of the Elements panel, which controls whether
60
+ * all properties of the currently selected DOM element are shown, or only meaningful properties (i.e.
61
+ * excluding properties whose values aren't set for example).
62
+ */
63
+ showAll: 'Show all',
64
+ /**
65
+ * @description Tooltip on the checkbox in the Properties tab of the Elements panel, which controls whether
66
+ * all properties of the currently selected DOM element are shown, or only meaningful properties (i.e.
67
+ * excluding properties whose values aren't set for example).
68
+ */
69
+ showAllTooltip: 'When unchecked, only properties whose values are neither null nor undefined will be shown',
70
+ /**
71
+ * @description Text shown to the user when a filter is applied in the Properties tab of the Elements panel, but
72
+ * no properties matched the filter and thus no results were returned.
73
+ */
74
+ noMatchingProperty: 'No matching property',
75
+ };
76
+ const str_ = i18n.i18n.registerUIStrings('panels/elements/PropertiesWidget.ts', UIStrings);
77
+ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
78
+
43
79
  let propertiesWidgetInstance: PropertiesWidget;
44
80
 
45
81
  export class PropertiesWidget extends UI.ThrottledWidget.ThrottledWidget {
46
82
  private node: SDK.DOMModel.DOMNode|null;
83
+ private readonly showAllPropertiesSetting: Common.Settings.Setting<boolean>;
84
+ private filterRegex: RegExp|null = null;
85
+ private readonly noMatchesElement: HTMLElement;
47
86
  private readonly treeOutline: ObjectUI.ObjectPropertiesSection.ObjectPropertiesSectionsTreeOutline;
48
87
  private readonly expandController: ObjectUI.ObjectPropertiesSection.ObjectPropertiesSectionsTreeExpandController;
49
88
  private lastRequestedNode?: SDK.DOMModel.DOMNode;
50
89
  constructor() {
51
90
  super(true /* isWebComponent */);
52
91
 
92
+ this.showAllPropertiesSetting = Common.Settings.Settings.instance().createSetting('showAllProperties', false);
93
+ this.showAllPropertiesSetting.addChangeListener(this.filterList.bind(this));
94
+
53
95
  SDK.TargetManager.TargetManager.instance().addModelListener(
54
96
  SDK.DOMModel.DOMModel, SDK.DOMModel.Events.AttrModified, this.onNodeChange, this);
55
97
  SDK.TargetManager.TargetManager.instance().addModelListener(
@@ -61,6 +103,20 @@ export class PropertiesWidget extends UI.ThrottledWidget.ThrottledWidget {
61
103
  UI.Context.Context.instance().addFlavorChangeListener(SDK.DOMModel.DOMNode, this.setNode, this);
62
104
  this.node = UI.Context.Context.instance().flavor(SDK.DOMModel.DOMNode);
63
105
 
106
+ const hbox = this.contentElement.createChild('div', 'hbox properties-widget-toolbar');
107
+ const filterContainerElement = hbox.createChild('div', 'properties-widget-filter-box');
108
+ const filterInput = StylesSidebarPane.createPropertyFilterElement(
109
+ i18nString(UIStrings.filter), hbox, this.filterProperties.bind(this));
110
+ UI.ARIAUtils.setAccessibleName(filterInput, i18nString(UIStrings.filterProperties));
111
+ filterContainerElement.appendChild(filterInput);
112
+
113
+ const toolbar = new UI.Toolbar.Toolbar('styles-pane-toolbar', hbox);
114
+ toolbar.appendToolbarItem(new UI.Toolbar.ToolbarSettingCheckbox(
115
+ this.showAllPropertiesSetting, i18nString(UIStrings.showAllTooltip), i18nString(UIStrings.showAll)));
116
+
117
+ this.noMatchesElement = this.contentElement.createChild('div', 'gray-info-message hidden');
118
+ this.noMatchesElement.textContent = i18nString(UIStrings.noMatchingProperty);
119
+
64
120
  this.treeOutline = new ObjectUI.ObjectPropertiesSection.ObjectPropertiesSectionsTreeOutline({readOnly: true});
65
121
  this.treeOutline.setShowSelectionOnKeyboardFocus(/* show */ true, /* preventTabOrder */ false);
66
122
  this.expandController =
@@ -73,6 +129,7 @@ export class PropertiesWidget extends UI.ThrottledWidget.ThrottledWidget {
73
129
 
74
130
  this.update();
75
131
  }
132
+
76
133
  static instance(opts: {
77
134
  forceNew: boolean|null,
78
135
  }|undefined = {forceNew: null}): PropertiesWidget {
@@ -84,6 +141,46 @@ export class PropertiesWidget extends UI.ThrottledWidget.ThrottledWidget {
84
141
  return propertiesWidgetInstance;
85
142
  }
86
143
 
144
+ private filterProperties(this: PropertiesWidget, regex: RegExp|null): void {
145
+ this.filterRegex = regex;
146
+ this.filterList();
147
+ }
148
+
149
+ private filterList(): void {
150
+ const isHidden = (property: SDK.RemoteObject.RemoteObjectProperty): boolean => {
151
+ if (!this.showAllPropertiesSetting.get()) {
152
+ if (SDK.RemoteObject.RemoteObject.isNullOrUndefined(property.value)) {
153
+ return true;
154
+ }
155
+ if (property.value?.type === Protocol.Runtime.RemoteObjectType.Undefined ||
156
+ (property.value?.type === Protocol.Runtime.RemoteObjectType.Object &&
157
+ property.value.subtype === Protocol.Runtime.RemoteObjectSubtype.Null)) {
158
+ return true;
159
+ }
160
+ }
161
+ if (this.filterRegex !== null) {
162
+ if (this.filterRegex.test(property.name)) {
163
+ return false;
164
+ }
165
+ if (this.filterRegex.test(property.value?.description ?? '')) {
166
+ return false;
167
+ }
168
+ return true;
169
+ }
170
+ return false;
171
+ };
172
+ let noMatches = true;
173
+ for (const element of this.treeOutline.rootElement().children()) {
174
+ const {property} = element as ObjectUI.ObjectPropertiesSection.ObjectPropertyTreeElement;
175
+ const hidden = isHidden(property);
176
+ if (!hidden) {
177
+ noMatches = false;
178
+ }
179
+ element.hidden = hidden;
180
+ }
181
+ this.noMatchesElement.classList.toggle('hidden', !noMatches);
182
+ }
183
+
87
184
  private setNode(event: Common.EventTarget.EventTargetEvent<SDK.DOMModel.DOMNode|null>): void {
88
185
  this.node = event.data;
89
186
  this.update();
@@ -106,8 +203,15 @@ export class PropertiesWidget extends UI.ThrottledWidget.ThrottledWidget {
106
203
  return;
107
204
  }
108
205
 
109
- await ObjectUI.ObjectPropertiesSection.ObjectPropertyTreeElement.populate(
110
- this.treeOutline.rootElement(), object, true, true, undefined, undefined);
206
+ const treeElement = this.treeOutline.rootElement();
207
+ let {properties} = await SDK.RemoteObject.RemoteObject.loadFromObjectPerProto(object, true /* generatePreview */);
208
+ treeElement.removeChildren();
209
+ if (properties === null) {
210
+ properties = [];
211
+ }
212
+ ObjectUI.ObjectPropertiesSection.ObjectPropertyTreeElement.populateWithProperties(
213
+ treeElement, properties, null, true /* skipProto */, true /* skipGettersAndSetters */, object);
214
+ this.filterList();
111
215
  }
112
216
 
113
217
  private onNodeChange(event: Common.EventTarget
@@ -122,6 +226,7 @@ export class PropertiesWidget extends UI.ThrottledWidget.ThrottledWidget {
122
226
  }
123
227
  this.update();
124
228
  }
229
+
125
230
  wasShown(): void {
126
231
  super.wasShown();
127
232
  this.registerCSSFiles([propertiesWidgetStyles]);
@@ -276,7 +276,7 @@ export class ElementsBreadcrumbs extends HTMLElement {
276
276
  // Disabled until https://crbug.com/1079231 is fixed.
277
277
  // clang-format off
278
278
  LitHtml.render(LitHtml.html`
279
- <nav class="crumbs" aria-label="${i18nString(UIStrings.breadcrumbs)}">
279
+ <nav class="crumbs" aria-label=${i18nString(UIStrings.breadcrumbs)}>
280
280
  ${this.renderOverflowButton('left', this.userScrollPosition === 'start')}
281
281
 
282
282
  <div class="crumbs-window" @scroll=${this.onCrumbsWindowScroll}>
@@ -8,3 +8,37 @@
8
8
  padding: 2px 0 2px 5px;
9
9
  flex: none;
10
10
  }
11
+
12
+ .properties-widget-toolbar {
13
+ border-bottom: 1px solid var(--color-details-hairline-light);
14
+ flex-shrink: 0;
15
+ }
16
+
17
+ .properties-widget-filter-box {
18
+ flex: auto;
19
+ display: flex;
20
+ }
21
+
22
+ .properties-widget-filter-box > input {
23
+ outline: none !important; /* stylelint-disable-line declaration-no-important */
24
+ border: none;
25
+ width: 100%;
26
+ background: var(--color-background);
27
+ padding-left: 4px;
28
+ margin: 3px;
29
+ }
30
+
31
+ .properties-widget-filter-box > input:focus,
32
+ .properties-widget-filter-box > input:not(:placeholder-shown) {
33
+ box-shadow: var(--legacy-focus-ring-active-shadow);
34
+ }
35
+
36
+ .properties-widget-filter-box > input::placeholder {
37
+ color: var(--color-text-disabled);
38
+ }
39
+
40
+ @media (forced-colors: active) {
41
+ .properties-widget-filter-box > input {
42
+ border: 1px solid ButtonText;
43
+ }
44
+ }
@@ -402,7 +402,7 @@ export class DeviceModeToolbar {
402
402
  private appendScaleMenuItems(contextMenu: UI.ContextMenu.ContextMenu): void {
403
403
  if (this.model.type() === EmulationModel.DeviceModeModel.Type.Device) {
404
404
  contextMenu.footerSection().appendItem(
405
- i18nString(UIStrings.fitToWindowF, {PH1: this.getPrettyZoomPercentage()}),
405
+ i18nString(UIStrings.fitToWindowF, {PH1: this.getPrettyFitZoomPercentage()}),
406
406
  this.onScaleMenuChanged.bind(this, this.model.fitScale()), false);
407
407
  }
408
408
  contextMenu.footerSection().appendCheckboxItem(
@@ -693,6 +693,10 @@ export class DeviceModeToolbar {
693
693
  }
694
694
  }
695
695
 
696
+ private getPrettyFitZoomPercentage(): string {
697
+ return `${(this.model.fitScale() * 100).toFixed(0)}`;
698
+ }
699
+
696
700
  private getPrettyZoomPercentage(): string {
697
701
  return `${(this.model.scale() * 100).toFixed(0)}`;
698
702
  }
@@ -174,11 +174,16 @@ export class CorsIssueDetailsView extends AffectedResourcesView {
174
174
  this.appendColumnTitle(header, i18nString(UIStrings.allowCredentialsValueFromHeader));
175
175
  break;
176
176
  case IssuesManager.CorsIssue.IssueCode.InsecurePrivateNetwork:
177
- case IssuesManager.CorsIssue.IssueCode.InsecurePrivateNetworkPreflight:
178
177
  this.appendColumnTitle(header, i18nString(UIStrings.resourceAddressSpace));
179
178
  this.appendColumnTitle(header, i18nString(UIStrings.initiatorAddressSpace));
180
179
  this.appendColumnTitle(header, i18nString(UIStrings.initiatorContext));
181
180
  break;
181
+ case IssuesManager.CorsIssue.IssueCode.PreflightAllowPrivateNetworkError:
182
+ this.appendColumnTitle(header, i18nString(UIStrings.preflightRequest));
183
+ this.appendColumnTitle(header, i18nString(UIStrings.invalidValue));
184
+ this.appendColumnTitle(header, i18nString(UIStrings.initiatorAddressSpace));
185
+ this.appendColumnTitle(header, i18nString(UIStrings.initiatorContext));
186
+ break;
182
187
  case IssuesManager.CorsIssue.IssueCode.MethodDisallowedByPreflightResponse:
183
188
  this.appendColumnTitle(header, i18nString(UIStrings.preflightRequest));
184
189
  this.appendColumnTitle(header, i18nString(UIStrings.disallowedRequestMethod));
@@ -207,9 +212,7 @@ export class CorsIssueDetailsView extends AffectedResourcesView {
207
212
  IssuesManager.CorsIssue.IssueCode.PreflightInvalidAllowExternal|
208
213
  IssuesManager.CorsIssue.IssueCode.InvalidResponse|
209
214
  IssuesManager.CorsIssue.IssueCode.InvalidPrivateNetworkAccess|
210
- IssuesManager.CorsIssue.IssueCode.UnexpectedPrivateNetworkAccess|
211
- IssuesManager.CorsIssue.IssueCode.PreflightMissingAllowPrivateNetwork|
212
- IssuesManager.CorsIssue.IssueCode.PreflightInvalidAllowPrivateNetwork>(issueCode);
215
+ IssuesManager.CorsIssue.IssueCode.UnexpectedPrivateNetworkAccess>(issueCode);
213
216
  }
214
217
 
215
218
  this.affectedResources.appendChild(header);
@@ -251,6 +254,9 @@ export class CorsIssueDetailsView extends AffectedResourcesView {
251
254
  case Protocol.Network.CorsError.InvalidAllowCredentials:
252
255
  case Protocol.Network.CorsError.PreflightInvalidAllowCredentials:
253
256
  return 'Access-Control-Allow-Credentials';
257
+ case Protocol.Network.CorsError.PreflightMissingAllowPrivateNetwork:
258
+ case Protocol.Network.CorsError.PreflightInvalidAllowPrivateNetwork:
259
+ return 'Access-Control-Allow-Private-Network';
254
260
  case Protocol.Network.CorsError.RedirectContainsCredentials:
255
261
  case Protocol.Network.CorsError.PreflightDisallowedRedirect:
256
262
  return 'Location';
@@ -362,13 +368,21 @@ export class CorsIssueDetailsView extends AffectedResourcesView {
362
368
  this.appendIssueDetailCell(element, details.corsErrorStatus.failedParameter, 'code-example');
363
369
  break;
364
370
  case IssuesManager.CorsIssue.IssueCode.InsecurePrivateNetwork:
365
- case IssuesManager.CorsIssue.IssueCode.InsecurePrivateNetworkPreflight:
366
371
  element.appendChild(this.createRequestCell(details.request, opts));
367
372
  this.appendStatus(element, details.isWarning);
368
373
  this.appendIssueDetailCell(element, details.resourceIPAddressSpace ?? '');
369
374
  this.appendIssueDetailCell(element, details.clientSecurityState?.initiatorIPAddressSpace ?? '');
370
375
  this.appendSecureContextCell(element, details.clientSecurityState?.initiatorIsSecureContext);
371
376
  break;
377
+ case IssuesManager.CorsIssue.IssueCode.PreflightAllowPrivateNetworkError: {
378
+ element.appendChild(this.createRequestCell(details.request, opts));
379
+ this.appendStatus(element, details.isWarning);
380
+ element.appendChild(this.createRequestCell(details.request, {...opts, linkToPreflight: true, highlightHeader}));
381
+ this.appendIssueDetailCell(element, details.corsErrorStatus.failedParameter, 'code-example');
382
+ this.appendIssueDetailCell(element, details.clientSecurityState?.initiatorIPAddressSpace ?? '');
383
+ this.appendSecureContextCell(element, details.clientSecurityState?.initiatorIsSecureContext);
384
+ break;
385
+ }
372
386
  case IssuesManager.CorsIssue.IssueCode.MethodDisallowedByPreflightResponse:
373
387
  element.appendChild(this.createRequestCell(details.request, opts));
374
388
  this.appendStatus(element, details.isWarning);
@@ -435,9 +449,7 @@ export class CorsIssueDetailsView extends AffectedResourcesView {
435
449
  IssuesManager.CorsIssue.IssueCode.PreflightInvalidAllowExternal|
436
450
  IssuesManager.CorsIssue.IssueCode.InvalidResponse|
437
451
  IssuesManager.CorsIssue.IssueCode.InvalidPrivateNetworkAccess|
438
- IssuesManager.CorsIssue.IssueCode.UnexpectedPrivateNetworkAccess|
439
- IssuesManager.CorsIssue.IssueCode.PreflightMissingAllowPrivateNetwork|
440
- IssuesManager.CorsIssue.IssueCode.PreflightInvalidAllowPrivateNetwork>(issueCode);
452
+ IssuesManager.CorsIssue.IssueCode.UnexpectedPrivateNetworkAccess>(issueCode);
441
453
  break;
442
454
  }
443
455
 
@@ -16,6 +16,7 @@ import {RequestTimeRangeNameToColor} from './NetworkOverview.js';
16
16
  import type {Label, NetworkTimeCalculator} from './NetworkTimeCalculator.js';
17
17
  import type {RequestTimeRange} from './RequestTimingView.js';
18
18
  import {RequestTimeRangeNames, RequestTimingView} from './RequestTimingView.js';
19
+ import networkingTimingTableStyles from './networkTimingTable.css.js';
19
20
 
20
21
  const BAR_SPACING = 1;
21
22
 
@@ -271,6 +272,7 @@ export class NetworkWaterfallColumn extends UI.Widget.VBox {
271
272
  show: (popover: UI.GlassPane.GlassPane): Promise<true> => {
272
273
  const content =
273
274
  RequestTimingView.createTimingTable((request as SDK.NetworkRequest.NetworkRequest), this.calculator);
275
+ popover.registerCSSFiles([networkingTimingTableStyles]);
274
276
  popover.contentElement.appendChild(content);
275
277
  return Promise.resolve(true);
276
278
  },
@@ -30,6 +30,7 @@
30
30
 
31
31
  import * as Common from '../../core/common/common.js';
32
32
  import * as Host from '../../core/host/host.js';
33
+ import * as Platform from '../../core/platform/platform.js';
33
34
  import * as PerfUI from '../../ui/legacy/components/perf_ui/perf_ui.js';
34
35
  import type * as SDK from '../../core/sdk/sdk.js';
35
36
  import * as UI from '../../ui/legacy/legacy.js';
@@ -217,7 +218,8 @@ export class CPUProfileFlameChart extends
217
218
  }
218
219
 
219
220
  performSearch(searchConfig: UI.SearchableView.SearchConfig, _shouldJump: boolean, jumpBackwards?: boolean): void {
220
- const matcher = createPlainTextSearchRegex(searchConfig.query, searchConfig.caseSensitive ? '' : 'i');
221
+ const matcher =
222
+ Platform.StringUtilities.createPlainTextSearchRegex(searchConfig.query, searchConfig.caseSensitive ? '' : 'i');
221
223
 
222
224
  const selectedEntryIndex: number = this.searchResultIndex !== -1 ? this.searchResults[this.searchResultIndex] : -1;
223
225
  this.searchResults = [];