all files / src/ parse-html.js

100% Statements 44/44
100% Branches 14/14
100% Functions 2/2
100% Lines 42/42
27 statements, 1 function, 8 branches Ignored     
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                                                                   
'use strict'
var parser = window.DOMParser && new window.DOMParser()
var documentRootName = 'HTML'
var supportsHTMLType = false
var supportsInnerHTML = false
var htmlType = 'text/html'
var xhtmlType = 'application/xhtml+xml'
var testClass = 'A'
var testCode = '<wbr class="' + testClass + '"/>'
 
/* istanbul ignore next: Fails in older browsers */
try {
  // Check if browser supports text/html DOMParser
  var parsed = parser.parseFromString(testCode, htmlType).body.firstChild
  // Some browsers (iOS 9 and Safari 9) lowercase classes for parsed elements
  // but only when appending to DOM, so use innerHTML instead
  var d = document.createElement('div')
  d.appendChild(parsed)
  Iif (d.firstChild.classList[0] !== testClass) throw new Error('Parsed classes not preserved')
  supportsHTMLType = true
} catch (e) {
  var mockDoc = document.implementation.createHTMLDocument('')
  var mockHTML = mockDoc.documentElement
  var mockBody = mockDoc.body
  try {
    // Check if browser supports documentElement.innerHTML
    mockHTML.innerHTML += ''
    supportsInnerHTML = true
  } catch (e) {
    // Check if browser supports xhtml parsing.
    parser.parseFromString(testCode, xhtmlType)
    var bodyReg = /(<body[^>]*>)([\s\S]*)<\/body>/
  }
}
 
/**
 * Returns the results of a DOMParser as an HTMLElement.
 * (Shims for older browsers).
 */
module.exports = supportsHTMLType
  ? function parseHTML (markup, rootName) {
    var doc = parser.parseFromString(markup, htmlType)
    return rootName === documentRootName
      ? doc.documentElement
      : doc.body.firstChild
  }
  /* istanbul ignore next: Only used in older browsers */
  : function parseHTML (markup, rootName) {
    // Fallback to innerHTML for other older browsers.
    if (rootName === documentRootName) {
      if (supportsInnerHTML) {
        mockHTML.innerHTML = markup
        return mockHTML
      } else {
        // IE9 does not support innerhtml at root level.
        // We get around this by parsing everything except the body as xhtml.
        var bodyMatch = markup.match(bodyReg)
        if (bodyMatch) {
          var bodyContent = bodyMatch[2]
          var startBody = bodyMatch.index + bodyMatch[1].length
          var endBody = startBody + bodyContent.length
          markup = markup.slice(0, startBody) + markup.slice(endBody)
          mockBody.innerHTML = bodyContent
        }
 
        var doc = parser.parseFromString(markup, xhtmlType)
        var body = doc.body
        while (mockBody.firstChild) body.appendChild(mockBody.firstChild)
        return doc.documentElement
      }
    } else {
      mockBody.innerHTML = markup
      return mockBody.firstChild
    }
  }