CoolFace
Apppublic

AK-21/Graphite-Industrial-Intelligence

sourceHugging Faceupdated 3mo agoView on Hugging Face
0likes
selector.js151 linesDownload Raw Back to lib
1let { list } = require('postcss')2 3let Browsers = require('./browsers')4let OldSelector = require('./old-selector')5let Prefixer = require('./prefixer')6let utils = require('./utils')7 8class Selector extends Prefixer {9  constructor(name, prefixes, all) {10    super(name, prefixes, all)11    this.regexpCache = new Map()12  }13 14  /**15   * Clone and add prefixes for at-rule16   */17  add(rule, prefix) {18    let prefixeds = this.prefixeds(rule)19 20    if (this.already(rule, prefixeds, prefix)) {21      return22    }23 24    let cloned = this.clone(rule, { selector: prefixeds[this.name][prefix] })25    rule.parent.insertBefore(rule, cloned)26  }27 28  /**29   * Is rule already prefixed before30   */31  already(rule, prefixeds, prefix) {32    let index = rule.parent.index(rule) - 133 34    while (index >= 0) {35      let before = rule.parent.nodes[index]36 37      if (before.type !== 'rule') {38        return false39      }40 41      let some = false42      for (let key in prefixeds[this.name]) {43        let prefixed = prefixeds[this.name][key]44        if (before.selector === prefixed) {45          if (prefix === key) {46            return true47          } else {48            some = true49            break50          }51        }52      }53      if (!some) {54        return false55      }56 57      index -= 158    }59 60    return false61  }62 63  /**64   * Is rule selectors need to be prefixed65   */66  check(rule) {67    if (rule.selector.includes(this.name)) {68      return !!rule.selector.match(this.regexp())69    }70 71    return false72  }73 74  /**75   * Return function to fast find prefixed selector76   */77  old(prefix) {78    return new OldSelector(this, prefix)79  }80 81  /**82   * All possible prefixes83   */84  possible() {85    return Browsers.prefixes()86  }87 88  /**89   * Return prefixed version of selector90   */91  prefixed(prefix) {92    return this.name.replace(/^(\W*)/, `$1${prefix}`)93  }94 95  /**96   * Return all possible selector prefixes97   */98  prefixeds(rule) {99    if (rule._autoprefixerPrefixeds) {100      if (rule._autoprefixerPrefixeds[this.name]) {101        return rule._autoprefixerPrefixeds102      }103    } else {104      rule._autoprefixerPrefixeds = {}105    }106 107    let prefixeds = {}108    if (rule.selector.includes(',')) {109      let ruleParts = list.comma(rule.selector)110      let toProcess = ruleParts.filter(el => el.includes(this.name))111 112      for (let prefix of this.possible()) {113        prefixeds[prefix] = toProcess114          .map(el => this.replace(el, prefix))115          .join(', ')116      }117    } else {118      for (let prefix of this.possible()) {119        prefixeds[prefix] = this.replace(rule.selector, prefix)120      }121    }122 123    rule._autoprefixerPrefixeds[this.name] = prefixeds124    return rule._autoprefixerPrefixeds125  }126 127  /**128   * Lazy loadRegExp for name129   */130  regexp(prefix) {131    if (!this.regexpCache.has(prefix)) {132      let name = prefix ? this.prefixed(prefix) : this.name133      this.regexpCache.set(134        prefix,135        new RegExp(`(^|[^:"'=])${utils.escapeRegexp(name)}`, 'gi')136      )137    }138 139    return this.regexpCache.get(prefix)140  }141 142  /**143   * Replace selectors by prefixed one144   */145  replace(selector, prefix) {146    return selector.replace(this.regexp(), `$1${this.prefixed(prefix)}`)147  }148}149 150module.exports = Selector151