enumset32-benchmarks
Version:
Benchmarks for enumset32 vs other set implementations
86 lines (85 loc) • 2.28 kB
JavaScript
/*!
* Copyright (c) 2019 Justin Johansson
*/
class NodeInfo {
constructor(name) {
this.name = name;
this.isIndented = false;
this.hasIndentedChildren = false;
}
}
const escapingEntities = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
function checkAttributeContent(content) {
content = content.toString();
return content.replace(/[&<>"']/g, (ch) => escapingEntities[ch]);
}
function checkTextContent(content) {
content = content.toString();
return content.replace(/[&<]/g, (ch) => escapingEntities[ch]);
}
export class XMLWriter {
constructor() {
this.stack = [];
this.sb = [];
this.openStartElement = false;
this.indentChars = ' ';
this.stack.push(new NodeInfo('#document'));
}
get result() {
return this.sb.join('');
}
startDocument() {
this.sb.push('<?xml version="1.0" encoding="UTF-8"?>');
return this;
}
endDocument() {
return this;
}
startElement(name) {
this._closeOpenStartElement();
const elem = new NodeInfo(name);
this._indent();
elem.isIndented = true;
this.stack[this.stack.length - 1].hasIndentedChildren = true;
this.stack.push(elem);
this.sb.push(`<${name}`);
this.openStartElement = true;
return this;
}
endElement() {
this._closeOpenStartElement();
const elem = this.stack.pop();
if (elem.isIndented && elem.hasIndentedChildren) {
this._indent();
}
this.sb.push(`</${elem.name}>`);
return this;
}
attribute(name, content) {
content = checkAttributeContent(content);
this.sb.push(` ${name}="${content}"`);
return this;
}
text(content) {
this._closeOpenStartElement();
content = checkTextContent(content);
this.sb.push(`${content}`);
return this;
}
_closeOpenStartElement() {
if (this.openStartElement) {
this.sb.push('>');
this.openStartElement = false;
}
}
_indent() {
const depth = this.stack.length - 1;
this.sb.push('\n' + this.indentChars.repeat(depth));
}
}