'use strict'; require('../util/polyfill.js'); const lodash = require('lodash'); const tags = require('../tags.js'); const events = require('../events.js'); const domParser = new DOMParser(); const misc = require('./misc.js'); function _imbueId(options) { if (!options.id) { options.id = 'gen-' + Math.random().toString(36).substring(7); } } function _makeLabel(options, attrs) { if (!options.text) { return ''; } if (!attrs) { attrs = {}; } attrs.for = options.id; return makeNonVoidElement('label', attrs, options.text); } function makeRelativeTime(time) { return makeNonVoidElement( 'time', {datetime: time, title: time}, misc.formatRelativeTime(time)); } function makeThumbnail(url) { return makeNonVoidElement( 'span', { class: 'thumbnail', style: `background-image: url(\'${url}\')`, }, makeVoidElement('img', {alt: 'thumbnail', src: url})); } function makeRadio(options) { _imbueId(options); return makeVoidElement( 'input', { id: options.id, name: options.name, value: options.value, type: 'radio', checked: options.selectedValue === options.value, required: options.required, }) + _makeLabel(options, {class: 'radio'}); } function makeCheckbox(options) { _imbueId(options); return makeVoidElement( 'input', { id: options.id, name: options.name, value: options.value, type: 'checkbox', checked: options.checked !== undefined ? options.checked : false, required: options.required, }) + _makeLabel(options, {class: 'checkbox'}); } function makeSelect(options) { return _makeLabel(options) + makeNonVoidElement( 'select', { id: options.id, name: options.name, disabled: options.readonly, }, Object.keys(options.keyValues).map(key => { return makeNonVoidElement( 'option', {value: key, selected: key === options.selectedKey}, options.keyValues[key]); }).join('')); } function makeInput(options) { return _makeLabel(options) + makeVoidElement( 'input', { type: options.inputType, name: options.name, id: options.id, value: options.value || '', required: options.required, pattern: options.pattern, placeholder: options.placeholder, readonly: options.readonly, }); } function makeTextInput(options) { options.inputType = 'text'; return makeInput(options); } function makePasswordInput(options) { options.inputType = 'password'; return makeInput(options); } function makeEmailInput(options) { options.inputType = 'email'; return makeInput(options); } function makeColorInput(options) { const textInput = makeVoidElement( 'input', { type: 'text', value: options.value || '', required: options.required, style: 'color: ' + options.value, disabled: true, }); const colorInput = makeVoidElement( 'input', { type: 'color', value: options.value || '', }); return makeNonVoidElement( 'label', {class: 'color'}, colorInput + textInput); } function makeTagLink(name) { let category = null; try { category = tags.getTagByName(name).category; } catch (e) { category = 'unknown'; } return makeNonVoidElement('a', { 'href': '/tag/' + name, 'class': 'tag-' + category, }, name); } function makeFlexboxAlign(options) { return Array.from(misc.range(20)) .map(() => '
').join(''); } function _serializeElement(name, attributes) { return [name] .concat(Object.keys(attributes).map(key => { if (attributes[key] === true) { return key; } else if (attributes[key] === false || attributes[key] === undefined) { return ''; } return `${key}="${attributes[key]}"`; })) .join(' '); } function makeNonVoidElement(name, attributes, content) { return `<${_serializeElement(name, attributes)}>${content}${name}>`; } function makeVoidElement(name, attributes) { return `<${_serializeElement(name, attributes)}/>`; } function _messageHandler(target, message, className) { if (!message) { message = 'Unknown message'; } const messagesHolder = target.querySelector('.messages'); if (!messagesHolder) { return false; } /* TODO: animate this */ const node = document.createElement('div'); node.innerHTML = message.replace(/\n/g, '