peterbe/minimalcss

Minimalcss fails on CSS selectors with backslashes

Opened this issue · 0 comments

cappe commented

HTML classes may include colons, e.g. <h1 class="md:title">Title</h1>.

As per the CSS spec, a corresponding CSS selector would be: .md\:title { font-size: 32px; }. Note that the colon is escaped by the backslash (\).

I found out that the minimalcss fails if the CSS includes selectors with backslashes:

// style.css

.md\:title {
	font-size: 32px;
}

========

user@container:/app# minimalcss --nosandbox http://localhost:8000/ > critical.css

SyntaxError: Unexpected input
    at Object.error (/app/node_modules/css-tree/lib/parser/create.js:239:19)
    at Object.parse (/app/node_modules/css-tree/lib/parser/create.js:284:20)
    at Object.getParentSelectors (/app/minimalcss/src/utils.js:61:31)
    at List.<anonymous> (/app/minimalcss/src/run.js:576:43)
    at List.each (/app/node_modules/css-tree/lib/common/List.js:158:12)
    at Object.enter (/app/minimalcss/src/run.js:564:33)
    at Object.<anonymous> (/app/node_modules/css-tree/lib/walker/create.js:11:16)
    at List.walkNode (/app/node_modules/css-tree/lib/walker/create.js:161:19) {
  source: '.md\\', <= THIS LINE RIGHT HERE
  offset: 3,
  line: 1,
  column: 4,
  sourceFragment: [Function (anonymous)],
  parseError: { offset: 3, line: 1, column: 4 }
}

See the line source: '.md\\'

I double checked that the CSSTree can handle this case just fine so I dove into the source of minimalcss. I found the method in src/utils.js#reduceCSSSelector which seemed to cause the issue. I think I figured out a solution as well so happy to open up a PR.

Thanks for the great tool though. I was about to do it on my own but luckily stumbled upon this by googling around.