Skip to content

Commit

Permalink
Begin diff with next DOM sibling in forceUpdate (#1689)
Browse files Browse the repository at this point in the history
Begin diff with next DOM sibling in forceUpdate
  • Loading branch information
marvinhagemeister authored Jun 10, 2019
2 parents c37cfee + 3688977 commit 93c626e
Show file tree
Hide file tree
Showing 4 changed files with 1,075 additions and 10 deletions.
33 changes: 32 additions & 1 deletion src/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ Component.prototype.forceUpdate = function(callback) {
const force = callback!==false;

let mounts = [];
diff(parentDom, vnode, assign({}, vnode), this._context, parentDom.ownerSVGElement!==undefined, null, mounts, force, dom);
diff(parentDom, vnode, assign({}, vnode), this._context, parentDom.ownerSVGElement!==undefined, null, mounts, force, dom == null ? getDomSibling(vnode) : dom);
commitRoot(mounts, vnode);
}
if (callback) callback();
Expand All @@ -87,6 +87,37 @@ Component.prototype.forceUpdate = function(callback) {
*/
Component.prototype.render = Fragment;

/**
* @param {import('./internal').VNode} vnode
* @param {number | null} [childIndex]
*/
export function getDomSibling(vnode, childIndex) {
if (childIndex == null) {
// Use childIndex==null as a signal to resume the search from the vnode's sibling
return vnode._parent
? getDomSibling(vnode._parent, vnode._parent._children.indexOf(vnode) + 1)
: null;
}

let sibling;
for (; childIndex < vnode._children.length; childIndex++) {
sibling = vnode._children[childIndex];

if (sibling != null) {
return typeof sibling.type !== 'function'
? sibling._dom
: getDomSibling(sibling, 0);
}
}

// If we get here, we have not found a DOM node in this vnode's children.
// We must resume from this vnode's sibling (in it's parent _children array)
// Only climb up and search the parent if we aren't searching through a DOM
// VNode (meaning we reached the DOM parent of the original vnode that began
// the search)
return typeof vnode.type === 'function' ? getDomSibling(vnode) : null;
}

/**
* The render queue
* @type {Array<import('./internal').Component>}
Expand Down
6 changes: 6 additions & 0 deletions test/_util/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ export const span = contents => `<span>${contents}</span>`;
*/
export const div = contents => `<div>${contents}</div>`;

/**
* A helper to generate innerHTML validation strings containing sections
* @param {string | number} contents The contents of the section, as a string
*/
export const section = contents => `<section>${contents}</section>`;

/**
* A helper to generate innerHTML validation strings containing uls
* @param {string | number} contents The contents of the ul, as a string
Expand Down
Loading

0 comments on commit 93c626e

Please sign in to comment.