Skip to content

Commit

Permalink
fix: render root check
Browse files Browse the repository at this point in the history
  • Loading branch information
edoardocavazza committed Oct 22, 2021
1 parent 4a7436e commit 46bbe49
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 10 deletions.
15 changes: 11 additions & 4 deletions src/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,13 @@ const setValue = <T extends HTMLElement>(element: T, propertyKey: PropertyKey, v
*/
const isListenerProperty = (propertyKey: string): propertyKey is `on${string}` => propertyKey[0] === 'o' && propertyKey[1] === 'n';

/**
* Check if an item is in a list.
* @param items List of child nodes.
* @param item The item to check.
*/
const contains = <T>(items: T[], item: T) => ([] as typeof items).indexOf.call(items, item) !== -1;

/**
* Render a set of Nodes into another, with some checks for Nodes in order to avoid
* useless changes in the tree and to mantain or update the state of compatible Nodes.
Expand Down Expand Up @@ -259,7 +266,7 @@ export const internalRender = (
}

const renderFragmentContext = getOrCreateContext(placeholder);
const isAttached = () => fragments.indexOf(renderFragmentContext) !== -1;
const isAttached = contains.bind(null, fragments, renderFragmentContext);
let running = true;
const requestUpdate: UpdateRequest = renderFragmentContext.requestUpdate = () => {
if (renderFragmentContext.requestUpdate !== requestUpdate) {
Expand Down Expand Up @@ -458,7 +465,7 @@ export const internalRender = (
const oldClasses = convertClasses(oldProperties.class);
for (let i = 0, len = oldClasses.length; i < len; i++) {
const className = oldClasses[i];
if (newClasses.indexOf(className) === -1) {
if (contains(newClasses, className)) {
classList.remove(className);
}
}
Expand Down Expand Up @@ -492,7 +499,7 @@ export const internalRender = (
const Component = template.Component;
if (type === 'string') {
const observedAttributes = Component.observedAttributes;
if (!observedAttributes || observedAttributes.indexOf(propertyKey) === -1) {
if (!observedAttributes || contains(observedAttributes, propertyKey)) {
const descriptor = (propertyKey in templateElement) && getPropertyDescriptor(templateElement, propertyKey);
if (!descriptor || !descriptor.get || descriptor.set) {
setValue(templateElement, propertyKey, value);
Expand Down Expand Up @@ -585,7 +592,7 @@ export const internalRender = (
// now, we are confident that if the input is a Node or a Component,
// check if Nodes are the same instance
// (patch result should return same Node instances for compatible types)
if (templateNode.parentNode === root) {
if (contains(childNodes, templateNode)) {
while (templateNode !== currentNode) {
DOM.removeChild(root, currentNode, slot);
currentNode = childNodes.item(currentIndex) as Node;
Expand Down
32 changes: 26 additions & 6 deletions test/render.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,23 +219,43 @@ describe('render', function() {
});

it('should update nodes', () => {
DNA.render(DNA.h('ul', { class: 'list' }, DNA.h('li', null, 'One'), DNA.h('li', null, 'Two'), DNA.h('li', null, 'Three'), DNA.h('li', null, 'Four')), wrapper);
DNA.render(DNA.h('ul', { class: 'list' },
DNA.h('li', null, 'One'),
DNA.h('li', null, 'Two'),
DNA.h('li', null, 'Three'),
DNA.h('li', null, 'Four'),
DNA.h('li', null, 5),
DNA.h('li', null, '6')
), wrapper);
const list = wrapper.querySelector('ul.list');
const children = list.childNodes;
expect(children[0].textContent).to.be.equal('One');
expect(children[1].textContent).to.be.equal('Two');
expect(children[2].textContent).to.be.equal('Three');
expect(children[3].textContent).to.be.equal('Four');
DNA.render(DNA.h('ul', { class: 'list' }, DNA.h('li', null, 'Five'), DNA.h('li', null, 'Six'), DNA.h('li', null, 'Seven'), DNA.h('li', null, 'Height')), wrapper);
expect(children[4].textContent).to.be.equal('5');
expect(children[5].textContent).to.be.equal('6');
DNA.render(DNA.h('ul', { class: 'list' },
DNA.h('li', null, 'Seven'),
DNA.h('li', null, 'Eight'),
DNA.h('li', null, 'Nine'),
DNA.h('li', null, 'Ten'),
DNA.h('li', null, 11),
DNA.h('li', null, 12)
), wrapper);
const newChildren = list.childNodes;
expect(children[0]).to.be.equal(newChildren[0]);
expect(children[1]).to.be.equal(newChildren[1]);
expect(children[2]).to.be.equal(newChildren[2]);
expect(children[3]).to.be.equal(newChildren[3]);
expect(children[0].textContent).to.be.equal('Five');
expect(children[1].textContent).to.be.equal('Six');
expect(children[2].textContent).to.be.equal('Seven');
expect(children[3].textContent).to.be.equal('Height');
expect(children[4]).to.be.equal(newChildren[4]);
expect(children[5]).to.be.equal(newChildren[5]);
expect(children[0].textContent).to.be.equal('Seven');
expect(children[1].textContent).to.be.equal('Eight');
expect(children[2].textContent).to.be.equal('Nine');
expect(children[3].textContent).to.be.equal('Ten');
expect(children[4].textContent).to.be.equal('11');
expect(children[5].textContent).to.be.equal('12');
});

it('should update add and remove attributes', () => {
Expand Down

0 comments on commit 46bbe49

Please sign in to comment.