Skip to content

Commit

Permalink
extend and fix data url imports (#534)
Browse files Browse the repository at this point in the history
* extend and fix data url imports

* explain the purpose of the code and couple bits that belong together
  • Loading branch information
romainmenke committed Jul 22, 2023
1 parent 4dbc931 commit 81a7701
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 35 deletions.
1 change: 1 addition & 0 deletions index.js
Expand Up @@ -62,6 +62,7 @@ function AtImport(options) {
state,
[],
[],
"",
postcss
)

Expand Down
20 changes: 16 additions & 4 deletions lib/data-url.js
@@ -1,14 +1,26 @@
"use strict"

const dataURLRegexp = /^data:text\/css;base64,/i
const anyDataURLRegexp = /^data:text\/css(?:;(base64|plain))?,/i
const base64DataURLRegexp = /^data:text\/css;base64,/i
const plainDataURLRegexp = /^data:text\/css;plain,/i

function isValid(url) {
return dataURLRegexp.test(url)
return anyDataURLRegexp.test(url)
}

function contents(url) {
// "data:text/css;base64,".length === 21
return Buffer.from(url.slice(21), "base64").toString()
if (base64DataURLRegexp.test(url)) {
// "data:text/css;base64,".length === 21
return Buffer.from(url.slice(21), "base64").toString()
}

if (plainDataURLRegexp.test(url)) {
// "data:text/css;plain,".length === 20
return decodeURIComponent(url.slice(20))
}

// "data:text/css,".length === 14
return decodeURIComponent(url.slice(14))
}

module.exports = {
Expand Down
19 changes: 12 additions & 7 deletions lib/parse-statements.js
Expand Up @@ -20,16 +20,16 @@ function split(params, start) {
return list
}

module.exports = function parseStatements(result, styles) {
module.exports = function parseStatements(result, styles, from) {
const statements = []
let nodes = []

styles.each(node => {
let stmt
if (node.type === "atrule") {
if (node.name === "import") stmt = parseImport(result, node)
else if (node.name === "media") stmt = parseMedia(result, node)
else if (node.name === "charset") stmt = parseCharset(result, node)
if (node.name === "import") stmt = parseImport(result, node, from)
else if (node.name === "media") stmt = parseMedia(result, node, from)
else if (node.name === "charset") stmt = parseCharset(result, node, from)
}

if (stmt) {
Expand All @@ -39,6 +39,7 @@ module.exports = function parseStatements(result, styles) {
nodes,
media: [],
layer: [],
from,
})
nodes = []
}
Expand All @@ -52,23 +53,25 @@ module.exports = function parseStatements(result, styles) {
nodes,
media: [],
layer: [],
from,
})
}

return statements
}

function parseMedia(result, atRule) {
function parseMedia(result, atRule, from) {
const params = valueParser(atRule.params).nodes
return {
type: "media",
node: atRule,
media: split(params, 0),
layer: [],
from,
}
}

function parseCharset(result, atRule) {
function parseCharset(result, atRule, from) {
if (atRule.prev()) {
return result.warn("@charset must precede all other statements", {
node: atRule,
Expand All @@ -79,10 +82,11 @@ function parseCharset(result, atRule) {
node: atRule,
media: [],
layer: [],
from,
}
}

function parseImport(result, atRule) {
function parseImport(result, atRule, from) {
let prev = atRule.prev()
if (prev) {
do {
Expand Down Expand Up @@ -119,6 +123,7 @@ function parseImport(result, atRule) {
media: [],
layer: [],
supports: [],
from,
}

for (let i = 0; i < params.length; i++) {
Expand Down
19 changes: 17 additions & 2 deletions lib/parse-styles.js
Expand Up @@ -17,9 +17,10 @@ async function parseStyles(
state,
media,
layer,
from,
postcss
) {
const statements = parseStatements(result, styles)
const statements = parseStatements(result, styles, from)

for (const stmt of statements) {
stmt.media = joinMedia(media, stmt.media || [])
Expand Down Expand Up @@ -90,6 +91,11 @@ async function resolveImportId(result, stmt, options, state, postcss) {
postcss
)

return
} else if (dataURL.isValid(stmt.from)) {
// Data urls can't be used a base url to resolve imports.
// When the parent statement has a data url
// and the current statement doesn't have a data url we ignore the statement.
return
}

Expand Down Expand Up @@ -201,7 +207,16 @@ async function loadImportContent(
}

// recursion: import @import from imported file
return parseStyles(result, styles, options, state, media, layer, postcss)
return parseStyles(
result,
styles,
options,
state,
media,
layer,
filename,
postcss
)
}

module.exports = parseStyles
4 changes: 4 additions & 0 deletions test/fixtures/data-url.css
Expand Up @@ -4,3 +4,7 @@
/* Mixed imports: */
@import url(data:text/css;base64,QGltcG9ydCB1cmwoZm9vLmNzcyk7CgpwIHsKICBjb2xvcjogYmx1ZTsKfQo=);
@import url(data-url.css);

/* url encoded: */
@import url(data:text/css;plain,bar%20%7B%20color%3A%20green%20%7D);
@import url(data:text/css,bar%20%7B%20color%3A%20pink%20%7D);
26 changes: 4 additions & 22 deletions test/fixtures/data-url.expected.css
@@ -1,24 +1,6 @@
p { color: green; }
@import url(foo.css);p { color: green; }p { color: blue; }@media (min-width: 320px){@layer foo{
p { color: green; } } }@media (min-width: 320px){@layer foo{

p { color: blue; }

@media (min-width: 320px) {

@layer foo {
p { color: green; } } }

@media (min-width: 320px) {

@layer foo {

p { color: blue; } } }

/* Mixed imports: */

foo{}

p {
p { color: blue; } } }/* Mixed imports: */p {
color: blue;
}

p { color: pink; }
}p { color: pink; }/* url encoded: */bar { color: green }bar { color: pink }

0 comments on commit 81a7701

Please sign in to comment.