Skip to content

Instantly share code, notes, and snippets.

@hraban
Last active October 7, 2019 14:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hraban/94ff19e5a7431c3f7599d039dc3ffdc8 to your computer and use it in GitHub Desktop.
Save hraban/94ff19e5a7431c3f7599d039dc3ffdc8 to your computer and use it in GitHub Desktop.
Lean XML DOM builder compatible with TypeScript's jsxFactory for Reactless .tsx files
/**
* Leanxml Runtime: lean TS jsxFactory runner for creating XML doms.
*
* N.B.: Doesn’t work on tagnames with uppercase first letter!
*/
const xmldom = require('xmldom');
function leanxml(tagname, attrs, ...children) {
return function leanxmlBuilder(doc) {
if (!doc) {
const impl = new xmldom.DOMImplementation();
doc = impl.createDocument();
}
const el = doc.createElement(tagname);
if (attrs) {
Object.entries(attrs).forEach(([name, value]) => {
el.setAttribute(name, value);
});
}
children.forEach(child => {
const node = typeof child === 'function' ? child(doc) : doc.createTextNode(child);
el.appendChild(node);
});
return el;
};
};
module.exports = leanxml;
/**
Copyright © 2019 Wonderbly <dev@wonderbly.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
// Compile with: tsc --jsx react --jsxFactory leanxml sample.tsx
import * as leanxml from './leanxml';
function hello() {
const name1 = 'Jim';
const name2 = 'Jom';
const size = 20;
const attrs = { size };
const dom =
<greet foo="bar" {...attrs}>
Hello <name>{name1}</name> & <name>{name2}</name> ({size})
</greet>;
return dom().toString();
}
console.log(hello());
// output: <greet foo="bar" size="20">Hello <name>Jim</name> &amp; <name>Jom</name> (20)</greet>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment