Skip to content
Permalink
Browse files

Initialize reconciler once (#170)

  • Loading branch information...
vadimdemedes committed Mar 23, 2019
1 parent 43c9390 commit 405fe7ad6bb993cb9b4924a290b45cadfa69e558
Showing with 99 additions and 100 deletions.
  1. +5 −5 src/instance.js
  2. +94 −95 src/reconciler.js
@@ -2,7 +2,7 @@ import React from 'react';
import throttle from 'lodash.throttle';
import autoBind from 'auto-bind';
import logUpdate from 'log-update';
import createReconciler from './reconciler';
import reconciler from './reconciler';
import createRenderer from './renderer';
import {createNode} from './dom';
import App from './components/App';
@@ -14,6 +14,7 @@ export default class Instance {
this.options = options;

this.rootNode = createNode('root');
this.rootNode.onRender = this.onRender;
this.renderer = createRenderer({
terminalWidth: options.stdout.columns
});
@@ -35,8 +36,7 @@ export default class Instance {
// so that it's rerendered every time, not just new static parts, like in non-debug mode
this.fullStaticOutput = '';

this.reconciler = createReconciler(this.onRender);
this.container = this.reconciler.createContainer(this.rootNode, false);
this.container = reconciler.createContainer(this.rootNode, false, false);

this.exitPromise = new Promise(resolve => {
this.resolveExitPromise = resolve;
@@ -91,14 +91,14 @@ export default class Instance {
</App>
);

this.reconciler.updateContainer(tree, this.container);
reconciler.updateContainer(tree, this.container);
}

unmount() {
this.onRender();
this.log.done();
this.ignoreRender = true;
this.reconciler.updateContainer(null, this.container);
reconciler.updateContainer(null, this.container);
this.resolveExitPromise();
}

@@ -12,114 +12,113 @@ import {
setAttribute
} from './dom';

export default onRender => {
const rootHostContext = {};
const childHostContext = {};
const NO_CONTEXT = true;

const hostConfig = {
schedulePassiveEffects,
cancelPassiveEffects,
now: Date.now,
getRootHostContext: () => rootHostContext,
prepareForCommit: () => {},
resetAfterCommit: onRender,
getChildHostContext: () => childHostContext,
shouldSetTextContent: (type, props) => {
return typeof props.children === 'string' || typeof props.children === 'number';
},
createInstance: (type, newProps) => {
const node = createNode(type);
const hostConfig = {
schedulePassiveEffects,
cancelPassiveEffects,
now: Date.now,
getRootHostContext: () => NO_CONTEXT,
prepareForCommit: () => {},
resetAfterCommit: rootNode => {
rootNode.onRender();
},
getChildHostContext: () => NO_CONTEXT,
shouldSetTextContent: (type, props) => {
return typeof props.children === 'string' || typeof props.children === 'number';
},
createInstance: (type, newProps) => {
const node = createNode(type);

for (const [key, value] of Object.entries(newProps)) {
if (key === 'children') {
if (typeof value === 'string' || typeof value === 'number') {
if (type === 'div') {
// Text node must be wrapped in another node, so that text can be aligned within container
const textElement = createNode('div');
textElement.textContent = String(value);
appendChildNode(node, textElement);
}
for (const [key, value] of Object.entries(newProps)) {
if (key === 'children') {
if (typeof value === 'string' || typeof value === 'number') {
if (type === 'div') {
// Text node must be wrapped in another node, so that text can be aligned within container
const textElement = createNode('div');
textElement.textContent = String(value);
appendChildNode(node, textElement);
}

if (type === 'span') {
node.textContent = String(value);
}
if (type === 'span') {
node.textContent = String(value);
}
} else if (key === 'style') {
Object.assign(node.style, value);
} else if (key === 'unstable__transformChildren') {
node.unstable__transformChildren = value; // eslint-disable-line camelcase
} else if (key === 'unstable__static') {
node.unstable__static = true; // eslint-disable-line camelcase
} else {
setAttribute(node, key, value);
}
} else if (key === 'style') {
Object.assign(node.style, value);
} else if (key === 'unstable__transformChildren') {
node.unstable__transformChildren = value; // eslint-disable-line camelcase
} else if (key === 'unstable__static') {
node.unstable__static = true; // eslint-disable-line camelcase
} else {
setAttribute(node, key, value);
}
}

return node;
},
createTextInstance: createTextNode,
resetTextContent: node => {
if (node.textContent) {
node.textContent = '';
}
return node;
},
createTextInstance: createTextNode,
resetTextContent: node => {
if (node.textContent) {
node.textContent = '';
}

if (node.childNodes.length > 0) {
for (const childNode of node.childNodes) {
childNode.yogaNode.free();
removeChildNode(node, childNode);
}
if (node.childNodes.length > 0) {
for (const childNode of node.childNodes) {
childNode.yogaNode.free();
removeChildNode(node, childNode);
}
},
getPublicInstance: instance => instance,
appendInitialChild: appendChildNode,
appendChild: appendChildNode,
insertBefore: insertBeforeNode,
finalizeInitialChildren: () => {},
supportsMutation: true,
appendChildToContainer: appendChildNode,
insertInContainerBefore: insertBeforeNode,
removeChildFromContainer: removeChildNode,
prepareUpdate: () => true,
commitUpdate: (node, updatePayload, type, oldProps, newProps) => {
for (const [key, value] of Object.entries(newProps)) {
if (key === 'children') {
if (typeof value === 'string' || typeof value === 'number') {
if (type === 'div') {
// Text node must be wrapped in another node, so that text can be aligned within container
// If there's no such node, a new one must be created
if (node.childNodes.length === 0) {
const textElement = createNode('div');
textElement.textContent = String(value);
appendChildNode(node, textElement);
} else {
node.childNodes[0].textContent = String(value);
}
}
},
getPublicInstance: instance => instance,
appendInitialChild: appendChildNode,
appendChild: appendChildNode,
insertBefore: insertBeforeNode,
finalizeInitialChildren: () => {},
supportsMutation: true,
appendChildToContainer: appendChildNode,
insertInContainerBefore: insertBeforeNode,
removeChildFromContainer: removeChildNode,
prepareUpdate: () => true,
commitUpdate: (node, updatePayload, type, oldProps, newProps) => {
for (const [key, value] of Object.entries(newProps)) {
if (key === 'children') {
if (typeof value === 'string' || typeof value === 'number') {
if (type === 'div') {
// Text node must be wrapped in another node, so that text can be aligned within container
// If there's no such node, a new one must be created
if (node.childNodes.length === 0) {
const textElement = createNode('div');
textElement.textContent = String(value);
appendChildNode(node, textElement);
} else {
node.childNodes[0].textContent = String(value);
}
}

if (type === 'span') {
node.textContent = String(value);
}
if (type === 'span') {
node.textContent = String(value);
}
} else if (key === 'style') {
Object.assign(node.style, value);
} else if (key === 'unstable__transformChildren') {
node.unstable__transformChildren = value; // eslint-disable-line camelcase
} else if (key === 'unstable__static') {
node.unstable__static = true; // eslint-disable-line camelcase
} else {
setAttribute(node, key, value);
}
}
},
commitTextUpdate: (node, oldText, newText) => {
if (node.nodeName === '#text') {
node.nodeValue = newText;
} else if (key === 'style') {
Object.assign(node.style, value);
} else if (key === 'unstable__transformChildren') {
node.unstable__transformChildren = value; // eslint-disable-line camelcase
} else if (key === 'unstable__static') {
node.unstable__static = true; // eslint-disable-line camelcase
} else {
node.textContent = newText;
setAttribute(node, key, value);
}
},
removeChild: removeChildNode
};

return ReactReconciler(hostConfig); // eslint-disable-line new-cap
}
},
commitTextUpdate: (node, oldText, newText) => {
if (node.nodeName === '#text') {
node.nodeValue = newText;
} else {
node.textContent = newText;
}
},
removeChild: removeChildNode
};

export default ReactReconciler(hostConfig); // eslint-disable-line new-cap

0 comments on commit 405fe7a

Please sign in to comment.
You can’t perform that action at this time.