All files / lib/filter convertUseToGroup.js

9.09% Statements 5/55
0% Branches 0/30
0% Functions 0/7
9.62% Lines 5/52

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 85 86 87 882x   2x   2x                                                                                                                                         2x                         2x  
const { SLICE } = require('../utils.js')
 
const symbolNodes = new Set([])
 
const transformUse = (document, Doc) => {
  SLICE.call(document.childNodes).forEach(node => {
    if (node.nodeName.toUpperCase() === 'USE') {
      const useID = node.getAttribute('xlink:href').replace('#', '')
      let symbolNode = Doc.getElementById(useID)
      symbolNodes.add(useID)
      if (symbolNode) {
        const group = Doc.createElement('g')
        const attributes = SLICE.call(node.attributes)
 
        if (attributes.length > 0) {
          let transform = ''
          let x = 0
          let y = 0
          if (node.hasAttributes('x')) x = node.getAttribute('x') || 0
          if (node.hasAttributes('y')) y = node.getAttribute('y') || 0
          if (node.hasAttributes('transform')) {
            transform = node.getAttribute('transform')
          }
 
          if (x != 0 && y != 0) transform += ` translate(${x}, ${y})`
 
          if (transform) {
            group.setAttribute(
              'transform',
              transform.replace(/(^\s+|\s+$)/g, '')
            )
          }
          node.removeAttribute('x')
          node.removeAttribute('y')
          node.removeAttribute('y')
          node.removeAttribute('xlink:href')
          node.removeAttribute('style')
 
          SLICE.call(node.attributes).map(({ nodeName, value }) => {
            group.setAttribute(nodeName, value)
          })
        }
 
        if (symbolNode.nodeName.toUpperCase() === 'SYMBOL') {
          const newSymbol = symbolNode.cloneNode(true)
          const symbolGroup = Doc.createElement('g')
          symbolNode.removeAttribute('transform')
          symbolNode.removeAttribute('viewBox')
          SLICE.call(symbolNode.attributes).map(({ nodeName, value }) => {
            symbolGroup.setAttribute(nodeName, value)
          })
 
          SLICE.call(newSymbol.childNodes).map(path => {
            symbolGroup.appendChild(path)
          })
          symbolNode = symbolGroup
        }
 
        group.appendChild(symbolNode.cloneNode(true))
 
        node.parentNode.replaceChild(group, node)
      }
    } else if (node.hasChildNodes()) {
      transformUse(node, Doc)
    }
  })
}
 
/**
 * convertUseToGroup 转换 use 标签为 g 标签 插件
 * 注意 symbol 标签 无 tranform 属性,含 viewBox 属性
 * @param {*} Doc
 */
const convertUseToGroup = Doc => {
  transformUse(Doc.documentElement, Doc)
 
  symbolNodes.forEach(id => {
    const node = Doc.getElementById(id)
    if (node.nodeName.toUpperCase() === 'SYMBOL') {
      node.parentNode.removeChild(node)
    } else if (node.parentNode.nodeName.toUpperCase() === 'DEFS') {
      node.parentNode.removeChild(node)
    }
  })
}
 
exports.fn = convertUseToGroup