blob: c56e2b0091718c0907277162445f7c9ee7a4892d [file] [log] [blame]
class CommonComponentBase {
renderReplace(element, content) { CommonComponentBase.renderReplace(element, content); }
// FIXME: Deprecate these static functions.
static renderReplace(element, content)
{
element.textContent = '';
if (content)
ComponentBase._addContentToElement(element, content);
}
_recursivelyUpgradeUnknownElements(parent, findUpgrade, didConstructComponent = () => { })
{
let nextSibling;
for (let child of parent.childNodes) {
const componentClass = findUpgrade(child);
if (componentClass) {
const intance = this._upgradeUnknownElement(parent, child, componentClass);
didConstructComponent(intance);
}
if (child.childNodes)
this._recursivelyUpgradeUnknownElements(child, findUpgrade, didConstructComponent);
}
}
_upgradeUnknownElement(parent, unknownElement, componentClass)
{
const instance = new componentClass;
const newElement = instance.element();
for (let i = 0; i < unknownElement.attributes.length; i++) {
const attr = unknownElement.attributes[i];
newElement.setAttribute(attr.name, attr.value);
}
parent.replaceChild(newElement, unknownElement);
for (const child of Array.from(unknownElement.childNodes))
newElement.appendChild(child);
return instance;
}
static _constructStylesheetFromTemplate(styleTemplate, didCreateRule = (selector, rule) => selector)
{
let stylesheet = '';
for (const selector in styleTemplate) {
const rules = styleTemplate[selector];
let ruleText = '';
for (const property in rules) {
const value = rules[property];
ruleText += ` ${property}: ${value};\n`;
}
const modifiedSelector = didCreateRule(selector, ruleText);
stylesheet += modifiedSelector + ' {\n' + ruleText + '}\n\n';
}
return stylesheet;
}
static _constructNodeTreeFromTemplate(template, didCreateElement = (element) => { })
{
if (typeof(template) == 'string')
return [CommonComponentBase._context.createTextNode(template)];
console.assert(Array.isArray(template));
if (typeof(template[0]) == 'string') {
const tagName = template[0];
let attributes = {};
let content = null;
if (Array.isArray(template[1])) {
content = template[1];
} else {
attributes = template[1];
content = template[2];
}
const element = this.createElement(tagName, attributes);
didCreateElement(element);
const children = content && content.length ? this._constructNodeTreeFromTemplate(content, didCreateElement) : [];
for (const child of children)
element.appendChild(child);
return [element];
} else {
let result = [];
for (const item of template) {
if (typeof(item) == 'string')
result.push(CommonComponentBase._context.createTextNode(item));
else
result = result.concat(this._constructNodeTreeFromTemplate(item, didCreateElement));
}
return result;
}
}
createElement(name, attributes, content) { return CommonComponentBase.createElement(name, attributes, content); }
static createElement(name, attributes, content)
{
const element = CommonComponentBase._context.createElement(name);
if (!content && (Array.isArray(attributes) || CommonComponentBase._isNode(attributes)
|| attributes instanceof CommonComponentBase._baseClass || typeof(attributes) != 'object')) {
content = attributes;
attributes = {};
}
if (attributes) {
for (const name in attributes) {
if (name.startsWith('on'))
element.addEventListener(name.substring(2), attributes[name]);
else if (attributes[name] === true)
element.setAttribute(name, '');
else if (attributes[name] !== false)
element.setAttribute(name, attributes[name]);
}
}
if (content)
CommonComponentBase._addContentToElement(element, content);
return element;
}
static _addContentToElement(element, content)
{
if (Array.isArray(content)) {
for (var nestedChild of content)
this._addContentToElement(element, nestedChild);
} else if (CommonComponentBase._isNode(content))
element.appendChild(content);
else if (content instanceof CommonComponentBase._baseClass)
element.appendChild(content.element());
else
element.appendChild(CommonComponentBase._context.createTextNode(content));
}
createLink(content, titleOrCallback, callback, isExternal, tabIndex=null)
{
return CommonComponentBase.createLink(content, titleOrCallback, callback, isExternal, tabIndex);
}
static createLink(content, titleOrCallback, callback, isExternal, tabIndex=null)
{
var title = titleOrCallback;
if (callback === undefined) {
title = content;
callback = titleOrCallback;
}
var attributes = {
href: '#',
title: title,
};
if (tabIndex)
attributes['tabindex'] = tabIndex;
if (typeof(callback) === 'string')
attributes['href'] = callback;
else
attributes['onclick'] = CommonComponentBase._baseClass.createEventHandler(callback);
if (isExternal)
attributes['target'] = '_blank';
return CommonComponentBase.createElement('a', attributes, content);
}
};
CommonComponentBase._context = null;
CommonComponentBase._isNode = null;
CommonComponentBase._baseClass = null;
if (typeof module != 'undefined')
module.exports.CommonComponentBase = CommonComponentBase;