| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 | let Prefixer = require('./prefixer')let Browsers = require('./browsers')let utils = require('./utils')class Declaration extends Prefixer {  /**   * Always true, because we already get prefixer by property name   */  check(/* decl */) {    return true  }  /**   * Return prefixed version of property   */  prefixed(prop, prefix) {    return prefix + prop  }  /**   * Return unprefixed version of property   */  normalize(prop) {    return prop  }  /**   * Check `value`, that it contain other prefixes, rather than `prefix`   */  otherPrefixes(value, prefix) {    for (let other of Browsers.prefixes()) {      if (other === prefix) {        continue      }      if (value.includes(other)) {        return value.replace(/var\([^)]+\)/, '').includes(other)      }    }    return false  }  /**   * Set prefix to declaration   */  set(decl, prefix) {    decl.prop = this.prefixed(decl.prop, prefix)    return decl  }  /**   * Should we use visual cascade for prefixes   */  needCascade(decl) {    if (!decl._autoprefixerCascade) {      decl._autoprefixerCascade =        this.all.options.cascade !== false && decl.raw('before').includes('\n')    }    return decl._autoprefixerCascade  }  /**   * Return maximum length of possible prefixed property   */  maxPrefixed(prefixes, decl) {    if (decl._autoprefixerMax) {      return decl._autoprefixerMax    }    let max = 0    for (let prefix of prefixes) {      prefix = utils.removeNote(prefix)      if (prefix.length > max) {        max = prefix.length      }    }    decl._autoprefixerMax = max    return decl._autoprefixerMax  }  /**   * Calculate indentation to create visual cascade   */  calcBefore(prefixes, decl, prefix = '') {    let max = this.maxPrefixed(prefixes, decl)    let diff = max - utils.removeNote(prefix).length    let before = decl.raw('before')    if (diff > 0) {      before += Array(diff).fill(' ').join('')    }    return before  }  /**   * Remove visual cascade   */  restoreBefore(decl) {    let lines = decl.raw('before').split('\n')    let min = lines[lines.length - 1]    this.all.group(decl).up(prefixed => {      let array = prefixed.raw('before').split('\n')      let last = array[array.length - 1]      if (last.length < min.length) {        min = last      }    })    lines[lines.length - 1] = min    decl.raws.before = lines.join('\n')  }  /**   * Clone and insert new declaration   */  insert(decl, prefix, prefixes) {    let cloned = this.set(this.clone(decl), prefix)    if (!cloned) return undefined    let already = decl.parent.some(      i => i.prop === cloned.prop && i.value === cloned.value    )    if (already) {      return undefined    }    if (this.needCascade(decl)) {      cloned.raws.before = this.calcBefore(prefixes, decl, prefix)    }    return decl.parent.insertBefore(decl, cloned)  }  /**   * Did this declaration has this prefix above   */  isAlready(decl, prefixed) {    let already = this.all.group(decl).up(i => i.prop === prefixed)    if (!already) {      already = this.all.group(decl).down(i => i.prop === prefixed)    }    return already  }  /**   * Clone and add prefixes for declaration   */  add(decl, prefix, prefixes, result) {    let prefixed = this.prefixed(decl.prop, prefix)    if (      this.isAlready(decl, prefixed) ||      this.otherPrefixes(decl.value, prefix)    ) {      return undefined    }    return this.insert(decl, prefix, prefixes, result)  }  /**   * Add spaces for visual cascade   */  process(decl, result) {    if (!this.needCascade(decl)) {      super.process(decl, result)      return    }    let prefixes = super.process(decl, result)    if (!prefixes || !prefixes.length) {      return    }    this.restoreBefore(decl)    decl.raws.before = this.calcBefore(prefixes, decl)  }  /**   * Return list of prefixed properties to clean old prefixes   */  old(prop, prefix) {    return [this.prefixed(prop, prefix)]  }}module.exports = Declaration
 |