zhangjian
2023-08-07 6b009b0f6d3ef3aee97c362cebcd679d1b9088a3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
const merge = require('merge-options');
const processor = require('posthtml-svg-mode');
const extractNamespacesToRoot = require('./transformations/extract-namespaces-to-root');
const moveFromSymbolToRoot = require('./transformations/move-from-symbol-to-root');
const { svg, xlink } = require('../namespaces');
 
const defaultConfig = {
  attrs: {
    [svg.name]: svg.uri,
    [xlink.name]: xlink.uri
  },
  styles: `
    .sprite-symbol-usage {display: none;}
    .sprite-symbol-usage:target {display: inline;}
  `,
  usages: true,
  symbols: []
};
 
/**
 * TODO simplify
 * @param {Object} [config] {@see defaultConfig}
 * @return {Function} PostHTML plugin
 */
function createSprite(config = {}) {
  const cfg = merge(defaultConfig, config);
  const symbols = cfg.symbols;
  const trees = symbols.map(s => s.tree);
  let usages = [];
 
  if (cfg.usages) {
    usages = symbols.map((symbol) => {
      const { id, useId } = symbol;
      return {
        tag: 'use',
        attrs: {
          id: useId,
          'xlink:href': `#${id}`,
          class: 'sprite-symbol-usage'
        }
      };
    });
  }
 
  let defsContent = [];
 
  if (cfg.styles !== false) {
    defsContent.push({
      tag: 'style',
      content: cfg.styles
    });
  }
 
  defsContent = defsContent.concat(trees);
 
  return (tree) => {
    tree[0] = {
      tag: 'svg',
      attrs: cfg.attrs,
      content: [{
        tag: 'defs',
        content: defsContent
      }].concat(usages)
    };
 
    return tree;
  };
}
 
/**
 * @param {Object} options {@see defaultConfig}
 * @return {Promise<PostHTMLProcessingResult>}
 */
function spriteFactory(options) {
  const plugins = [
    createSprite(options),
    extractNamespacesToRoot(),
    moveFromSymbolToRoot()
  ];
  return processor(plugins).process('');
}
 
module.exports = spriteFactory;
module.exports.createSprite = createSprite;