chrome-devtools-frontend 1.0.1029692 → 1.0.1029795

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.
@@ -280,6 +280,7 @@ grd_files_release_sources = [
280
280
  "front_end/models/issues_manager/descriptions/TwaHttpError.md",
281
281
  "front_end/models/issues_manager/descriptions/TwaPageUnavailableOffline.md",
282
282
  "front_end/models/issues_manager/descriptions/arInsecureContext.md",
283
+ "front_end/models/issues_manager/descriptions/arInvalidEligibleHeader.md",
283
284
  "front_end/models/issues_manager/descriptions/arInvalidRegisterSourceHeader.md",
284
285
  "front_end/models/issues_manager/descriptions/arInvalidRegisterTriggerHeader.md",
285
286
  "front_end/models/issues_manager/descriptions/arPermissionPolicyDisabled.md",
@@ -14,6 +14,7 @@ export const enum IssueCode {
14
14
  InsecureContext = 'AttributionReportingIssue::InsecureContext',
15
15
  InvalidRegisterSourceHeader = 'AttributionReportingIssue::InvalidRegisterSourceHeader',
16
16
  InvalidRegisterTriggerHeader = 'AttributionReportingIssue::InvalidRegisterTriggerHeader',
17
+ InvalidEligibleHeader = 'AttributionReportingIssue::InvalidEligibleHeader',
17
18
  // TODO(apaseltiner): Remove this once old issue types are removed from
18
19
  // protocol.
19
20
  Unknown = 'AttributionReportingIssue::Unknown',
@@ -31,6 +32,8 @@ function getIssueCode(details: Protocol.Audits.AttributionReportingIssueDetails)
31
32
  return IssueCode.InvalidRegisterSourceHeader;
32
33
  case Protocol.Audits.AttributionReportingIssueType.InvalidRegisterTriggerHeader:
33
34
  return IssueCode.InvalidRegisterTriggerHeader;
35
+ case Protocol.Audits.AttributionReportingIssueType.InvalidEligibleHeader:
36
+ return IssueCode.InvalidEligibleHeader;
34
37
  default:
35
38
  return IssueCode.Unknown;
36
39
  }
@@ -76,6 +79,14 @@ export class AttributionReportingIssue extends Issue<IssueCode> {
76
79
  file: 'arInvalidRegisterTriggerHeader.md',
77
80
  links: [],
78
81
  };
82
+ case IssueCode.InvalidEligibleHeader:
83
+ return {
84
+ file: 'arInvalidEligibleHeader.md',
85
+ links: [{
86
+ link: 'https://tools.ietf.org/id/draft-ietf-httpbis-header-structure-15.html#rfc.section.4.2.2',
87
+ linkTitle: 'Structured Headers RFC',
88
+ }],
89
+ };
79
90
  case IssueCode.Unknown:
80
91
  return null;
81
92
  }
@@ -0,0 +1,19 @@
1
+ # Ensure that the `Attribution-Reporting-Eligible` header is valid
2
+
3
+ This page sent a request containing an `Attribution-Reporting-Eligible` header,
4
+ but the header value was not a valid structured dictionary, causing any source
5
+ or trigger registration in the response to be ignored.
6
+
7
+ The header should contain a structured dictionary as follows:
8
+
9
+ To allow the response to register an event source:
10
+ `Attribution-Reporting-Eligible: event-source`
11
+
12
+ To allow the response to register a trigger:
13
+ `Attribution-Reporting-Eligible: trigger`
14
+
15
+ To allow the response to register an event source or a trigger:
16
+ `Attribution-Reporting-Eligible: event-source, trigger`
17
+
18
+ To prevent the response from registering anything:
19
+ `Attribution-Reporting-Eligible: `
@@ -26,6 +26,8 @@ import {cssRuleValidatorsMap, type AuthoringHint} from './CSSRuleValidator.js';
26
26
  const FlexboxEditor = ElementsComponents.StylePropertyEditor.FlexboxEditor;
27
27
  const GridEditor = ElementsComponents.StylePropertyEditor.GridEditor;
28
28
 
29
+ export const activeHints = new WeakMap<Element, AuthoringHint>();
30
+
29
31
  const UIStrings = {
30
32
  /**
31
33
  *@description Text in Color Swatch Popover Icon of the Elements panel
@@ -719,11 +721,7 @@ export class StylePropertyTreeElement extends UI.TreeOutline.TreeElement {
719
721
  const showAuthoringHint = authoringHint !== null && this.property.parsedOk;
720
722
  if (showAuthoringHint) {
721
723
  const hintIcon = UI.Icon.Icon.create('mediumicon-info', 'hint');
722
- const hintPopover =
723
- new UI.PopoverHelper.PopoverHelper(hintIcon, event => this.handleHintPopoverRequest(authoringHint, event));
724
- hintPopover.setHasPadding(true);
725
- hintPopover.setTimeout(0, 100);
726
-
724
+ activeHints.set(hintIcon, authoringHint);
727
725
  this.listItemElement.append(hintIcon);
728
726
  }
729
727
 
@@ -836,24 +834,6 @@ export class StylePropertyTreeElement extends UI.TreeOutline.TreeElement {
836
834
  return null;
837
835
  }
838
836
 
839
- private handleHintPopoverRequest(authoringHint: AuthoringHint, event: Event): UI.PopoverHelper.PopoverRequest|null {
840
- const link = event.composedPath()[0];
841
- Platform.DCHECK(() => link instanceof Element, 'Link is not an instance of Element');
842
-
843
- return {
844
- box: (link as Element).boxInWindow(),
845
- show: async(popover: UI.GlassPane.GlassPane): Promise<boolean> => {
846
- const node = this.node();
847
- if (!node) {
848
- return false;
849
- }
850
- const popupElement = new ElementsComponents.CSSHintDetailsView.CSSHintDetailsView(authoringHint);
851
- popover.contentElement.insertAdjacentElement('beforeend', popupElement);
852
- return true;
853
- },
854
- };
855
- }
856
-
857
837
  private mouseUp(event: MouseEvent): void {
858
838
  const activeTreeElement = parentMap.get(this.parentPaneInternal);
859
839
  parentMap.delete(this.parentPaneInternal);
@@ -60,7 +60,7 @@ import {StyleEditorWidget} from './StyleEditorWidget.js';
60
60
  import {StylePropertyHighlighter} from './StylePropertyHighlighter.js';
61
61
  import stylesSidebarPaneStyles from './stylesSidebarPane.css.js';
62
62
 
63
- import {type StylePropertyTreeElement} from './StylePropertyTreeElement.js';
63
+ import {activeHints, type StylePropertyTreeElement} from './StylePropertyTreeElement.js';
64
64
  import {
65
65
  StylePropertiesSection,
66
66
  BlankStylePropertiesSection,
@@ -213,6 +213,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
213
213
  private needsForceUpdate: boolean;
214
214
  private readonly resizeThrottler: Common.Throttler.Throttler;
215
215
  private readonly imagePreviewPopover: ImagePreviewPopover;
216
+ #hintPopoverHelper: UI.PopoverHelper.PopoverHelper;
216
217
  activeCSSAngle: InlineEditor.CSSAngle.CSSAngle|null;
217
218
  #urlToChangeTracker: Map<Platform.DevToolsPath.UrlString, ChangeTracker> = new Map();
218
219
  #copyChangesButton?: UI.Toolbar.ToolbarButton;
@@ -282,6 +283,35 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
282
283
  }, () => this.node());
283
284
 
284
285
  this.activeCSSAngle = null;
286
+
287
+ this.#hintPopoverHelper = new UI.PopoverHelper.PopoverHelper(this.contentElement, event => {
288
+ const icon = event.composedPath()[0] as Element;
289
+
290
+ if (!icon) {
291
+ return null;
292
+ }
293
+
294
+ if (!icon.matches('.hint')) {
295
+ return null;
296
+ }
297
+
298
+ const hint = activeHints.get(icon);
299
+
300
+ if (!hint) {
301
+ return null;
302
+ }
303
+
304
+ return {
305
+ box: icon.boxInWindow(),
306
+ show: async(popover: UI.GlassPane.GlassPane): Promise<boolean> => {
307
+ const popupElement = new ElementsComponents.CSSHintDetailsView.CSSHintDetailsView(hint);
308
+ popover.contentElement.appendChild(popupElement);
309
+ return true;
310
+ },
311
+ };
312
+ });
313
+ this.#hintPopoverHelper.setTimeout(200);
314
+ this.#hintPopoverHelper.setHasPadding(true);
285
315
  }
286
316
 
287
317
  swatchPopoverHelper(): InlineEditor.SwatchPopoverHelper.SwatchPopoverHelper {
@@ -57,6 +57,7 @@ export class AttributionReportingIssueDetailsView extends AffectedResourcesView
57
57
  switch (issueCode) {
58
58
  case IssuesManager.AttributionReportingIssue.IssueCode.InvalidRegisterSourceHeader:
59
59
  case IssuesManager.AttributionReportingIssue.IssueCode.InvalidRegisterTriggerHeader:
60
+ case IssuesManager.AttributionReportingIssue.IssueCode.InvalidEligibleHeader:
60
61
  this.appendColumnTitle(header, i18nString(UIStrings.request));
61
62
  this.appendColumnTitle(header, i18nString(UIStrings.invalidHeaderValue));
62
63
  break;
@@ -92,6 +93,7 @@ export class AttributionReportingIssueDetailsView extends AffectedResourcesView
92
93
  switch (issueCode) {
93
94
  case IssuesManager.AttributionReportingIssue.IssueCode.InvalidRegisterSourceHeader:
94
95
  case IssuesManager.AttributionReportingIssue.IssueCode.InvalidRegisterTriggerHeader:
96
+ case IssuesManager.AttributionReportingIssue.IssueCode.InvalidEligibleHeader:
95
97
  this.#appendRequestOrEmptyCell(element, details.request);
96
98
  this.appendIssueDetailCell(element, details.invalidParameter || '');
97
99
  break;
@@ -173,12 +173,16 @@ export class RequestHeadersView extends UI.Widget.VBox {
173
173
  wasShown(): void {
174
174
  this.#request.addEventListener(SDK.NetworkRequest.Events.RemoteAddressChanged, this.#refreshHeadersView, this);
175
175
  this.#request.addEventListener(SDK.NetworkRequest.Events.FinishedLoading, this.#refreshHeadersView, this);
176
+ this.#request.addEventListener(SDK.NetworkRequest.Events.RequestHeadersChanged, this.#refreshHeadersView, this);
177
+ this.#request.addEventListener(SDK.NetworkRequest.Events.ResponseHeadersChanged, this.#refreshHeadersView, this);
176
178
  this.#refreshHeadersView();
177
179
  }
178
180
 
179
181
  willHide(): void {
180
182
  this.#request.removeEventListener(SDK.NetworkRequest.Events.RemoteAddressChanged, this.#refreshHeadersView, this);
181
183
  this.#request.removeEventListener(SDK.NetworkRequest.Events.FinishedLoading, this.#refreshHeadersView, this);
184
+ this.#request.removeEventListener(SDK.NetworkRequest.Events.RequestHeadersChanged, this.#refreshHeadersView, this);
185
+ this.#request.removeEventListener(SDK.NetworkRequest.Events.ResponseHeadersChanged, this.#refreshHeadersView, this);
182
186
  }
183
187
 
184
188
  #refreshHeadersView(): void {
@@ -385,7 +389,10 @@ export class RequestHeadersComponent extends HTMLElement {
385
389
  LitHtml.nothing
386
390
  }${header.name}:
387
391
  </div>
388
- <div class="header-value ${header.headerValueIncorrect ? 'header-warning' : ''}">
392
+ <div
393
+ class="header-value ${header.headerValueIncorrect ? 'header-warning' : ''}"
394
+ @copy=${():void => Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelCopyValue)}
395
+ >
389
396
  ${header.value?.toString() || ''}
390
397
  ${this.#maybeRenderHeaderValueSuffix(header)}
391
398
  </div>
@@ -582,28 +589,43 @@ export class RequestHeadersComponent extends HTMLElement {
582
589
  >
583
590
  <div class="row">
584
591
  <div class="header-name">${i18nString(UIStrings.requestUrl)}:</div>
585
- <div class="header-value">${this.#request.url()}</div>
592
+ <div
593
+ class="header-value"
594
+ @copy=${():void => Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelCopyValue)}
595
+ >${this.#request.url()}</div>
586
596
  </div>
587
597
  ${this.#request.statusCode? html`
588
598
  <div class="row">
589
599
  <div class="header-name">${i18nString(UIStrings.requestMethod)}:</div>
590
- <div class="header-value">${this.#request.requestMethod}</div>
600
+ <div
601
+ class="header-value"
602
+ @copy=${():void => Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelCopyValue)}
603
+ >${this.#request.requestMethod}</div>
591
604
  </div>
592
605
  <div class="row">
593
606
  <div class="header-name">${i18nString(UIStrings.statusCode)}:</div>
594
- <div class="header-value ${coloredCircleClassName} ${statusTextHasComment ? 'status-with-comment' : ''}">${statusText}</div>
607
+ <div
608
+ class="header-value ${coloredCircleClassName} ${statusTextHasComment ? 'status-with-comment' : ''}"
609
+ @copy=${():void => Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelCopyValue)}
610
+ >${statusText}</div>
595
611
  </div>
596
612
  ` : ''}
597
613
  ${this.#request.remoteAddress()? html`
598
614
  <div class="row">
599
615
  <div class="header-name">${i18nString(UIStrings.remoteAddress)}:</div>
600
- <div class="header-value">${this.#request.remoteAddress()}</div>
616
+ <div
617
+ class="header-value"
618
+ @copy=${():void => Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelCopyValue)}
619
+ >${this.#request.remoteAddress()}</div>
601
620
  </div>
602
621
  ` : ''}
603
622
  ${this.#request.referrerPolicy()? html`
604
623
  <div class="row">
605
624
  <div class="header-name">${i18nString(UIStrings.referrerPolicy)}:</div>
606
- <div class="header-value">${this.#request.referrerPolicy()}</div>
625
+ <div
626
+ class="header-value"
627
+ @copy=${():void => Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelCopyValue)}
628
+ >${this.#request.referrerPolicy()}</div>
607
629
  </div>
608
630
  ` : ''}
609
631
  </${Category.litTagName}>
@@ -125,6 +125,8 @@ export class ProtocolMonitorImpl extends UI.Widget.VBox {
125
125
  private messages: LogMessage[] = [];
126
126
  private isRecording: boolean = false;
127
127
 
128
+ #historyAutocompleteDataProvider = new HistoryAutocompleteDataProvider();
129
+
128
130
  constructor() {
129
131
  super(true);
130
132
  this.started = false;
@@ -303,21 +305,24 @@ export class ProtocolMonitorImpl extends UI.Widget.VBox {
303
305
  const shrinkFactor = 0.2;
304
306
  const tooltip = i18nString(UIStrings.sendRawCDPCommandExplanation);
305
307
  const input = new UI.Toolbar.ToolbarInput(
306
- placeholder, accessiblePlaceholder, growFactor, shrinkFactor, tooltip, undefined, false);
308
+ placeholder, accessiblePlaceholder, growFactor, shrinkFactor, tooltip,
309
+ this.#historyAutocompleteDataProvider.buildTextPromptCompletions, false);
307
310
  input.addEventListener(UI.Toolbar.ToolbarInput.Event.EnterPressed, () => this.#onCommandSend(input));
308
311
  return input;
309
312
  }
310
313
 
311
314
  #onCommandSend(input: UI.Toolbar.ToolbarInput): void {
312
- const {command, parameters} = parseCommandInput(input.value());
315
+ const value = input.value();
316
+ const {command, parameters} = parseCommandInput(value);
313
317
  const test = ProtocolClient.InspectorBackend.test;
314
318
  // TODO: TS thinks that properties are read-only because
315
319
  // in TS test is defined as a namespace.
316
320
  // @ts-ignore
317
321
  test.sendRawMessage(command, parameters, () => {});
322
+ this.#historyAutocompleteDataProvider.addEntry(value);
318
323
  }
319
324
 
320
- static instance(opts = {forceNew: null}): ProtocolMonitorImpl {
325
+ static instance(opts: {forceNew: null|boolean} = {forceNew: null}): ProtocolMonitorImpl {
321
326
  const {forceNew} = opts;
322
327
  if (!protocolMonitorImplInstance || forceNew) {
323
328
  protocolMonitorImplInstance = new ProtocolMonitorImpl();
@@ -487,6 +492,39 @@ export class ProtocolMonitorImpl extends UI.Widget.VBox {
487
492
  }
488
493
  }
489
494
 
495
+ export class HistoryAutocompleteDataProvider {
496
+ #maxHistorySize = 200;
497
+ #commandHistory = new Set<string>();
498
+
499
+ constructor(maxHistorySize?: number) {
500
+ if (maxHistorySize !== undefined) {
501
+ this.#maxHistorySize = maxHistorySize;
502
+ }
503
+ }
504
+
505
+ buildTextPromptCompletions =
506
+ async(expression: string, prefix: string, force?: boolean): Promise<UI.SuggestBox.Suggestions> => {
507
+ if (!prefix && !force && expression) {
508
+ return [];
509
+ }
510
+ const newestToOldest = [...this.#commandHistory].reverse();
511
+ return newestToOldest.filter(cmd => cmd.startsWith(prefix)).map(text => ({
512
+ text,
513
+ }));
514
+ };
515
+
516
+ addEntry(value: string): void {
517
+ if (this.#commandHistory.has(value)) {
518
+ this.#commandHistory.delete(value);
519
+ }
520
+ this.#commandHistory.add(value);
521
+ if (this.#commandHistory.size > this.#maxHistorySize) {
522
+ const earliestEntry = this.#commandHistory.values().next().value;
523
+ this.#commandHistory.delete(earliestEntry);
524
+ }
525
+ }
526
+ }
527
+
490
528
  export class InfoWidget extends UI.Widget.VBox {
491
529
  private readonly tabbedPane: UI.TabbedPane.TabbedPane;
492
530
  constructor() {
@@ -89,7 +89,7 @@ export class TextPrompt extends Common.ObjectWrapper.ObjectWrapper<EventTypes> i
89
89
  }
90
90
 
91
91
  initialize(
92
- completions: (this: null, arg1: string, arg2: string, arg3?: boolean|undefined) => Promise<Suggestion[]>,
92
+ completions: (this: null, expression: string, filter: string, force?: boolean|undefined) => Promise<Suggestion[]>,
93
93
  stopCharacters?: string, usesSuggestionBuilder?: boolean): void {
94
94
  this.loadCompletions = completions;
95
95
  this.completionStopCharacters = stopCharacters || ' =:[({;,!+-*/&|^<>.';
package/package.json CHANGED
@@ -55,5 +55,5 @@
55
55
  "unittest": "scripts/test/run_unittests.py --no-text-coverage",
56
56
  "watch": "vpython third_party/node/node.py --output scripts/watch_build.js"
57
57
  },
58
- "version": "1.0.1029692"
58
+ "version": "1.0.1029795"
59
59
  }