From 69890ebd8fd5e2afa512186036a2e32833bd8e38 Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 27 Oct 2017 10:43:44 +0200 Subject: [PATCH] prototype alternate datastructure for trees in listmap --- www/common/flat-dom.js | 79 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 www/common/flat-dom.js diff --git a/www/common/flat-dom.js b/www/common/flat-dom.js new file mode 100644 index 000000000..c6b2bc4d9 --- /dev/null +++ b/www/common/flat-dom.js @@ -0,0 +1,79 @@ +define([], function () { + var Flat = {}; + + var slice = function (coll) { + return Array.prototype.slice.call(coll); + }; + + var getAttrs = function (el) { + var i = 0; + var l = el.attributes.length; + var attr; + var data = {}; + for (;i < l;i++) { + attr = el.attributes[i]; + if (attr.name && attr.value) { data[attr.name] = attr.value; } + } + return data; + }; + + Flat.fromDOM = function (dom) { + var data = { + map: {}, + }; + + var i = 1; // start from 1 so we're always truthey + var uid = function () { return i++; }; + + var process = function (el) { + if (!el || el.attributes) { return void console.error(el); } + var id = uid(); + if (!el.tagName && el.nodeType === Node.TEXT_NODE) { + data.map[id] = el.textContent; + return id; + } + data.map[id] = [ + el.tagName, + getAttrs(el), + slice(el.childNodes).map(function (e) { + return process(e); + }) + ]; + return id; + }; + + data.root = process(dom); + return data; + }; + + Flat.toDOM = function (data) { + var visited = {}; + var process = function (key) { + if (visited[key]) { + // TODO handle this more gracefully. + throw new Error('duplicate id or loop detected'); + } + visited[key] = true; // mark paths as visited. + + var hj = data.map[key]; + if (typeof(hj) === 'string') { return document.createTextNode(hj); } + if (typeof(hj) === 'undefined') { return; } + if (!Array.isArray(hj)) { console.error(hj); throw new Error('expected array'); } + + var e = document.createElement(hj[0]); + for (var x in hj[1]) { e.setAttribute(x, hj[1][x]); } + var child; + for (var i = 0; i < hj[2].length; i++) { + child = process(hj[2][i]); + if (child) { + e.appendChild(child); + } + } + return e; + }; + + return process(data.root); + }; + + return Flat; +});