mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
move demo/static/src/ts/core to src/
This commit is contained in:
Executable
+98
@@ -0,0 +1,98 @@
|
||||
var assert = require('assert');
|
||||
var snabbdom = require('../snabbdom');
|
||||
|
||||
var patch = snabbdom.init([]);
|
||||
var attachTo = require('../helpers/attachto').default;
|
||||
var h = require('../h').default;
|
||||
|
||||
describe('attachTo', function() {
|
||||
var elm, vnode0;
|
||||
beforeEach(function() {
|
||||
elm = document.createElement('div');
|
||||
vnode0 = elm;
|
||||
});
|
||||
it('adds element to target', function() {
|
||||
var vnode1 = h('div', [
|
||||
h('div#wrapper', [
|
||||
h('div', 'Some element'),
|
||||
attachTo(elm, h('div#attached', 'Test')),
|
||||
]),
|
||||
]);
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.equal(elm.children.length, 2);
|
||||
});
|
||||
it('updates element at target', function() {
|
||||
var vnode1 = h('div', [
|
||||
h('div#wrapper', [
|
||||
h('div', 'Some element'),
|
||||
attachTo(elm, h('div#attached', 'First text')),
|
||||
]),
|
||||
]);
|
||||
var vnode2 = h('div', [
|
||||
h('div#wrapper', [
|
||||
h('div', 'Some element'),
|
||||
attachTo(elm, h('div#attached', 'New text')),
|
||||
]),
|
||||
]);
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.equal(elm.children[0].innerHTML, 'First text');
|
||||
elm = patch(vnode1, vnode2).elm;
|
||||
assert.equal(elm.children[0].innerHTML, 'New text');
|
||||
});
|
||||
it('element can be inserted before modal', function() {
|
||||
var vnode1 = h('div', [
|
||||
h('div#wrapper', [
|
||||
h('div', 'Some element'),
|
||||
attachTo(elm, h('div#attached', 'Text')),
|
||||
]),
|
||||
]);
|
||||
var vnode2 = h('div', [
|
||||
h('div#wrapper', [
|
||||
h('div', 'Some element'),
|
||||
h('div', 'A new element'),
|
||||
attachTo(elm, h('div#attached', 'Text')),
|
||||
]),
|
||||
]);
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.equal(elm.children[0].innerHTML, 'Text');
|
||||
elm = patch(vnode1, vnode2).elm;
|
||||
assert.equal(elm.children[0].innerHTML, 'Text');
|
||||
});
|
||||
it('removes element at target', function() {
|
||||
var vnode1 = h('div', [
|
||||
h('div#wrapper', [
|
||||
h('div', 'Some element'),
|
||||
attachTo(elm, h('div#attached', 'First text')),
|
||||
]),
|
||||
]);
|
||||
var vnode2 = h('div', [
|
||||
h('div#wrapper', [
|
||||
h('div', 'Some element'),
|
||||
]),
|
||||
]);
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.equal(elm.children[0].innerHTML, 'First text');
|
||||
elm = patch(vnode1, vnode2).elm;
|
||||
assert.equal(elm.children.length, 1);
|
||||
});
|
||||
it('remove hook receives real element', function() {
|
||||
function rm(vnode, cb) {
|
||||
assert.equal(vnode.elm.tagName, 'DIV');
|
||||
assert.equal(vnode.elm.innerHTML, 'First text');
|
||||
cb();
|
||||
}
|
||||
var vnode1 = h('div', [
|
||||
h('div#wrapper', [
|
||||
h('div', 'Some element'),
|
||||
attachTo(elm, h('div#attached', {hook: {remove: rm}}, 'First text')),
|
||||
]),
|
||||
]);
|
||||
var vnode2 = h('div', [
|
||||
h('div#wrapper', [
|
||||
h('div', 'Some element'),
|
||||
]),
|
||||
]);
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
elm = patch(vnode1, vnode2).elm;
|
||||
});
|
||||
});
|
||||
Executable
+97
@@ -0,0 +1,97 @@
|
||||
var assert = require('assert');
|
||||
|
||||
var snabbdom = require('../snabbdom');
|
||||
var patch = snabbdom.init([
|
||||
require('../modules/attributes').default,
|
||||
]);
|
||||
var h = require('../h').default;
|
||||
|
||||
describe('attributes', function() {
|
||||
var elm, vnode0;
|
||||
beforeEach(function() {
|
||||
elm = document.createElement('div');
|
||||
vnode0 = elm;
|
||||
});
|
||||
it('have their provided values', function() {
|
||||
var vnode1 = h('div', {attrs: {href: '/foo', minlength: 1, selected: true, disabled: false}});
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.strictEqual(elm.getAttribute('href'), '/foo');
|
||||
assert.strictEqual(elm.getAttribute('minlength'), '1');
|
||||
assert.strictEqual(elm.hasAttribute('selected'), true);
|
||||
assert.strictEqual(elm.getAttribute('selected'), '');
|
||||
assert.strictEqual(elm.hasAttribute('disabled'), false);
|
||||
});
|
||||
it('can be memoized', function() {
|
||||
var cachedAttrs = {href: '/foo', minlength: 1, selected: true};
|
||||
var vnode1 = h('div', {attrs: cachedAttrs});
|
||||
var vnode2 = h('div', {attrs: cachedAttrs});
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.strictEqual(elm.getAttribute('href'), '/foo');
|
||||
assert.strictEqual(elm.getAttribute('minlength'), '1');
|
||||
assert.strictEqual(elm.getAttribute('selected'), '');
|
||||
elm = patch(vnode1, vnode2).elm;
|
||||
assert.strictEqual(elm.getAttribute('href'), '/foo');
|
||||
assert.strictEqual(elm.getAttribute('minlength'), '1');
|
||||
assert.strictEqual(elm.getAttribute('selected'), '');
|
||||
});
|
||||
it('are not omitted when falsy values are provided', function() {
|
||||
var vnode1 = h('div', {attrs: {href: null, minlength: 0, value: '', title:'undefined'}});
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.strictEqual(elm.getAttribute('href'), 'null');
|
||||
assert.strictEqual(elm.getAttribute('minlength'), '0');
|
||||
assert.strictEqual(elm.getAttribute('value'), '');
|
||||
assert.strictEqual(elm.getAttribute('title'), 'undefined');
|
||||
});
|
||||
it('are set correctly when namespaced', function() {
|
||||
var vnode1 = h('div', {attrs: {'xlink:href': '#foo'}});
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.strictEqual(elm.getAttributeNS('http://www.w3.org/1999/xlink', 'href'), '#foo');
|
||||
});
|
||||
it('should not touch class nor id fields', function() {
|
||||
elm = document.createElement('div');
|
||||
elm.id = 'myId';
|
||||
elm.className = 'myClass';
|
||||
vnode0 = elm;
|
||||
var vnode1 = h('div#myId.myClass', {attrs: {}}, ['Hello']);
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.strictEqual(elm.tagName, 'DIV');
|
||||
assert.strictEqual(elm.id, 'myId');
|
||||
assert.strictEqual(elm.className, 'myClass');
|
||||
assert.strictEqual(elm.textContent, 'Hello');
|
||||
});
|
||||
describe('boolean attribute', function() {
|
||||
it('is present and empty string if the value is truthy', function() {
|
||||
var vnode1 = h('div', {attrs: {required: true, readonly: 1, noresize: 'truthy'}});
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.strictEqual(elm.hasAttribute('required'), true);
|
||||
assert.strictEqual(elm.getAttribute('required'), '');
|
||||
assert.strictEqual(elm.hasAttribute('readonly'), true);
|
||||
assert.strictEqual(elm.getAttribute('readonly'), '1');
|
||||
assert.strictEqual(elm.hasAttribute('noresize'), true);
|
||||
assert.strictEqual(elm.getAttribute('noresize'), 'truthy');
|
||||
});
|
||||
it('is omitted if the value is false', function() {
|
||||
var vnode1 = h('div', {attrs: {required: false}});
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.strictEqual(elm.hasAttribute('required'), false);
|
||||
assert.strictEqual(elm.getAttribute('required'), null);
|
||||
});
|
||||
it('is not omitted if the value is falsy but casted to string', function() {
|
||||
var vnode1 = h('div', {attrs: {readonly: 0, noresize: null}});
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.strictEqual(elm.getAttribute('readonly'), '0');
|
||||
assert.strictEqual(elm.getAttribute('noresize'), 'null');
|
||||
});
|
||||
});
|
||||
describe('Object.prototype property', function() {
|
||||
it('is not considered as a boolean attribute and shouldn\'t be omitted', function() {
|
||||
var vnode1 = h('div', {attrs: {constructor: true}});
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.strictEqual(elm.hasAttribute('constructor'), true);
|
||||
assert.strictEqual(elm.getAttribute('constructor'), '');
|
||||
var vnode2 = h('div', {attrs: {constructor: false}});
|
||||
elm = patch(vnode0, vnode2).elm;
|
||||
assert.strictEqual(elm.hasAttribute('constructor'), false);
|
||||
});
|
||||
});
|
||||
});
|
||||
Executable
+1114
File diff suppressed because it is too large
Load Diff
Executable
+56
@@ -0,0 +1,56 @@
|
||||
var assert = require('assert');
|
||||
var fakeRaf = require('fake-raf');
|
||||
|
||||
var snabbdom = require('../snabbdom');
|
||||
fakeRaf.use();
|
||||
var patch = snabbdom.init([
|
||||
require('../modules/dataset').default,
|
||||
]);
|
||||
var h = require('../h').default;
|
||||
|
||||
describe('dataset', function() {
|
||||
var elm, vnode0;
|
||||
beforeEach(function() {
|
||||
elm = document.createElement('div');
|
||||
vnode0 = elm;
|
||||
});
|
||||
it('is set on initial element creation', function() {
|
||||
elm = patch(vnode0, h('div', {dataset: {foo: 'foo'}})).elm;
|
||||
assert.equal(elm.dataset.foo, 'foo');
|
||||
});
|
||||
it('updates dataset', function() {
|
||||
var vnode1 = h('i', {dataset: {foo: 'foo', bar: 'bar'}});
|
||||
var vnode2 = h('i', {dataset: {baz: 'baz'}});
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.equal(elm.dataset.foo, 'foo');
|
||||
assert.equal(elm.dataset.bar, 'bar');
|
||||
elm = patch(vnode1, vnode2).elm;
|
||||
assert.equal(elm.dataset.baz, 'baz');
|
||||
assert.equal(elm.dataset.foo, undefined);
|
||||
});
|
||||
it('can be memoized', function() {
|
||||
var cachedDataset = {foo: 'foo', bar: 'bar'};
|
||||
var vnode1 = h('i', {dataset: cachedDataset});
|
||||
var vnode2 = h('i', {dataset: cachedDataset});
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.equal(elm.dataset.foo, 'foo');
|
||||
assert.equal(elm.dataset.bar, 'bar');
|
||||
elm = patch(vnode1, vnode2).elm;
|
||||
assert.equal(elm.dataset.foo, 'foo');
|
||||
assert.equal(elm.dataset.bar, 'bar');
|
||||
});
|
||||
it('handles string conversions', function() {
|
||||
var vnode1 = h('i', {dataset: {empty: '', dash: '-', dashed:'foo-bar', camel: 'fooBar', integer:0, float:0.1}});
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
|
||||
assert.equal(elm.dataset.empty, '');
|
||||
assert.equal(elm.dataset.dash, '-');
|
||||
assert.equal(elm.dataset.dashed, 'foo-bar');
|
||||
assert.equal(elm.dataset.camel, 'fooBar');
|
||||
assert.equal(elm.dataset.integer, '0');
|
||||
assert.equal(elm.dataset.float, '0.1');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
fakeRaf.restore();
|
||||
Executable
+178
@@ -0,0 +1,178 @@
|
||||
var assert = require('assert');
|
||||
|
||||
var snabbdom = require('../snabbdom');
|
||||
var patch = snabbdom.init([
|
||||
require('../modules/eventlisteners.js').default,
|
||||
]);
|
||||
var h = require('../h').default;
|
||||
|
||||
describe('event listeners', function() {
|
||||
var elm, vnode0;
|
||||
beforeEach(function() {
|
||||
elm = document.createElement('div');
|
||||
vnode0 = elm;
|
||||
});
|
||||
it('attaches click event handler to element', function() {
|
||||
var result = [];
|
||||
function clicked(ev) { result.push(ev); }
|
||||
var vnode = h('div', {on: {click: clicked}}, [
|
||||
h('a', 'Click my parent'),
|
||||
]);
|
||||
elm = patch(vnode0, vnode).elm;
|
||||
elm.click();
|
||||
assert.equal(1, result.length);
|
||||
});
|
||||
it('does not attach new listener', function() {
|
||||
var result = [];
|
||||
//function clicked(ev) { result.push(ev); }
|
||||
var vnode1 = h('div', {on: {click: function(ev) { result.push(1); }}}, [
|
||||
h('a', 'Click my parent'),
|
||||
]);
|
||||
var vnode2 = h('div', {on: {click: function(ev) { result.push(2); }}}, [
|
||||
h('a', 'Click my parent'),
|
||||
]);
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
elm.click();
|
||||
elm = patch(vnode1, vnode2).elm;
|
||||
elm.click();
|
||||
assert.deepEqual(result, [1, 2]);
|
||||
});
|
||||
it('does calls handler for function in array', function() {
|
||||
var result = [];
|
||||
function clicked(ev) { result.push(ev); }
|
||||
var vnode = h('div', {on: {click: [clicked, 1]}}, [
|
||||
h('a', 'Click my parent'),
|
||||
]);
|
||||
elm = patch(vnode0, vnode).elm;
|
||||
elm.click();
|
||||
assert.deepEqual(result, [1]);
|
||||
});
|
||||
it('handles changed value in array', function() {
|
||||
var result = [];
|
||||
function clicked(ev) { result.push(ev); }
|
||||
var vnode1 = h('div', {on: {click: [clicked, 1]}}, [
|
||||
h('a', 'Click my parent'),
|
||||
]);
|
||||
var vnode2 = h('div', {on: {click: [clicked, 2]}}, [
|
||||
h('a', 'Click my parent'),
|
||||
]);
|
||||
var vnode3 = h('div', {on: {click: [clicked, 3]}}, [
|
||||
h('a', 'Click my parent'),
|
||||
]);
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
elm.click();
|
||||
elm = patch(vnode1, vnode2).elm;
|
||||
elm.click();
|
||||
elm = patch(vnode2, vnode3).elm;
|
||||
elm.click();
|
||||
assert.deepEqual(result, [1, 2, 3]);
|
||||
});
|
||||
it('handles changed several values in array', function() {
|
||||
var result = [];
|
||||
function clicked() { result.push([].slice.call(arguments, 0, arguments.length-2)); }
|
||||
var vnode1 = h('div', {on: {click: [clicked, 1, 2, 3]}}, [
|
||||
h('a', 'Click my parent'),
|
||||
]);
|
||||
var vnode2 = h('div', {on: {click: [clicked, 1, 2]}}, [
|
||||
h('a', 'Click my parent'),
|
||||
]);
|
||||
var vnode3 = h('div', {on: {click: [clicked, 2, 3]}}, [
|
||||
h('a', 'Click my parent'),
|
||||
]);
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
elm.click();
|
||||
elm = patch(vnode1, vnode2).elm;
|
||||
elm.click();
|
||||
elm = patch(vnode2, vnode3).elm;
|
||||
elm.click();
|
||||
assert.deepEqual(result, [[1, 2, 3], [1, 2], [2, 3]]);
|
||||
});
|
||||
it('detach attached click event handler to element', function() {
|
||||
var result = [];
|
||||
function clicked(ev) { result.push(ev); }
|
||||
var vnode1 = h('div', {on: {click: clicked}}, [
|
||||
h('a', 'Click my parent'),
|
||||
]);
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
elm.click();
|
||||
assert.equal(1, result.length);
|
||||
var vnode2 = h('div', {on: {}}, [
|
||||
h('a', 'Click my parent'),
|
||||
]);
|
||||
elm = patch(vnode1, vnode2).elm;
|
||||
elm.click();
|
||||
assert.equal(1, result.length);
|
||||
});
|
||||
it('multiple event handlers for same event on same element', function() {
|
||||
var called = 0;
|
||||
function clicked(ev, vnode) {
|
||||
++called;
|
||||
// Check that the first argument is an event
|
||||
assert.equal(true, 'target' in ev);
|
||||
// Check that the second argument was a vnode
|
||||
assert.equal(vnode.sel, 'div');
|
||||
}
|
||||
var vnode1 = h('div', {on: {click: [[clicked], [clicked], [clicked]]}}, [
|
||||
h('a', 'Click my parent'),
|
||||
]);
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
elm.click();
|
||||
assert.equal(3, called);
|
||||
var vnode2 = h('div', {on: {click: [[clicked], [clicked]]}}, [
|
||||
h('a', 'Click my parent'),
|
||||
]);
|
||||
elm = patch(vnode1, vnode2).elm;
|
||||
elm.click();
|
||||
assert.equal(5, called);
|
||||
});
|
||||
it('access to virtual node in event handler', function() {
|
||||
var result = [];
|
||||
function clicked(ev, vnode) { result.push(this); result.push(vnode); }
|
||||
var vnode1 = h('div', {on: {click: clicked }}, [
|
||||
h('a', 'Click my parent'),
|
||||
]);
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
elm.click();
|
||||
assert.equal(2, result.length);
|
||||
assert.equal(vnode1, result[0]);
|
||||
assert.equal(vnode1, result[1]);
|
||||
}),
|
||||
it('access to virtual node in event handler with argument', function() {
|
||||
var result = [];
|
||||
function clicked(arg, ev, vnode) { result.push(this); result.push(vnode); }
|
||||
var vnode1 = h('div', {on: {click: [clicked, 1] }}, [
|
||||
h('a', 'Click my parent'),
|
||||
]);
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
elm.click();
|
||||
assert.equal(2, result.length);
|
||||
assert.equal(vnode1, result[0]);
|
||||
assert.equal(vnode1, result[1]);
|
||||
}),
|
||||
it('access to virtual node in event handler with arguments', function() {
|
||||
var result = [];
|
||||
function clicked(arg1, arg2, ev, vnode) { result.push(this); result.push(vnode); }
|
||||
var vnode1 = h('div', {on: {click: [clicked, 1, "2"] }}, [
|
||||
h('a', 'Click my parent'),
|
||||
]);
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
elm.click();
|
||||
assert.equal(2, result.length);
|
||||
assert.equal(vnode1, result[0]);
|
||||
assert.equal(vnode1, result[1]);
|
||||
});
|
||||
it('shared handlers in parent and child nodes', function() {
|
||||
var result = [];
|
||||
var sharedHandlers = {
|
||||
click: function(ev) { result.push(ev); }
|
||||
};
|
||||
var vnode1 = h('div', {on: sharedHandlers}, [
|
||||
h('a', {on: sharedHandlers}, 'Click my parent'),
|
||||
]);
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
elm.click();
|
||||
assert.equal(1, result.length);
|
||||
elm.firstChild.click();
|
||||
assert.equal(3, result.length);
|
||||
});
|
||||
});
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
var assert = require('assert');
|
||||
|
||||
var snabbdom = require('../snabbdom');
|
||||
var h = require('../h').default;
|
||||
var patch = snabbdom.init([
|
||||
require('../modules/attributes').default
|
||||
]);
|
||||
|
||||
describe('svg', function () {
|
||||
var elm, vnode0;
|
||||
beforeEach(function() {
|
||||
elm = document.createElement('svg');
|
||||
vnode0 = elm;
|
||||
});
|
||||
|
||||
it('removes child svg elements', function(){
|
||||
var a = h('svg', {}, [
|
||||
h('g'),
|
||||
h('g')
|
||||
]);
|
||||
var b = h('svg', {}, [
|
||||
h('g')
|
||||
]);
|
||||
var result = patch(patch(vnode0, a), b).elm;
|
||||
assert.equal(result.childNodes.length, 1);
|
||||
});
|
||||
|
||||
it('adds correctly xlink namespaced attribute', function(){
|
||||
var xlinkNS = 'http://www.w3.org/1999/xlink';
|
||||
var testUrl = '/test';
|
||||
var a = h('svg', {}, [
|
||||
h('use', {
|
||||
attrs: { 'xlink:href': testUrl }
|
||||
}, [])
|
||||
]);
|
||||
|
||||
var result = patch(vnode0, a).elm;
|
||||
assert.equal(result.childNodes.length, 1);
|
||||
assert.equal(result.childNodes[0].getAttribute('xlink:href'), testUrl);
|
||||
assert.equal(result.childNodes[0].getAttributeNS(xlinkNS,'href'), testUrl);
|
||||
|
||||
});
|
||||
|
||||
it('adds correctly xml namespaced attribute', function(){
|
||||
var xmlNS = 'http://www.w3.org/XML/1998/namespace';
|
||||
var testAttrValue = 'und';
|
||||
var a = h('svg', { attrs: { 'xml:lang': testAttrValue } }, []);
|
||||
|
||||
var result = patch(vnode0, a).elm;
|
||||
assert.equal(result.getAttributeNS(xmlNS, 'lang'), testAttrValue);
|
||||
assert.equal(result.getAttribute('xml:lang'), testAttrValue);
|
||||
});
|
||||
})
|
||||
Executable
+151
@@ -0,0 +1,151 @@
|
||||
var assert = require('assert');
|
||||
var fakeRaf = require('fake-raf');
|
||||
|
||||
var snabbdom = require('../snabbdom');
|
||||
fakeRaf.use();
|
||||
var patch = snabbdom.init([
|
||||
require('../modules/style').default,
|
||||
]);
|
||||
var h = require('../h').default;
|
||||
var toVNode = require('../tovnode').default;
|
||||
|
||||
describe('style', function() {
|
||||
var elm, vnode0;
|
||||
beforeEach(function() {
|
||||
elm = document.createElement('div');
|
||||
vnode0 = elm;
|
||||
});
|
||||
it('is being styled', function() {
|
||||
elm = patch(vnode0, h('div', {style: {fontSize: '12px'}})).elm;
|
||||
assert.equal(elm.style.fontSize, '12px');
|
||||
});
|
||||
it('can be memoized', function() {
|
||||
var cachedStyles = {fontSize: '14px', display: 'inline'};
|
||||
var vnode1 = h('i', {style: cachedStyles});
|
||||
var vnode2 = h('i', {style: cachedStyles});
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.equal(elm.style.fontSize, '14px');
|
||||
assert.equal(elm.style.display, 'inline');
|
||||
elm = patch(vnode1, vnode2).elm;
|
||||
assert.equal(elm.style.fontSize, '14px');
|
||||
assert.equal(elm.style.display, 'inline');
|
||||
});
|
||||
it('updates styles', function() {
|
||||
var vnode1 = h('i', {style: {fontSize: '14px', display: 'inline'}});
|
||||
var vnode2 = h('i', {style: {fontSize: '12px', display: 'block'}});
|
||||
var vnode3 = h('i', {style: {fontSize: '10px', display: 'block'}});
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.equal(elm.style.fontSize, '14px');
|
||||
assert.equal(elm.style.display, 'inline');
|
||||
elm = patch(vnode1, vnode2).elm;
|
||||
assert.equal(elm.style.fontSize, '12px');
|
||||
assert.equal(elm.style.display, 'block');
|
||||
elm = patch(vnode2, vnode3).elm;
|
||||
assert.equal(elm.style.fontSize, '10px');
|
||||
assert.equal(elm.style.display, 'block');
|
||||
});
|
||||
it('explicialy removes styles', function() {
|
||||
var vnode1 = h('i', {style: {fontSize: '14px'}});
|
||||
var vnode2 = h('i', {style: {fontSize: ''}});
|
||||
var vnode3 = h('i', {style: {fontSize: '10px'}});
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.equal(elm.style.fontSize, '14px');
|
||||
patch(vnode1, vnode2);
|
||||
assert.equal(elm.style.fontSize, '');
|
||||
patch(vnode2, vnode3);
|
||||
assert.equal(elm.style.fontSize, '10px');
|
||||
});
|
||||
it('implicially removes styles from element', function() {
|
||||
var vnode1 = h('div', [h('i', {style: {fontSize: '14px'}})]);
|
||||
var vnode2 = h('div', [h('i')]);
|
||||
var vnode3 = h('div', [h('i', {style: {fontSize: '10px'}})]);
|
||||
patch(vnode0, vnode1);
|
||||
assert.equal(elm.firstChild.style.fontSize, '14px');
|
||||
patch(vnode1, vnode2);
|
||||
assert.equal(elm.firstChild.style.fontSize, '');
|
||||
patch(vnode2, vnode3);
|
||||
assert.equal(elm.firstChild.style.fontSize, '10px');
|
||||
});
|
||||
it('updates css variables', function() {
|
||||
var vnode1 = h('div', {style: {'--myVar': 1}});
|
||||
var vnode2 = h('div', {style: {'--myVar': 2}});
|
||||
var vnode3 = h('div', {style: {'--myVar': 3}});
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.equal(elm.style.getPropertyValue('--myVar'), 1);
|
||||
elm = patch(vnode1, vnode2).elm;
|
||||
assert.equal(elm.style.getPropertyValue('--myVar'), 2);
|
||||
elm = patch(vnode2, vnode3).elm;
|
||||
assert.equal(elm.style.getPropertyValue('--myVar'), 3);
|
||||
});
|
||||
it('explicialy removes css variables', function() {
|
||||
var vnode1 = h('i', {style: {'--myVar': 1}});
|
||||
var vnode2 = h('i', {style: {'--myVar': ''}});
|
||||
var vnode3 = h('i', {style: {'--myVar': 2}});
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.equal(elm.style.getPropertyValue('--myVar'), 1);
|
||||
patch(vnode1, vnode2);
|
||||
assert.equal(elm.style.getPropertyValue('--myVar'), '');
|
||||
patch(vnode2, vnode3);
|
||||
assert.equal(elm.style.getPropertyValue('--myVar'), 2);
|
||||
});
|
||||
it('implicially removes css variables from element', function() {
|
||||
var vnode1 = h('div', [h('i', {style: {'--myVar': 1}})]);
|
||||
var vnode2 = h('div', [h('i')]);
|
||||
var vnode3 = h('div', [h('i', {style: {'--myVar': 2}})]);
|
||||
patch(vnode0, vnode1);
|
||||
assert.equal(elm.firstChild.style.getPropertyValue('--myVar'), 1);
|
||||
patch(vnode1, vnode2);
|
||||
assert.equal(elm.firstChild.style.getPropertyValue('--myVar'), '');
|
||||
patch(vnode2, vnode3);
|
||||
assert.equal(elm.firstChild.style.getPropertyValue('--myVar'), 2);
|
||||
});
|
||||
it('updates delayed styles in next frame', function() {
|
||||
var patch = snabbdom.init([
|
||||
require('../modules/style').default,
|
||||
]);
|
||||
var vnode1 = h('i', {style: {fontSize: '14px', delayed: {fontSize: '16px'}}});
|
||||
var vnode2 = h('i', {style: {fontSize: '18px', delayed: {fontSize: '20px'}}});
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.equal(elm.style.fontSize, '14px');
|
||||
fakeRaf.step();
|
||||
fakeRaf.step();
|
||||
assert.equal(elm.style.fontSize, '16px');
|
||||
elm = patch(vnode1, vnode2).elm;
|
||||
assert.equal(elm.style.fontSize, '18px');
|
||||
fakeRaf.step();
|
||||
fakeRaf.step();
|
||||
assert.equal(elm.style.fontSize, '20px');
|
||||
});
|
||||
it('applies tranform as transition on remove', function(done) {
|
||||
var btn = h('button', { style: {
|
||||
transition: 'transform 0.5s',
|
||||
remove: { transform: 'translateY(100%)' }
|
||||
}}, ['A button']);
|
||||
var vnode1 = h('div.parent', {}, [btn]);
|
||||
var vnode2 = h('div.parent', {}, [null]);
|
||||
document.body.appendChild(vnode0);
|
||||
patch(vnode0, vnode1);
|
||||
patch(vnode1, vnode2);
|
||||
assert.strictEqual(document.querySelectorAll('button').length, 1);
|
||||
setTimeout(function () {
|
||||
assert.strictEqual(document.querySelectorAll('button').length, 0);
|
||||
done();
|
||||
}, 700);
|
||||
});
|
||||
describe('using toVNode()', function () {
|
||||
it('handles (ignoring) comment nodes', function() {
|
||||
var comment = document.createComment('yolo');
|
||||
var prevElm = document.createElement('div');
|
||||
prevElm.appendChild(comment);
|
||||
var nextVNode = h('div', [h('span', 'Hi')]);
|
||||
elm = patch(toVNode(prevElm), nextVNode).elm;
|
||||
assert.strictEqual(elm, prevElm);
|
||||
assert.equal(elm.tagName, 'DIV');
|
||||
assert.strictEqual(elm.childNodes.length, 1);
|
||||
assert.strictEqual(elm.childNodes[0].tagName, 'SPAN');
|
||||
assert.strictEqual(elm.childNodes[0].textContent, 'Hi');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
fakeRaf.restore();
|
||||
Executable
+232
@@ -0,0 +1,232 @@
|
||||
var assert = require('assert');
|
||||
|
||||
var snabbdom = require('../snabbdom');
|
||||
var patch = snabbdom.init([
|
||||
]);
|
||||
var h = require('../h').default;
|
||||
var thunk = require('../thunk').default;
|
||||
|
||||
describe('thunk', function() {
|
||||
var elm, vnode0;
|
||||
beforeEach(function() {
|
||||
elm = vnode0 = document.createElement('div');
|
||||
});
|
||||
it('returns vnode with data and render function', function() {
|
||||
function numberInSpan(n) {
|
||||
return h('span', 'Number is ' + n);
|
||||
}
|
||||
var vnode = thunk('span', 'num', numberInSpan, [22]);
|
||||
assert.deepEqual(vnode.sel, 'span');
|
||||
assert.deepEqual(vnode.data.key, 'num');
|
||||
assert.deepEqual(vnode.data.args, [22]);
|
||||
});
|
||||
it('calls render function once on data change', function() {
|
||||
var called = 0;
|
||||
function numberInSpan(n) {
|
||||
called++;
|
||||
return h('span', {key: 'num'}, 'Number is ' + n);
|
||||
}
|
||||
var vnode1 = h('div', [
|
||||
thunk('span', 'num', numberInSpan, [1])
|
||||
]);
|
||||
var vnode2 = h('div', [
|
||||
thunk('span', 'num', numberInSpan, [2])
|
||||
]);
|
||||
patch(vnode0, vnode1);
|
||||
assert.equal(called, 1);
|
||||
patch(vnode1, vnode2);
|
||||
assert.equal(called, 2);
|
||||
});
|
||||
it('does not call render function on data unchanged', function() {
|
||||
var called = 0;
|
||||
function numberInSpan(n) {
|
||||
called++;
|
||||
return h('span', {key: 'num'}, 'Number is ' + n);
|
||||
}
|
||||
var vnode1 = h('div', [
|
||||
thunk('span', 'num', numberInSpan, [1])
|
||||
]);
|
||||
var vnode2 = h('div', [
|
||||
thunk('span', 'num', numberInSpan, [1])
|
||||
]);
|
||||
patch(vnode0, vnode1);
|
||||
assert.equal(called, 1);
|
||||
patch(vnode1, vnode2);
|
||||
assert.equal(called, 1);
|
||||
});
|
||||
it('calls render function once on data-length change', function() {
|
||||
var called = 0;
|
||||
function numberInSpan(n) {
|
||||
called++;
|
||||
return h('span', {key: 'num'}, 'Number is ' + n);
|
||||
}
|
||||
var vnode1 = h('div', [
|
||||
thunk('span', 'num', numberInSpan, [1])
|
||||
]);
|
||||
var vnode2 = h('div', [
|
||||
thunk('span', 'num', numberInSpan, [1, 2])
|
||||
]);
|
||||
patch(vnode0, vnode1);
|
||||
assert.equal(called, 1);
|
||||
patch(vnode1, vnode2);
|
||||
assert.equal(called, 2);
|
||||
});
|
||||
it('calls render function once on function change', function() {
|
||||
var called = 0;
|
||||
function numberInSpan(n) {
|
||||
called++;
|
||||
return h('span', {key: 'num'}, 'Number is ' + n);
|
||||
}
|
||||
function numberInSpan2(n) {
|
||||
called++;
|
||||
return h('span', {key: 'num'}, 'Number really is ' + n);
|
||||
}
|
||||
var vnode1 = h('div', [
|
||||
thunk('span', 'num', numberInSpan, [1])
|
||||
]);
|
||||
var vnode2 = h('div', [
|
||||
thunk('span', 'num', numberInSpan2, [1])
|
||||
]);
|
||||
patch(vnode0, vnode1);
|
||||
assert.equal(called, 1);
|
||||
patch(vnode1, vnode2);
|
||||
assert.equal(called, 2);
|
||||
});
|
||||
it('renders correctly', function() {
|
||||
var called = 0;
|
||||
function numberInSpan(n) {
|
||||
called++;
|
||||
return h('span', {key: 'num'}, 'Number is ' + n);
|
||||
}
|
||||
var vnode1 = h('div', [
|
||||
thunk('span', 'num', numberInSpan, [1])
|
||||
]);
|
||||
var vnode2 = h('div', [
|
||||
thunk('span', 'num', numberInSpan, [1])
|
||||
]);
|
||||
var vnode3 = h('div', [
|
||||
thunk('span', 'num', numberInSpan, [2])
|
||||
]);
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.equal(elm.firstChild.tagName.toLowerCase(), 'span');
|
||||
assert.equal(elm.firstChild.innerHTML, 'Number is 1');
|
||||
elm = patch(vnode1, vnode2).elm;
|
||||
assert.equal(elm.firstChild.tagName.toLowerCase(), 'span');
|
||||
assert.equal(elm.firstChild.innerHTML, 'Number is 1');
|
||||
elm = patch(vnode2, vnode3).elm;
|
||||
assert.equal(elm.firstChild.tagName.toLowerCase(), 'span');
|
||||
assert.equal(elm.firstChild.innerHTML, 'Number is 2');
|
||||
assert.equal(called, 2);
|
||||
});
|
||||
it('supports leaving out the `key` argument', function() {
|
||||
function vnodeFn(s) {
|
||||
return h('span.number', 'Hello ' + s);
|
||||
}
|
||||
var vnode1 = thunk('span.number', vnodeFn, ['World!']);
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.equal(elm.innerText, 'Hello World!');
|
||||
});
|
||||
it('renders correctly when root', function() {
|
||||
var called = 0;
|
||||
function numberInSpan(n) {
|
||||
called++;
|
||||
return h('span', {key: 'num'}, 'Number is ' + n);
|
||||
}
|
||||
var vnode1 = thunk('span', 'num', numberInSpan, [1]);
|
||||
var vnode2 = thunk('span', 'num', numberInSpan, [1]);
|
||||
var vnode3 = thunk('span', 'num', numberInSpan, [2]);
|
||||
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.equal(elm.tagName.toLowerCase(), 'span');
|
||||
assert.equal(elm.innerHTML, 'Number is 1');
|
||||
|
||||
elm = patch(vnode1, vnode2).elm;
|
||||
assert.equal(elm.tagName.toLowerCase(), 'span');
|
||||
assert.equal(elm.innerHTML, 'Number is 1');
|
||||
|
||||
elm = patch(vnode2, vnode3).elm;
|
||||
assert.equal(elm.tagName.toLowerCase(), 'span');
|
||||
assert.equal(elm.innerHTML, 'Number is 2');
|
||||
assert.equal(called, 2);
|
||||
});
|
||||
it('can be replaced and removed', function() {
|
||||
function numberInSpan(n) {
|
||||
return h('span', {key: 'num'}, 'Number is ' + n);
|
||||
}
|
||||
function oddEven(n) {
|
||||
var prefix = (n % 2) === 0 ? 'Even' : 'Odd';
|
||||
return h('div', {key: oddEven}, prefix + ': ' + n);
|
||||
}
|
||||
var vnode1 = h('div', [thunk('span', 'num', numberInSpan, [1])]);
|
||||
var vnode2 = h('div', [thunk('div', 'oddEven', oddEven, [4])]);
|
||||
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.equal(elm.firstChild.tagName.toLowerCase(), 'span');
|
||||
assert.equal(elm.firstChild.innerHTML, 'Number is 1');
|
||||
|
||||
elm = patch(vnode1, vnode2).elm;
|
||||
assert.equal(elm.firstChild.tagName.toLowerCase(), 'div');
|
||||
assert.equal(elm.firstChild.innerHTML, 'Even: 4');
|
||||
});
|
||||
it('can be replaced and removed when root', function() {
|
||||
function numberInSpan(n) {
|
||||
return h('span', {key: 'num'}, 'Number is ' + n);
|
||||
}
|
||||
function oddEven(n) {
|
||||
var prefix = (n % 2) === 0 ? 'Even' : 'Odd';
|
||||
return h('div', {key: oddEven}, prefix + ': ' + n);
|
||||
}
|
||||
var vnode1 = thunk('span', 'num', numberInSpan, [1]);
|
||||
var vnode2 = thunk('div', 'oddEven', oddEven, [4]);
|
||||
|
||||
elm = patch(vnode0, vnode1).elm;
|
||||
assert.equal(elm.tagName.toLowerCase(), 'span');
|
||||
assert.equal(elm.innerHTML, 'Number is 1');
|
||||
|
||||
elm = patch(vnode1, vnode2).elm;
|
||||
assert.equal(elm.tagName.toLowerCase(), 'div');
|
||||
assert.equal(elm.innerHTML, 'Even: 4');
|
||||
});
|
||||
it('invokes destroy hook on thunks', function() {
|
||||
var called = 0;
|
||||
function destroyHook() {
|
||||
called++;
|
||||
}
|
||||
function numberInSpan(n) {
|
||||
return h('span', {key: 'num', hook: {destroy: destroyHook}}, 'Number is ' + n);
|
||||
}
|
||||
var vnode1 = h('div', [
|
||||
h('div', 'Foo'),
|
||||
thunk('span', 'num', numberInSpan, [1]),
|
||||
h('div', 'Foo')
|
||||
]);
|
||||
var vnode2 = h('div', [
|
||||
h('div', 'Foo'),
|
||||
h('div', 'Foo')
|
||||
]);
|
||||
patch(vnode0, vnode1);
|
||||
patch(vnode1, vnode2);
|
||||
assert.equal(called, 1);
|
||||
});
|
||||
it('invokes remove hook on thunks', function() {
|
||||
var called = 0;
|
||||
function hook() {
|
||||
called++;
|
||||
}
|
||||
function numberInSpan(n) {
|
||||
return h('span', {key: 'num', hook: {remove: hook}}, 'Number is ' + n);
|
||||
}
|
||||
var vnode1 = h('div', [
|
||||
h('div', 'Foo'),
|
||||
thunk('span', 'num', numberInSpan, [1]),
|
||||
h('div', 'Foo')
|
||||
]);
|
||||
var vnode2 = h('div', [
|
||||
h('div', 'Foo'),
|
||||
h('div', 'Foo')
|
||||
]);
|
||||
patch(vnode0, vnode1);
|
||||
patch(vnode1, vnode2);
|
||||
assert.equal(called, 1);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user