From 23c305f71fc7b8bca051307a7096a20847fa0497 Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 27 Oct 2017 10:37:44 +0200 Subject: [PATCH 1/3] implement removeItem so localForage doesn't complain --- www/common/sframe-boot2.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/www/common/sframe-boot2.js b/www/common/sframe-boot2.js index dd0370ca8..9b0f055b3 100644 --- a/www/common/sframe-boot2.js +++ b/www/common/sframe-boot2.js @@ -13,7 +13,8 @@ define(['/common/requireconfig.js'], function (RequireConfig) { var mkFakeStore = function () { var fakeStorage = { getItem: function (k) { return fakeStorage[k]; }, - setItem: function (k, v) { fakeStorage[k] = v; return v; } + setItem: function (k, v) { fakeStorage[k] = v; return v; }, + removeItem: function (k) { delete fakeStorage[k]; } }; return fakeStorage; }; From 69890ebd8fd5e2afa512186036a2e32833bd8e38 Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 27 Oct 2017 10:43:44 +0200 Subject: [PATCH 2/3] 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; +}); From df1a700cb20e560722d7c8f553ada73287857fc7 Mon Sep 17 00:00:00 2001 From: ansuz Date: Fri, 27 Oct 2017 11:01:22 +0200 Subject: [PATCH 3/3] disable thumbnail test. add test for flat dom --- www/assert/main.js | 16 +++++++++++++++- www/common/flat-dom.js | 10 +++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/www/assert/main.js b/www/assert/main.js index 0913674ae..ad7883de3 100644 --- a/www/assert/main.js +++ b/www/assert/main.js @@ -7,7 +7,8 @@ define([ '/drive/tests.js', '/common/test.js', '/common/common-thumbnail.js', -], function ($, Hyperjson, TextPatcher, Sortify, Cryptpad, Drive, Test, Thumb) { + '/common/flat-dom.js', +], function ($, Hyperjson, TextPatcher, Sortify, Cryptpad, Drive, Test, Thumb, Flat) { window.Hyperjson = Hyperjson; window.TextPatcher = TextPatcher; window.Sortify = Sortify; @@ -241,6 +242,7 @@ define([ return cb(true); }, "version 2 hash failed to parse correctly"); +/* assert(function (cb) { var getBlob = function (url, cb) { var xhr = new XMLHttpRequest(); @@ -266,9 +268,21 @@ define([ }); }); }); +*/ Drive.test(assert); + assert(function (cb) { + // extract dom elements into a flattened JSON representation + var flat = Flat.fromDOM(document.body); + // recreate a _mostly_ equivalent DOM + var dom = Flat.toDOM(flat); + // assume we don't care about comments + var bodyText = document.body.outerHTML.replace(//g, '') + // check for equality + cb(dom.outerHTML === bodyText); + }); + var swap = function (str, dict) { return str.replace(/\{\{(.*?)\}\}/g, function (all, key) { return typeof dict[key] !== 'undefined'? dict[key] : all; diff --git a/www/common/flat-dom.js b/www/common/flat-dom.js index c6b2bc4d9..51c3d07b3 100644 --- a/www/common/flat-dom.js +++ b/www/common/flat-dom.js @@ -17,6 +17,7 @@ define([], function () { return data; }; + var identity = function (x) { return x; }; Flat.fromDOM = function (dom) { var data = { map: {}, @@ -26,18 +27,20 @@ define([], function () { var uid = function () { return i++; }; var process = function (el) { - if (!el || el.attributes) { return void console.error(el); } - var id = uid(); + var id; if (!el.tagName && el.nodeType === Node.TEXT_NODE) { + id = uid(); data.map[id] = el.textContent; return id; } + if (!el || !el.attributes) { return void console.error(el); } + id = uid(); data.map[id] = [ el.tagName, getAttrs(el), slice(el.childNodes).map(function (e) { return process(e); - }) + }).filter(identity) ]; return id; }; @@ -49,6 +52,7 @@ define([], function () { Flat.toDOM = function (data) { var visited = {}; var process = function (key) { + if (!key) { return; } // ignore falsey keys if (visited[key]) { // TODO handle this more gracefully. throw new Error('duplicate id or loop detected');