Skip to content

Instantly share code, notes, and snippets.

@intrnl
Last active May 23, 2022 05:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save intrnl/4ff1c9e4edcf8226500696e76a5df01b to your computer and use it in GitHub Desktop.
Save intrnl/4ff1c9e4edcf8226500696e76a5df01b to your computer and use it in GitHub Desktop.
Velvet document object notation
let SVG_NS = 'http://www.w3.org/2000/svg';
let ELEMENT_BRANCH = 1;
let ELEMENT_CE_BRANCH = 2; // separate branch for `is`
let ELEMENT_PLACEHOLDER_BRANCH = 3; // creates `x` element
let ATTRIBUTE_LEAF = 4;
let ATTRIBUTE_BOOLEAN_LEAF = 5;
let TEXT_LEAF = 6;
let WHITESPACE_LEAF = 7; // the same as TEXT_NODE but only one space
let MARKER_LEAF = 8; // the same as TEXT_NODE but no content
function template (array) {
let fragment = document.createDocumentFragment();
let curr = fragment;
let length = array.length;
let idx = 0;
while (idx < length) {
let type = array[idx++];
switch (type) {
case ELEMENT_BRANCH: {
let tag = array[idx++];
let node = null;
if (tag === 'svg' || curr instanceof SVGElement) {
node = document.createElementNS(SVG_NS, tag);
}
else {
node = document.createElement(tag);
}
curr.appendChild(node);
curr = node;
break;
}
case ELEMENT_CE_BRANCH: {
let tag = array[idx++];
let is = array[idx++];
let node = document.createElement(tag, { is });
node.setAttribute('is', is);
curr.appendChild(node);
curr = node;
break;
}
case ELEMENT_PLACEHOLDER_BRANCH: {
let node = document.createElement('x');
curr.appendChild(node);
curr = node;
break;
}
case ATTRIBUTE_LEAF: {
let name = array[idx++];
let value = array[idx++];
curr.setAttribute(name, value);
break;
}
case ATTRIBUTE_BOOLEAN_LEAF: {
let name = array[idx++];
curr.toggleAttribute(name, true);
break;
}
case TEXT_LEAF: {
let text = array[idx++];
let node = document.createTextNode(text);
curr.appendChild(node);
break;
}
case WHITESPACE_LEAF: {
let node = document.createTextNode(' ');
curr.appendChild(node);
break;
}
case MARKER_LEAF: {
let node = document.createTextNode('');
curr.appendChild(node);
break;
}
default: {
// we're dealing with negative numbers, which means it's time to go up
while (type < 0) {
curr = curr.parentNode;
type++;
}
}
}
}
return curr;
}
template([
ELEMENT_BRANCH, 'section',
ATTRIBUTE_LEAF, 'class', 'main',
WHITESPACE_LEAF,
ELEMENT_BRANCH, 'input',
ATTRIBUTE_LEAF, 'id', 'toggle-all',
ATTRIBUTE_LEAF, 'class', 'toggle-all',
ATTRIBUTE_LEAF, 'type', 'checkbox',
-1,
WHITESPACE_LEAF,
ELEMENT_BRANCH, 'label',
ATTRIBUTE_LEAF, 'for', 'toggle-all',
TEXT_LEAF, 'Mark all as complete',
-1,
ELEMENT_BRANCH, 'ul',
ATTRIBUTE_LEAF, 'class', 'todo-list',
WHITESPACE_LEAF,
MARKER_LEAF,
WHITESPACE_LEAF,
-1,
ELEMENT_BRANCH, 'footer',
ATTRIBUTE_LEAF, 'class', 'footer',
ELEMENT_BRANCH, 'span',
ATTRIBUTE_LEAF, 'class', 'todo-count',
ELEMENT_BRANCH, 'strong',
MARKER_LEAF,
-1,
WHITESPACE_LEAF,
MARKER_LEAF,
TEXT_LEAF, ' left ',
-1,
ELEMENT_BRANCH, 'ul',
ATTRIBUTE_LEAF, 'class', 'filters',
ELEMENT_BRANCH, 'li',
ELEMENT_BRANCH, 'a',
ATTRIBUTE_LEAF, 'href', '#/',
TEXT_LEAF, 'All',
-2,
ELEMENT_BRANCH, 'li',
ELEMENT_BRANCH, 'a',
ATTRIBUTE_LEAF, 'href', '#/active',
TEXT_LEAF, 'Active',
-2,
ELEMENT_BRANCH, 'li',
ELEMENT_BRANCH, 'a',
ATTRIBUTE_LEAF, 'href', '#/completed',
TEXT_LEAF, 'Completed',
-5,
]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment