import collapseWhitespace from './collapse-whitespace'
import HTMLParser from './html-parser'
import {
isBlock, isVoid } from './utilities'
export default function RootNode (input, options) {
var root
if (typeof input === 'string') {
var doc = htmlParser().parseFromString(
'<x-turndown id="turndown-root">' + input + '</x-turndown>',
'text/html'
)
root = doc.getElementById('turndown-root')
} else {
root = input.cloneNode(true)
}
collapseWhitespace({
element: root,
isBlock: isBlock,
isVoid: isVoid,
isPre: options.preformattedCode ? isPreOrCode : null
})
return root
}
var _htmlParser
function htmlParser () {
_htmlParser = _htmlParser || new HTMLParser()
return _htmlParser
}
function isPreOrCode (node) {
return node.nodeName === 'PRE' || node.nodeName === 'CODE'
}
import {
isBlock, isVoid, hasVoid, isMeaningfulWhenBlank, hasMeaningfulWhenBlank } from './utilities'
export default function Node (node, options) {
node.isBlock = isBlock(node)
node.isCode = node.nodeName === 'CODE' || node.parentNode.isCode
node.isBlank = isBlank(node)
node.flankingWhitespace = flankingWhitespace(node, options)
return node
}
function isBlank (node) {
return (
!isVoid(node) &&
!isMeaningfulWhenBlank(node) &&
/^\s*$/i.test(node.textContent) &&
!hasVoid(node) &&
!hasMeaningfulWhenBlank(node)
)
}
function flankingWhitespace (node, options) {
if (node.isBlock || (options.preformattedCode && node.isCode)) {
return {
leading: '', trailing: '' }
}
var edges = edgeWhitespace(node.textContent)
if (edges.leadingAscii && isFlankedByWhitespace('left', node, options)) {
edges.leading = edges.leadingNonAscii
}
if (edges.trailingAscii && isFlankedByWhitespace('right', node, options)) {
edges.trailing = edges.trailingNonAscii
}
return {
leading: edges.leading, trailing: edges.trailing }
}
function edgeWhitespace (string) {
var m = string.match(/^(([ \t\r\n]*)(\s*))(?:(?=\S)[\s\S]*\S)?((\s*?)([ \t\r\n]*))$/)
return {
leading: m[1],
leadingAscii: m[2],
leadingNonAscii: m[3],
trailing: m[4],
trailingNonAscii: m[5],
trailingAscii: m[6]
}
}
function isFlankedByWhitespace (side, node, options) {
var sibling
var regExp
var isFlanked
if (side === 'left') {
sibling = node.previousSibling
regExp = / $/
} else {
sibling = node.nextSibling
regExp = /^ /
}
if (sibling) {
if (sibling.nodeType === 3) {
isFlanked = regExp.test(sibling.nodeValue)
} else if (options.preformattedCode && sibling.nodeName === 'CODE') {
isFlanked = false
} else if (sibling.nodeType === 1 && !isBlock(sibling)) {
isFlanked = regExp.test(sibling.textContent)
}
}
return isFlanked
}