// @ts-check /** @typedef {import("../typings").HtmlTagObject} HtmlTagObject */ /** * @file * This file provides to helper to create html as a object representation as * those objects are easier to modify than pure string representations * * Usage: * ``` * const element = createHtmlTagObject('h1', {class: 'demo'}, 'Hello World'); * const html = htmlTagObjectToString(element); * console.log(html) // ->

Hello World

* ``` */ /** * All html tag elements which must not contain innerHTML * @see https://www.w3.org/TR/html5/syntax.html#void-elements */ const voidTags = ['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr']; /** * Turn a tag definition into a html string * @param {HtmlTagObject} tagDefinition * A tag element according to the htmlWebpackPlugin object notation * * @param xhtml {boolean} * Wether the generated html should add closing slashes to be xhtml compliant */ function htmlTagObjectToString (tagDefinition, xhtml) { const attributes = Object.keys(tagDefinition.attributes || {}) .filter(function (attributeName) { return tagDefinition.attributes[attributeName] !== false; }) .map(function (attributeName) { if (tagDefinition.attributes[attributeName] === true) { return xhtml ? attributeName + '="' + attributeName + '"' : attributeName; } return attributeName + '="' + tagDefinition.attributes[attributeName] + '"'; }); return '<' + [tagDefinition.tagName].concat(attributes).join(' ') + (tagDefinition.voidTag && xhtml ? '/' : '') + '>' + (tagDefinition.innerHTML || '') + (tagDefinition.voidTag ? '' : ''); } /** * Static helper to create a tag object to be get injected into the dom * * @param {string} tagName * the name of the tag e.g. 'div' * * @param {{[attributeName: string]: string|boolean}} [attributes] * tag attributes e.g. `{ 'class': 'example', disabled: true }` * * @param {string} [innerHTML] * * @returns {HtmlTagObject} */ function createHtmlTagObject (tagName, attributes, innerHTML) { return { tagName: tagName, voidTag: voidTags.indexOf(tagName) !== -1, attributes: attributes || {}, innerHTML: innerHTML }; } /** * The `HtmlTagArray Array with a custom `.toString()` method. * * This allows the following: * ``` * const tags = HtmlTagArray.from([tag1, tag2]); * const scriptTags = tags.filter((tag) => tag.tagName === 'script'); * const html = scriptTags.toString(); * ``` * * Or inside a string literal: * ``` * const tags = HtmlTagArray.from([tag1, tag2]); * const html = `${tags.filter((tag) => tag.tagName === 'script')}`; * ``` * */ class HtmlTagArray extends Array { toString () { return this.join(''); } } module.exports = { HtmlTagArray: HtmlTagArray, createHtmlTagObject: createHtmlTagObject, htmlTagObjectToString: htmlTagObjectToString };