CoolFace
Apppublic

AK-21/Graphite-Industrial-Intelligence

sourceHugging Faceupdated 3mo agoView on Hugging Face
0likes
container.js448 linesDownload Raw Back to lib
1'use strict'2 3let Comment = require('./comment')4let Declaration = require('./declaration')5let Node = require('./node')6let { isClean, my } = require('./symbols')7 8let AtRule, parse, Root, Rule9 10function cleanSource(nodes) {11  return nodes.map(i => {12    if (i.nodes) i.nodes = cleanSource(i.nodes)13    delete i.source14    return i15  })16}17 18function markTreeDirty(node) {19  node[isClean] = false20  if (node.proxyOf.nodes) {21    for (let i of node.proxyOf.nodes) {22      markTreeDirty(i)23    }24  }25}26 27class Container extends Node {28  get first() {29    if (!this.proxyOf.nodes) return undefined30    return this.proxyOf.nodes[0]31  }32 33  get last() {34    if (!this.proxyOf.nodes) return undefined35    return this.proxyOf.nodes[this.proxyOf.nodes.length - 1]36  }37 38  append(...children) {39    for (let child of children) {40      let nodes = this.normalize(child, this.last)41      for (let node of nodes) this.proxyOf.nodes.push(node)42    }43 44    this.markDirty()45 46    return this47  }48 49  cleanRaws(keepBetween) {50    super.cleanRaws(keepBetween)51    if (this.nodes) {52      for (let node of this.nodes) node.cleanRaws(keepBetween)53    }54  }55 56  each(callback) {57    if (!this.proxyOf.nodes) return undefined58    let iterator = this.getIterator()59 60    let index, result61    while (this.indexes[iterator] < this.proxyOf.nodes.length) {62      index = this.indexes[iterator]63      result = callback(this.proxyOf.nodes[index], index)64      if (result === false) break65 66      this.indexes[iterator] += 167    }68 69    delete this.indexes[iterator]70    return result71  }72 73  every(condition) {74    return this.nodes.every(condition)75  }76 77  getIterator() {78    if (!this.lastEach) this.lastEach = 079    if (!this.indexes) this.indexes = {}80 81    this.lastEach += 182    let iterator = this.lastEach83    this.indexes[iterator] = 084 85    return iterator86  }87 88  getProxyProcessor() {89    return {90      get(node, prop) {91        if (prop === 'proxyOf') {92          return node93        } else if (!node[prop]) {94          return node[prop]95        } else if (96          prop === 'each' ||97          (typeof prop === 'string' && prop.startsWith('walk'))98        ) {99          return (...args) => {100            return node[prop](101              ...args.map(i => {102                if (typeof i === 'function') {103                  return (child, index) => i(child.toProxy(), index)104                } else {105                  return i106                }107              })108            )109          }110        } else if (prop === 'every' || prop === 'some') {111          return cb => {112            return node[prop]((child, ...other) =>113              cb(child.toProxy(), ...other)114            )115          }116        } else if (prop === 'root') {117          return () => node.root().toProxy()118        } else if (prop === 'nodes') {119          return node.nodes.map(i => i.toProxy())120        } else if (prop === 'first' || prop === 'last') {121          return node[prop].toProxy()122        } else {123          return node[prop]124        }125      },126 127      set(node, prop, value) {128        if (node[prop] === value) return true129        node[prop] = value130        if (prop === 'name' || prop === 'params' || prop === 'selector') {131          node.markDirty()132        }133        return true134      }135    }136  }137 138  index(child) {139    if (typeof child === 'number') return child140    if (child.proxyOf) child = child.proxyOf141    return this.proxyOf.nodes.indexOf(child)142  }143 144  insertAfter(exist, add) {145    let existIndex = this.index(exist)146    let nodes = this.normalize(add, this.proxyOf.nodes[existIndex]).reverse()147    existIndex = this.index(exist)148    for (let node of nodes) this.proxyOf.nodes.splice(existIndex + 1, 0, node)149 150    let index151    for (let id in this.indexes) {152      index = this.indexes[id]153      if (existIndex < index) {154        this.indexes[id] = index + nodes.length155      }156    }157 158    this.markDirty()159 160    return this161  }162 163  insertBefore(exist, add) {164    let existIndex = this.index(exist)165    let type = existIndex === 0 ? 'prepend' : false166    let nodes = this.normalize(167      add,168      this.proxyOf.nodes[existIndex],169      type170    ).reverse()171    existIndex = this.index(exist)172    for (let node of nodes) this.proxyOf.nodes.splice(existIndex, 0, node)173 174    let index175    for (let id in this.indexes) {176      index = this.indexes[id]177      if (existIndex <= index) {178        this.indexes[id] = index + nodes.length179      }180    }181 182    this.markDirty()183 184    return this185  }186 187  normalize(nodes, sample) {188    if (typeof nodes === 'string') {189      nodes = cleanSource(parse(nodes).nodes)190    } else if (typeof nodes === 'undefined') {191      nodes = []192    } else if (Array.isArray(nodes)) {193      nodes = nodes.slice(0)194      for (let i of nodes) {195        if (i.parent) i.parent.removeChild(i, 'ignore')196      }197    } else if (nodes.type === 'root' && this.type !== 'document') {198      nodes = nodes.nodes.slice(0)199      for (let i of nodes) {200        if (i.parent) i.parent.removeChild(i, 'ignore')201      }202    } else if (nodes.type) {203      nodes = [nodes]204    } else if (nodes.prop) {205      if (typeof nodes.value === 'undefined') {206        throw new Error('Value field is missed in node creation')207      } else if (typeof nodes.value !== 'string') {208        nodes.value = String(nodes.value)209      }210      nodes = [new Declaration(nodes)]211    } else if (nodes.selector || nodes.selectors) {212      nodes = [new Rule(nodes)]213    } else if (nodes.name) {214      nodes = [new AtRule(nodes)]215    } else if (nodes.text) {216      nodes = [new Comment(nodes)]217    } else {218      throw new Error('Unknown node type in node creation')219    }220 221    let processed = nodes.map(i => {222      /* c8 ignore next */223      if (!i[my]) Container.rebuild(i)224      i = i.proxyOf225      if (i.parent) i.parent.removeChild(i)226      if (i[isClean]) markTreeDirty(i)227 228      if (!i.raws) i.raws = {}229      if (typeof i.raws.before === 'undefined') {230        if (sample && typeof sample.raws.before !== 'undefined') {231          i.raws.before = sample.raws.before.replace(/\S/g, '')232        }233      }234      i.parent = this.proxyOf235      return i236    })237 238    return processed239  }240 241  prepend(...children) {242    children = children.reverse()243    for (let child of children) {244      let nodes = this.normalize(child, this.first, 'prepend').reverse()245      for (let node of nodes) this.proxyOf.nodes.unshift(node)246      for (let id in this.indexes) {247        this.indexes[id] = this.indexes[id] + nodes.length248      }249    }250 251    this.markDirty()252 253    return this254  }255 256  push(child) {257    child.parent = this258    this.proxyOf.nodes.push(child)259    return this260  }261 262  removeAll() {263    for (let node of this.proxyOf.nodes) node.parent = undefined264    this.proxyOf.nodes = []265 266    this.markDirty()267 268    return this269  }270 271  removeChild(child) {272    child = this.index(child)273    this.proxyOf.nodes[child].parent = undefined274    this.proxyOf.nodes.splice(child, 1)275 276    let index277    for (let id in this.indexes) {278      index = this.indexes[id]279      if (index >= child) {280        this.indexes[id] = index - 1281      }282    }283 284    this.markDirty()285 286    return this287  }288 289  replaceValues(pattern, opts, callback) {290    if (!callback) {291      callback = opts292      opts = {}293    }294 295    this.walkDecls(decl => {296      if (opts.props && !opts.props.includes(decl.prop)) return297      if (opts.fast && !decl.value.includes(opts.fast)) return298 299      decl.value = decl.value.replace(pattern, callback)300    })301 302    this.markDirty()303 304    return this305  }306 307  some(condition) {308    return this.nodes.some(condition)309  }310 311  walk(callback) {312    return this.each((child, i) => {313      let result314      try {315        result = callback(child, i)316      } catch (e) {317        throw child.addToError(e)318      }319      if (result !== false && child.walk) {320        result = child.walk(callback)321      }322 323      return result324    })325  }326 327  walkAtRules(name, callback) {328    if (!callback) {329      callback = name330      return this.walk((child, i) => {331        if (child.type === 'atrule') {332          return callback(child, i)333        }334      })335    }336    if (name instanceof RegExp) {337      return this.walk((child, i) => {338        if (child.type === 'atrule' && name.test(child.name)) {339          return callback(child, i)340        }341      })342    }343    return this.walk((child, i) => {344      if (child.type === 'atrule' && child.name === name) {345        return callback(child, i)346      }347    })348  }349 350  walkComments(callback) {351    return this.walk((child, i) => {352      if (child.type === 'comment') {353        return callback(child, i)354      }355    })356  }357 358  walkDecls(prop, callback) {359    if (!callback) {360      callback = prop361      return this.walk((child, i) => {362        if (child.type === 'decl') {363          return callback(child, i)364        }365      })366    }367    if (prop instanceof RegExp) {368      return this.walk((child, i) => {369        if (child.type === 'decl' && prop.test(child.prop)) {370          return callback(child, i)371        }372      })373    }374    return this.walk((child, i) => {375      if (child.type === 'decl' && child.prop === prop) {376        return callback(child, i)377      }378    })379  }380 381  walkRules(selector, callback) {382    if (!callback) {383      callback = selector384 385      return this.walk((child, i) => {386        if (child.type === 'rule') {387          return callback(child, i)388        }389      })390    }391    if (selector instanceof RegExp) {392      return this.walk((child, i) => {393        if (child.type === 'rule' && selector.test(child.selector)) {394          return callback(child, i)395        }396      })397    }398    return this.walk((child, i) => {399      if (child.type === 'rule' && child.selector === selector) {400        return callback(child, i)401      }402    })403  }404}405 406Container.registerParse = dependant => {407  parse = dependant408}409 410Container.registerRule = dependant => {411  Rule = dependant412}413 414Container.registerAtRule = dependant => {415  AtRule = dependant416}417 418Container.registerRoot = dependant => {419  Root = dependant420}421 422module.exports = Container423Container.default = Container424 425/* c8 ignore start */426Container.rebuild = node => {427  if (node.type === 'atrule') {428    Object.setPrototypeOf(node, AtRule.prototype)429  } else if (node.type === 'rule') {430    Object.setPrototypeOf(node, Rule.prototype)431  } else if (node.type === 'decl') {432    Object.setPrototypeOf(node, Declaration.prototype)433  } else if (node.type === 'comment') {434    Object.setPrototypeOf(node, Comment.prototype)435  } else if (node.type === 'root') {436    Object.setPrototypeOf(node, Root.prototype)437  }438 439  node[my] = true440 441  if (node.nodes) {442    node.nodes.forEach(child => {443      Container.rebuild(child)444    })445  }446}447/* c8 ignore stop */448