Skip to content

Commit 646a06d

Browse files
authored
feat: inject theme-querying snippets to each report (#455)
1 parent 19c9ee8 commit 646a06d

File tree

3 files changed

+81
-2
lines changed

3 files changed

+81
-2
lines changed

src/index.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const fs = require('fs').promises;
77
const minify = require('html-minifier').minify;
88
const { getConfiguration } = require('./config');
99
const { getBrowserPath, runLighthouse } = require('./lighthouse');
10+
const { makeReplacements } = require('./replacements');
1011

1112
const getServer = ({ serveDir, auditUrl }) => {
1213
if (auditUrl) {
@@ -271,8 +272,11 @@ module.exports = {
271272
console.log({ results: summary });
272273
}
273274

275+
let formattedReport;
274276
if (report) {
275-
const size = Buffer.byteLength(JSON.stringify(report));
277+
formattedReport = makeReplacements(report);
278+
279+
const size = Buffer.byteLength(JSON.stringify(formattedReport));
276280
console.log(
277281
`Report collected: audited_uri: '${chalk.magenta(
278282
url || path,
@@ -283,7 +287,13 @@ module.exports = {
283287
if (Array.isArray(errors) && errors.length > 0) {
284288
allErrors.push({ path, url, errors });
285289
} else {
286-
data.push({ path, url, summary, shortSummary, report });
290+
data.push({
291+
path,
292+
url,
293+
summary,
294+
shortSummary,
295+
report: formattedReport,
296+
});
287297
}
288298
}
289299

src/replacements.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Lighthouse only runs the theme checking function on load if a user is using
3+
* a dark theme. This change modifies the check to _always_ pass regardless of
4+
* theme preference.
5+
*
6+
* This ensures we always run the function on load, where we add additional
7+
* custom logic to test if a preferred theme was set as a querystring parameter,
8+
* falling back to a standard dark theme check.
9+
*/
10+
const forceThemeChecking = {
11+
source: `(prefers-color-scheme: dark)`,
12+
replacement: `(prefers-color-scheme)`,
13+
};
14+
15+
/*
16+
* Relative line numbers of the replacements:
17+
* 1. Ensure original source line is retained
18+
* 2-3. We only want to trigger this on first run. This function is also run
19+
* each time the theme is manually toggled using the dropdown menu and
20+
* we don't want to interfere.
21+
* 4. Check the URL querystring for a light/dark theme preference.
22+
* 5-7. If we recognise the value, use it to set/remove the theme class.
23+
* 8-9. We made a change to the Lighthouse-supplied matchMedia check which
24+
* runs on page load, to always trigger this function regardless of theme.
25+
* This means we can't rely on the second parameter being passed to this
26+
* function being accurate. If we make it this far, we need to run our own
27+
* check to replicate that original functionality.
28+
*/
29+
const enableQuerystringThemeCheck = {
30+
source: `const n=e.rootEl;`,
31+
replacement: `const n=e.rootEl;
32+
if (!window.qsThemeChecked) {
33+
window.qsThemeChecked = true;
34+
const qsTheme = new URLSearchParams(window.location.search).get('theme');
35+
if (qsTheme === 'dark' || qsTheme === 'light') {
36+
return n.classList.toggle('lh-dark', qsTheme === 'dark');
37+
}
38+
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
39+
return n.classList.toggle('lh-dark', prefersDark);
40+
}`,
41+
};
42+
43+
const replacements = [forceThemeChecking, enableQuerystringThemeCheck];
44+
45+
const makeReplacements = (str) => {
46+
return replacements.reduce((acc, { source, replacement }) => {
47+
return acc.replace(source, replacement);
48+
}, str);
49+
};
50+
51+
module.exports = { makeReplacements };

src/replacements.test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
const { makeReplacements } = require('./replacements');
2+
3+
describe('replacements', () => {
4+
it('should make forceThemeChecking replacement', () => {
5+
const data = 'window.matchMedia("(prefers-color-scheme: dark)").matches';
6+
const result = 'window.matchMedia("(prefers-color-scheme)").matches';
7+
expect(makeReplacements(data)).toEqual(result);
8+
});
9+
10+
it('should make enableQuerystringThemeCheck replacement', () => {
11+
const data = 'prepended;const n=e.rootEl;appended';
12+
expect(makeReplacements(data)).toContain('prepended;const n=e.rootEl;');
13+
expect(makeReplacements(data)).toContain(
14+
'URLSearchParams(window.location.search)',
15+
);
16+
expect(makeReplacements(data)).toContain('appended');
17+
});
18+
});

0 commit comments

Comments
 (0)