tsbase
Version:
Base class libraries for TypeScript
89 lines • 3.85 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.JsxRenderer = exports.Fragment = void 0;
exports.ParseJsx = ParseJsx;
const Guid_1 = require("../../System/Guid");
const Strings_1 = require("../../System/Strings");
const voidElementTagNames = ['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr'];
const isClassComponent = (nodeName) => !!nodeName['prototype'];
exports.Fragment = 'fragment';
function ParseJsx(nodeName, attributes, ...children) {
return { nodeName, attributes, children: [].concat(...children) };
}
class JsxRenderer {
constructor() { }
static RenderJsx(jsx, documentRef = globalThis.document || null, globalAttributes = {}) {
return JsxRenderer.transformJsxToHtml(jsx, documentRef, globalAttributes)
.replace(/<(f|.f)ragment>/g, Strings_1.Strings.Empty);
}
static addElementEventListener(attributeName, handler, element, documentRef) {
if (documentRef) {
const event = attributeName.split('on')[1];
let id;
if (element.includes(' id')) {
id = element.split(' id="')[1].split('"')[0];
}
else {
id = Guid_1.Guid.NewGuid();
element += ` id="${id}"`;
}
setTimeout(() => {
var _a;
try {
(_a = documentRef.querySelector(`[id="${id}"]`)) === null || _a === void 0 ? void 0 : _a.addEventListener(event, handler);
}
catch ( /* empty */_b) { /* empty */ }
});
}
return element;
}
// eslint-disable-next-line complexity
static transformJsxToHtml(jsx, documentRef, globalAttributes = {}) {
const attributes = { ...globalAttributes, ...jsx.attributes };
if (typeof jsx.nodeName === 'function') {
jsx = isClassComponent(jsx.nodeName) ?
new jsx.nodeName().render(attributes, jsx.children) :
jsx.nodeName({ ...globalAttributes, ...jsx.attributes }, jsx.children);
}
let element = `<${jsx.nodeName}`;
for (const key in jsx.attributes) {
const value = jsx.attributes[key];
if (key.startsWith('on')) {
element = this.addElementEventListener(key, value, element, documentRef);
}
else {
const shouldAddAttribute = value !== undefined && value !== null && !(typeof value === 'boolean' && value === false);
if (shouldAddAttribute) {
element += ` ${key}="${JsxRenderer.sanitize(value.toString(), true)}"`;
}
}
}
element += '>';
for (const child of jsx.children || []) {
if (typeof child === 'string' || typeof child === 'number') {
element += JsxRenderer.sanitize(child.toString());
}
else if (child) {
element += JsxRenderer.transformJsxToHtml(child, documentRef, globalAttributes);
}
}
return `${element}${typeof jsx.nodeName === 'string' && !voidElementTagNames.includes(jsx.nodeName) ?
`</${jsx.nodeName}>` : Strings_1.Strings.Empty}`;
}
static sanitize(value, allowAmpersand = false) {
const replacePatterns = [
[/&/g, '&'],
[/</g, '<'],
[/>/g, '>'],
[/"/g, '"'],
[/'/g, ''']
];
let sanitizedValue = value;
replacePatterns.slice(allowAmpersand ? 1 : 0).forEach((pattern) => {
sanitizedValue = sanitizedValue.replace(pattern[0], pattern[1]);
});
return sanitizedValue;
}
}
exports.JsxRenderer = JsxRenderer;
//# sourceMappingURL=Jsx.js.map