| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439 | 'use strict'let { isClean, my } = require('./symbols')let Declaration = require('./declaration')let Comment = require('./comment')let Node = require('./node')let parse, Rule, AtRule, Rootfunction cleanSource(nodes) {  return nodes.map(i => {    if (i.nodes) i.nodes = cleanSource(i.nodes)    delete i.source    return i  })}function markDirtyUp(node) {  node[isClean] = false  if (node.proxyOf.nodes) {    for (let i of node.proxyOf.nodes) {      markDirtyUp(i)    }  }}class Container extends Node {  push(child) {    child.parent = this    this.proxyOf.nodes.push(child)    return this  }  each(callback) {    if (!this.proxyOf.nodes) return undefined    let iterator = this.getIterator()    let index, result    while (this.indexes[iterator] < this.proxyOf.nodes.length) {      index = this.indexes[iterator]      result = callback(this.proxyOf.nodes[index], index)      if (result === false) break      this.indexes[iterator] += 1    }    delete this.indexes[iterator]    return result  }  walk(callback) {    return this.each((child, i) => {      let result      try {        result = callback(child, i)      } catch (e) {        throw child.addToError(e)      }      if (result !== false && child.walk) {        result = child.walk(callback)      }      return result    })  }  walkDecls(prop, callback) {    if (!callback) {      callback = prop      return this.walk((child, i) => {        if (child.type === 'decl') {          return callback(child, i)        }      })    }    if (prop instanceof RegExp) {      return this.walk((child, i) => {        if (child.type === 'decl' && prop.test(child.prop)) {          return callback(child, i)        }      })    }    return this.walk((child, i) => {      if (child.type === 'decl' && child.prop === prop) {        return callback(child, i)      }    })  }  walkRules(selector, callback) {    if (!callback) {      callback = selector      return this.walk((child, i) => {        if (child.type === 'rule') {          return callback(child, i)        }      })    }    if (selector instanceof RegExp) {      return this.walk((child, i) => {        if (child.type === 'rule' && selector.test(child.selector)) {          return callback(child, i)        }      })    }    return this.walk((child, i) => {      if (child.type === 'rule' && child.selector === selector) {        return callback(child, i)      }    })  }  walkAtRules(name, callback) {    if (!callback) {      callback = name      return this.walk((child, i) => {        if (child.type === 'atrule') {          return callback(child, i)        }      })    }    if (name instanceof RegExp) {      return this.walk((child, i) => {        if (child.type === 'atrule' && name.test(child.name)) {          return callback(child, i)        }      })    }    return this.walk((child, i) => {      if (child.type === 'atrule' && child.name === name) {        return callback(child, i)      }    })  }  walkComments(callback) {    return this.walk((child, i) => {      if (child.type === 'comment') {        return callback(child, i)      }    })  }  append(...children) {    for (let child of children) {      let nodes = this.normalize(child, this.last)      for (let node of nodes) this.proxyOf.nodes.push(node)    }    this.markDirty()    return this  }  prepend(...children) {    children = children.reverse()    for (let child of children) {      let nodes = this.normalize(child, this.first, 'prepend').reverse()      for (let node of nodes) this.proxyOf.nodes.unshift(node)      for (let id in this.indexes) {        this.indexes[id] = this.indexes[id] + nodes.length      }    }    this.markDirty()    return this  }  cleanRaws(keepBetween) {    super.cleanRaws(keepBetween)    if (this.nodes) {      for (let node of this.nodes) node.cleanRaws(keepBetween)    }  }  insertBefore(exist, add) {    let existIndex = this.index(exist)    let type = existIndex === 0 ? 'prepend' : false    let nodes = this.normalize(add, this.proxyOf.nodes[existIndex], type).reverse()    existIndex = this.index(exist)    for (let node of nodes) this.proxyOf.nodes.splice(existIndex, 0, node)    let index    for (let id in this.indexes) {      index = this.indexes[id]      if (existIndex <= index) {        this.indexes[id] = index + nodes.length      }    }    this.markDirty()    return this  }  insertAfter(exist, add) {    let existIndex = this.index(exist)    let nodes = this.normalize(add, this.proxyOf.nodes[existIndex]).reverse()    existIndex = this.index(exist)    for (let node of nodes) this.proxyOf.nodes.splice(existIndex + 1, 0, node)    let index    for (let id in this.indexes) {      index = this.indexes[id]      if (existIndex < index) {        this.indexes[id] = index + nodes.length      }    }    this.markDirty()    return this  }  removeChild(child) {    child = this.index(child)    this.proxyOf.nodes[child].parent = undefined    this.proxyOf.nodes.splice(child, 1)    let index    for (let id in this.indexes) {      index = this.indexes[id]      if (index >= child) {        this.indexes[id] = index - 1      }    }    this.markDirty()    return this  }  removeAll() {    for (let node of this.proxyOf.nodes) node.parent = undefined    this.proxyOf.nodes = []    this.markDirty()    return this  }  replaceValues(pattern, opts, callback) {    if (!callback) {      callback = opts      opts = {}    }    this.walkDecls(decl => {      if (opts.props && !opts.props.includes(decl.prop)) return      if (opts.fast && !decl.value.includes(opts.fast)) return      decl.value = decl.value.replace(pattern, callback)    })    this.markDirty()    return this  }  every(condition) {    return this.nodes.every(condition)  }  some(condition) {    return this.nodes.some(condition)  }  index(child) {    if (typeof child === 'number') return child    if (child.proxyOf) child = child.proxyOf    return this.proxyOf.nodes.indexOf(child)  }  get first() {    if (!this.proxyOf.nodes) return undefined    return this.proxyOf.nodes[0]  }  get last() {    if (!this.proxyOf.nodes) return undefined    return this.proxyOf.nodes[this.proxyOf.nodes.length - 1]  }  normalize(nodes, sample) {    if (typeof nodes === 'string') {      nodes = cleanSource(parse(nodes).nodes)    } else if (Array.isArray(nodes)) {      nodes = nodes.slice(0)      for (let i of nodes) {        if (i.parent) i.parent.removeChild(i, 'ignore')      }    } else if (nodes.type === 'root' && this.type !== 'document') {      nodes = nodes.nodes.slice(0)      for (let i of nodes) {        if (i.parent) i.parent.removeChild(i, 'ignore')      }    } else if (nodes.type) {      nodes = [nodes]    } else if (nodes.prop) {      if (typeof nodes.value === 'undefined') {        throw new Error('Value field is missed in node creation')      } else if (typeof nodes.value !== 'string') {        nodes.value = String(nodes.value)      }      nodes = [new Declaration(nodes)]    } else if (nodes.selector) {      nodes = [new Rule(nodes)]    } else if (nodes.name) {      nodes = [new AtRule(nodes)]    } else if (nodes.text) {      nodes = [new Comment(nodes)]    } else {      throw new Error('Unknown node type in node creation')    }    let processed = nodes.map(i => {      /* c8 ignore next */      if (!i[my]) Container.rebuild(i)      i = i.proxyOf      if (i.parent) i.parent.removeChild(i)      if (i[isClean]) markDirtyUp(i)      if (typeof i.raws.before === 'undefined') {        if (sample && typeof sample.raws.before !== 'undefined') {          i.raws.before = sample.raws.before.replace(/\S/g, '')        }      }      i.parent = this.proxyOf      return i    })    return processed  }  getProxyProcessor() {    return {      set(node, prop, value) {        if (node[prop] === value) return true        node[prop] = value        if (prop === 'name' || prop === 'params' || prop === 'selector') {          node.markDirty()        }        return true      },      get(node, prop) {        if (prop === 'proxyOf') {          return node        } else if (!node[prop]) {          return node[prop]        } else if (          prop === 'each' ||          (typeof prop === 'string' && prop.startsWith('walk'))        ) {          return (...args) => {            return node[prop](              ...args.map(i => {                if (typeof i === 'function') {                  return (child, index) => i(child.toProxy(), index)                } else {                  return i                }              })            )          }        } else if (prop === 'every' || prop === 'some') {          return cb => {            return node[prop]((child, ...other) =>              cb(child.toProxy(), ...other)            )          }        } else if (prop === 'root') {          return () => node.root().toProxy()        } else if (prop === 'nodes') {          return node.nodes.map(i => i.toProxy())        } else if (prop === 'first' || prop === 'last') {          return node[prop].toProxy()        } else {          return node[prop]        }      }    }  }  getIterator() {    if (!this.lastEach) this.lastEach = 0    if (!this.indexes) this.indexes = {}    this.lastEach += 1    let iterator = this.lastEach    this.indexes[iterator] = 0    return iterator  }}Container.registerParse = dependant => {  parse = dependant}Container.registerRule = dependant => {  Rule = dependant}Container.registerAtRule = dependant => {  AtRule = dependant}Container.registerRoot = dependant => {  Root = dependant}module.exports = ContainerContainer.default = Container/* c8 ignore start */Container.rebuild = node => {  if (node.type === 'atrule') {    Object.setPrototypeOf(node, AtRule.prototype)  } else if (node.type === 'rule') {    Object.setPrototypeOf(node, Rule.prototype)  } else if (node.type === 'decl') {    Object.setPrototypeOf(node, Declaration.prototype)  } else if (node.type === 'comment') {    Object.setPrototypeOf(node, Comment.prototype)  } else if (node.type === 'root') {    Object.setPrototypeOf(node, Root.prototype)  }  node[my] = true  if (node.nodes) {    node.nodes.forEach(child => {      Container.rebuild(child)    })  }}/* c8 ignore stop */
 |