diff --git a/src/index.js b/src/index.js
index 03389bc..ae45075 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,4 +1,11 @@
+/* global document */
+
const puppeteer = require('puppeteer')
+const crypto = require('crypto')
+
+function hashString(str) {
+ return crypto.createHash('md5').update(str, 'utf8').digest('hex')
+}
function InvalidUrlError({url, statusCode, statusText}) {
this.name = 'InvalidUrlError'
@@ -44,7 +51,6 @@ module.exports = async (url, {waitUntil = 'networkidle0'} = {}) => {
// This is primarily for CSS-in-JS solutions
// See: https://developer.mozilla.org/en-US/docs/Web/API/CSSRule/cssText
const styleSheetsApiCss = await page.evaluate(() => {
- /* global document */
return [...document.styleSheets]
.filter(stylesheet => stylesheet.href === null)
.map(stylesheet =>
@@ -55,6 +61,33 @@ module.exports = async (url, {waitUntil = 'networkidle0'} = {}) => {
.join('\n')
})
+ // Get all inline styles: Another inline styled element Element with empty style attribute Another empty style attributeText
+ //
+ // CSSRule:
+ // [x-inline-style-237a7d] { color: red; }
+ // ^^^^^^
+ //
+ // The 6-digit hash is based on the actual CSS, so it's not
+ // necessarily unique!
+ const inlineCssRules = await page.evaluate(() => {
+ return [...document.querySelectorAll('[style]')]
+ .map(element => element.getAttribute('style'))
+ .filter(Boolean)
+ })
+ const inlineCss = inlineCssRules
+ .map(rule => {
+ const hash = hashString(rule).slice(-6)
+ return `[x-inline-style-${hash}] { ${rule} }`
+ })
+ .join('\n')
+
await browser.close()
// Turn the coverage Array into a single string of CSS
@@ -68,7 +101,7 @@ module.exports = async (url, {waitUntil = 'networkidle0'} = {}) => {
.map(({text}) => text)
.join('\n')
- const css = [styleSheetsApiCss, coverageCss]
+ const css = [styleSheetsApiCss, coverageCss, inlineCss]
.filter(Boolean)
.join('\n')
diff --git a/test/index.js b/test/index.js
index 1e0104c..8eb3619 100644
--- a/test/index.js
+++ b/test/index.js
@@ -83,10 +83,30 @@ test('it does not report the same CSS twice', async t => {
t.true(actual.includes('.fixture { color: red; }'))
t.true(actual.includes('.style-tag-fixture-js { color: yellow; }'))
t.true(actual.includes('.style-tag-fixture-html { color: green; }'))
+ t.true(actual.includes('border-style: solid'))
+ t.true(actual.includes('background-color: red'))
t.snapshot(actual)
})
+test('it finds inline styles - HTML', async t => {
+ server.get('/inline-style-html.html', serveStatic)
+ const actual = await extractCss(server.url + '/inline-style-html.html')
+
+ t.true(actual.includes('[x-inline-style-dfc776] { color: red; font-size: 12px; }'))
+ t.true(actual.includes('[x-inline-style-ea2739] { color: blue }'))
+ t.snapshot(actual)
+})
+
+test('it finds inline styles - JS', async t => {
+ server.get('/inline-style-js.html', serveStatic)
+ const actual = await extractCss(server.url + '/inline-style-js.html')
+
+ t.true(actual.includes('[x-inline-style-874435] { color: red; font-size: 12px; border-style: solid; }'))
+ t.true(actual.includes('[x-inline-style-ea1c8f] { border-color: blue; border-width: 1px; }'))
+ t.snapshot(actual)
+})
+
test('it rejects if the url has an HTTP error status', async t => {
server.get('/404-page', (req, res) => {
res.status(404).send()
diff --git a/test/inline-style-html.html b/test/inline-style-html.html
index 8aa1536..e8c892d 100644
--- a/test/inline-style-html.html
+++ b/test/inline-style-html.html
@@ -7,5 +7,8 @@
Inline style in HTML
+