chrome-devtools-frontend 1.0.945329 → 1.0.945579
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 +1 -0
- package/config/gni/devtools_image_files.gni +1 -0
- package/front_end/Images/src/circled_exclamation_icon.svg +3 -0
- package/front_end/core/sdk/CSSMetadata.ts +0 -1
- package/front_end/generated/protocol.d.ts +0 -4
- package/front_end/models/emulation/EmulatedDevices.ts +2 -4
- package/front_end/panels/application/BackForwardCacheView.ts +8 -1
- package/front_end/panels/elements/StyleEditorWidget.ts +13 -2
- package/front_end/panels/elements/StylePropertyTreeElement.ts +8 -12
- package/front_end/panels/elements/StylesSidebarPane.ts +35 -9
- package/front_end/ui/components/adorners/Adorner.ts +14 -14
- package/front_end/ui/components/buttons/Button.ts +116 -42
- package/front_end/ui/components/data_grid/DataGrid.ts +122 -122
- package/front_end/ui/components/data_grid/DataGridController.ts +42 -42
- package/front_end/ui/components/diff_view/DiffView.ts +4 -4
- package/front_end/ui/components/docs/button/basic.html +3 -0
- package/front_end/ui/components/docs/button/basic.ts +16 -0
- package/front_end/ui/components/expandable_list/ExpandableList.ts +11 -11
- package/front_end/ui/components/icon_button/Icon.ts +24 -21
- package/front_end/ui/components/icon_button/IconButton.ts +31 -31
- package/front_end/ui/components/issue_counter/IssueCounter.ts +52 -52
- package/front_end/ui/components/issue_counter/IssueLinkIcon.ts +42 -42
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryInspector.ts +67 -67
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryInspectorController.ts +22 -22
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryInspectorPane.ts +36 -36
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryNavigator.ts +19 -19
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryValueInterpreter.ts +25 -25
- package/front_end/ui/components/linear_memory_inspector/LinearMemoryViewer.ts +52 -52
- package/front_end/ui/components/linear_memory_inspector/ValueInterpreterDisplay.ts +21 -21
- package/front_end/ui/components/linear_memory_inspector/ValueInterpreterSettings.ts +6 -6
- package/front_end/ui/components/markdown_view/MarkdownImage.ts +14 -14
- package/front_end/ui/components/markdown_view/MarkdownLink.ts +8 -8
- package/front_end/ui/components/markdown_view/MarkdownView.ts +6 -6
- package/front_end/ui/components/render_coordinator/RenderCoordinator.ts +33 -33
- package/front_end/ui/components/report_view/ReportView.ts +18 -18
- package/front_end/ui/components/request_link_icon/RequestLinkIcon.ts +53 -53
- package/front_end/ui/components/settings/SettingCheckbox.ts +15 -15
- package/front_end/ui/components/survey_link/SurveyLink.ts +28 -28
- package/front_end/ui/components/text_editor/TextEditor.ts +51 -51
- package/front_end/ui/components/text_editor/javascript.ts +6 -6
- package/front_end/ui/components/text_prompt/TextPrompt.ts +19 -19
- package/front_end/ui/components/tree_outline/TreeOutline.ts +56 -56
- package/front_end/ui/legacy/Infobar.ts +9 -0
- package/front_end/ui/legacy/tabbedPane.css +1 -1
- package/package.json +1 -1
|
@@ -27,12 +27,12 @@ export interface DataGridControllerData {
|
|
|
27
27
|
|
|
28
28
|
export class DataGridController extends HTMLElement {
|
|
29
29
|
static readonly litTagName = LitHtml.literal`devtools-data-grid-controller`;
|
|
30
|
-
|
|
30
|
+
readonly #shadow = this.attachShadow({mode: 'open'});
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
#hasRenderedAtLeastOnce = false;
|
|
33
|
+
#columns: readonly Column[] = [];
|
|
34
|
+
#rows: Row[] = [];
|
|
35
|
+
#contextMenus?: DataGridContextMenusConfiguration = undefined;
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* Because the controller will sort data in place (e.g. mutate it) when we get
|
|
@@ -40,41 +40,41 @@ export class DataGridController extends HTMLElement {
|
|
|
40
40
|
* mutate the data we're given, but a copy of the data. If our `get data` is
|
|
41
41
|
* called, we'll return the original, not the sorted data.
|
|
42
42
|
*/
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
#originalColumns: readonly Column[] = [];
|
|
44
|
+
#originalRows: Row[] = [];
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
#sortState: Readonly<SortState>|null = null;
|
|
47
|
+
#filters: readonly TextUtils.TextUtils.ParsedFilter[] = [];
|
|
48
48
|
|
|
49
49
|
connectedCallback(): void {
|
|
50
|
-
this
|
|
50
|
+
this.#shadow.adoptedStyleSheets = [dataGridControllerStyles];
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
get data(): DataGridControllerData {
|
|
54
54
|
return {
|
|
55
|
-
columns: this
|
|
56
|
-
rows: this
|
|
57
|
-
filters: this
|
|
58
|
-
contextMenus: this
|
|
55
|
+
columns: this.#originalColumns as Column[],
|
|
56
|
+
rows: this.#originalRows as Row[],
|
|
57
|
+
filters: this.#filters,
|
|
58
|
+
contextMenus: this.#contextMenus,
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
set data(data: DataGridControllerData) {
|
|
63
|
-
this
|
|
64
|
-
this
|
|
65
|
-
this
|
|
66
|
-
this
|
|
67
|
-
this
|
|
63
|
+
this.#originalColumns = data.columns;
|
|
64
|
+
this.#originalRows = data.rows;
|
|
65
|
+
this.#contextMenus = data.contextMenus;
|
|
66
|
+
this.#filters = data.filters || [];
|
|
67
|
+
this.#contextMenus = data.contextMenus;
|
|
68
68
|
|
|
69
|
-
this
|
|
70
|
-
this
|
|
69
|
+
this.#columns = [...this.#originalColumns];
|
|
70
|
+
this.#rows = this.cloneAndFilterRows(data.rows, this.#filters);
|
|
71
71
|
|
|
72
|
-
if (!this
|
|
73
|
-
this
|
|
72
|
+
if (!this.#hasRenderedAtLeastOnce && data.initialSort) {
|
|
73
|
+
this.#sortState = data.initialSort;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
if (this
|
|
77
|
-
this.sortRows(this
|
|
76
|
+
if (this.#sortState) {
|
|
77
|
+
this.sortRows(this.#sortState);
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
this.render();
|
|
@@ -134,7 +134,7 @@ export class DataGridController extends HTMLElement {
|
|
|
134
134
|
private sortRows(state: SortState): void {
|
|
135
135
|
const {columnId, direction} = state;
|
|
136
136
|
|
|
137
|
-
this
|
|
137
|
+
this.#rows.sort((row1, row2) => {
|
|
138
138
|
const cell1 = getRowEntryForColumnId(row1, columnId);
|
|
139
139
|
const cell2 = getRowEntryForColumnId(row2, columnId);
|
|
140
140
|
|
|
@@ -157,34 +157,34 @@ export class DataGridController extends HTMLElement {
|
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
private applySortOnColumn(column: Column): void {
|
|
160
|
-
if (this
|
|
161
|
-
const {columnId, direction} = this
|
|
160
|
+
if (this.#sortState && this.#sortState.columnId === column.id) {
|
|
161
|
+
const {columnId, direction} = this.#sortState;
|
|
162
162
|
|
|
163
163
|
/* When users sort, we go No Sort => ASC => DESC => No sort
|
|
164
164
|
* So if the current direction is DESC, we clear the state.
|
|
165
165
|
*/
|
|
166
166
|
if (direction === SortDirection.DESC) {
|
|
167
|
-
this
|
|
167
|
+
this.#sortState = null;
|
|
168
168
|
} else {
|
|
169
169
|
/* The state is ASC, so toggle to DESC */
|
|
170
|
-
this
|
|
170
|
+
this.#sortState = {
|
|
171
171
|
columnId,
|
|
172
172
|
direction: SortDirection.DESC,
|
|
173
173
|
};
|
|
174
174
|
}
|
|
175
175
|
} else {
|
|
176
176
|
/* The column wasn't previously sorted, so we sort it in ASC order. */
|
|
177
|
-
this
|
|
177
|
+
this.#sortState = {
|
|
178
178
|
columnId: column.id,
|
|
179
179
|
direction: SortDirection.ASC,
|
|
180
180
|
};
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
if (this
|
|
184
|
-
this.sortRows(this
|
|
183
|
+
if (this.#sortState) {
|
|
184
|
+
this.sortRows(this.#sortState);
|
|
185
185
|
} else {
|
|
186
186
|
// No sortstate = render the original rows.
|
|
187
|
-
this
|
|
187
|
+
this.#rows = this.cloneAndFilterRows(this.#originalRows, this.#filters);
|
|
188
188
|
this.render();
|
|
189
189
|
}
|
|
190
190
|
}
|
|
@@ -194,8 +194,8 @@ export class DataGridController extends HTMLElement {
|
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
private onContextMenuHeaderResetClick(): void {
|
|
197
|
-
this
|
|
198
|
-
this
|
|
197
|
+
this.#sortState = null;
|
|
198
|
+
this.#rows = [...this.#originalRows];
|
|
199
199
|
this.render();
|
|
200
200
|
}
|
|
201
201
|
|
|
@@ -204,20 +204,20 @@ export class DataGridController extends HTMLElement {
|
|
|
204
204
|
// clang-format off
|
|
205
205
|
LitHtml.render(LitHtml.html`
|
|
206
206
|
<${DataGrid.litTagName} .data=${{
|
|
207
|
-
columns: this
|
|
208
|
-
rows: this
|
|
209
|
-
activeSort: this
|
|
210
|
-
contextMenus: this
|
|
207
|
+
columns: this.#columns,
|
|
208
|
+
rows: this.#rows,
|
|
209
|
+
activeSort: this.#sortState,
|
|
210
|
+
contextMenus: this.#contextMenus,
|
|
211
211
|
} as DataGridData}
|
|
212
212
|
@columnheaderclick=${this.onColumnHeaderClick}
|
|
213
213
|
@contextmenucolumnsortclick=${this.onContextMenuColumnSortClick}
|
|
214
214
|
@contextmenuheaderresetclick=${this.onContextMenuHeaderResetClick}
|
|
215
215
|
></${DataGrid.litTagName}>
|
|
216
|
-
`, this
|
|
216
|
+
`, this.#shadow, {
|
|
217
217
|
host: this,
|
|
218
218
|
});
|
|
219
219
|
// clang-format on
|
|
220
|
-
this
|
|
220
|
+
this.#hasRenderedAtLeastOnce = true;
|
|
221
221
|
}
|
|
222
222
|
}
|
|
223
223
|
|
|
@@ -267,21 +267,21 @@ export type DiffViewData = {
|
|
|
267
267
|
export class DiffView extends HTMLElement {
|
|
268
268
|
static readonly litTagName = LitHtml.literal`devtools-diff-view`;
|
|
269
269
|
|
|
270
|
-
|
|
270
|
+
readonly #shadow = this.attachShadow({mode: 'open'});
|
|
271
271
|
loaded: Promise<void>;
|
|
272
272
|
|
|
273
273
|
constructor(data?: DiffViewData) {
|
|
274
274
|
super();
|
|
275
|
-
this
|
|
275
|
+
this.#shadow.adoptedStyleSheets = [diffViewStyles, CodeHighlighter.Style.default];
|
|
276
276
|
if (data) {
|
|
277
|
-
this.loaded = DiffRenderer.render(data.diff, data.mimeType, this
|
|
277
|
+
this.loaded = DiffRenderer.render(data.diff, data.mimeType, this.#shadow);
|
|
278
278
|
} else {
|
|
279
279
|
this.loaded = Promise.resolve();
|
|
280
280
|
}
|
|
281
281
|
}
|
|
282
282
|
|
|
283
283
|
set data(data: DiffViewData) {
|
|
284
|
-
this.loaded = DiffRenderer.render(data.diff, data.mimeType, this
|
|
284
|
+
this.loaded = DiffRenderer.render(data.diff, data.mimeType, this.#shadow);
|
|
285
285
|
}
|
|
286
286
|
}
|
|
287
287
|
|
|
@@ -50,6 +50,9 @@
|
|
|
50
50
|
</div>
|
|
51
51
|
<div id="small-toolbar">
|
|
52
52
|
</div>
|
|
53
|
+
<form onsubmit="event.preventDefault(); alert('submitted');" id="form">
|
|
54
|
+
<input name="field" placeholder="Enter smth" />
|
|
55
|
+
</form>
|
|
53
56
|
<script type="module" src="./basic.js"></script>
|
|
54
57
|
</body>
|
|
55
58
|
</html>
|
|
@@ -201,3 +201,19 @@ for (let i = 0; i < 6; i++) {
|
|
|
201
201
|
appendToSmallToolbar(sep);
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
|
+
|
|
205
|
+
const submitButton = new Buttons.Button.Button();
|
|
206
|
+
submitButton.data = {
|
|
207
|
+
variant: Buttons.Button.Variant.PRIMARY,
|
|
208
|
+
type: 'submit',
|
|
209
|
+
};
|
|
210
|
+
submitButton.innerText = 'Submit';
|
|
211
|
+
document.querySelector('#form')?.append(submitButton);
|
|
212
|
+
|
|
213
|
+
const resetButton = new Buttons.Button.Button();
|
|
214
|
+
resetButton.data = {
|
|
215
|
+
variant: Buttons.Button.Variant.SECONDARY,
|
|
216
|
+
type: 'reset',
|
|
217
|
+
};
|
|
218
|
+
resetButton.innerText = 'Reset';
|
|
219
|
+
document.querySelector('#form')?.append(resetButton);
|
|
@@ -13,26 +13,26 @@ export interface ExpandableListData {
|
|
|
13
13
|
export class ExpandableList extends HTMLElement {
|
|
14
14
|
static readonly litTagName = LitHtml.literal`devtools-expandable-list`;
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
readonly #shadow = this.attachShadow({mode: 'open'});
|
|
17
|
+
#expanded = false;
|
|
18
|
+
#rows: LitHtml.TemplateResult[] = [];
|
|
19
19
|
|
|
20
20
|
set data(data: ExpandableListData) {
|
|
21
|
-
this
|
|
21
|
+
this.#rows = data.rows;
|
|
22
22
|
this.render();
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
private onArrowClick(): void {
|
|
26
|
-
this
|
|
26
|
+
this.#expanded = !this.#expanded;
|
|
27
27
|
this.render();
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
connectedCallback(): void {
|
|
31
|
-
this
|
|
31
|
+
this.#shadow.adoptedStyleSheets = [expandableListStyles];
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
private render(): void {
|
|
35
|
-
if (this
|
|
35
|
+
if (this.#rows.length < 1) {
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
|
|
@@ -42,22 +42,22 @@ export class ExpandableList extends HTMLElement {
|
|
|
42
42
|
LitHtml.html`
|
|
43
43
|
<div class="expandable-list-container">
|
|
44
44
|
<div>
|
|
45
|
-
${this
|
|
45
|
+
${this.#rows.length > 1 ?
|
|
46
46
|
LitHtml.html`
|
|
47
47
|
<button @click=${(): void => this.onArrowClick()} class="arrow-icon-button">
|
|
48
|
-
<span class="arrow-icon ${this
|
|
48
|
+
<span class="arrow-icon ${this.#expanded ? 'expanded' : ''}"></span>
|
|
49
49
|
</button>
|
|
50
50
|
`
|
|
51
51
|
: LitHtml.nothing}
|
|
52
52
|
</div>
|
|
53
53
|
<div class="expandable-list-items">
|
|
54
|
-
${this
|
|
54
|
+
${this.#rows.filter((_, index) => (this.#expanded || index === 0)).map(row => LitHtml.html`
|
|
55
55
|
${row}
|
|
56
56
|
`)}
|
|
57
57
|
</div>
|
|
58
58
|
</div>
|
|
59
59
|
`,
|
|
60
|
-
this
|
|
60
|
+
this.#shadow, {host: this});
|
|
61
61
|
// clang-format on
|
|
62
62
|
}
|
|
63
63
|
}
|
|
@@ -29,52 +29,55 @@ const coordinator = Coordinator.RenderCoordinator.RenderCoordinator.instance();
|
|
|
29
29
|
export class Icon extends HTMLElement {
|
|
30
30
|
static readonly litTagName = LitHtml.literal`devtools-icon`;
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
readonly #shadow = this.attachShadow({mode: 'open'});
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
#iconPath: Readonly<string> = '';
|
|
35
|
+
#color: Readonly<string> = 'rgb(110 110 110)';
|
|
36
|
+
#width: Readonly<string> = '100%';
|
|
37
|
+
#height: Readonly<string> = '100%';
|
|
38
|
+
#iconName?: Readonly<string>;
|
|
39
39
|
|
|
40
40
|
connectedCallback(): void {
|
|
41
|
-
this
|
|
41
|
+
this.#shadow.adoptedStyleSheets = [iconStyles];
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
set data(data: IconData) {
|
|
45
45
|
const {width, height} = data;
|
|
46
|
-
this
|
|
47
|
-
this
|
|
48
|
-
this
|
|
46
|
+
this.#color = data.color;
|
|
47
|
+
this.#width = isString(width) ? width : (isString(height) ? height : this.#width);
|
|
48
|
+
this.#height = isString(height) ? height : (isString(width) ? width : this.#height);
|
|
49
49
|
if ('iconPath' in data) {
|
|
50
|
-
this
|
|
50
|
+
this.#iconPath = data.iconPath;
|
|
51
51
|
} else {
|
|
52
|
-
this
|
|
53
|
-
this
|
|
52
|
+
this.#iconPath = new URL(`../../../Images/${data.iconName}.svg`, import.meta.url).toString();
|
|
53
|
+
this.#iconName = data.iconName;
|
|
54
54
|
}
|
|
55
55
|
this.render();
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
get data(): IconData {
|
|
59
59
|
const commonData = {
|
|
60
|
-
color: this
|
|
61
|
-
width: this
|
|
62
|
-
height: this
|
|
60
|
+
color: this.#color,
|
|
61
|
+
width: this.#width,
|
|
62
|
+
height: this.#height,
|
|
63
63
|
};
|
|
64
|
-
if (this
|
|
64
|
+
if (this.#iconName) {
|
|
65
65
|
return {
|
|
66
66
|
...commonData,
|
|
67
|
-
iconName: this
|
|
67
|
+
iconName: this.#iconName,
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
70
|
return {
|
|
71
71
|
...commonData,
|
|
72
|
-
iconPath: this
|
|
72
|
+
iconPath: this.#iconPath,
|
|
73
73
|
};
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
private getStyles(): {[key: string]: string} {
|
|
77
|
-
const
|
|
77
|
+
const iconPath = this.#iconPath;
|
|
78
|
+
const width = this.#width;
|
|
79
|
+
const height = this.#height;
|
|
80
|
+
const color = this.#color;
|
|
78
81
|
const commonStyles = {
|
|
79
82
|
width,
|
|
80
83
|
height,
|
|
@@ -106,7 +109,7 @@ export class Icon extends HTMLElement {
|
|
|
106
109
|
// clang-format off
|
|
107
110
|
LitHtml.render(LitHtml.html`
|
|
108
111
|
<div class="icon-basic" style=${LitHtml.Directives.styleMap(this.getStyles())}></div>
|
|
109
|
-
`, this
|
|
112
|
+
`, this.#shadow, {host: this});
|
|
110
113
|
// clang-format on
|
|
111
114
|
});
|
|
112
115
|
}
|
|
@@ -29,69 +29,69 @@ export interface IconButtonData {
|
|
|
29
29
|
|
|
30
30
|
export class IconButton extends HTMLElement {
|
|
31
31
|
static readonly litTagName = LitHtml.literal`icon-button`;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
readonly #shadow = this.attachShadow({mode: 'open'});
|
|
33
|
+
#clickHandler: undefined|(() => void) = undefined;
|
|
34
|
+
#groups: IconWithTextData[] = [];
|
|
35
|
+
#compact: boolean = false;
|
|
36
|
+
#leadingText: string = '';
|
|
37
|
+
#trailingText: string = '';
|
|
38
|
+
#accessibleName: string|undefined;
|
|
39
39
|
|
|
40
40
|
set data(data: IconButtonData) {
|
|
41
|
-
this
|
|
42
|
-
this
|
|
43
|
-
this
|
|
44
|
-
this
|
|
45
|
-
this
|
|
46
|
-
this
|
|
41
|
+
this.#groups = data.groups.map(group => ({...group})); // Ensure we make a deep copy.
|
|
42
|
+
this.#clickHandler = data.clickHandler;
|
|
43
|
+
this.#trailingText = data.trailingText ?? '';
|
|
44
|
+
this.#leadingText = data.leadingText ?? '';
|
|
45
|
+
this.#accessibleName = data.accessibleName;
|
|
46
|
+
this.#compact = Boolean(data.compact);
|
|
47
47
|
this.render();
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
get data(): IconButtonData {
|
|
51
51
|
return {
|
|
52
|
-
groups: this
|
|
53
|
-
accessibleName: this
|
|
54
|
-
clickHandler: this
|
|
55
|
-
leadingText: this
|
|
56
|
-
trailingText: this
|
|
57
|
-
compact: this
|
|
52
|
+
groups: this.#groups.map(group => ({...group})), // Ensure we make a deep copy.
|
|
53
|
+
accessibleName: this.#accessibleName,
|
|
54
|
+
clickHandler: this.#clickHandler,
|
|
55
|
+
leadingText: this.#leadingText,
|
|
56
|
+
trailingText: this.#trailingText,
|
|
57
|
+
compact: this.#compact,
|
|
58
58
|
};
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
connectedCallback(): void {
|
|
62
|
-
this
|
|
62
|
+
this.#shadow.adoptedStyleSheets = [iconButtonStyles];
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
private onClickHandler(event: Event): void {
|
|
66
|
-
if (this
|
|
66
|
+
if (this.#clickHandler) {
|
|
67
67
|
event.preventDefault();
|
|
68
|
-
this
|
|
68
|
+
this.#clickHandler();
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
private render(): void {
|
|
73
73
|
const buttonClasses = LitHtml.Directives.classMap({
|
|
74
74
|
'icon-button': true,
|
|
75
|
-
'with-click-handler': Boolean(this
|
|
76
|
-
'compact': this
|
|
75
|
+
'with-click-handler': Boolean(this.#clickHandler),
|
|
76
|
+
'compact': this.#compact,
|
|
77
77
|
});
|
|
78
|
-
const filteredGroups = this
|
|
79
|
-
.filter((_, index) => this
|
|
78
|
+
const filteredGroups = this.#groups.filter(counter => counter.text !== undefined)
|
|
79
|
+
.filter((_, index) => this.#compact ? index === 0 : true);
|
|
80
80
|
// Disabled until https://crbug.com/1079231 is fixed.
|
|
81
81
|
// clang-format off
|
|
82
82
|
LitHtml.render(LitHtml.html`
|
|
83
|
-
<button class="${buttonClasses}" @click=${this.onClickHandler} aria-label="${LitHtml.Directives.ifDefined(this
|
|
84
|
-
${(!this
|
|
83
|
+
<button class="${buttonClasses}" @click=${this.onClickHandler} aria-label="${LitHtml.Directives.ifDefined(this.#accessibleName)}">
|
|
84
|
+
${(!this.#compact && this.#leadingText) ? LitHtml.html`<span class="icon-button-title">${this.#leadingText}</span>` : LitHtml.nothing}
|
|
85
85
|
${filteredGroups.map(counter =>
|
|
86
86
|
LitHtml.html`
|
|
87
87
|
<${Icon.litTagName} class="status-icon"
|
|
88
88
|
.data=${{iconName: counter.iconName, color: counter.iconColor || '', width: counter.iconWidth || '1.5ex', height: counter.iconHeight || '1.5ex'} as IconData}>
|
|
89
89
|
</${Icon.litTagName}>
|
|
90
|
-
${this
|
|
90
|
+
${this.#compact ? LitHtml.html`<!-- Force line-height for this element --><span>​</span>` : LitHtml.nothing}
|
|
91
91
|
<span class="icon-button-title">${counter.text}</span>
|
|
92
92
|
</button>`)}
|
|
93
|
-
${(!this
|
|
94
|
-
`, this
|
|
93
|
+
${(!this.#compact && this.#trailingText) ? LitHtml.html`<span class="icon-button-title">${this.#trailingText}</span>` : LitHtml.nothing}
|
|
94
|
+
`, this.#shadow, { host: this});
|
|
95
95
|
// clang-format on
|
|
96
96
|
}
|
|
97
97
|
}
|
|
@@ -83,84 +83,84 @@ export function getIssueCountsEnumeration(
|
|
|
83
83
|
|
|
84
84
|
export class IssueCounter extends HTMLElement {
|
|
85
85
|
static readonly litTagName = LitHtml.literal`issue-counter`;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
86
|
+
readonly #shadow = this.attachShadow({mode: 'open'});
|
|
87
|
+
#clickHandler: undefined|(() => void) = undefined;
|
|
88
|
+
#tooltipCallback: undefined|(() => void) = undefined;
|
|
89
|
+
#leadingText: string = '';
|
|
90
|
+
#throttler: undefined|Common.Throttler.Throttler;
|
|
91
|
+
#counts: [number, number, number] = [0, 0, 0];
|
|
92
|
+
#displayMode: DisplayMode = DisplayMode.OmitEmpty;
|
|
93
|
+
#issuesManager: IssuesManager.IssuesManager.IssuesManager|undefined = undefined;
|
|
94
|
+
#accessibleName: string|undefined = undefined;
|
|
95
|
+
#throttlerTimeout: number|undefined;
|
|
96
|
+
#compact = false;
|
|
97
97
|
|
|
98
98
|
scheduleUpdate(): void {
|
|
99
|
-
if (this
|
|
100
|
-
this
|
|
99
|
+
if (this.#throttler) {
|
|
100
|
+
this.#throttler.schedule(async () => this.render());
|
|
101
101
|
} else {
|
|
102
102
|
this.render();
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
connectedCallback(): void {
|
|
107
|
-
this
|
|
107
|
+
this.#shadow.adoptedStyleSheets = [issueCounterStyles];
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
set data(data: IssueCounterData) {
|
|
111
|
-
this
|
|
112
|
-
this
|
|
113
|
-
this
|
|
114
|
-
this
|
|
115
|
-
this
|
|
116
|
-
this
|
|
117
|
-
this
|
|
118
|
-
if (this
|
|
119
|
-
this
|
|
111
|
+
this.#clickHandler = data.clickHandler;
|
|
112
|
+
this.#leadingText = data.leadingText ?? '';
|
|
113
|
+
this.#tooltipCallback = data.tooltipCallback;
|
|
114
|
+
this.#displayMode = data.displayMode ?? DisplayMode.OmitEmpty;
|
|
115
|
+
this.#accessibleName = data.accessibleName;
|
|
116
|
+
this.#throttlerTimeout = data.throttlerTimeout;
|
|
117
|
+
this.#compact = Boolean(data.compact);
|
|
118
|
+
if (this.#issuesManager !== data.issuesManager) {
|
|
119
|
+
this.#issuesManager?.removeEventListener(
|
|
120
120
|
IssuesManager.IssuesManager.Events.IssuesCountUpdated, this.scheduleUpdate, this);
|
|
121
|
-
this
|
|
122
|
-
this
|
|
121
|
+
this.#issuesManager = data.issuesManager;
|
|
122
|
+
this.#issuesManager.addEventListener(
|
|
123
123
|
IssuesManager.IssuesManager.Events.IssuesCountUpdated, this.scheduleUpdate, this);
|
|
124
124
|
}
|
|
125
125
|
if (data.throttlerTimeout !== 0) {
|
|
126
|
-
this
|
|
126
|
+
this.#throttler = new Common.Throttler.Throttler(data.throttlerTimeout ?? 100);
|
|
127
127
|
} else {
|
|
128
|
-
this
|
|
128
|
+
this.#throttler = undefined;
|
|
129
129
|
}
|
|
130
130
|
this.scheduleUpdate();
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
get data(): IssueCounterData {
|
|
134
134
|
return {
|
|
135
|
-
clickHandler: this
|
|
136
|
-
leadingText: this
|
|
137
|
-
tooltipCallback: this
|
|
138
|
-
displayMode: this
|
|
139
|
-
accessibleName: this
|
|
140
|
-
throttlerTimeout: this
|
|
141
|
-
compact: this
|
|
142
|
-
issuesManager: this
|
|
135
|
+
clickHandler: this.#clickHandler,
|
|
136
|
+
leadingText: this.#leadingText,
|
|
137
|
+
tooltipCallback: this.#tooltipCallback,
|
|
138
|
+
displayMode: this.#displayMode,
|
|
139
|
+
accessibleName: this.#accessibleName,
|
|
140
|
+
throttlerTimeout: this.#throttlerTimeout,
|
|
141
|
+
compact: this.#compact,
|
|
142
|
+
issuesManager: this.#issuesManager as IssuesManager.IssuesManager.IssuesManager,
|
|
143
143
|
};
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
private render(): void {
|
|
147
|
-
if (!this
|
|
147
|
+
if (!this.#issuesManager) {
|
|
148
148
|
return;
|
|
149
149
|
}
|
|
150
|
-
this
|
|
151
|
-
this
|
|
152
|
-
this
|
|
153
|
-
this
|
|
150
|
+
this.#counts = [
|
|
151
|
+
this.#issuesManager.numberOfIssues(IssuesManager.Issue.IssueKind.PageError),
|
|
152
|
+
this.#issuesManager.numberOfIssues(IssuesManager.Issue.IssueKind.BreakingChange),
|
|
153
|
+
this.#issuesManager.numberOfIssues(IssuesManager.Issue.IssueKind.Improvement),
|
|
154
154
|
];
|
|
155
155
|
const importance = [
|
|
156
156
|
IssuesManager.Issue.IssueKind.PageError,
|
|
157
157
|
IssuesManager.Issue.IssueKind.BreakingChange,
|
|
158
158
|
IssuesManager.Issue.IssueKind.Improvement,
|
|
159
159
|
];
|
|
160
|
-
const mostImportant = importance[this
|
|
160
|
+
const mostImportant = importance[this.#counts.findIndex(x => x > 0) ?? 2];
|
|
161
161
|
|
|
162
162
|
const countToString = (kind: IssuesManager.Issue.IssueKind, count: number): string|undefined => {
|
|
163
|
-
switch (this
|
|
163
|
+
switch (this.#displayMode) {
|
|
164
164
|
case DisplayMode.OmitEmpty:
|
|
165
165
|
return count > 0 ? `${count}` : undefined;
|
|
166
166
|
case DisplayMode.ShowAlways:
|
|
@@ -174,29 +174,29 @@ export class IssueCounter extends HTMLElement {
|
|
|
174
174
|
groups: [
|
|
175
175
|
{
|
|
176
176
|
...toIconGroup(getIssueKindIconData(IssuesManager.Issue.IssueKind.PageError), iconSize),
|
|
177
|
-
text: countToString(IssuesManager.Issue.IssueKind.PageError, this
|
|
177
|
+
text: countToString(IssuesManager.Issue.IssueKind.PageError, this.#counts[0]),
|
|
178
178
|
},
|
|
179
179
|
{
|
|
180
180
|
...toIconGroup(getIssueKindIconData(IssuesManager.Issue.IssueKind.BreakingChange), iconSize),
|
|
181
|
-
text: countToString(IssuesManager.Issue.IssueKind.BreakingChange, this
|
|
181
|
+
text: countToString(IssuesManager.Issue.IssueKind.BreakingChange, this.#counts[1]),
|
|
182
182
|
},
|
|
183
183
|
{
|
|
184
184
|
...toIconGroup(getIssueKindIconData(IssuesManager.Issue.IssueKind.Improvement), iconSize),
|
|
185
|
-
text: countToString(IssuesManager.Issue.IssueKind.Improvement, this
|
|
185
|
+
text: countToString(IssuesManager.Issue.IssueKind.Improvement, this.#counts[2]),
|
|
186
186
|
},
|
|
187
187
|
],
|
|
188
|
-
clickHandler: this
|
|
189
|
-
leadingText: this
|
|
190
|
-
accessibleName: this
|
|
191
|
-
compact: this
|
|
188
|
+
clickHandler: this.#clickHandler,
|
|
189
|
+
leadingText: this.#leadingText,
|
|
190
|
+
accessibleName: this.#accessibleName,
|
|
191
|
+
compact: this.#compact,
|
|
192
192
|
};
|
|
193
193
|
LitHtml.render(
|
|
194
194
|
LitHtml.html`
|
|
195
195
|
<icon-button .data=${data as IconButton.IconButton.IconButtonData} .accessibleName="${
|
|
196
|
-
this
|
|
196
|
+
this.#accessibleName}"></icon-button>
|
|
197
197
|
`,
|
|
198
|
-
this
|
|
199
|
-
this
|
|
198
|
+
this.#shadow, {host: this});
|
|
199
|
+
this.#tooltipCallback?.();
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
202
|
|