/**
* Some fields may have values outside normal dates, handle them here.
- * @param {Date} date
+ * @param {Date|Number} date
* @param {String} otherwise
*/
const dateOrNot = (date, otherwise) => {
* @returns {String}
*/
function renderNavLink(nav) {
- return `<a href="${nav.href}"${nav.class ? (' class="' + nav.class + '"') : ''}>${nav.text}</a>`;
+ const aClass = nav.class ? ` class="${nav.class}"` : '';
+ return `<a href="${nav.href}"${aClass}>${nav.text}</a>`;
}
* @returns {String}
*/
function elementAttributes(attributes) {
- const attr = Object.entries(attributes).map(([name, value]) => `${name}="${value}"`).join(' ');
+ const attr = Object.entries(attributes).map(([name, value]) => {
+ const v = value ? `="${value}"` : '';
+ return `${name}${v}`;
+ }).join(' ');
return attr ? ' ' + attr : '';
}
}
+/**
+ * Wrap an array of items in a list container element.
+ * @param {String} element
+ * @param {Number} indent
+ * @param {Object} attributes
+ * @param {String[]} items
+ * @param {(item, index, array) => {Object}} itemAttributeGenerator
+ * @returns {String}
+ */
+function listContainer(element, indent, attributes, items, itemAttributeGenerator) {
+ const spacer = '\t'.repeat(indent);
+ return `${spacer}<${element}${elementAttributes(attributes)}>
+${items.map((item, index, array) => LI(item, indent + 1, itemAttributeGenerator(item, index, array))).join('\n')}
+${spacer}</${element}>`;
+}
+
+
/**
* Wrap a list of items in an unordered list.
* @param {String[]} items
* @param {Number} indent
* @param {Object} attributes
- * @param {(item) => Object} itemAttributeGenerator
+ * @param {(item, index, array) => Object} itemAttributeGenerator
* @returns {String}
*/
function UL(items, indent = 0, attributes = {}, itemAttributeGenerator = () => {}) {
- const spacer = '\t'.repeat(indent);
- return `${spacer}<ul${elementAttributes(attributes)}>
-${items.map((item) => LI(item, indent + 1, itemAttributeGenerator(item))).join('\n')}
-${spacer}</ul>`;
+ return listContainer('ul', indent, attributes, items, itemAttributeGenerator);
}
* @param {String[]} items
* @param {Number} indent
* @param {Object} attributes
- * @param {(item) => Object} itemAttributeGenerator
+ * @param {(item, index, array) => Object} itemAttributeGenerator
* @returns {String}
*/
function OL(items, indent = 0, attributes = {}, itemAttributeGenerator = () => {}) {
- const spacer = '\t'.repeat(indent);
- return `${spacer}<ol${elementAttributes(attributes)}>
-${items.map((item) => LI(item, indent + 1, itemAttributeGenerator(item))).join('\n')}
-${spacer}</ol>`;
+ return listContainer('ol', indent, attributes, items, itemAttributeGenerator);
}
indented,
renderNavLink,
LI,
+ listContainer,
UL,
OL,
htmlPage,
+ elementAttributes,
};
});
}); // renderNavLink
+ describe('elementAttributes', function () {
+ it('covers', function () {
+ const attributes = {
+ class: 'foo bar',
+ disabled: '',
+ };
+ const result = th.elementAttributes(attributes);
+ assert.strictEqual(result, ' class="foo bar" disabled');
+ });
+ }); // elementAttributes
+
describe('OL', function () {
it('covers', function () {
const result = th.OL(['item', 'another item'], 1, { class: 'class' }, (item) => ({ class: `${item}-class` }));
];
});
it('covers', async function () {
+ this.slow(1000); // First invocation of htmlLint takes some time.
const result = th.htmlPage(pagePathLevel, ctx, options, main);
await htmlLint(result);
assert(result);