import { assert } from 'chai' import { init, styleModule, h, toVNode } from '../../src/index'; const patch = init([ styleModule ]) const featureDiscoveryElm = document.createElement('div') featureDiscoveryElm.style.setProperty('--foo', 'foo') const hasCssVariables = featureDiscoveryElm.style.getPropertyValue('--foo') === 'foo' describe('style', function () { let elm: any, vnode0: any beforeEach(function () { elm = document.createElement('div') vnode0 = elm }) it('is being styled', function () { elm = patch(vnode0, h('div', { style: { fontSize: '12px' } })).elm assert.strictEqual(elm.style.fontSize, '12px') }) it('can be memoized', function () { const cachedStyles = { fontSize: '14px', display: 'inline' } const vnode1 = h('i', { style: cachedStyles }) const vnode2 = h('i', { style: cachedStyles }) elm = patch(vnode0, vnode1).elm assert.strictEqual(elm.style.fontSize, '14px') assert.strictEqual(elm.style.display, 'inline') elm = patch(vnode1, vnode2).elm assert.strictEqual(elm.style.fontSize, '14px') assert.strictEqual(elm.style.display, 'inline') }) it('updates styles', function () { const vnode1 = h('i', { style: { fontSize: '14px', display: 'inline' } }) const vnode2 = h('i', { style: { fontSize: '12px', display: 'block' } }) const vnode3 = h('i', { style: { fontSize: '10px', display: 'block' } }) elm = patch(vnode0, vnode1).elm assert.strictEqual(elm.style.fontSize, '14px') assert.strictEqual(elm.style.display, 'inline') elm = patch(vnode1, vnode2).elm assert.strictEqual(elm.style.fontSize, '12px') assert.strictEqual(elm.style.display, 'block') elm = patch(vnode2, vnode3).elm assert.strictEqual(elm.style.fontSize, '10px') assert.strictEqual(elm.style.display, 'block') }) it('explicialy removes styles', function () { const vnode1 = h('i', { style: { fontSize: '14px' } }) const vnode2 = h('i', { style: { fontSize: '' } }) const vnode3 = h('i', { style: { fontSize: '10px' } }) elm = patch(vnode0, vnode1).elm assert.strictEqual(elm.style.fontSize, '14px') patch(vnode1, vnode2) assert.strictEqual(elm.style.fontSize, '') patch(vnode2, vnode3) assert.strictEqual(elm.style.fontSize, '10px') }) it('implicially removes styles from element', function () { const vnode1 = h('div', [h('i', { style: { fontSize: '14px' } })]) const vnode2 = h('div', [h('i')]) const vnode3 = h('div', [h('i', { style: { fontSize: '10px' } })]) patch(vnode0, vnode1) assert.strictEqual(elm.firstChild.style.fontSize, '14px') patch(vnode1, vnode2) assert.strictEqual(elm.firstChild.style.fontSize, '') patch(vnode2, vnode3) assert.strictEqual(elm.firstChild.style.fontSize, '10px') }) it('updates css variables', function () { if (!hasCssVariables) { this.skip() } else { const vnode1 = h('div', { style: { '--myVar': 1 as any } }) const vnode2 = h('div', { style: { '--myVar': 2 as any } }) const vnode3 = h('div', { style: { '--myVar': 3 as any } }) elm = patch(vnode0, vnode1).elm assert.strictEqual(elm.style.getPropertyValue('--myVar'), '1') elm = patch(vnode1, vnode2).elm assert.strictEqual(elm.style.getPropertyValue('--myVar'), '2') elm = patch(vnode2, vnode3).elm assert.strictEqual(elm.style.getPropertyValue('--myVar'), '3') } }) it('explicialy removes css variables', function () { if (!hasCssVariables) { this.skip() } else { const vnode1 = h('i', { style: { '--myVar': 1 as any } }) const vnode2 = h('i', { style: { '--myVar': '' } }) const vnode3 = h('i', { style: { '--myVar': 2 as any } }) elm = patch(vnode0, vnode1).elm assert.strictEqual(elm.style.getPropertyValue('--myVar'), '1') patch(vnode1, vnode2) assert.strictEqual(elm.style.getPropertyValue('--myVar'), '') patch(vnode2, vnode3) assert.strictEqual(elm.style.getPropertyValue('--myVar'), '2') } }) it('implicially removes css variables from element', function () { if (!hasCssVariables) { this.skip() } else { const vnode1 = h('div', [h('i', { style: { '--myVar': 1 as any } })]) const vnode2 = h('div', [h('i')]) const vnode3 = h('div', [h('i', { style: { '--myVar': 2 as any } })]) patch(vnode0, vnode1) assert.strictEqual(elm.firstChild.style.getPropertyValue('--myVar'), '1') patch(vnode1, vnode2) assert.strictEqual(elm.firstChild.style.getPropertyValue('--myVar'), '') patch(vnode2, vnode3) assert.strictEqual(elm.firstChild.style.getPropertyValue('--myVar'), '2') } }) it('updates delayed styles in next frame', function (done) { const vnode1 = h('i', { style: { fontSize: '14px', delayed: { fontSize: '16px' } as any } }) const vnode2 = h('i', { style: { fontSize: '18px', delayed: { fontSize: '20px' } as any } }) elm = patch(vnode0, vnode1).elm assert.strictEqual(elm.style.fontSize, '14px') requestAnimationFrame(() => { requestAnimationFrame(() => { assert.strictEqual(elm.style.fontSize, '16px') elm = patch(vnode1, vnode2).elm assert.strictEqual(elm.style.fontSize, '18px') requestAnimationFrame(() => { requestAnimationFrame(() => { assert.strictEqual(elm.style.fontSize, '20px') done() }) }) }) }) }) it('applies tranform as transition on remove', function (done) { const btn = h('button', { style: { transition: 'transform 0.1s', remove: { transform: 'translateY(100%)' } as any } }, ['A button']) const vnode1 = h('div.parent', {}, [btn]) const vnode2 = h('div.parent', {}, [null]) document.body.appendChild(vnode0) patch(vnode0, vnode1) patch(vnode1, vnode2) const button = document.querySelector('button') as HTMLButtonElement assert.notStrictEqual(button, null) button.addEventListener('transitionend', function () { assert.strictEqual(document.querySelector('button'), null) done() }) }) describe('using toVNode()', function () { it('handles (ignoring) comment nodes', function () { const comment = document.createComment('yolo') const prevElm = document.createElement('div') prevElm.appendChild(comment) const nextVNode = h('div', [h('span', 'Hi')]) elm = patch(toVNode(prevElm), nextVNode).elm assert.strictEqual(elm, prevElm) assert.strictEqual(elm.tagName, 'DIV') assert.strictEqual(elm.childNodes.length, 1) assert.strictEqual(elm.childNodes[0].tagName, 'SPAN') assert.strictEqual(elm.childNodes[0].textContent, 'Hi') }) }) })