import createElement from './createElement.js';
/**
* Converts content of various types into an Array of DOM nodes.
*
* @param {Element|NodeList|HTMLCollection|Array|Promise|Function|Object|string} content - Content to convert
* @param {boolean} [escape] - When true, do not parse strings as HTML. If not a boolean, treated as context.
* @param {*} [context] - The value to be passed as `this` if content is a function
* @param {string} [namespace] - A namespace URI passed to createElement for object content
* @returns {Array} Array of DOM nodes
*
* @example
* toNodes(el)
* toNodes([el, el2, el3])
* toNodes(el.children)
* toNodes(el.childNodes)
* toNodes(new Promise(resolve => {
* records.load().then(records => {
* resolve(records.map(record => {
* template(record)
* }))
* })
* }))
* toNodes({
* class: 'label',
* content: "Hello World"
* })
* toNodes("<span>Hello World</span>")
* toNodes("<b>bold</b>", true)
* toNodes(() => "<span>test</span>")
*/
export default function toNodes(content, escape, context, namespace) {
if (typeof escape != "boolean") {
if (!namespace) namespace = context;
context = escape;
escape = undefined;
}
if (content === null || content === undefined) {
return []
} else if (Array.isArray(content) || content instanceof NodeList || content instanceof HTMLCollection) {
return Array.from(content).flatMap(i => toNodes(i, escape, context, namespace))
} else if (content instanceof Element || content instanceof Node) {
return [content]
} else if (content instanceof Promise || content.then) {
return [toNodes.fromPromise(content, escape, context, namespace)]
} else if (typeof content == "function") {
return toNodes(content.bind(context)(), escape, context, namespace)
} else if (typeof content == "object") {
const result = toNodes.fromObject(content, namespace)
return Array.isArray(result) ? result : [result]
} else if (!escape) {
return toNodes.fromHTML(content)
} else {
return [content]
}
}
toNodes.fromObject = function(obj, namespace) {
return createElement(obj, namespace)
}
toNodes.fromPromise = function(p, escape, context, namespace) {
const placeholder = document.createElement('span');
p.then(resolvedItem => {
if (placeholder.parentNode) {
const nodes = toNodes(resolvedItem, escape, context, namespace)
placeholder.replaceWith(...nodes)
}
});
return placeholder
}
toNodes.fromHTML = function(html) {
const container = document.createElement('template');
container.innerHTML = html;
return Array.from(container.content.childNodes)
}