"use strict" // external tooling const valueParser = require("postcss-value-parser") // extended tooling const { stringify } = valueParser function split(params, start) { const list = [] const last = params.reduce((item, node, index) => { if (index < start) return "" if (node.type === "div" && node.value === ",") { list.push(item) return "" } return item + stringify(node) }, "") list.push(last) return list } module.exports = function (result, styles) { 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 (stmt) { if (nodes.length) { statements.push({ type: "nodes", nodes, media: [], }) nodes = [] } statements.push(stmt) } else nodes.push(node) }) if (nodes.length) { statements.push({ type: "nodes", nodes, media: [], }) } return statements } function parseMedia(result, atRule) { const params = valueParser(atRule.params).nodes return { type: "media", node: atRule, media: split(params, 0), } } function parseCharset(result, atRule) { if (atRule.prev()) { return result.warn("@charset must precede all other statements", { node: atRule, }) } return { type: "charset", node: atRule, media: [], } } function parseImport(result, atRule) { let prev = atRule.prev() if (prev) { do { if ( prev.type !== "comment" && (prev.type !== "atrule" || (prev.name !== "import" && prev.name !== "charset")) ) { return result.warn( "@import must precede all other statements (besides @charset)", { node: atRule } ) } prev = prev.prev() } while (prev) } if (atRule.nodes) { return result.warn( "It looks like you didn't end your @import statement correctly. " + "Child nodes are attached to it.", { node: atRule } ) } const params = valueParser(atRule.params).nodes const stmt = { type: "import", node: atRule, media: [], } // prettier-ignore if ( !params.length || ( params[0].type !== "string" || !params[0].value ) && ( params[0].type !== "function" || params[0].value !== "url" || !params[0].nodes.length || !params[0].nodes[0].value ) ) { return result.warn(`Unable to find uri in '${ atRule.toString() }'`, { node: atRule, }) } if (params[0].type === "string") stmt.uri = params[0].value else stmt.uri = params[0].nodes[0].value stmt.fullUri = stringify(params[0]) if (params.length > 2) { if (params[1].type !== "space") { return result.warn("Invalid import media statement", { node: atRule }) } stmt.media = split(params, 2) } return stmt }