all files / src/ create-element.js

100% Statements 30/30
100% Branches 16/16
100% Functions 1/1
100% Lines 24/24
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      20×   22×   31×       31× 20×   20×   18×           16× 16×           31×   20× 27× 22× 22×     20×      
 
const getSvgAttributeNamespace = require('./get-svg-attribute-namespace')
const isBooleanAttribute = require('./is-boolean-attribute')
const isSvgElement = require('./is-svg-element')
const document = require('global-undom')
 
const normalizeEvent = (ev) => 'on' + ev.slice(2, ev.length).toLowerCase()
 
const isEventHandler = (key) => key.slice(0, 2) === 'on'
 
const isString = (val) => typeof val === 'string'
 
const createElement = (transformAttrs, { node, children, attrs }) => {
  let el = isSvgElement(node)
    ? document.createElementNS('http://www.w3.org/2000/svg', node)
    : document.createElement(node)
 
  for (const nkey in attrs) {
    const [key, val] = transformAttrs(nkey, attrs[nkey])
 
    if (isEventHandler(key)) {
      // add event listeners to the node directly
      el[normalizeEvent(key)] = val
    } else if (isBooleanAttribute(key)) {
      // if it's a truthy boolean value, set the value to its own key.
      // If it's a falsy boolean value, ignore the attribute
      val !== false && el.setAttribute(key, key)
    } else {
      // otherwise just set the attribute on the element. Set the
      // namespace if it's an svg
      const ns = getSvgAttributeNamespace(key)
      ns
        ? el.setAttributeNS(ns, key, val)
        : el.setAttribute(key, val)
    }
  }
 
  if (children.length === 0) return el
 
  children.forEach(function (child) {
    if (!child) return
    if (isString(child)) child = document.createTextNode(child)
    el.appendChild(child)
  })
 
  return el
}
 
module.exports = createElement