import createElement from './createElement.js';
import insertBefore from './insertBefore.js';
import remove from './remove.js';
/**
* This method adds a listener callback for an Element that is triggered when a containing target matching the selector is fired. Sets event.delegateTarget to the element that matches to selector, while target remains as element that fired the event.
*
* @param {Element} element - An Element to add the event listener to
* @param {Element|NodeList|HTMLCollection|Array|Promise|string|Object} content - A Element, NodeList, HTMLCollection, Array, Promise, String of text or html, Object passed to dolla's createElement
* @param {boolean} [escape] - A Boolean directing method to escape or not escape content that is a string
* @param {*} [context] - The value to be passed as the this parameter if content is a method
* @param {string} [method="append"] - A String stating which method of Element instance to use to add content
* @returns {undefined}
*
* @example
* append(el, el2)
* append(el, [el2, el3, el4])
* append(el, el2.children)
* append(el, el2.childNodes)
* append(el, new Promise(resolve => {
* records.load().then(records => {
* resolve(records.map(record => {
* template(record)
* }))
* })
* }))
* append(el, {
* class: 'label',
* content: "Hello World"
* })
* append(el, "<span>Hello World</span>")
*/
export default function append(el, content, escape, context, method) {
if (!method) method = 'append'
if (Array.isArray(content) || content instanceof NodeList || content instanceof HTMLCollection) {
let contents = Array.from(content)
if (method == 'prepend') contents = contents.reverse()
contents.forEach(i => append(el, i, escape, context, method));
} else if (escape instanceof Element) {
let contents = Array.from(arguments).slice(1).filter(x => x instanceof Element);
if (method == 'prepend') contents = contents.reverse()
contents.forEach(i => append(el, i, undefined, context, method));
} else {
if (typeof escape != "boolean") {
context = escape;
escape = undefined;
}
if (content === null || content === undefined) {
// do nothing
} else if (content instanceof Promise || content.then) {
const holder = document.createElement('span');
el[method](holder);
return content.then(resolvedItem => {
if (holder.parentNode) {
append(holder, resolvedItem, escape, context);
insertBefore(holder, holder.childNodes)
remove(holder);
}
});
} else if (content instanceof Element || content instanceof Node) {
return el[method](content);
} else if (typeof content == "function") {
return append(el, content.bind(context)(el), escape, context);
} else if (typeof content == "object") {
return el[method](createElement(content, el.namespaceURI))
} else {
if (escape) {
return el[method](content);
} else {
const container = document.createElement('div');
container.innerHTML = content;
return el[method](...container.childNodes);
}
}
}
}