Skip to content

Commit

Permalink
patch not rendered elements
Browse files Browse the repository at this point in the history
  • Loading branch information
mbasso committed Apr 27, 2017
1 parent 088b475 commit 221c9f7
Show file tree
Hide file tree
Showing 15 changed files with 781 additions and 896 deletions.
Binary file modified compiled/asm-dom.bc
Binary file not shown.
Binary file modified compiled/asm-dom.o
Binary file not shown.
278 changes: 138 additions & 140 deletions compiled/asmjs/asm-dom.asm.js

Large diffs are not rendered by default.

1,267 changes: 577 additions & 690 deletions compiled/wasm/asm-dom.asm.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion compiled/wasm/asm-dom.js

Large diffs are not rendered by default.

Binary file modified compiled/wasm/asm-dom.wasm
Binary file not shown.
12 changes: 12 additions & 0 deletions src/cpp/H/h.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ std::size_t h_stdc(const std::string& sel, const std::string& text, const std::m
return reinterpret_cast<std::size_t>(adjustVNode(new VNode(sel, text, nodeProps, vnodes)));
};

std::size_t h_elm(const std::string& sel, const std::map<std::string, std::string>& nodeProps, const int elm) {
VNode* vnode = adjustVNode(new VNode(sel, nodeProps));
vnode->elm = elm;
return reinterpret_cast<std::size_t>(vnode);
};

void deleteVNode(VNode* const vnode) {
for (std::vector<VNode*>::size_type i = vnode->children.size(); i--;) {
deleteVNode(vnode->children[i]);
Expand All @@ -81,6 +87,10 @@ void deleteVNodePtr(const std::size_t& vnodePtr) {
deleteVNode(reinterpret_cast<VNode*>(vnodePtr));
};

int getNode(const std::size_t& vnodePtr) {
return reinterpret_cast<VNode*>(vnodePtr)->elm;
}

EMSCRIPTEN_BINDINGS(h_function) {
emscripten::function("_h_s", &h_s, emscripten::allow_raw_pointers());
emscripten::function("_h_ti", &h_ti, emscripten::allow_raw_pointers());
Expand All @@ -92,5 +102,7 @@ EMSCRIPTEN_BINDINGS(h_function) {
emscripten::function("_h_sdt", &h_sdt, emscripten::allow_raw_pointers());
emscripten::function("_h_sdc", &h_sdc, emscripten::allow_raw_pointers());
emscripten::function("_h_stdc", &h_stdc, emscripten::allow_raw_pointers());
emscripten::function("_h_elm", &h_elm, emscripten::allow_raw_pointers());
emscripten::function("_deleteVNode", &deleteVNodePtr, emscripten::allow_raw_pointer<emscripten::arg<0>>());
emscripten::function("_getNode", &getNode, emscripten::allow_raw_pointer<emscripten::arg<0>>());
}
2 changes: 2 additions & 0 deletions src/cpp/H/h.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ std::size_t h_sdc(const std::string& sel, const std::map<std::string, std::strin

std::size_t h_stdc(const std::string& sel, const std::string& text, const std::map<std::string, std::string>& nodeProps, const std::vector<std::size_t>& children);

std::size_t h_elm(const std::string& sel, const std::map<std::string, std::string>& nodeProps, const int elm);

void deleteVNode(VNode* const vnode);
void deleteVNodePtr(const std::size_t& vnode);

Expand Down
37 changes: 1 addition & 36 deletions src/cpp/Main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include "../H/h.hpp"
#include "../Diff/diff.hpp"
#include "../VNode/VNode.hpp"
#include <emscripten.h>
#include <emscripten/val.h>
#include <emscripten/bind.h>
#include <algorithm>
#include <vector>
Expand All @@ -20,36 +20,6 @@ bool sameVnode(const VNode* __restrict__ const vnode1, const VNode* __restrict__
return vnode1->key.compare(vnode2->key) == 0 && vnode1->sel.compare(vnode2->sel) == 0;
};

VNode* emptyNodeAt(const emscripten::val& elm) {
VNode* vnode = new VNode(elm["tagName"].as<std::string>());
std::string id = elm["id"].as<std::string>();

vnode->elm = EM_ASM_INT({
return window['asmDomHelpers']['domApi']['addNode'](
window['asmDom']['Pointer_stringify']($0)
);
}, id.c_str());
std::transform(vnode->sel.begin(), vnode->sel.end(), vnode->sel.begin(), ::tolower);

vnode->props.insert(
std::make_pair(
std::string("id"),
id
)
);

if (isDefined(elm["className"])) {
vnode->props.insert(
std::make_pair(
std::string("class"),
elm["className"].as<std::string>()
)
);
}

return vnode;
};

std::map<std::string, int>* createKeyToOldIdx(const std::vector<VNode*>& children, const int beginIdx, const int endIdx) {
std::size_t i = beginIdx;
std::map<std::string, int>* map = new std::map<std::string, int>();
Expand Down Expand Up @@ -280,11 +250,6 @@ std::size_t patch_vnodePtr(const std::size_t oldVnode, const std::size_t vnode)
return reinterpret_cast<std::size_t>(patch_vnode(reinterpret_cast<VNode*>(oldVnode), reinterpret_cast<VNode*>(vnode)));
};

std::size_t patch_elementPtr(const emscripten::val element, const std::size_t vnode) {
return reinterpret_cast<std::size_t>(patch_vnode(emptyNodeAt(element), reinterpret_cast<VNode*>(vnode)));
};

EMSCRIPTEN_BINDINGS(patch_function) {
emscripten::function("patchVNode", &patch_vnodePtr, emscripten::allow_raw_pointers());
emscripten::function("patchElement", &patch_elementPtr, emscripten::allow_raw_pointers());
}
1 change: 0 additions & 1 deletion src/cpp/Main/main.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include <vector>

std::size_t patch_vnodePtr(const std::size_t oldVnode, const std::size_t vnode);
std::size_t patch_elementPtr(const emscripten::val element, const std::size_t vnode);
void updateChildren(
emscripten::val parentElm,
std::vector<VNode*>& oldCh,
Expand Down
3 changes: 2 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import h from './js/h';
import patch from './js/patch';
import diff from './js/diff';
import domApi from './js/domApi';
import domApi, { nodes } from './js/domApi';

// import() is compiled to require.ensure, this is a polyfill for nodejs
// an alternative solution is needed
Expand Down Expand Up @@ -29,6 +29,7 @@ export default (config) => {

lib.h = h;
lib.patch = patch;
lib.getNode = vnode => nodes[lib._getNode(vnode)];
lib.deleteVNode = (oldVnode) => {
window.asmDomHelpers.vnodesData[oldVnode] = undefined;
lib._deleteVNode(oldVnode);
Expand Down
8 changes: 5 additions & 3 deletions src/js/domApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ const addPtr = (node, ns) => {
};

export default {
'addNode'(id) {
const node = document.getElementById(id);
'addNode'(node) {
nodes[++ptr] = addPtr(node.parentNode);
nodes[++ptr] = addPtr(node.nextSibling);
return (nodes[++ptr] = addPtr(node)) && ptr;
Expand Down Expand Up @@ -61,7 +60,10 @@ export default {
nodes[nodePtr].setAttribute(attr, value);
}
},
'parentNode': nodePtr => nodes[nodePtr].parentNode.asmDomPtr,
'parentNode': nodePtr => (
nodes[nodePtr] && nodes[nodePtr].parentNode && nodes[nodePtr].parentNode.asmDomPtr ||
0
),
'nextSibling': nodePtr => (
nodes[nodePtr] && nodes[nodePtr].nextSibling && nodes[nodePtr].nextSibling.asmDomPtr ||
0
Expand Down
25 changes: 13 additions & 12 deletions src/js/patch.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
export default (oldVnode, vnode, options) => {
let result;
if (typeof oldVnode === 'number') {
result = window.asmDom.patchVNode(oldVnode, vnode);
options = options || {};
if (options.clearMemory === undefined || options.clearMemory) {
setTimeout(() => {
window.asmDom.deleteVNode(oldVnode);
});
}
} else {
result = window.asmDom.patchElement(oldVnode, vnode);
export default (oldVnode, vnode) => {
if (typeof oldVnode !== 'number') {
const props = new window.asmDom.MapStringString();
if (oldVnode.id) props.set('id', oldVnode.id);
if (oldVnode.className) props.set('class', oldVnode.className);
oldVnode = window.asmDom._h_elm(
oldVnode.tagName.toLowerCase(),
props,
window.asmDomHelpers.domApi.addNode(oldVnode),
);
props.delete();
}
const result = window.asmDom.patchVNode(oldVnode, vnode);
setTimeout(window.asmDom.deleteVNode.bind(null, oldVnode));
return result;
};
17 changes: 17 additions & 0 deletions test/h.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ describe('h', function test() {
});
});

it('should get a vnode', () => {
const vnode = h('div');
expect(vdom.getNode(vnode)).toEqual(null);
vdom.deleteVNode(vnode);
});

it('should delete a vnode', () => {
const div = h('div', [
h('span'),
Expand All @@ -27,6 +33,17 @@ describe('h', function test() {
).toNotThrow();
});

it('should create vnode with tag, props and elm', () => {
expect(() => {
const props = new window.asmDom.MapStringString();
props.set('id', 'foo');
props.set('class', 'bar');
const vnode = vdom._h_elm('div', props, 1);
vdom.deleteVNode(vnode);
props.delete();
}).toNotThrow();
});

it('should create a vnode with proper tag', () => {
const vnodePtr = h('div');
vdom.deleteVNode(vnodePtr);
Expand Down
25 changes: 13 additions & 12 deletions test/patch.spec.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import expect from 'expect';
// import { knuthShuffle } from 'knuth-shuffle';
import { knuthShuffle } from 'knuth-shuffle';
import init from '../src/';

describe('patch', function testPatch() {
this.timeout(30000);

// const shuffle = knuthShuffle;
const shuffle = knuthShuffle;
let root;
let vdom;
let h;
let patch;
let getNode;

const spanNum = (n) => {
let result = n;
Expand Down Expand Up @@ -40,6 +41,7 @@ describe('patch', function testPatch() {
vdom = asmDom;
h = vdom.h;
patch = vdom.patch;
getNode = vdom.getNode;
done();
});
});
Expand Down Expand Up @@ -116,21 +118,22 @@ describe('patch', function testPatch() {
vdom.deleteVNode(elmPtr);
});

/*
it('is a patch of the root element', () => {
const elmWithIdAndClass = document.createElement('div');
elmWithIdAndClass.id = 'id';
elmWithIdAndClass.className = 'class';
const vnode = h('div#id.class', [h('span', 'Hi')]);
const vnode = h('div', {
id: 'id',
className: 'class',
}, [h('span', 'Hi')]);
patch(elmWithIdAndClass, vnode);
const elm = document.body.firstChild;
const elm = getNode(vnode);
expect(elm).toEqual(elmWithIdAndClass);
expect(elm.tagName).toEqual('DIV');
expect(elm.id).toEqual('id');
expect(elm.className).toEqual('class');
vdom.deleteVNode(vnode);
});
*/

it('should create comments', () => {
const vnode = h('!', 'test');
Expand Down Expand Up @@ -440,7 +443,6 @@ describe('patch', function testPatch() {
vdom.deleteVNode(vnode2);
});

/*
it('should handle random shuffles', () => {
let n;
let i;
Expand All @@ -454,21 +456,22 @@ describe('patch', function testPatch() {
for (n = 0; n < samples; ++n) {
const vnode1 = h('span', arr.map(z => spanNumWithOpacity(z, '1')));
const shufArr = shuffle(arr.slice(0));
const elm = document.createElement('div');
let elm = document.createElement('div');
patch(elm, vnode1);
elm = getNode(vnode1);
for (i = 0; i < elms; ++i) {
expect(elm.children[i].innerHTML, i.toString());
opacities[i] = Math.random().toFixed(5).toString();
}
const vnode2 = h('span', arr.map(z => spanNumWithOpacity(shufArr[z], opacities[z])));
patch(vnode1, vnode2);
elm = getNode(vnode2);
for (i = 0; i < elms; ++i) {
expect(elm.children[i].innerHTML, shufArr[i].toString());
expect(opacities[i].indexOf(elm.children[i].style.opacity), 0);
}
}
});
*/

it('should support null/undefined children', () => {
const vnode1 = h('i', [0, 1, 2, 3, 4, 5].map(spanNum));
Expand Down Expand Up @@ -496,7 +499,6 @@ describe('patch', function testPatch() {
vdom.deleteVNode(vnode3);
});

/*
it('should handle random shuffles with null/undefined children', () => {
let i;
let j;
Expand All @@ -521,10 +523,9 @@ describe('patch', function testPatch() {
patch(vnode1, vnode2);
const elm = document.body.firstChild;
expect(map(inner, elm.children), arr.filter(x => x !== null && x !== undefined));
vdom.deleteVNode(vnode2);
}
vdom.deleteVNode(vnode2);
});
*/

it('should append elements', () => {
const vnode1 = h('div', [h('span', 'Hello')]);
Expand Down

0 comments on commit 221c9f7

Please sign in to comment.