| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 | const Promise = require('bluebird');const merge = require('merge-options');const FileRequest = require('./request');const RuleSet = require('./rules');const Sprite = require('./sprite');const SpriteSymbol = require('./symbol');const symbolFactory = require('./symbol-factory');const spriteFactory = require('./sprite-factory');const defaultConfig = {  rules: [    { test: /\.svg$/, value: 'sprite.svg' }  ],  symbolFactory,  spriteFactory};class Compiler {  static sortSymbols(symbols) {    symbols.sort((leftSymbol, rightSymbol) => {      const leftId = leftSymbol.id;      const rightId = rightSymbol.id;      if (leftId === rightId) {        return 0;      }      return leftId < rightId ? -1 : 1;    });    return symbols;  }  constructor(cfg = {}) {    const config = this.config = merge(defaultConfig, cfg);    this.rules = new RuleSet(config.rules);    this.symbols = [];  }  /**   * @param {string} content   * @param {string} path   * @param {string} [id]   * @return {Promise<SpriteSymbol>}   */  addSymbol({ path, content, id }) {    const symbols = this.symbols;    const factory = this.config.symbolFactory;    const request = new FileRequest(path);    const options = { id, request, content, factory };    return SpriteSymbol.create(options).then((newSymbol) => {      const existing = symbols.find(s => s.request.equals(request));      if (!existing) {        symbols.push(newSymbol);        Compiler.sortSymbols(symbols);        return newSymbol;      }      const existingIndex = existing ? symbols.indexOf(existing) : -1;      const allExceptCurrent = symbols        .filter(s => s.request.fileEquals(request) && !s.request.queryEquals(request))        .map(symbol => ({ symbol, index: symbols.indexOf(symbol) }));      symbols[existingIndex] = newSymbol;      Compiler.sortSymbols(symbols);      return Promise.map(allExceptCurrent, ({ symbol, index }) => {        const opts = { id: symbol.id, request: symbol.request, content, factory };        return SpriteSymbol.create(opts).then(created => symbols[index] = created);      }).then(() => newSymbol);    });  }  /**   * @return {Promise<Array<Sprite>>}   */  compile() {    const symbols = this.symbols;    const rules = this.rules.rules;    const factory = this.config.spriteFactory;    return Promise.map(rules, (rule) => {      const spriteSymbols = [];      const filename = rule.uri;      symbols.forEach((symbol) => {        const isMatch = rule.match(symbol.request.file);        if (isMatch) {          spriteSymbols.push(symbol);        }      });      return spriteSymbols.length > 0 ?        Sprite.create({ symbols: spriteSymbols, filename, factory }) :        null;    }).filter(result => result !== null);  }}module.exports = Compiler;module.exports.defaultConfig = defaultConfig;
 |