| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 | "use strict"// external toolingconst valueParser = require("postcss-value-parser")// extended toolingconst { stringify } = valueParserfunction 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}
 |