markup = function (tag, content = '', attributes = {}) {
  let contentType = getContentType(content)
  const { events, ...attrs } = attributes
  const field = document.createElement(tag)

  const appendContent = {
    string: content => {
      setElementContent(field,field.innerHTML + content)
    },
    object: config => {
      const { tag, content, ...data } = config
      return field.appendChild(markup(tag, content, data))
    },
    node: content => {
      return field.appendChild(content)
    },
    array: content => {
      for (let i = 0; i < content.length; i++) {
        contentType = getContentType(content[i])
        appendContent[contentType](content[i])
      }
    },
    function: content => {
      content = content()
      contentType = getContentType(content)
      appendContent[contentType](content)
    },
    undefined: () => {},
  }

  for (const attr in attrs) {
    if (attrs.hasOwnProperty(attr)) {
      const name = safeAttrName(attr)
      let attrVal = Array.isArray(attrs[attr]) ? unique(attrs[attr].join(' ').split(' ')).join(' ') : attrs[attr]
      //If the Sanitizer is disabled this will always return false
      if (isPotentiallyDangerousAttribute(name, attrVal)) {
        continue
      }
      if (typeof attrVal === 'boolean') {
        if (attrVal === true) {
          const val = name === 'contenteditable' ? true : name
          field.setAttribute(name, val)
        }
      } else {
        if (name === 'id' || name === 'name') {
          attrVal = sanitizeNamedAttribute(attrVal)
        }
        if (attrVal !== undefined) {
          field.setAttribute(name, attrVal)
        }
      }
    }
  }

  if (content) {
    appendContent[contentType](content)
  }

  bindEvents(field, events)

  return field
}
Generate markup wrapper where needed

@param  {string} tag Tag name
@param  {string|Array|object|Node|Function|null} content content to wrap
@param  {Object} attributes attributes to assign to element
@return {HTMLElement} DOM Element