lighthouse 8.4.0 → 8.5.0-dev.20210921
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/changelog.md +79 -0
- package/flow-report/assets/styles.css +85 -61
- package/flow-report/src/app.tsx +6 -2
- package/flow-report/src/common.tsx +0 -41
- package/flow-report/src/icons.tsx +11 -0
- package/flow-report/src/summary/summary.tsx +32 -25
- package/flow-report/src/topbar.tsx +60 -0
- package/flow-report/src/util.ts +0 -1
- package/flow-report/src/wrappers/{gauge.tsx → category-score.tsx} +11 -5
- package/flow-report/test/summary/summary-test.tsx +3 -3
- package/flow-report/tsconfig.json +6 -22
- package/{lighthouse-core/gather/gatherers/gather-context.js → lighthouse-cli/.eslintrc.cjs} +20 -18
- package/lighthouse-cli/bin.js +31 -21
- package/lighthouse-cli/cli-flags.js +12 -7
- package/lighthouse-cli/commands/commands.js +2 -7
- package/lighthouse-cli/commands/list-audits.js +2 -2
- package/lighthouse-cli/commands/list-trace-categories.js +2 -2
- package/lighthouse-cli/index.js +3 -1
- package/lighthouse-cli/package.json +4 -0
- package/lighthouse-cli/printer.js +4 -3
- package/lighthouse-cli/run.js +14 -15
- package/lighthouse-cli/sentry-prompt.js +5 -6
- package/lighthouse-cli/test/smokehouse/frontends/back-compat-util.js +1 -1
- package/lighthouse-cli/test/smokehouse/frontends/lib.js +5 -4
- package/lighthouse-cli/test/smokehouse/frontends/node.js +1 -1
- package/lighthouse-cli/test/smokehouse/frontends/smokehouse-bin.js +93 -14
- package/lighthouse-cli/test/smokehouse/lib/child-process-error.js +1 -1
- package/lighthouse-cli/test/smokehouse/lib/concurrent-mapper.js +1 -1
- package/lighthouse-cli/test/smokehouse/lib/local-console.js +1 -1
- package/lighthouse-cli/test/smokehouse/lighthouse-runners/bundle.js +20 -16
- package/lighthouse-cli/test/smokehouse/lighthouse-runners/cli.js +15 -12
- package/lighthouse-cli/test/smokehouse/report-assert.js +23 -13
- package/lighthouse-cli/test/smokehouse/smokehouse.js +32 -11
- package/lighthouse-core/audits/byte-efficiency/byte-efficiency-audit.js +0 -2
- package/lighthouse-core/audits/byte-efficiency/uses-responsive-images-snapshot.js +6 -1
- package/lighthouse-core/audits/dobetterweb/js-libraries.js +5 -0
- package/lighthouse-core/audits/dobetterweb/uses-http2.js +1 -0
- package/lighthouse-core/audits/lcp-lazy-loaded.js +1 -0
- package/lighthouse-core/audits/oopif-iframe-test-audit.js +30 -0
- package/lighthouse-core/computed/metrics/metric.js +2 -1
- package/lighthouse-core/config/config-helpers.js +47 -3
- package/lighthouse-core/config/config.js +3 -46
- package/lighthouse-core/config/default-config.js +0 -1
- package/lighthouse-core/fraggle-rock/config/config.js +22 -4
- package/lighthouse-core/fraggle-rock/config/default-config.js +0 -9
- package/lighthouse-core/fraggle-rock/config/filters.js +3 -0
- package/lighthouse-core/fraggle-rock/config/validation.js +19 -1
- package/lighthouse-core/fraggle-rock/gather/base-artifacts.js +8 -3
- package/lighthouse-core/fraggle-rock/gather/driver.js +10 -0
- package/lighthouse-core/fraggle-rock/gather/navigation-runner.js +40 -19
- package/lighthouse-core/fraggle-rock/gather/runner-helpers.js +3 -0
- package/lighthouse-core/fraggle-rock/gather/session.js +44 -1
- package/lighthouse-core/fraggle-rock/gather/snapshot-runner.js +4 -1
- package/lighthouse-core/fraggle-rock/gather/timespan-runner.js +5 -1
- package/lighthouse-core/gather/devtools-log.js +9 -3
- package/lighthouse-core/gather/driver/network-monitor.js +57 -13
- package/lighthouse-core/gather/driver/prepare.js +43 -17
- package/lighthouse-core/gather/driver/target-manager.js +125 -0
- package/lighthouse-core/gather/driver.js +20 -0
- package/lighthouse-core/gather/fetcher.js +2 -2
- package/lighthouse-core/gather/gather-runner.js +1 -1
- package/lighthouse-core/gather/gatherers/css-usage.js +0 -2
- package/lighthouse-core/gather/gatherers/devtools-log.js +11 -9
- package/lighthouse-core/gather/gatherers/js-usage.js +0 -1
- package/lighthouse-core/gather/gatherers/script-elements.js +4 -5
- package/lighthouse-core/gather/gatherers/seo/robots-txt.js +3 -3
- package/lighthouse-core/gather/gatherers/trace.js +4 -5
- package/lighthouse-core/index.js +4 -0
- package/lighthouse-core/lib/emulation.js +0 -1
- package/lighthouse-core/lib/i18n/locales/en-US.json +6 -0
- package/lighthouse-core/lib/i18n/locales/en-XL.json +6 -0
- package/lighthouse-core/lib/network-recorder.js +8 -0
- package/lighthouse-core/lib/proto-preprocessor.js +5 -10
- package/lighthouse-core/runner.js +1 -3
- package/package.json +12 -9
- package/readme.md +2 -0
- package/report/assets/styles.css +120 -12
- package/report/assets/templates.html +13 -0
- package/report/clients/psi.js +5 -1
- package/report/generator/tsconfig.json +5 -16
- package/report/renderer/category-renderer.js +58 -5
- package/report/renderer/components.js +25 -5
- package/report/renderer/performance-category-renderer.js +5 -5
- package/report/renderer/pwa-category-renderer.js +10 -0
- package/report/renderer/report-renderer.js +12 -3
- package/report/renderer/report-ui-features.js +1 -4
- package/report/test/renderer/category-renderer-test.js +19 -0
- package/report/tsconfig.json +6 -21
- package/report/types/report-result.d.ts +1 -1
- package/root.js +3 -1
- package/third-party/snyk/snapshot.json +2 -2
- package/tsconfig-all.json +15 -0
- package/tsconfig-base.json +24 -0
- package/tsconfig.json +8 -18
- package/types/artifacts.d.ts +7 -7
- package/types/config.d.ts +1 -1
- package/types/gatherer.d.ts +7 -1
- package/types/lhr/flow.d.ts +0 -1
- package/types/lhr/lhr.d.ts +5 -1
- package/types/lhr/tsconfig.json +4 -14
- package/types/protocol.d.ts +2 -0
- package/types/smokehouse.d.ts +2 -1
- package/dist/report/flow.js +0 -149
- package/dist/report/standalone.js +0 -228
- package/flow-report/test/common-test.tsx +0 -131
- package/lighthouse-core/gather/gatherers/host-form-factor.js +0 -31
- package/lighthouse-core/gather/gatherers/host-user-agent.js +0 -29
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lighthouse",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.5.0-dev.20210921",
|
|
4
4
|
"description": "Automated auditing, performance metrics, and best practices for the web.",
|
|
5
5
|
"main": "./lighthouse-core/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"build-extension-firefox": "node ./build/build-extension.js firefox",
|
|
22
22
|
"build-devtools": "yarn reset-link && node ./build/build-bundle.js clients/devtools-entry.js dist/lighthouse-dt-bundle.js && node ./build/build-dt-report-resources.js",
|
|
23
23
|
"build-smokehouse-bundle": "node ./build/build-smokehouse-bundle.js",
|
|
24
|
-
"build-lr": "yarn reset-link && node ./build/build-lightrider-bundles.js",
|
|
24
|
+
"build-lr": "yarn reset-link && node ./build/build-lightrider-bundles.js && rollup lighthouse-cli/test/fixtures/static-server.js -o dist/lightrider/static-server.js -f commonjs -p commonjs -p node-resolve -e mime-types,glob",
|
|
25
25
|
"build-pack": "bash build/build-pack.sh",
|
|
26
26
|
"build-report": "node build/build-report-components.js && yarn eslint --fix report/renderer/components.js && node build/build-report.js",
|
|
27
27
|
"build-sample-reports": "yarn build-report && node build/build-sample-reports.js",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"dogfood-lhci": "./lighthouse-core/scripts/dogfood-lhci.sh",
|
|
69
69
|
"timing-trace": "node lighthouse-core/scripts/generate-timing-trace.js",
|
|
70
70
|
"changelog": "conventional-changelog --config ./build/changelog-generator/index.js --infile changelog.md --same-file",
|
|
71
|
-
"type-check": "tsc --build ./
|
|
71
|
+
"type-check": "tsc --build ./tsconfig-all.json",
|
|
72
72
|
"i18n:checks": "./lighthouse-core/scripts/i18n/assert-strings-collected.sh",
|
|
73
73
|
"i18n:collect-strings": "node lighthouse-core/scripts/i18n/collect-strings.js",
|
|
74
74
|
"update:lantern-baseline": "node lighthouse-core/scripts/lantern/update-baseline-lantern-values.js",
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
"@firebase/auth-types": "0.3.2",
|
|
97
97
|
"@firebase/util": "0.2.1",
|
|
98
98
|
"@rollup/plugin-node-resolve": "^13.0.4",
|
|
99
|
-
"@rollup/plugin-typescript": "^2.
|
|
99
|
+
"@rollup/plugin-typescript": "^8.2.5",
|
|
100
100
|
"@testing-library/preact": "^2.0.1",
|
|
101
101
|
"@testing-library/preact-hooks": "^1.1.0",
|
|
102
102
|
"@types/archiver": "^2.1.2",
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
"@types/tabulator-tables": "^4.9.1",
|
|
124
124
|
"@types/update-notifier": "^4.1.0",
|
|
125
125
|
"@types/ws": "^7.0.0",
|
|
126
|
-
"@types/yargs": "^
|
|
126
|
+
"@types/yargs": "^16.0.0",
|
|
127
127
|
"@types/yargs-parser": "^15.0.0",
|
|
128
128
|
"@typescript-eslint/eslint-plugin": "^4.30.0",
|
|
129
129
|
"@typescript-eslint/parser": "^4.30.0",
|
|
@@ -139,7 +139,8 @@
|
|
|
139
139
|
"cpy": "^7.0.1",
|
|
140
140
|
"cross-env": "^7.0.2",
|
|
141
141
|
"csv-validator": "^0.0.3",
|
|
142
|
-
"devtools-protocol": "0.0.
|
|
142
|
+
"devtools-protocol": "0.0.901419",
|
|
143
|
+
"es-main": "^1.0.2",
|
|
143
144
|
"eslint": "^7.23.0",
|
|
144
145
|
"eslint-config-google": "^0.9.1",
|
|
145
146
|
"eslint-plugin-import": "^2.24.2",
|
|
@@ -150,7 +151,7 @@
|
|
|
150
151
|
"glob": "^7.1.3",
|
|
151
152
|
"idb-keyval": "2.2.0",
|
|
152
153
|
"intl-messageformat-parser": "^1.8.1",
|
|
153
|
-
"jest": "
|
|
154
|
+
"jest": "27.1.1",
|
|
154
155
|
"jsdom": "^12.2.0",
|
|
155
156
|
"jsonld": "^5.2.0",
|
|
156
157
|
"jsonlint-mod": "^1.7.6",
|
|
@@ -162,15 +163,17 @@
|
|
|
162
163
|
"pako": "^2.0.3",
|
|
163
164
|
"preact": "^10.5.14",
|
|
164
165
|
"pretty-json-stringify": "^0.0.2",
|
|
165
|
-
"puppeteer": "^
|
|
166
|
+
"puppeteer": "^10.2.0",
|
|
166
167
|
"rollup": "^2.50.6",
|
|
167
168
|
"rollup-plugin-commonjs": "^10.1.0",
|
|
169
|
+
"rollup-plugin-node-resolve": "^5.2.0",
|
|
170
|
+
"rollup-plugin-shim": "^1.0.0",
|
|
168
171
|
"rollup-plugin-terser": "^7.0.2",
|
|
169
172
|
"tabulator-tables": "^4.9.3",
|
|
170
173
|
"terser": "^5.3.8",
|
|
171
174
|
"ts-jest": "^27.0.4",
|
|
172
175
|
"typed-query-selector": "^2.4.0",
|
|
173
|
-
"typescript": "4.4.
|
|
176
|
+
"typescript": "4.4.3",
|
|
174
177
|
"webtreemap-cdt": "^3.2.1"
|
|
175
178
|
},
|
|
176
179
|
"dependencies": {
|
package/readme.md
CHANGED
|
@@ -363,6 +363,8 @@ This section details services that have integrated Lighthouse data. If you're wo
|
|
|
363
363
|
|
|
364
364
|
* **[Microlink](https://microlink.io)** — Microlink is a cloud browser as API. It offers Lighthouse reports on demand, making it easy to build any service on top. Similar functionality is available via the underlying open-source project named browserless.
|
|
365
365
|
|
|
366
|
+
* **[Peyk](https://peyk.com)** - Peyk is a website change detection & monitoring service. Peyk can detect changes in cookies, network requests, technologies, local & session storage, lighthouse audits, screenshots and so much more. Peyk is offered via free and paid plans.
|
|
367
|
+
|
|
366
368
|
* **[Wattspeed](https://wattspeed.com/)** — Wattspeed is a free tool that generates snapshots - historical captures of your web pages that include Lighthouse scores, a list of technologies, W3C HTML validator results, DOM size, mixed content info, and more.
|
|
367
369
|
|
|
368
370
|
* **[AwesomeTechStack](https://awesometechstack.com)** — AwesomeTechStack is a free to use website tech stack analyzer. AwesomeTechStack provides insights into the security, modernity, and performance of any website's technology stack and guidance to improve performance. Lighthouse insights are a crucial part of a website's tech stack rating.
|
package/report/assets/styles.css
CHANGED
|
@@ -104,8 +104,8 @@
|
|
|
104
104
|
--icon-square-size: calc(var(--score-icon-size) * 0.88);
|
|
105
105
|
--image-preview-size: 48px;
|
|
106
106
|
--metric-toggle-lines-fill: #7F7F7F;
|
|
107
|
+
--metric-value-font-size: 28px;
|
|
107
108
|
--metrics-toggle-background-color: var(--color-gray-200);
|
|
108
|
-
--screenshot-overlay-background: rgba(0, 0, 0, 0.3);
|
|
109
109
|
--plugin-badge-background-color: var(--color-white);
|
|
110
110
|
--plugin-badge-size-big: calc(var(--gauge-circle-size-big) / 2.7);
|
|
111
111
|
--plugin-badge-size: calc(var(--gauge-circle-size) / 2.7);
|
|
@@ -130,9 +130,11 @@
|
|
|
130
130
|
--score-icon-margin-right: 12px;
|
|
131
131
|
--score-icon-margin: 0 var(--score-icon-margin-right) 0 var(--score-icon-margin-left);
|
|
132
132
|
--score-icon-size: 12px;
|
|
133
|
+
--score-icon-size-big: 16px;
|
|
133
134
|
--scores-container-padding: 20px 0 20px 0;
|
|
134
135
|
--scorescale-height: 6px;
|
|
135
136
|
--scorescale-width: 18px;
|
|
137
|
+
--screenshot-overlay-background: rgba(0, 0, 0, 0.3);
|
|
136
138
|
--section-padding-vertical: 12px;
|
|
137
139
|
--snippet-background-color: var(--color-gray-50);
|
|
138
140
|
--snippet-color: #0938C2;
|
|
@@ -677,7 +679,11 @@
|
|
|
677
679
|
|
|
678
680
|
.lh-metric__innerwrap {
|
|
679
681
|
display: grid;
|
|
680
|
-
|
|
682
|
+
/**
|
|
683
|
+
* Icon -- Metric Name
|
|
684
|
+
* -- Metric Value
|
|
685
|
+
*/
|
|
686
|
+
grid-template-columns: calc(var(--score-icon-size) + var(--score-icon-margin-left) + var(--score-icon-margin-right)) 1fr;
|
|
681
687
|
align-items: center;
|
|
682
688
|
padding: 10px 0;
|
|
683
689
|
}
|
|
@@ -703,14 +709,30 @@
|
|
|
703
709
|
.lh-metric__description {
|
|
704
710
|
display: none;
|
|
705
711
|
grid-column-start: 2;
|
|
706
|
-
grid-column-end:
|
|
712
|
+
grid-column-end: 4;
|
|
707
713
|
color: var(--report-text-color-secondary);
|
|
708
714
|
}
|
|
709
715
|
|
|
710
716
|
.lh-metric__value {
|
|
717
|
+
font-size: var(--metric-value-font-size);
|
|
718
|
+
margin: calc(var(--default-padding) / 2) 0;
|
|
711
719
|
white-space: nowrap; /* No wrapping between metric value and the icon */
|
|
712
720
|
font-weight: 500;
|
|
713
|
-
|
|
721
|
+
grid-column-start: 2;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
/* Change the grid to 3 columns for narrow viewport. */
|
|
725
|
+
@media screen and (max-width: 535px) {
|
|
726
|
+
.lh-metric__innerwrap {
|
|
727
|
+
/**
|
|
728
|
+
* Icon -- Metric Name -- Metric Value
|
|
729
|
+
*/
|
|
730
|
+
grid-template-columns: calc(var(--score-icon-size) + var(--score-icon-margin-left) + var(--score-icon-margin-right)) 2fr 1fr;
|
|
731
|
+
}
|
|
732
|
+
.lh-metric__value {
|
|
733
|
+
justify-self: end;
|
|
734
|
+
grid-column-start: unset;
|
|
735
|
+
}
|
|
714
736
|
}
|
|
715
737
|
|
|
716
738
|
/* No-JS toggle switch */
|
|
@@ -777,7 +799,7 @@
|
|
|
777
799
|
flex: 1;
|
|
778
800
|
}
|
|
779
801
|
|
|
780
|
-
.lh-
|
|
802
|
+
.lh-metric__icon,
|
|
781
803
|
.lh-scorescale-range::before {
|
|
782
804
|
content: '';
|
|
783
805
|
width: var(--score-icon-size);
|
|
@@ -789,7 +811,7 @@
|
|
|
789
811
|
.lh-metric--pass .lh-metric__value {
|
|
790
812
|
color: var(--color-pass-secondary);
|
|
791
813
|
}
|
|
792
|
-
.lh-metric--pass .lh-
|
|
814
|
+
.lh-metric--pass .lh-metric__icon {
|
|
793
815
|
border-radius: 100%;
|
|
794
816
|
background: var(--color-pass);
|
|
795
817
|
}
|
|
@@ -797,7 +819,7 @@
|
|
|
797
819
|
.lh-metric--average .lh-metric__value {
|
|
798
820
|
color: var(--color-average-secondary);
|
|
799
821
|
}
|
|
800
|
-
.lh-metric--average .lh-
|
|
822
|
+
.lh-metric--average .lh-metric__icon {
|
|
801
823
|
background: var(--color-average);
|
|
802
824
|
width: var(--icon-square-size);
|
|
803
825
|
height: var(--icon-square-size);
|
|
@@ -806,8 +828,8 @@
|
|
|
806
828
|
.lh-metric--fail .lh-metric__value {
|
|
807
829
|
color: var(--color-fail-secondary);
|
|
808
830
|
}
|
|
809
|
-
.lh-metric--fail .lh-
|
|
810
|
-
.lh-metric--error .lh-
|
|
831
|
+
.lh-metric--fail .lh-metric__icon,
|
|
832
|
+
.lh-metric--error .lh-metric__icon {
|
|
811
833
|
border-left: calc(var(--score-icon-size) / 2) solid transparent;
|
|
812
834
|
border-right: calc(var(--score-icon-size) / 2) solid transparent;
|
|
813
835
|
border-bottom: var(--score-icon-size) solid var(--color-fail);
|
|
@@ -1153,6 +1175,80 @@
|
|
|
1153
1175
|
stroke: var(--color-not-applicable);
|
|
1154
1176
|
}
|
|
1155
1177
|
|
|
1178
|
+
.lh-fraction__wrapper .lh-fraction__content::before {
|
|
1179
|
+
content: '';
|
|
1180
|
+
height: var(--score-icon-size);
|
|
1181
|
+
width: var(--score-icon-size);
|
|
1182
|
+
margin: var(--score-icon-margin);
|
|
1183
|
+
display: inline-block;
|
|
1184
|
+
}
|
|
1185
|
+
.lh-fraction__wrapper--pass .lh-fraction__content {
|
|
1186
|
+
color: var(--color-pass);
|
|
1187
|
+
}
|
|
1188
|
+
.lh-fraction__wrapper--pass .lh-fraction__background {
|
|
1189
|
+
background-color: var(--color-pass);
|
|
1190
|
+
}
|
|
1191
|
+
.lh-fraction__wrapper--pass .lh-fraction__content::before {
|
|
1192
|
+
background-color: var(--color-pass);
|
|
1193
|
+
border-radius: 50%;
|
|
1194
|
+
}
|
|
1195
|
+
.lh-fraction__wrapper--average .lh-fraction__content {
|
|
1196
|
+
color: var(--color-average);
|
|
1197
|
+
}
|
|
1198
|
+
.lh-fraction__wrapper--average .lh-fraction__background {
|
|
1199
|
+
background-color: var(--color-average);
|
|
1200
|
+
}
|
|
1201
|
+
.lh-fraction__wrapper--average .lh-fraction__content::before {
|
|
1202
|
+
background-color: var(--color-average);
|
|
1203
|
+
}
|
|
1204
|
+
.lh-fraction__wrapper--fail .lh-fraction__content {
|
|
1205
|
+
color: var(--color-fail);
|
|
1206
|
+
}
|
|
1207
|
+
.lh-fraction__wrapper--fail .lh-fraction__background {
|
|
1208
|
+
background-color: var(--color-fail);
|
|
1209
|
+
}
|
|
1210
|
+
.lh-fraction__wrapper--fail .lh-fraction__content::before {
|
|
1211
|
+
border-left: calc(var(--score-icon-size) / 2) solid transparent;
|
|
1212
|
+
border-right: calc(var(--score-icon-size) / 2) solid transparent;
|
|
1213
|
+
border-bottom: var(--score-icon-size) solid var(--color-fail);
|
|
1214
|
+
}
|
|
1215
|
+
.lh-fraction__wrapper--null .lh-fraction__content {
|
|
1216
|
+
color: var(--color-gray-700);
|
|
1217
|
+
}
|
|
1218
|
+
.lh-fraction__wrapper--null .lh-fraction__background {
|
|
1219
|
+
background-color: var(--color-gray-700);
|
|
1220
|
+
}
|
|
1221
|
+
.lh-fraction__wrapper--null .lh-fraction__content::before {
|
|
1222
|
+
border-radius: 50%;
|
|
1223
|
+
border: 2px solid var(--color-gray-700);
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
.lh-fraction__background {
|
|
1227
|
+
position: absolute;
|
|
1228
|
+
height: 100%;
|
|
1229
|
+
width: 100%;
|
|
1230
|
+
border-radius: calc(var(--gauge-circle-size) / 2);
|
|
1231
|
+
opacity: 0.1;
|
|
1232
|
+
z-index: -1;
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
.lh-fraction__content-wrapper {
|
|
1236
|
+
height: var(--gauge-circle-size);
|
|
1237
|
+
display: flex;
|
|
1238
|
+
align-items: center;
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
.lh-fraction__content {
|
|
1242
|
+
display: flex;
|
|
1243
|
+
position: relative;
|
|
1244
|
+
align-items: center;
|
|
1245
|
+
justify-content: center;
|
|
1246
|
+
font-size: var(--gauge-label-font-size);
|
|
1247
|
+
width: max-content;
|
|
1248
|
+
padding: 1em;
|
|
1249
|
+
min-width: 6em;
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1156
1252
|
.lh-gauge {
|
|
1157
1253
|
stroke-linecap: round;
|
|
1158
1254
|
width: var(--gauge-circle-size);
|
|
@@ -1181,6 +1277,10 @@
|
|
|
1181
1277
|
.lh-category .lh-gauge__svg-wrapper {
|
|
1182
1278
|
--gauge-circle-size: var(--gauge-circle-size-big);
|
|
1183
1279
|
}
|
|
1280
|
+
.lh-category .lh-fraction__wrapper {
|
|
1281
|
+
--gauge-circle-size: var(--gauge-circle-size-big);
|
|
1282
|
+
--score-icon-size: var(--score-icon-size-big)
|
|
1283
|
+
}
|
|
1184
1284
|
|
|
1185
1285
|
/* The plugin badge overlay */
|
|
1186
1286
|
.lh-gauge__wrapper--plugin .lh-gauge__svg-wrapper::before {
|
|
@@ -1225,7 +1325,8 @@
|
|
|
1225
1325
|
--gauge-percentage-font-size: var(--gauge-percentage-font-size-big);
|
|
1226
1326
|
}
|
|
1227
1327
|
|
|
1228
|
-
.lh-gauge__wrapper
|
|
1328
|
+
.lh-gauge__wrapper,
|
|
1329
|
+
.lh-fraction__wrapper {
|
|
1229
1330
|
position: relative;
|
|
1230
1331
|
display: flex;
|
|
1231
1332
|
align-items: center;
|
|
@@ -1240,7 +1341,8 @@
|
|
|
1240
1341
|
will-change: opacity; /* Only using for layer promotion */
|
|
1241
1342
|
}
|
|
1242
1343
|
|
|
1243
|
-
.lh-gauge__label
|
|
1344
|
+
.lh-gauge__label,
|
|
1345
|
+
.lh-fraction__label {
|
|
1244
1346
|
font-size: var(--gauge-label-font-size);
|
|
1245
1347
|
line-height: var(--gauge-label-line-height);
|
|
1246
1348
|
margin-top: 10px;
|
|
@@ -1249,16 +1351,22 @@
|
|
|
1249
1351
|
}
|
|
1250
1352
|
|
|
1251
1353
|
/* TODO(#8185) use more BEM (.lh-gauge__label--big) instead of relying on descendant selector */
|
|
1252
|
-
.lh-category .lh-gauge__label
|
|
1354
|
+
.lh-category .lh-gauge__label,
|
|
1355
|
+
.lh-category .lh-fraction__label {
|
|
1253
1356
|
--gauge-label-font-size: var(--gauge-label-font-size-big);
|
|
1254
1357
|
--gauge-label-line-height: var(--gauge-label-line-height-big);
|
|
1255
1358
|
margin-top: 14px;
|
|
1256
1359
|
}
|
|
1360
|
+
.lh-category .lh-fraction__content {
|
|
1361
|
+
--gauge-label-font-size: var(--gauge-label-font-size-big);
|
|
1362
|
+
}
|
|
1257
1363
|
|
|
1258
1364
|
|
|
1259
1365
|
.lh-scores-header .lh-gauge__wrapper,
|
|
1366
|
+
.lh-scores-header .lh-fraction__wrapper,
|
|
1260
1367
|
.lh-scores-header .lh-gauge--pwa__wrapper,
|
|
1261
1368
|
.lh-sticky-header .lh-gauge__wrapper,
|
|
1369
|
+
.lh-sticky-header .lh-fraction__wrapper,
|
|
1262
1370
|
.lh-sticky-header .lh-gauge--pwa__wrapper {
|
|
1263
1371
|
width: var(--gauge-wrapper-width);
|
|
1264
1372
|
}
|
|
@@ -110,6 +110,7 @@ limitations under the License.
|
|
|
110
110
|
<template id="metric">
|
|
111
111
|
<div class="lh-metric">
|
|
112
112
|
<div class="lh-metric__innerwrap">
|
|
113
|
+
<div class="lh-metric__icon"></div>
|
|
113
114
|
<span class="lh-metric__title"></span>
|
|
114
115
|
<div class="lh-metric__value"></div>
|
|
115
116
|
<div class="lh-metric__description"></div>
|
|
@@ -562,6 +563,18 @@ limitations under the License.
|
|
|
562
563
|
</a>
|
|
563
564
|
</template>
|
|
564
565
|
|
|
566
|
+
<!-- Lighthouse category fraction -->
|
|
567
|
+
<template id="fraction">
|
|
568
|
+
<a href="#" class="lh-fraction__wrapper">
|
|
569
|
+
<div class="lh-fraction__content-wrapper">
|
|
570
|
+
<div class="lh-fraction__content">
|
|
571
|
+
<div class="lh-fraction__background"></div>
|
|
572
|
+
</div>
|
|
573
|
+
</div>
|
|
574
|
+
<div class="lh-fraction__label"></div>
|
|
575
|
+
</a>
|
|
576
|
+
</template>
|
|
577
|
+
|
|
565
578
|
|
|
566
579
|
<!-- Lighthouse PWA badge gauge -->
|
|
567
580
|
<template id="gaugePwa">
|
package/report/clients/psi.js
CHANGED
|
@@ -72,7 +72,11 @@ export function prepareLabData(LHResult, document) {
|
|
|
72
72
|
const detailsRenderer = new DetailsRenderer(dom, {fullPageScreenshot});
|
|
73
73
|
const perfRenderer = new PerformanceCategoryRenderer(dom, detailsRenderer);
|
|
74
74
|
// PSI environment string will ensure the categoryHeader and permalink elements are excluded
|
|
75
|
-
const perfCategoryEl = perfRenderer.render(
|
|
75
|
+
const perfCategoryEl = perfRenderer.render(
|
|
76
|
+
perfCategory,
|
|
77
|
+
reportLHR.categoryGroups,
|
|
78
|
+
{environment: 'PSI', gatherMode: lhResult.gatherMode}
|
|
79
|
+
);
|
|
76
80
|
|
|
77
81
|
const scoreGaugeEl = dom.find('.lh-score__gauge', perfCategoryEl);
|
|
78
82
|
scoreGaugeEl.remove();
|
|
@@ -1,23 +1,12 @@
|
|
|
1
1
|
{
|
|
2
|
+
"extends": "../../tsconfig-base.json",
|
|
2
3
|
"compilerOptions": {
|
|
3
|
-
"composite": true,
|
|
4
4
|
"outDir": "../../.tmp/tsbuildinfo/report/generator",
|
|
5
|
-
"emitDeclarationOnly": true,
|
|
6
|
-
"declarationMap": true,
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"allowJs": true,
|
|
13
|
-
"checkJs": true,
|
|
14
|
-
"strict": true,
|
|
15
|
-
// TODO: remove the next line to be fully `strict`.
|
|
16
|
-
"useUnknownInCatchVariables": false,
|
|
17
|
-
|
|
18
|
-
// "listFiles": true,
|
|
19
|
-
// "noErrorTruncation": true,
|
|
20
|
-
"extendedDiagnostics": true,
|
|
6
|
+
// Limit defs to base JS and DOM (for URL: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/34960).
|
|
7
|
+
"lib": ["es2020", "dom"],
|
|
8
|
+
// Only include `@types/node` from node_modules/.
|
|
9
|
+
"types": ["node"],
|
|
21
10
|
},
|
|
22
11
|
"references": [
|
|
23
12
|
{"path": "../../types/lhr/"},
|
|
@@ -171,13 +171,14 @@ export class CategoryRenderer {
|
|
|
171
171
|
/**
|
|
172
172
|
* @param {LH.ReportResult.Category} category
|
|
173
173
|
* @param {Record<string, LH.Result.ReportGroup>} groupDefinitions
|
|
174
|
+
* @param {{gatherMode: LH.Result.GatherMode}=} options
|
|
174
175
|
* @return {DocumentFragment}
|
|
175
176
|
*/
|
|
176
|
-
renderCategoryHeader(category, groupDefinitions) {
|
|
177
|
+
renderCategoryHeader(category, groupDefinitions, options) {
|
|
177
178
|
const component = this.dom.createComponent('categoryHeader');
|
|
178
179
|
|
|
179
180
|
const gaugeContainerEl = this.dom.find('.lh-score__gauge', component);
|
|
180
|
-
const gaugeEl = this.
|
|
181
|
+
const gaugeEl = this.renderCategoryScore(category, groupDefinitions, options);
|
|
181
182
|
gaugeContainerEl.appendChild(gaugeEl);
|
|
182
183
|
|
|
183
184
|
if (category.description) {
|
|
@@ -311,6 +312,19 @@ export class CategoryRenderer {
|
|
|
311
312
|
return clumpElement;
|
|
312
313
|
}
|
|
313
314
|
|
|
315
|
+
/**
|
|
316
|
+
* @param {LH.ReportResult.Category} category
|
|
317
|
+
* @param {Record<string, LH.Result.ReportGroup>} groupDefinitions
|
|
318
|
+
* @param {{gatherMode: LH.Result.GatherMode}=} options
|
|
319
|
+
* @return {DocumentFragment}
|
|
320
|
+
*/
|
|
321
|
+
renderCategoryScore(category, groupDefinitions, options) {
|
|
322
|
+
if (options && (options.gatherMode === 'snapshot' || options.gatherMode === 'timespan')) {
|
|
323
|
+
return this.renderCategoryFraction(category);
|
|
324
|
+
}
|
|
325
|
+
return this.renderScoreGauge(category, groupDefinitions);
|
|
326
|
+
}
|
|
327
|
+
|
|
314
328
|
/**
|
|
315
329
|
* @param {LH.ReportResult.Category} category
|
|
316
330
|
* @param {Record<string, LH.Result.ReportGroup>} groupDefinitions
|
|
@@ -353,6 +367,44 @@ export class CategoryRenderer {
|
|
|
353
367
|
return tmpl;
|
|
354
368
|
}
|
|
355
369
|
|
|
370
|
+
/**
|
|
371
|
+
* @param {LH.ReportResult.Category} category
|
|
372
|
+
* @return {DocumentFragment}
|
|
373
|
+
*/
|
|
374
|
+
renderCategoryFraction(category) {
|
|
375
|
+
const tmpl = this.dom.createComponent('fraction');
|
|
376
|
+
const wrapper = this.dom.find('a.lh-fraction__wrapper', tmpl);
|
|
377
|
+
this.dom.safelySetHref(wrapper, `#${category.id}`);
|
|
378
|
+
|
|
379
|
+
const numAudits = category.auditRefs.length;
|
|
380
|
+
|
|
381
|
+
let numPassed = 0;
|
|
382
|
+
let totalWeight = 0;
|
|
383
|
+
for (const auditRef of category.auditRefs) {
|
|
384
|
+
totalWeight += auditRef.weight;
|
|
385
|
+
if (Util.showAsPassed(auditRef.result)) numPassed++;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
const fraction = numPassed / numAudits;
|
|
389
|
+
const content = this.dom.find('.lh-fraction__content', tmpl);
|
|
390
|
+
const text = this.dom.createElement('span');
|
|
391
|
+
text.textContent = `${numPassed}/${numAudits}`;
|
|
392
|
+
content.appendChild(text);
|
|
393
|
+
|
|
394
|
+
let rating = Util.calculateRating(fraction);
|
|
395
|
+
|
|
396
|
+
// If none of the available audits can affect the score, a rating isn't useful.
|
|
397
|
+
// The flow report should display the fraction with neutral icon and coloring in this case.
|
|
398
|
+
if (totalWeight === 0) {
|
|
399
|
+
rating = 'null';
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
wrapper.classList.add(`lh-fraction__wrapper--${rating}`);
|
|
403
|
+
|
|
404
|
+
this.dom.find('.lh-fraction__label', tmpl).textContent = category.title;
|
|
405
|
+
return tmpl;
|
|
406
|
+
}
|
|
407
|
+
|
|
356
408
|
/**
|
|
357
409
|
* Returns true if an LH category has any non-"notApplicable" audits.
|
|
358
410
|
* @param {LH.ReportResult.Category} category
|
|
@@ -434,13 +486,14 @@ export class CategoryRenderer {
|
|
|
434
486
|
* ├── …
|
|
435
487
|
* ⋮
|
|
436
488
|
* @param {LH.ReportResult.Category} category
|
|
437
|
-
* @param {Object<string, LH.Result.ReportGroup
|
|
489
|
+
* @param {Object<string, LH.Result.ReportGroup>=} groupDefinitions
|
|
490
|
+
* @param {{environment?: 'PSI', gatherMode: LH.Result.GatherMode}=} options
|
|
438
491
|
* @return {Element}
|
|
439
492
|
*/
|
|
440
|
-
render(category, groupDefinitions = {}) {
|
|
493
|
+
render(category, groupDefinitions = {}, options) {
|
|
441
494
|
const element = this.dom.createElement('div', 'lh-category');
|
|
442
495
|
this.createPermalinkSpan(element, category.id);
|
|
443
|
-
element.appendChild(this.renderCategoryHeader(category, groupDefinitions));
|
|
496
|
+
element.appendChild(this.renderCategoryHeader(category, groupDefinitions, options));
|
|
444
497
|
|
|
445
498
|
// Top level clumps for audits, in order they will appear in the report.
|
|
446
499
|
/** @type {Map<TopLevelClumpId, Array<LH.ReportResult.AuditRef>>} */
|
|
@@ -209,6 +209,24 @@ function createFooterComponent(dom) {
|
|
|
209
209
|
return el0;
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
+
/**
|
|
213
|
+
* @param {DOM} dom
|
|
214
|
+
*/
|
|
215
|
+
function createFractionComponent(dom) {
|
|
216
|
+
const el0 = dom.document().createDocumentFragment();
|
|
217
|
+
const el1 = dom.createElement('a', 'lh-fraction__wrapper');
|
|
218
|
+
el1.setAttribute('href', '#');
|
|
219
|
+
const el2 = dom.createElement('div', 'lh-fraction__content-wrapper');
|
|
220
|
+
const el3 = dom.createElement('div', 'lh-fraction__content');
|
|
221
|
+
const el4 = dom.createElement('div', 'lh-fraction__background');
|
|
222
|
+
el3.append(' ', el4, ' ');
|
|
223
|
+
el2.append(' ', el3, ' ');
|
|
224
|
+
const el5 = dom.createElement('div', 'lh-fraction__label');
|
|
225
|
+
el1.append(' ', el2, ' ', el5, ' ');
|
|
226
|
+
el0.append(el1);
|
|
227
|
+
return el0;
|
|
228
|
+
}
|
|
229
|
+
|
|
212
230
|
/**
|
|
213
231
|
* @param {DOM} dom
|
|
214
232
|
*/
|
|
@@ -361,10 +379,11 @@ function createMetricComponent(dom) {
|
|
|
361
379
|
const el0 = dom.document().createDocumentFragment();
|
|
362
380
|
const el1 = dom.createElement('div', 'lh-metric');
|
|
363
381
|
const el2 = dom.createElement('div', 'lh-metric__innerwrap');
|
|
364
|
-
const el3 = dom.createElement('
|
|
365
|
-
const el4 = dom.createElement('
|
|
366
|
-
const el5 = dom.createElement('div', 'lh-
|
|
367
|
-
|
|
382
|
+
const el3 = dom.createElement('div', 'lh-metric__icon');
|
|
383
|
+
const el4 = dom.createElement('span', 'lh-metric__title');
|
|
384
|
+
const el5 = dom.createElement('div', 'lh-metric__value');
|
|
385
|
+
const el6 = dom.createElement('div', 'lh-metric__description');
|
|
386
|
+
el2.append(' ', el3, ' ', el4, ' ', el5, ' ', el6, ' ');
|
|
368
387
|
el1.append(' ', el2, ' ');
|
|
369
388
|
el0.append(el1);
|
|
370
389
|
return el0;
|
|
@@ -752,7 +771,7 @@ function createWarningsToplevelComponent(dom) {
|
|
|
752
771
|
}
|
|
753
772
|
|
|
754
773
|
|
|
755
|
-
/** @typedef {'3pFilter'|'audit'|'categoryHeader'|'chevron'|'clump'|'crc'|'crcChain'|'elementScreenshot'|'envItem'|'footer'|'gauge'|'gaugePwa'|'heading'|'metric'|'metricsToggle'|'opportunity'|'opportunityHeader'|'scorescale'|'scoresWrapper'|'snippet'|'snippetContent'|'snippetHeader'|'snippetLine'|'topbar'|'warningsToplevel'} ComponentName */
|
|
774
|
+
/** @typedef {'3pFilter'|'audit'|'categoryHeader'|'chevron'|'clump'|'crc'|'crcChain'|'elementScreenshot'|'envItem'|'footer'|'fraction'|'gauge'|'gaugePwa'|'heading'|'metric'|'metricsToggle'|'opportunity'|'opportunityHeader'|'scorescale'|'scoresWrapper'|'snippet'|'snippetContent'|'snippetHeader'|'snippetLine'|'topbar'|'warningsToplevel'} ComponentName */
|
|
756
775
|
/**
|
|
757
776
|
* @param {DOM} dom
|
|
758
777
|
* @param {ComponentName} componentName
|
|
@@ -770,6 +789,7 @@ export function createComponent(dom, componentName) {
|
|
|
770
789
|
case 'elementScreenshot': return createElementScreenshotComponent(dom);
|
|
771
790
|
case 'envItem': return createEnvItemComponent(dom);
|
|
772
791
|
case 'footer': return createFooterComponent(dom);
|
|
792
|
+
case 'fraction': return createFractionComponent(dom);
|
|
773
793
|
case 'gauge': return createGaugeComponent(dom);
|
|
774
794
|
case 'gaugePwa': return createGaugePwaComponent(dom);
|
|
775
795
|
case 'heading': return createHeadingComponent(dom);
|
|
@@ -155,20 +155,20 @@ export class PerformanceCategoryRenderer extends CategoryRenderer {
|
|
|
155
155
|
/**
|
|
156
156
|
* @param {LH.ReportResult.Category} category
|
|
157
157
|
* @param {Object<string, LH.Result.ReportGroup>} groups
|
|
158
|
-
* @param {
|
|
158
|
+
* @param {{gatherMode: LH.Result.GatherMode, environment?: 'PSI'}=} options
|
|
159
159
|
* @return {Element}
|
|
160
160
|
* @override
|
|
161
161
|
*/
|
|
162
|
-
render(category, groups,
|
|
162
|
+
render(category, groups, options) {
|
|
163
163
|
const strings = Util.i18n.strings;
|
|
164
164
|
const element = this.dom.createElement('div', 'lh-category');
|
|
165
|
-
if (environment === 'PSI') {
|
|
165
|
+
if (options && options.environment === 'PSI') {
|
|
166
166
|
const gaugeEl = this.dom.createElement('div', 'lh-score__gauge');
|
|
167
|
-
gaugeEl.appendChild(this.
|
|
167
|
+
gaugeEl.appendChild(this.renderCategoryScore(category, groups, options));
|
|
168
168
|
element.appendChild(gaugeEl);
|
|
169
169
|
} else {
|
|
170
170
|
this.createPermalinkSpan(element, category.id);
|
|
171
|
-
element.appendChild(this.renderCategoryHeader(category, groups));
|
|
171
|
+
element.appendChild(this.renderCategoryHeader(category, groups, options));
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
// Metrics.
|
|
@@ -48,11 +48,21 @@ export class PwaCategoryRenderer extends CategoryRenderer {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
|
+
* Alias for backcompat.
|
|
51
52
|
* @param {LH.ReportResult.Category} category
|
|
52
53
|
* @param {Record<string, LH.Result.ReportGroup>} groupDefinitions
|
|
53
54
|
* @return {DocumentFragment}
|
|
54
55
|
*/
|
|
55
56
|
renderScoreGauge(category, groupDefinitions) {
|
|
57
|
+
return this.renderCategoryScore(category, groupDefinitions);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @param {LH.ReportResult.Category} category
|
|
62
|
+
* @param {Record<string, LH.Result.ReportGroup>} groupDefinitions
|
|
63
|
+
* @return {DocumentFragment}
|
|
64
|
+
*/
|
|
65
|
+
renderCategoryScore(category, groupDefinitions) {
|
|
56
66
|
// Defer to parent-gauge style if category error.
|
|
57
67
|
if (category.score === null) {
|
|
58
68
|
return super.renderScoreGauge(category, groupDefinitions);
|
|
@@ -160,11 +160,15 @@ export class ReportRenderer {
|
|
|
160
160
|
|
|
161
161
|
for (const category of Object.values(report.categories)) {
|
|
162
162
|
const renderer = specificCategoryRenderers[category.id] || categoryRenderer;
|
|
163
|
-
const categoryGauge = renderer.
|
|
163
|
+
const categoryGauge = renderer.renderCategoryScore(
|
|
164
|
+
category,
|
|
165
|
+
report.categoryGroups || {},
|
|
166
|
+
{gatherMode: report.gatherMode}
|
|
167
|
+
);
|
|
164
168
|
|
|
165
169
|
if (Util.isPluginCategory(category.id)) {
|
|
166
170
|
pluginGauges.push(categoryGauge);
|
|
167
|
-
} else if (renderer.
|
|
171
|
+
} else if (renderer.renderCategoryScore === categoryRenderer.renderCategoryScore) {
|
|
168
172
|
// The renderer for default categories is just the default CategoryRenderer.
|
|
169
173
|
// If the functions are equal, then renderer is an instance of CategoryRenderer.
|
|
170
174
|
// For example, the PWA category uses PwaCategoryRenderer, which overrides
|
|
@@ -238,12 +242,17 @@ export class ReportRenderer {
|
|
|
238
242
|
}
|
|
239
243
|
|
|
240
244
|
const categories = reportSection.appendChild(this._dom.createElement('div', 'lh-categories'));
|
|
245
|
+
const categoryOptions = {gatherMode: report.gatherMode};
|
|
241
246
|
for (const category of Object.values(report.categories)) {
|
|
242
247
|
const renderer = specificCategoryRenderers[category.id] || categoryRenderer;
|
|
243
248
|
// .lh-category-wrapper is full-width and provides horizontal rules between categories.
|
|
244
249
|
// .lh-category within has the max-width: var(--report-width);
|
|
245
250
|
const wrapper = renderer.dom.createChildOf(categories, 'div', 'lh-category-wrapper');
|
|
246
|
-
wrapper.appendChild(renderer.render(
|
|
251
|
+
wrapper.appendChild(renderer.render(
|
|
252
|
+
category,
|
|
253
|
+
report.categoryGroups,
|
|
254
|
+
categoryOptions
|
|
255
|
+
));
|
|
247
256
|
}
|
|
248
257
|
|
|
249
258
|
const reportFragment = this._dom.createFragment();
|
|
@@ -219,16 +219,14 @@ export class ReportUIFeatures {
|
|
|
219
219
|
return !thirdPartyFilterAuditExclusions.includes(containingAudit.id);
|
|
220
220
|
});
|
|
221
221
|
|
|
222
|
-
tablesWithUrls.forEach((tableEl
|
|
222
|
+
tablesWithUrls.forEach((tableEl) => {
|
|
223
223
|
const rowEls = getTableRows(tableEl);
|
|
224
224
|
const thirdPartyRows = this._getThirdPartyRows(rowEls, this.json.finalUrl);
|
|
225
225
|
|
|
226
226
|
// create input box
|
|
227
227
|
const filterTemplate = this._dom.createComponent('3pFilter');
|
|
228
228
|
const filterInput = this._dom.find('input', filterTemplate);
|
|
229
|
-
const id = `lh-3p-filter-label--${index}`;
|
|
230
229
|
|
|
231
|
-
filterInput.id = id;
|
|
232
230
|
filterInput.addEventListener('change', e => {
|
|
233
231
|
const shouldHideThirdParty = e.target instanceof HTMLInputElement && !e.target.checked;
|
|
234
232
|
let even = true;
|
|
@@ -250,7 +248,6 @@ export class ReportUIFeatures {
|
|
|
250
248
|
}
|
|
251
249
|
});
|
|
252
250
|
|
|
253
|
-
this._dom.find('label', filterTemplate).setAttribute('for', id);
|
|
254
251
|
this._dom.find('.lh-3p-filter-count', filterTemplate).textContent =
|
|
255
252
|
`${thirdPartyRows.length}`;
|
|
256
253
|
this._dom.find('.lh-3p-ui-string', filterTemplate).textContent =
|