diff options
Diffstat (limited to 'node_modules/postcss-import/lib/parse-statements.js')
| -rw-r--r-- | node_modules/postcss-import/lib/parse-statements.js | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/node_modules/postcss-import/lib/parse-statements.js b/node_modules/postcss-import/lib/parse-statements.js new file mode 100644 index 0000000..0c94e5a --- /dev/null +++ b/node_modules/postcss-import/lib/parse-statements.js @@ -0,0 +1,172 @@ +"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: [], + layer: [], + }) + nodes = [] + } + statements.push(stmt) + } else nodes.push(node) + }) + + if (nodes.length) { + statements.push({ + type: "nodes", + nodes, + media: [], + layer: [], + }) + } + + return statements +} + +function parseMedia(result, atRule) { + const params = valueParser(atRule.params).nodes + return { + type: "media", + node: atRule, + media: split(params, 0), + layer: [], + } +} + +function parseCharset(result, atRule) { + if (atRule.prev()) { + return result.warn("@charset must precede all other statements", { + node: atRule, + }) + } + return { + type: "charset", + node: atRule, + media: [], + layer: [], + } +} + +function parseImport(result, atRule) { + let prev = atRule.prev() + if (prev) { + do { + if ( + prev.type !== "comment" && + (prev.type !== "atrule" || + (prev.name !== "import" && + prev.name !== "charset" && + !(prev.name === "layer" && !prev.nodes))) + ) { + return result.warn( + "@import must precede all other statements (besides @charset or empty @layer)", + { 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: [], + layer: [], + } + + // 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]) + + let remainder = params + if (remainder.length > 2) { + if ( + (remainder[2].type === "word" || remainder[2].type === "function") && + remainder[2].value === "layer" + ) { + if (remainder[1].type !== "space") { + return result.warn("Invalid import layer statement", { node: atRule }) + } + + if (remainder[2].nodes) { + stmt.layer = [stringify(remainder[2].nodes)] + } else { + stmt.layer = [""] + } + remainder = remainder.slice(2) + } + } + + if (remainder.length > 2) { + if (remainder[1].type !== "space") { + return result.warn("Invalid import media statement", { node: atRule }) + } + + stmt.media = split(remainder, 2) + } + + return stmt +} |