chrome-devtools-frontend 1.0.1029692 → 1.0.1030457
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config/gni/devtools_grd_files.gni +4 -0
- package/config/gni/devtools_image_files.gni +2 -0
- package/docs/workflows.md +1 -1
- package/front_end/Images/src/file-sync_icon.svg +62 -0
- package/front_end/Images/src/file_icon.svg +52 -0
- package/front_end/core/i18n/locales/en-US.json +6 -0
- package/front_end/core/i18n/locales/en-XL.json +6 -0
- package/front_end/models/issues_manager/AttributionReportingIssue.ts +11 -0
- package/front_end/models/issues_manager/DeprecationIssue.ts +5 -1
- package/front_end/models/issues_manager/descriptions/arInvalidEligibleHeader.md +19 -0
- package/front_end/panels/elements/CSSRuleValidator.ts +356 -21
- package/front_end/panels/elements/CSSRuleValidatorHelper.ts +34 -0
- package/front_end/panels/elements/StylePropertyTreeElement.ts +4 -24
- package/front_end/panels/elements/StylesSidebarPane.ts +31 -1
- package/front_end/panels/issues/AttributionReportingIssueDetailsView.ts +2 -0
- package/front_end/panels/network/components/RequestHeadersView.css +40 -8
- package/front_end/panels/network/components/RequestHeadersView.ts +123 -18
- package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +42 -3
- package/front_end/ui/components/data_grid/DataGrid.ts +15 -10
- package/front_end/ui/components/data_grid/DataGridController.ts +7 -0
- package/front_end/ui/legacy/TextPrompt.ts +1 -1
- package/package.json +6 -5
@@ -6,9 +6,12 @@ import * as Common from '../../../core/common/common.js';
|
|
6
6
|
import * as Host from '../../../core/host/host.js';
|
7
7
|
import * as i18n from '../../../core/i18n/i18n.js';
|
8
8
|
import * as Platform from '../../../core/platform/platform.js';
|
9
|
+
import * as Root from '../../../core/root/root.js';
|
9
10
|
import * as SDK from '../../../core/sdk/sdk.js';
|
10
11
|
import * as Protocol from '../../../generated/protocol.js';
|
11
12
|
import * as IssuesManager from '../../../models/issues_manager/issues_manager.js';
|
13
|
+
import * as Persistence from '../../../models/persistence/persistence.js';
|
14
|
+
import * as Workspace from '../../../models/workspace/workspace.js';
|
12
15
|
import * as ClientVariations from '../../../third_party/chromium/client-variations/client-variations.js';
|
13
16
|
import * as Buttons from '../../../ui/components/buttons/buttons.js';
|
14
17
|
import * as ComponentHelpers from '../../../ui/components/helpers/helpers.js';
|
@@ -16,6 +19,7 @@ import * as IconButton from '../../../ui/components/icon_button/icon_button.js';
|
|
16
19
|
import * as Input from '../../../ui/components/input/input.js';
|
17
20
|
import * as UI from '../../../ui/legacy/legacy.js';
|
18
21
|
import * as LitHtml from '../../../ui/lit-html/lit-html.js';
|
22
|
+
import * as Sources from '../../sources/sources.js';
|
19
23
|
|
20
24
|
import requestHeadersViewStyles from './RequestHeadersView.css.js';
|
21
25
|
|
@@ -69,6 +73,11 @@ const UIStrings = {
|
|
69
73
|
*/
|
70
74
|
general: 'General',
|
71
75
|
/**
|
76
|
+
*@description Label for a link from the network panel's headers view to the file in which
|
77
|
+
* header overrides are defined in the sources panel.
|
78
|
+
*/
|
79
|
+
headerOverrides: 'Header overrides',
|
80
|
+
/**
|
72
81
|
*@description Text that is usually a hyperlink to more documentation
|
73
82
|
*/
|
74
83
|
learnMore: 'Learn more',
|
@@ -173,12 +182,16 @@ export class RequestHeadersView extends UI.Widget.VBox {
|
|
173
182
|
wasShown(): void {
|
174
183
|
this.#request.addEventListener(SDK.NetworkRequest.Events.RemoteAddressChanged, this.#refreshHeadersView, this);
|
175
184
|
this.#request.addEventListener(SDK.NetworkRequest.Events.FinishedLoading, this.#refreshHeadersView, this);
|
185
|
+
this.#request.addEventListener(SDK.NetworkRequest.Events.RequestHeadersChanged, this.#refreshHeadersView, this);
|
186
|
+
this.#request.addEventListener(SDK.NetworkRequest.Events.ResponseHeadersChanged, this.#refreshHeadersView, this);
|
176
187
|
this.#refreshHeadersView();
|
177
188
|
}
|
178
189
|
|
179
190
|
willHide(): void {
|
180
191
|
this.#request.removeEventListener(SDK.NetworkRequest.Events.RemoteAddressChanged, this.#refreshHeadersView, this);
|
181
192
|
this.#request.removeEventListener(SDK.NetworkRequest.Events.FinishedLoading, this.#refreshHeadersView, this);
|
193
|
+
this.#request.removeEventListener(SDK.NetworkRequest.Events.RequestHeadersChanged, this.#refreshHeadersView, this);
|
194
|
+
this.#request.removeEventListener(SDK.NetworkRequest.Events.ResponseHeadersChanged, this.#refreshHeadersView, this);
|
182
195
|
}
|
183
196
|
|
184
197
|
#refreshHeadersView(): void {
|
@@ -200,6 +213,7 @@ export class RequestHeadersComponent extends HTMLElement {
|
|
200
213
|
#showRequestHeadersText = false;
|
201
214
|
#showResponseHeadersTextFull = false;
|
202
215
|
#showRequestHeadersTextFull = false;
|
216
|
+
readonly #workspace = Workspace.Workspace.WorkspaceImpl.instance();
|
203
217
|
|
204
218
|
set data(data: RequestHeadersComponentData) {
|
205
219
|
this.#request = data.request;
|
@@ -208,6 +222,23 @@ export class RequestHeadersComponent extends HTMLElement {
|
|
208
222
|
|
209
223
|
connectedCallback(): void {
|
210
224
|
this.#shadow.adoptedStyleSheets = [requestHeadersViewStyles];
|
225
|
+
this.#workspace.addEventListener(
|
226
|
+
Workspace.Workspace.Events.UISourceCodeAdded, this.#uiSourceCodeAddedOrRemoved, this);
|
227
|
+
this.#workspace.addEventListener(
|
228
|
+
Workspace.Workspace.Events.UISourceCodeRemoved, this.#uiSourceCodeAddedOrRemoved, this);
|
229
|
+
}
|
230
|
+
|
231
|
+
disconnectedCallback(): void {
|
232
|
+
this.#workspace.removeEventListener(
|
233
|
+
Workspace.Workspace.Events.UISourceCodeAdded, this.#uiSourceCodeAddedOrRemoved, this);
|
234
|
+
this.#workspace.removeEventListener(
|
235
|
+
Workspace.Workspace.Events.UISourceCodeRemoved, this.#uiSourceCodeAddedOrRemoved, this);
|
236
|
+
}
|
237
|
+
|
238
|
+
#uiSourceCodeAddedOrRemoved(event: Common.EventTarget.EventTargetEvent<Workspace.UISourceCode.UISourceCode>): void {
|
239
|
+
if (this.#getHeaderOverridesFileUrl() === event.data.url()) {
|
240
|
+
this.#render();
|
241
|
+
}
|
211
242
|
}
|
212
243
|
|
213
244
|
#render(): void {
|
@@ -290,6 +321,7 @@ export class RequestHeadersComponent extends HTMLElement {
|
|
290
321
|
title: i18nString(UIStrings.responseHeaders),
|
291
322
|
headerCount: this.#request.sortedResponseHeaders.length,
|
292
323
|
checked: this.#request.responseHeadersText ? this.#showResponseHeadersText : undefined,
|
324
|
+
additionalContent: this.#renderHeaderOverridesLink(),
|
293
325
|
} as CategoryData}
|
294
326
|
aria-label=${i18nString(UIStrings.responseHeaders)}
|
295
327
|
>
|
@@ -302,6 +334,57 @@ export class RequestHeadersComponent extends HTMLElement {
|
|
302
334
|
// clang-format on
|
303
335
|
}
|
304
336
|
|
337
|
+
#renderHeaderOverridesLink(): LitHtml.LitTemplate {
|
338
|
+
const overrideable = Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.HEADER_OVERRIDES);
|
339
|
+
if (!overrideable || !this.#workspace.uiSourceCodeForURL(this.#getHeaderOverridesFileUrl())) {
|
340
|
+
return LitHtml.nothing;
|
341
|
+
}
|
342
|
+
|
343
|
+
const overridesSetting: Common.Settings.Setting<boolean> =
|
344
|
+
Common.Settings.Settings.instance().moduleSetting('persistenceNetworkOverridesEnabled');
|
345
|
+
// Disabled until https://crbug.com/1079231 is fixed.
|
346
|
+
// clang-format off
|
347
|
+
const fileIcon = overridesSetting.get() ? html`
|
348
|
+
<${IconButton.Icon.Icon.litTagName} class="inline-icon purple-dot" .data=${{
|
349
|
+
iconName: 'file-sync_icon',
|
350
|
+
width: '11px',
|
351
|
+
height: '13px',
|
352
|
+
} as IconButton.Icon.IconData}>
|
353
|
+
</${IconButton.Icon.Icon.litTagName}>` : html`
|
354
|
+
<${IconButton.Icon.Icon.litTagName} class="inline-icon" .data=${{
|
355
|
+
iconName: 'file_icon',
|
356
|
+
color: 'var(--color-text-primary)',
|
357
|
+
width: '12px',
|
358
|
+
height: '12px',
|
359
|
+
} as IconButton.Icon.IconData}>
|
360
|
+
</${IconButton.Icon.Icon.litTagName}>`;
|
361
|
+
// clang-format on
|
362
|
+
|
363
|
+
const revealHeadersFile = (event: Event): void => {
|
364
|
+
event.preventDefault();
|
365
|
+
const uiSourceCode = this.#workspace.uiSourceCodeForURL(this.#getHeaderOverridesFileUrl());
|
366
|
+
if (uiSourceCode) {
|
367
|
+
Sources.SourcesPanel.SourcesPanel.instance().showUISourceCode(uiSourceCode);
|
368
|
+
}
|
369
|
+
};
|
370
|
+
|
371
|
+
return html`
|
372
|
+
<x-link @click=${revealHeadersFile} class="link devtools-link">
|
373
|
+
${fileIcon}${i18nString(UIStrings.headerOverrides)}
|
374
|
+
</x-link>
|
375
|
+
`;
|
376
|
+
}
|
377
|
+
|
378
|
+
#getHeaderOverridesFileUrl(): Platform.DevToolsPath.UrlString {
|
379
|
+
if (!this.#request) {
|
380
|
+
return Platform.DevToolsPath.EmptyUrlString;
|
381
|
+
}
|
382
|
+
const fileUrl = Persistence.NetworkPersistenceManager.NetworkPersistenceManager.instance().fileUrlFromNetworkUrl(
|
383
|
+
this.#request.url(), /* ignoreInactive */ true);
|
384
|
+
return fileUrl.substring(0, fileUrl.lastIndexOf('/')) + '/' +
|
385
|
+
Persistence.NetworkPersistenceManager.HEADERS_FILENAME as Platform.DevToolsPath.UrlString;
|
386
|
+
}
|
387
|
+
|
305
388
|
#renderRequestHeaders(): LitHtml.LitTemplate {
|
306
389
|
if (!this.#request) {
|
307
390
|
return LitHtml.nothing;
|
@@ -385,7 +468,10 @@ export class RequestHeadersComponent extends HTMLElement {
|
|
385
468
|
LitHtml.nothing
|
386
469
|
}${header.name}:
|
387
470
|
</div>
|
388
|
-
<div
|
471
|
+
<div
|
472
|
+
class="header-value ${header.headerValueIncorrect ? 'header-warning' : ''}"
|
473
|
+
@copy=${():void => Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelCopyValue)}
|
474
|
+
>
|
389
475
|
${header.value?.toString() || ''}
|
390
476
|
${this.#maybeRenderHeaderValueSuffix(header)}
|
391
477
|
</div>
|
@@ -582,28 +668,43 @@ export class RequestHeadersComponent extends HTMLElement {
|
|
582
668
|
>
|
583
669
|
<div class="row">
|
584
670
|
<div class="header-name">${i18nString(UIStrings.requestUrl)}:</div>
|
585
|
-
<div
|
671
|
+
<div
|
672
|
+
class="header-value"
|
673
|
+
@copy=${():void => Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelCopyValue)}
|
674
|
+
>${this.#request.url()}</div>
|
586
675
|
</div>
|
587
676
|
${this.#request.statusCode? html`
|
588
677
|
<div class="row">
|
589
678
|
<div class="header-name">${i18nString(UIStrings.requestMethod)}:</div>
|
590
|
-
<div
|
679
|
+
<div
|
680
|
+
class="header-value"
|
681
|
+
@copy=${():void => Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelCopyValue)}
|
682
|
+
>${this.#request.requestMethod}</div>
|
591
683
|
</div>
|
592
684
|
<div class="row">
|
593
685
|
<div class="header-name">${i18nString(UIStrings.statusCode)}:</div>
|
594
|
-
<div
|
686
|
+
<div
|
687
|
+
class="header-value ${coloredCircleClassName} ${statusTextHasComment ? 'status-with-comment' : ''}"
|
688
|
+
@copy=${():void => Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelCopyValue)}
|
689
|
+
>${statusText}</div>
|
595
690
|
</div>
|
596
691
|
` : ''}
|
597
692
|
${this.#request.remoteAddress()? html`
|
598
693
|
<div class="row">
|
599
694
|
<div class="header-name">${i18nString(UIStrings.remoteAddress)}:</div>
|
600
|
-
<div
|
695
|
+
<div
|
696
|
+
class="header-value"
|
697
|
+
@copy=${():void => Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelCopyValue)}
|
698
|
+
>${this.#request.remoteAddress()}</div>
|
601
699
|
</div>
|
602
700
|
` : ''}
|
603
701
|
${this.#request.referrerPolicy()? html`
|
604
702
|
<div class="row">
|
605
703
|
<div class="header-name">${i18nString(UIStrings.referrerPolicy)}:</div>
|
606
|
-
<div
|
704
|
+
<div
|
705
|
+
class="header-value"
|
706
|
+
@copy=${():void => Host.userMetrics.actionTaken(Host.UserMetrics.Action.NetworkPanelCopyValue)}
|
707
|
+
>${this.#request.referrerPolicy()}</div>
|
607
708
|
</div>
|
608
709
|
` : ''}
|
609
710
|
</${Category.litTagName}>
|
@@ -625,6 +726,7 @@ export interface CategoryData {
|
|
625
726
|
title: Common.UIString.LocalizedString;
|
626
727
|
headerCount?: number;
|
627
728
|
checked?: boolean;
|
729
|
+
additionalContent?: LitHtml.LitTemplate;
|
628
730
|
}
|
629
731
|
|
630
732
|
export class Category extends HTMLElement {
|
@@ -634,6 +736,7 @@ export class Category extends HTMLElement {
|
|
634
736
|
#title: Common.UIString.LocalizedString = Common.UIString.LocalizedEmptyString;
|
635
737
|
#headerCount?: number = undefined;
|
636
738
|
#checked: boolean|undefined = undefined;
|
739
|
+
#additionalContent: LitHtml.LitTemplate|undefined = undefined;
|
637
740
|
|
638
741
|
connectedCallback(): void {
|
639
742
|
this.#shadow.adoptedStyleSheets = [requestHeadersViewStyles, Input.checkboxStyles];
|
@@ -645,6 +748,7 @@ export class Category extends HTMLElement {
|
|
645
748
|
Common.Settings.Settings.instance().createSetting('request-info-' + data.name + '-category-expanded', true);
|
646
749
|
this.#headerCount = data.headerCount;
|
647
750
|
this.#checked = data.checked;
|
751
|
+
this.#additionalContent = data.additionalContent;
|
648
752
|
this.#render();
|
649
753
|
}
|
650
754
|
|
@@ -659,18 +763,19 @@ export class Category extends HTMLElement {
|
|
659
763
|
render(html`
|
660
764
|
<details ?open=${isOpen} @toggle=${this.#onToggle}>
|
661
765
|
<summary class="header" @keydown=${this.#onSummaryKeyDown}>
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
766
|
+
<div class="header-grid-container">
|
767
|
+
<div>
|
768
|
+
${this.#title}${this.#headerCount ?
|
769
|
+
html`<span class="header-count"> (${this.#headerCount})</span>` :
|
770
|
+
LitHtml.nothing
|
771
|
+
}
|
772
|
+
</div>
|
773
|
+
<div class="hide-when-closed">
|
774
|
+
${this.#checked !== undefined ? html`
|
775
|
+
<label><input type="checkbox" .checked=${this.#checked} @change=${this.#onCheckboxToggle} />${i18nString(UIStrings.raw)}</label>
|
776
|
+
` : LitHtml.nothing}
|
777
|
+
</div>
|
778
|
+
<div class="hide-when-closed">${this.#additionalContent}</div>
|
674
779
|
</summary>
|
675
780
|
<slot></slot>
|
676
781
|
</details>
|
@@ -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;
|
@@ -162,6 +164,7 @@ export class ProtocolMonitorImpl extends UI.Widget.VBox {
|
|
162
164
|
this.infoWidget = new InfoWidget();
|
163
165
|
|
164
166
|
const dataGridInitialData: DataGrid.DataGridController.DataGridControllerData = {
|
167
|
+
paddingRowsCount: 100,
|
165
168
|
columns: [
|
166
169
|
{
|
167
170
|
id: 'type',
|
@@ -303,21 +306,24 @@ export class ProtocolMonitorImpl extends UI.Widget.VBox {
|
|
303
306
|
const shrinkFactor = 0.2;
|
304
307
|
const tooltip = i18nString(UIStrings.sendRawCDPCommandExplanation);
|
305
308
|
const input = new UI.Toolbar.ToolbarInput(
|
306
|
-
placeholder, accessiblePlaceholder, growFactor, shrinkFactor, tooltip,
|
309
|
+
placeholder, accessiblePlaceholder, growFactor, shrinkFactor, tooltip,
|
310
|
+
this.#historyAutocompleteDataProvider.buildTextPromptCompletions, false);
|
307
311
|
input.addEventListener(UI.Toolbar.ToolbarInput.Event.EnterPressed, () => this.#onCommandSend(input));
|
308
312
|
return input;
|
309
313
|
}
|
310
314
|
|
311
315
|
#onCommandSend(input: UI.Toolbar.ToolbarInput): void {
|
312
|
-
const
|
316
|
+
const value = input.value();
|
317
|
+
const {command, parameters} = parseCommandInput(value);
|
313
318
|
const test = ProtocolClient.InspectorBackend.test;
|
314
319
|
// TODO: TS thinks that properties are read-only because
|
315
320
|
// in TS test is defined as a namespace.
|
316
321
|
// @ts-ignore
|
317
322
|
test.sendRawMessage(command, parameters, () => {});
|
323
|
+
this.#historyAutocompleteDataProvider.addEntry(value);
|
318
324
|
}
|
319
325
|
|
320
|
-
static instance(opts = {forceNew: null}): ProtocolMonitorImpl {
|
326
|
+
static instance(opts: {forceNew: null|boolean} = {forceNew: null}): ProtocolMonitorImpl {
|
321
327
|
const {forceNew} = opts;
|
322
328
|
if (!protocolMonitorImplInstance || forceNew) {
|
323
329
|
protocolMonitorImplInstance = new ProtocolMonitorImpl();
|
@@ -487,6 +493,39 @@ export class ProtocolMonitorImpl extends UI.Widget.VBox {
|
|
487
493
|
}
|
488
494
|
}
|
489
495
|
|
496
|
+
export class HistoryAutocompleteDataProvider {
|
497
|
+
#maxHistorySize = 200;
|
498
|
+
#commandHistory = new Set<string>();
|
499
|
+
|
500
|
+
constructor(maxHistorySize?: number) {
|
501
|
+
if (maxHistorySize !== undefined) {
|
502
|
+
this.#maxHistorySize = maxHistorySize;
|
503
|
+
}
|
504
|
+
}
|
505
|
+
|
506
|
+
buildTextPromptCompletions =
|
507
|
+
async(expression: string, prefix: string, force?: boolean): Promise<UI.SuggestBox.Suggestions> => {
|
508
|
+
if (!prefix && !force && expression) {
|
509
|
+
return [];
|
510
|
+
}
|
511
|
+
const newestToOldest = [...this.#commandHistory].reverse();
|
512
|
+
return newestToOldest.filter(cmd => cmd.startsWith(prefix)).map(text => ({
|
513
|
+
text,
|
514
|
+
}));
|
515
|
+
};
|
516
|
+
|
517
|
+
addEntry(value: string): void {
|
518
|
+
if (this.#commandHistory.has(value)) {
|
519
|
+
this.#commandHistory.delete(value);
|
520
|
+
}
|
521
|
+
this.#commandHistory.add(value);
|
522
|
+
if (this.#commandHistory.size > this.#maxHistorySize) {
|
523
|
+
const earliestEntry = this.#commandHistory.values().next().value;
|
524
|
+
this.#commandHistory.delete(earliestEntry);
|
525
|
+
}
|
526
|
+
}
|
527
|
+
}
|
528
|
+
|
490
529
|
export class InfoWidget extends UI.Widget.VBox {
|
491
530
|
private readonly tabbedPane: UI.TabbedPane.TabbedPane;
|
492
531
|
constructor() {
|
@@ -58,6 +58,7 @@ export interface DataGridData {
|
|
58
58
|
activeSort: SortState|null;
|
59
59
|
contextMenus?: DataGridContextMenusConfiguration;
|
60
60
|
label?: string;
|
61
|
+
paddingRowsCount?: number;
|
61
62
|
}
|
62
63
|
|
63
64
|
const enum UserScrollState {
|
@@ -69,7 +70,6 @@ const enum UserScrollState {
|
|
69
70
|
const KEYS_TREATED_AS_CLICKS = new Set([' ', 'Enter']);
|
70
71
|
|
71
72
|
const ROW_HEIGHT_PIXELS = 18;
|
72
|
-
const PADDING_ROWS_COUNT = 10;
|
73
73
|
|
74
74
|
export class DataGrid extends HTMLElement {
|
75
75
|
static readonly litTagName = LitHtml.literal`devtools-data-grid`;
|
@@ -82,6 +82,7 @@ export class DataGrid extends HTMLElement {
|
|
82
82
|
#userScrollState: UserScrollState = UserScrollState.NOT_SCROLLED;
|
83
83
|
#contextMenus?: DataGridContextMenusConfiguration = undefined;
|
84
84
|
#label?: string = undefined;
|
85
|
+
#paddingRowsCount = 10;
|
85
86
|
#currentResize: {
|
86
87
|
rightCellCol: HTMLTableColElement,
|
87
88
|
leftCellCol: HTMLTableColElement,
|
@@ -139,6 +140,7 @@ export class DataGrid extends HTMLElement {
|
|
139
140
|
activeSort: this.#sortState,
|
140
141
|
contextMenus: this.#contextMenus,
|
141
142
|
label: this.#label,
|
143
|
+
paddingRowsCount: this.#paddingRowsCount,
|
142
144
|
};
|
143
145
|
}
|
144
146
|
|
@@ -171,6 +173,10 @@ export class DataGrid extends HTMLElement {
|
|
171
173
|
this.#cellToFocusIfUserTabsIn = calculateFirstFocusableCell({columns: this.#columns, rows: this.#rows});
|
172
174
|
}
|
173
175
|
|
176
|
+
if (data.paddingRowsCount !== undefined) {
|
177
|
+
this.#paddingRowsCount = data.paddingRowsCount;
|
178
|
+
}
|
179
|
+
|
174
180
|
if (this.#hasRenderedAtLeastOnce && this.#userHasCellFocused()) {
|
175
181
|
const [selectedColIndex, selectedRowIndex] = this.#tabbableCell();
|
176
182
|
const columnOutOfBounds = selectedColIndex > this.#columns.length;
|
@@ -220,15 +226,14 @@ export class DataGrid extends HTMLElement {
|
|
220
226
|
return;
|
221
227
|
}
|
222
228
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
229
|
+
const wrapper = this.#shadow.querySelector('.wrapping-container');
|
230
|
+
if (!wrapper) {
|
231
|
+
return;
|
232
|
+
}
|
233
|
+
|
234
|
+
void coordinator.scroll(() => {
|
228
235
|
const scrollHeight = wrapper.scrollHeight;
|
229
|
-
|
230
|
-
wrapper.scrollTo(0, scrollHeight);
|
231
|
-
});
|
236
|
+
wrapper.scrollTo(0, scrollHeight);
|
232
237
|
});
|
233
238
|
}
|
234
239
|
|
@@ -643,7 +648,7 @@ export class DataGrid extends HTMLElement {
|
|
643
648
|
scrollTop = wrapper.scrollTop;
|
644
649
|
clientHeight = wrapper.clientHeight;
|
645
650
|
}
|
646
|
-
const padding = ROW_HEIGHT_PIXELS *
|
651
|
+
const padding = ROW_HEIGHT_PIXELS * this.#paddingRowsCount;
|
647
652
|
let topVisibleRow = Math.floor((scrollTop - padding) / ROW_HEIGHT_PIXELS);
|
648
653
|
let bottomVisibleRow = Math.ceil((scrollTop + clientHeight + padding) / ROW_HEIGHT_PIXELS);
|
649
654
|
|
@@ -31,6 +31,7 @@ export interface DataGridControllerData {
|
|
31
31
|
initialSort?: SortState;
|
32
32
|
contextMenus?: DataGridContextMenusConfiguration;
|
33
33
|
label?: string;
|
34
|
+
paddingRowsCount?: number;
|
34
35
|
}
|
35
36
|
|
36
37
|
export class DataGridController extends HTMLElement {
|
@@ -55,6 +56,8 @@ export class DataGridController extends HTMLElement {
|
|
55
56
|
#sortState: Readonly<SortState>|null = null;
|
56
57
|
#filters: readonly TextUtils.TextUtils.ParsedFilter[] = [];
|
57
58
|
|
59
|
+
#paddingRowsCount?: number;
|
60
|
+
|
58
61
|
connectedCallback(): void {
|
59
62
|
this.#shadow.adoptedStyleSheets = [dataGridControllerStyles];
|
60
63
|
}
|
@@ -66,6 +69,7 @@ export class DataGridController extends HTMLElement {
|
|
66
69
|
filters: this.#filters,
|
67
70
|
contextMenus: this.#contextMenus,
|
68
71
|
label: this.#label,
|
72
|
+
paddingRowsCount: this.#paddingRowsCount,
|
69
73
|
};
|
70
74
|
}
|
71
75
|
|
@@ -88,6 +92,8 @@ export class DataGridController extends HTMLElement {
|
|
88
92
|
this.#sortRows(this.#sortState);
|
89
93
|
}
|
90
94
|
|
95
|
+
this.#paddingRowsCount = data.paddingRowsCount;
|
96
|
+
|
91
97
|
this.#render();
|
92
98
|
}
|
93
99
|
|
@@ -222,6 +228,7 @@ export class DataGridController extends HTMLElement {
|
|
222
228
|
activeSort: this.#sortState,
|
223
229
|
contextMenus: this.#contextMenus,
|
224
230
|
label: this.#label,
|
231
|
+
paddingRowsCount: this.#paddingRowsCount,
|
225
232
|
} as DataGridData}
|
226
233
|
@columnheaderclick=${this.#onColumnHeaderClick}
|
227
234
|
@contextmenucolumnsortclick=${this.#onContextMenuColumnSortClick}
|
@@ -89,7 +89,7 @@ export class TextPrompt extends Common.ObjectWrapper.ObjectWrapper<EventTypes> i
|
|
89
89
|
}
|
90
90
|
|
91
91
|
initialize(
|
92
|
-
completions: (this: null,
|
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
@@ -19,12 +19,13 @@
|
|
19
19
|
"url": "git+https://github.com/ChromeDevTools/devtools-frontend.git"
|
20
20
|
},
|
21
21
|
"scripts": {
|
22
|
-
"auto-debug-e2etest": "
|
23
|
-
"auto-debug-interactionstest": "
|
22
|
+
"auto-debug-e2etest": "npm run build && npm run debug-e2etest --",
|
23
|
+
"auto-debug-interactionstest": "npm run build && npm run debug-interactionstest --",
|
24
24
|
"auto-debug-unittest": "DEBUG_TEST=1 npm run auto-unittest --",
|
25
|
-
"auto-e2etest": "
|
26
|
-
"auto-interactionstest": "
|
25
|
+
"auto-e2etest": "npm run build && npm run e2etest --",
|
26
|
+
"auto-interactionstest": "npm run build && npm run interactionstest --",
|
27
27
|
"auto-unittest": "scripts/test/run_auto_unittests.py --no-text-coverage",
|
28
|
+
"prebuild": "gn gen out/Default",
|
28
29
|
"build": "autoninja -C out/Default",
|
29
30
|
"build-release": "autoninja -C out/Release",
|
30
31
|
"check": "npm run check-lint && npm run check-loc",
|
@@ -55,5 +56,5 @@
|
|
55
56
|
"unittest": "scripts/test/run_unittests.py --no-text-coverage",
|
56
57
|
"watch": "vpython third_party/node/node.py --output scripts/watch_build.js"
|
57
58
|
},
|
58
|
-
"version": "1.0.
|
59
|
+
"version": "1.0.1030457"
|
59
60
|
}
|