diff --git a/.github/linters/.stylelintrc.json b/.github/linters/.stylelintrc.json index 8f6d5a3b..1827eecd 100644 --- a/.github/linters/.stylelintrc.json +++ b/.github/linters/.stylelintrc.json @@ -10,7 +10,6 @@ ], "color-function-notation": null, "comment-empty-line-before": null, - "declaration-colon-newline-after": null, "font-family-no-duplicate-names": [ true, { @@ -18,22 +17,14 @@ } ], "length-zero-no-unit": null, - "max-line-length": null, "media-feature-range-notation": "prefix", "no-descending-specificity": null, - "no-eol-whitespace": [ - true, - { - "ignore": ["empty-lines"] - } - ], "property-no-unknown": [ true, { "ignoreProperties": ["prince-pdf-display-doc-title","prince-pdf-tag-type"] } ], - "selector-list-comma-newline-after": "always", "selector-pseudo-element-no-unknown": [ true, { diff --git a/.github/workflows/code-static-analysis.yml b/.github/workflows/code-static-analysis.yml index 7c06114f..5a93404f 100644 --- a/.github/workflows/code-static-analysis.yml +++ b/.github/workflows/code-static-analysis.yml @@ -35,7 +35,7 @@ jobs: uses: actions/checkout@v4 - name: Set up Python 3.12 if: ${{ matrix.language == 'python' }} - uses: actions/setup-python@v5 + uses: actions/setup-python with: python-version: '3.12' - name: Install dependencies diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 279482c7..babcb86a 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -2,7 +2,7 @@ ## Linter GitHub Actions ## ########################### # -# Documentation: https://github.com/github/super-linter/ +# Documentation: https://github.com/super-linter/super-linter/ # # Exception config files are in the .github/linters directory # @@ -24,12 +24,11 @@ jobs: # Only run the full workflow for manual runs or if upgrading the super linter if: | github.event_name != 'workflow_dispatch' && - startsWith(github.event.pull_request.title,'Bump github/super-linter') != true + startsWith(github.event.pull_request.title,'Bump super-linter/super-linter') != true run: | echo "VALIDATE_ALL_CODEBASE=false" >> $GITHUB_ENV - name: Lint Code Base - #uses: docker://github/super-linter:v3.15.3 - uses: github/super-linter/slim@v4.10.1 + uses: super-linter/super-linter/slim@v7 env: DEFAULT_BRANCH: main GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/predeploy.yml b/.github/workflows/predeploy.yml index 4ef56773..95abcadb 100644 --- a/.github/workflows/predeploy.yml +++ b/.github/workflows/predeploy.yml @@ -26,7 +26,7 @@ jobs: with: node-version: '20' - name: Set up Python 3.12 - uses: actions/setup-python@v5 + uses: actions/setup-python with: python-version: '3.12' - name: Run the website diff --git a/.github/workflows/test-website.yml b/.github/workflows/test-website.yml index d6046b08..c09b574e 100644 --- a/.github/workflows/test-website.yml +++ b/.github/workflows/test-website.yml @@ -25,7 +25,7 @@ jobs: with: node-version: '20' - name: Set up Python 3.12 - uses: actions/setup-python@v5 + uses: actions/setup-python with: python-version: '3.12' - name: Run the website @@ -35,7 +35,7 @@ jobs: - name: Use more complete checks for generated HTML linting run: cp -f .github/linters/.htmlhintrc_morechecks .github/linters/.htmlhintrc - name: Lint Generated HTML - uses: github/super-linter/slim@v4.10.1 + uses: super-linter/super-linter/slim@v7 env: DEFAULT_BRANCH: main FILTER_REGEX_INCLUDE: static/html/.* diff --git a/config/reports.json b/config/reports.json index 7e78ec7a..f0d8ee02 100644 --- a/config/reports.json +++ b/config/reports.json @@ -1203,7 +1203,7 @@ }, "progressive-web-apps": { "name": "Progressive Web Apps", - "summary": "This report examines the state of [Progressive Web Apps (PWAs)](https://developers.google.com/web/progressive-web-apps/). PWAs are a new class of web applications, enabled by the [Service Worker APIs](https://developer.mozilla.org/en/docs/Web/API/Service_Worker_API). Service workers allow apps to support network-independent loading, to receive push notifications as well as to synchronize data in the background, and — together with [Web App Manifests](https://developer.mozilla.org/en-US/docs/Web/Manifest) — allow users to install PWAs.", + "summary": "This report examines the state of [Progressive Web Apps (PWAs)](https://developers.google.com/web/progressive-web-apps/). PWAs are a new class of web applications, enabled by the [Service Worker APIs](https://developer.mozilla.org/en/docs/Web/API/Service_Worker_API). Service workers allow apps to support network-independent loading, to receive push notifications as well as to synchronize data in the background, and — together with [Web App Manifests](https://developer.mozilla.org/en-US/docs/Web/Manifest) — allow users to install PWAs.", "image": "/static/img/reports/progressive-web-apps-report.png", "metrics": [ "pwaScores", diff --git a/src/js/components/filters.js b/src/js/components/filters.js index 7ad9f4e9..b47c4d33 100644 --- a/src/js/components/filters.js +++ b/src/js/components/filters.js @@ -182,7 +182,7 @@ class Filters { updateCategory(event) { // Get the techs associated with the selected category const selectedCategory = this.categories.find(category => category.category === event.target.value); - let selectedTechs = selectedCategory?.technologies || []; + let selectedTechs = selectedCategory?.technologies || []; if(event.target.value === 'ALL') { selectedTechs = this.technologies.map(technology => technology.technology); } diff --git a/src/js/histogram.js b/src/js/histogram.js index b82bab44..7deed702 100644 --- a/src/js/histogram.js +++ b/src/js/histogram.js @@ -1,3 +1,5 @@ +/* global Highcharts */ + import { Colors } from './colors'; import debounce from './debounce'; import { Metric } from './metric'; @@ -38,13 +40,13 @@ function drawClientSummary(data, options, client) { } function getSummary(data, options) { - const summary = getPrimaryMetric(data, options); + const summary = getPrimaryMetric(data); const metric = new Metric(options, summary); return metric.toString(); } -function getPrimaryMetric(data, options) { +function getPrimaryMetric(data) { data = data.filter(o => +o.cdf > 0.5); if (!data.length) { return '?'; @@ -110,12 +112,13 @@ class Bin { format(property) { switch(property) { case 'pdf': - case 'cdf': + case 'cdf': { let value = (Math.floor(this[property] * 10000) / 100).toFixed(2); if (value < 10) { value = '0' + value; } return value + '%'; + } case 'volume': return this[property].toLocaleString(); default: @@ -265,8 +268,8 @@ function drawHistogram(data, containerId, options) { const chart = document.getElementById(`${options.metric}-chart`); callOnceWhenVisible(chart, () => { drawChart(series, containerId, options); - }); -}; + }) +} function drawChart(series, containerId, options) { const chart = Highcharts.chart(containerId, { @@ -326,7 +329,7 @@ function drawChart(series, containerId, options) { borderColor: 'rgba(247,247,247,0.85)', formatter: function() { const metric = new Metric(options, Math.round(this.points[0].x * 100) / 100); - const tooltips = this.points.filter(p => !p.series.name.includes('CDF')).map((point, points) => { + const tooltips = this.points.filter(p => !p.series.name.includes('CDF')).map((point) => { const cdf = this.points.find(p => p.series.name == `${point.series.name} CDF`); return `
diff --git a/src/js/index.js b/src/js/index.js index 23246634..2dccb14e 100644 --- a/src/js/index.js +++ b/src/js/index.js @@ -15,7 +15,7 @@ function renderBlogPosts() { } const blog = new BlogRenderer(); - blog.renderPosts(blog_posts, template).then(_ => blog_section.classList.remove('hidden')); + blog.renderPosts(blog_posts, template).then(() => blog_section.classList.remove('hidden')); } function getDiscussTopics() { @@ -27,12 +27,12 @@ function getDiscussTopics() { const topics = r.topic_list.topics.slice(0, 2); topics.forEach(topic => latestTopicIds.add(topic.id)); drawTopics(topics, r.users); - }).then(_ => { + }).then(() => { return fetch(`${Discussion.ORIGIN}/top.json`); }).then(r => r.json()).then(r => { const topics = r.topic_list.topics.filter(topic => !latestTopicIds.has(topic.id)).slice(0, 3); drawTopics(topics, r.users); - }).then(_ => discuss_section.classList.remove('hidden')); + }).then(() => discuss_section.classList.remove('hidden')); } function drawTopics(topics, rUsers) { diff --git a/src/js/main.js b/src/js/main.js index 118b9320..ff125b33 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -4,7 +4,7 @@ const hamburger = document.querySelector('.hamburger'); if (mobileNav) { if (hamburger) { - hamburger.addEventListener('click', (e) => { + hamburger.addEventListener('click', () => { const expanded = hamburger.getAttribute('aria-expanded'); mobileNav.classList.toggle('active'); hamburger.ariaExpanded = expanded === 'true' ? 'false' : 'true'; diff --git a/src/js/report.js b/src/js/report.js index 35e1f4cf..1b2ae63c 100644 --- a/src/js/report.js +++ b/src/js/report.js @@ -1,3 +1,5 @@ +/* global charts */ + import { Colors } from './colors'; import { Metric } from './metric'; import { prettyDate, drawMetricSummary } from './utils'; @@ -32,21 +34,21 @@ class Report { } bindChangeListener(id) { - document.getElementById(id).addEventListener('change', e => { + document.getElementById(id).addEventListener('change', (e) => { this[id] = e.target.value this.updatePermalink(); }); } bindUpdateListener() { - document.getElementById('update').addEventListener('click', _ => { + document.getElementById('update').addEventListener('click', () => { // TODO: Consider using history.replaceState on field changes instead. location.href = this.permalink.value; }); } bindTableVisibilityToggle() { - document.body.addEventListener('click', e => { + document.body.addEventListener('click', (e) => { if (!e.target.classList.contains('show-hide')) { return; } @@ -83,7 +85,7 @@ class Report { } bindPermalinkClick() { - this.permalink.addEventListener('click', _ => { + this.permalink.addEventListener('click', () => { this.permalink.select(); }); } @@ -180,7 +182,7 @@ class Report { const gridExpanderSelector = '.grid-expansion, .metric-header a'; Array.from(document.querySelectorAll(gridExpanderSelector)).forEach(btn => { const metricId = btn.dataset.metric; - btn.addEventListener('click', e => { + btn.addEventListener('click', () => { this.toggleMetricExpansion(metricId); }); }); @@ -208,7 +210,7 @@ class Report { getWPT(wptId) { const wpt = new WPT(wptId); - wpt.fetchResults().then(results => { + wpt.fetchResults().then(() => { const metrics = wpt.getMetrics(this.report); Object.entries(metrics).forEach(([metric, value]) => { const options = this.report.metrics.find(m => m.id === metric); diff --git a/src/js/send-web-vitals.js b/src/js/send-web-vitals.js index 4a03f489..64b2829a 100644 --- a/src/js/send-web-vitals.js +++ b/src/js/send-web-vitals.js @@ -1,3 +1,5 @@ +/* global gtag, webVitals */ + function sendWebVitals() { function getLoafAttribution(attribution) { @@ -80,7 +82,7 @@ function sendWebVitals() { debug_target: attribution.loadState || '(not set)', }; break; - case 'INP': + case 'INP': { const loafAttribution = getLoafAttribution(attribution); overrides = { debug_event: attribution.interactionType, @@ -93,6 +95,7 @@ function sendWebVitals() { ...loafAttribution }; break; + } case 'LCP': overrides = { debug_url: attribution.url, diff --git a/src/js/techreport/index.js b/src/js/techreport/index.js index 1bd0cca9..dbd76b31 100644 --- a/src/js/techreport/index.js +++ b/src/js/techreport/index.js @@ -1,3 +1,5 @@ +/* global Section */ + import Filters from '../components/filters'; import { Constants } from './utils/constants'; const { DrilldownHeader } = require("../components/drilldownHeader"); @@ -87,11 +89,12 @@ class TechReport { this.getAllMetricData(); break; - case 'category': - const category = this.filters.category || 'CMS'; + case 'category': { + const category = this.filters.category || 'CMS'; this.initializeReport(); this.getCategoryData(category); break; + } } } diff --git a/src/js/techreport/section.js b/src/js/techreport/section.js index 4a7c70ba..fa03011f 100644 --- a/src/js/techreport/section.js +++ b/src/js/techreport/section.js @@ -1,3 +1,5 @@ +/* global Timeseries */ + import SummaryCard from "./summaryCards"; import TableLinked from "./tableLinked"; diff --git a/src/js/techreport/table.js b/src/js/techreport/table.js index 8b6dd254..55364f92 100644 --- a/src/js/techreport/table.js +++ b/src/js/techreport/table.js @@ -75,7 +75,7 @@ function sortTableBy(dataset, key) { } function getColumnCell(columnConfig, data, date) { - const { config, column, client, app, subcategory, metric, endpoint } = columnConfig; + const { column, client, app, subcategory, endpoint } = columnConfig; const _data = data[app]?.find(entry => entry.date === date); const endpointData = _data?.[endpoint]; @@ -96,7 +96,7 @@ function getColumnCell(columnConfig, data, date) { function getSubcategory(config) { const urlParams = new URLSearchParams(window.location.search); const urlSubcategory = urlParams.get(config.param); - const subcategory = urlSubcategory || config.default || ''; + const subcategory = urlSubcategory || config.default || ''; return subcategory; } diff --git a/src/js/techreport/tableLinked.js b/src/js/techreport/tableLinked.js index 2b618454..46ba9991 100644 --- a/src/js/techreport/tableLinked.js +++ b/src/js/techreport/tableLinked.js @@ -115,7 +115,7 @@ class TableLinked { checkbox.setAttribute('data-name', `table-${this.id}`); checkbox.setAttribute('id', `${app}-table-${this.id}`); checkbox.setAttribute('name', `${app}-table-${this.id}`); - checkbox.addEventListener('change', (e) => { + checkbox.addEventListener('change', () => { const appLinks = document.querySelectorAll('[data-name="selected-apps"]'); const selectedApps = document.querySelectorAll(`[data-name="table-${this.id}"]:checked`); diff --git a/src/js/techreport/timeseries.js b/src/js/techreport/timeseries.js index 932ba573..d8e4c9bb 100644 --- a/src/js/techreport/timeseries.js +++ b/src/js/techreport/timeseries.js @@ -1,3 +1,5 @@ +/* global Highcharts */ + import { Table } from "./table"; import { DataUtils } from "./utils/data"; import { UIUtils } from "./utils/ui"; @@ -120,7 +122,7 @@ class Timeseries { /* Get the currently selected subcategory based on the URL */ const urlParams = new URLSearchParams(window.location.search); const urlSubcategory = urlParams.get(config.param); - const subcategory = urlSubcategory || config.default; + const subcategory = urlSubcategory || config.default; /* Remove the previous content */ container.innerHTML = ''; @@ -182,7 +184,7 @@ class Timeseries { /* Get the currently selected subcategory based on the URL */ const urlParams = new URLSearchParams(window.location.search); const urlSubcategory = urlParams.get(config.param); - const subcategory = urlSubcategory || config.default; + const subcategory = urlSubcategory || config.default; /* Get settings */ const metric = component.dataset.metric; @@ -398,7 +400,7 @@ class Timeseries { const config = this.pageConfig[this.id]?.viz; const urlParams = new URLSearchParams(window.location.search); const urlSubcategory = urlParams.get(config.param); - const subcategory = urlSubcategory || config.default; + const subcategory = urlSubcategory || config.default; // Get default colors const colors = this.defaults(config)?.chart?.colors; @@ -412,7 +414,7 @@ class Timeseries { const value = row?.[endpoint]?.find(row => row.name === subcategory)?.[client]?.[metric]; return { x: new Date(row.date).getTime(), - y: value || 0, + y: value || 0, }; }); diff --git a/src/js/timeseries.js b/src/js/timeseries.js index 14cd26b0..f7c0f083 100644 --- a/src/js/timeseries.js +++ b/src/js/timeseries.js @@ -1,3 +1,5 @@ +/* global Highcharts */ + import Changelog from './changelog'; import { Colors } from './colors'; import debounce from './debounce'; @@ -141,7 +143,7 @@ function drawTimeseries(data, options) { .then(flagSeries => series.push(flagSeries)) // If the getFlagSeries request fails (503), catch so we can still draw the chart .catch(console.error) - .then(_ => { + .then( () => { const chart = document.getElementById(options.chartId); callOnceWhenVisible(chart, () => drawChart(options, series)); }); @@ -175,7 +177,7 @@ function drawTimeseriesTable(data, options, [start, end]=[-Infinity, Infinity]) if (!options.timeseries || !options.timeseries.fields) { const trMeta = el('tr'); trMeta.classList.add('meta-row'); - DEFAULT_COLS.map(col => { + DEFAULT_COLS.map(() => { return el('td'); }).forEach(td => trMeta.appendChild(td)); const th = el('th'); @@ -210,7 +212,7 @@ function drawTimeseriesTable(data, options, [start, end]=[-Infinity, Infinity]) const isDesktop = o => o.client == 'desktop'; const isMobile = o => o.client == 'mobile'; -const toNumeric = ({client, date, ...other}) => { +const toNumeric = ({client, ...other}) => { return Object.entries(other).reduce((o, [k, v]) => { o[k] = +v; return o; @@ -450,7 +452,7 @@ const zip = data => { let row = dates[o.timestamp]; if (row) { row.push(o); - row.sort((a, b) => a.client == 'desktop' ? -1 : 1) + row.sort((a) => a.client == 'desktop' ? -1 : 1) return; } dates[o.timestamp] = [o]; diff --git a/static/css/techreport/techreport.css b/static/css/techreport/techreport.css index 0d0cd0e7..a4506ee8 100644 --- a/static/css/techreport/techreport.css +++ b/static/css/techreport/techreport.css @@ -774,7 +774,7 @@ select { .summary-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); - gap: 1rem 1rem; + gap: 1rem 1rem; /* stylelint-disable shorthand-property-no-redundant-values */ } .summary-grid + .card { @@ -1169,7 +1169,7 @@ select { display: flex; flex-wrap: wrap; column-gap: 2rem; - row-gap: 0.5rem; + row-gap: 0.5rem; /* stylelint-disable declaration-block-no-redundant-longhand-properties */ align-items: start; justify-content: space-between; } diff --git a/tools/generate/generate_js.js b/tools/generate/generate_js.js index dbcf8732..730f513a 100644 --- a/tools/generate/generate_js.js +++ b/tools/generate/generate_js.js @@ -1,6 +1,6 @@ const fs = require('fs-extra'); -node_module_files = [ +const node_module_files = [ 'highcharts/highcharts.js', 'highcharts/highcharts-more.js', 'highcharts/highstock.js', diff --git a/tools/generate/generate_sitemap.js b/tools/generate/generate_sitemap.js index 8bb4c55d..158bf5a8 100644 --- a/tools/generate/generate_sitemap.js +++ b/tools/generate/generate_sitemap.js @@ -65,10 +65,10 @@ const get_lastmod_date = (file) => { const convert_file_name = (url) => { if ( url.substr(url.length - 10) == "index.html" ) { return url.substr(0, url.length - 10); - }; + } if ( url.endsWith(".html")) { return url.substr(0, url.length - 5).replace(/_/g,'-'); - }; + } return url.replace(/_/g,'-'); }; diff --git a/tools/scripts/run_linter_locally.sh b/tools/scripts/run_linter_locally.sh index fd385964..ea5c977f 100755 --- a/tools/scripts/run_linter_locally.sh +++ b/tools/scripts/run_linter_locally.sh @@ -17,7 +17,7 @@ set -e # Annoyingly super-linter includes node_modules and env which take a long time -# https://github.com/github/super-linter/issues/985 +# https://github.com/super-linter/super-linter/issues/985 # So let's copy to /tmp folder and lint from there. It has the added advantage # of us being able to lint specific subsets of files easily. diff --git a/tools/scripts/set_lighthouse_urls.sh b/tools/scripts/set_lighthouse_urls.sh index fb2eb74b..20c8cd86 100755 --- a/tools/scripts/set_lighthouse_urls.sh +++ b/tools/scripts/set_lighthouse_urls.sh @@ -54,7 +54,7 @@ if [ "${production}" == "1" ]; then elif [ "${RUN_TYPE}" == "pull_request" ] && [ "${COMMIT_SHA}" != "" ]; then # If this is part of pull request then get list of files as those changed - # Uses similar logic to GitHub Super Linter (https://github.com/github/super-linter/blob/master/lib/buildFileList.sh) + # Uses similar logic to GitHub Super Linter (https://github.com/super-linter/super-linter/blob/master/lib/buildFileList.sh) # First checkout main to get list of differences git pull --quiet git checkout main