Skip to content

Commit

Permalink
Merge c23c721 into e206b07
Browse files Browse the repository at this point in the history
  • Loading branch information
jviide committed May 4, 2019
2 parents e206b07 + c23c721 commit d1d76f5
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 74 deletions.
75 changes: 35 additions & 40 deletions src/create-context.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,44 @@ export let i = 0;
* @param {any} defaultValue
*/
export function createContext(defaultValue) {
let context = {
const ctx = {};

const context = {
_id: '__cC' + i++,
_defaultValue: defaultValue
_defaultValue: defaultValue,
Consumer(props, context) {
return props.children(context);
},
Provider(props) {
if (!this.getChildContext) {
const subs = [];
this.getChildContext = () => {
ctx[context._id] = this;
return ctx;
};
this.shouldComponentUpdate = props => {
subs.some(c => {
// Check if still mounted
if (c._parentDom) {
c.context = props.value;
enqueueRender(c);
}
});
};
this.sub = (c) => {
subs.push(c);
let old = c.componentWillUnmount;
c.componentWillUnmount = () => {
subs.splice(subs.indexOf(c), 1);
old && old();
};
};
}
return props.children;
}
};

function Consumer(props, context) {
return props.children(context);
}
Consumer.contextType = context;
context.Consumer = Consumer;

let ctx = {};

function initProvider(comp) {
const subs = [];
comp.getChildContext = () => {
ctx[context._id] = comp;
return ctx;
};
comp.shouldComponentUpdate = props => {
subs.map(c => {
// Check if still mounted
if (c._parentDom) {
c.context = props.value;
enqueueRender(c);
}
});
};
comp.sub = (c) => {
subs.push(c);
let old = c.componentWillUnmount;
c.componentWillUnmount = () => {
subs.splice(subs.indexOf(c), 1);
old && old();
};
};
}

function Provider(props) {
if (!this.getChildContext) initProvider(this);
return props.children;
}
context.Provider = Provider;
context.Consumer.contextType = context;

return context;
}
7 changes: 3 additions & 4 deletions src/diff/children.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,9 @@ export function diffChildren(parentDom, newParentVNode, oldParentVNode, context,
parentDom.appendChild(newDom);
}
else {
sibDom = oldDom;
j = 0;
while ((sibDom=sibDom.nextSibling) && j++<oldChildrenLength/2) {
if (sibDom===newDom) {
// `j<oldChildrenLength; j+=2` is an alternative to `j++<oldChildrenLength/2`
for (sibDom=oldDom, j=0; (sibDom=sibDom.nextSibling) && j<oldChildrenLength; j+=2) {
if (sibDom==newDom) {
break outer;
}
}
Expand Down
31 changes: 16 additions & 15 deletions src/diff/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ export function diff(parentDom, newVNode, oldVNode, context, isSvg, excessDomChi
oldVNode = EMPTY_OBJ;
}

let c, tmp, isNew = false, oldProps, oldState, snapshot,
newType = newVNode.type, clearProcessingException;

// When passing through createElement it assigns the object
// ref on _self, to prevent JSON Injection we check if this attribute
// is equal.
if (newVNode._self!==newVNode) return null;

if (options.diff) options.diff(newVNode);

let c, p, isNew = false, oldProps, oldState, snapshot,
newType = newVNode.type, clearProcessingException;
if (tmp = options.diff) tmp(newVNode);

try {
outer: if (oldVNode.type===Fragment || newType===Fragment) {
Expand All @@ -48,15 +48,16 @@ export function diff(parentDom, newVNode, oldVNode, context, isSvg, excessDomChi
// Mark dom as empty in case `_children` is any empty array. If it isn't
// we'll set `dom` to the correct value just a few lines later.

if (newVNode._children.length && newVNode._children[0]!=null) {
newVNode._dom = newVNode._children[0]._dom;
let i = newVNode._children.length;
if (i && (tmp=newVNode._children[0]) != null) {
newVNode._dom = tmp._dom;

// If the last child is a Fragment, use _lastDomChild, else use _dom
// We have no guarantee that the last child rendered something into the
// dom, so we iterate backwards to find the last child with a dom node.
for (let i = newVNode._children.length; i--;) {
p = newVNode._children[i];
newVNode._lastDomChild = p && (p._lastDomChild || p._dom);
while (i--) {
tmp = newVNode._children[i];
newVNode._lastDomChild = tmp && (tmp._lastDomChild || tmp._dom);
if (newVNode._lastDomChild) break;
}
}
Expand Down Expand Up @@ -136,7 +137,7 @@ export function diff(parentDom, newVNode, oldVNode, context, isSvg, excessDomChi
c.props = newVNode.props;
c.state = c._nextState;

if (options.render) options.render(newVNode);
if (tmp = options.render) tmp(newVNode);

let prev = c._prevVNode || null;
c._dirty = false;
Expand Down Expand Up @@ -164,7 +165,7 @@ export function diff(parentDom, newVNode, oldVNode, context, isSvg, excessDomChi

if (newVNode.ref) applyRef(newVNode.ref, c, ancestorComponent);

while (p=c._renderCallbacks.pop()) p.call(c);
while (tmp=c._renderCallbacks.pop()) tmp.call(c);

// Don't call componentDidUpdate on mount or when we bailed out via
// `shouldComponentUpdate`
Expand All @@ -184,7 +185,7 @@ export function diff(parentDom, newVNode, oldVNode, context, isSvg, excessDomChi
c._pendingError = c._processingException = null;
}

if (options.diffed) options.diffed(newVNode);
if (tmp = options.diffed) tmp(newVNode);
}
catch (e) {
catchErrorInComponent(e, ancestorComponent);
Expand Down Expand Up @@ -342,9 +343,9 @@ export function unmount(vnode, ancestorComponent, skipRemove) {
if (r = r._prevVNode) unmount(r, ancestorComponent, skipRemove);
}
else if (r = vnode._children) {
for (let i = 0; i < r.length; i++) {
if (r[i]) unmount(r[i], ancestorComponent, skipRemove);
}
r.some(c => {
c && unmount(c, ancestorComponent, skipRemove);
});
}

if (dom!=null) removeNode(dom);
Expand Down
37 changes: 22 additions & 15 deletions src/diff/props.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ import options from '../options';
* @param {boolean} isSvg Whether or not this node is an SVG node
*/
export function diffProps(dom, newProps, oldProps, isSvg) {
let keys = Object.keys(newProps).sort();
for (let i = 0; i < keys.length; i++) {
if (keys[i]!=='children' && keys[i]!=='key' && (!oldProps || ((keys[i]==='value' || keys[i]==='checked') ? dom : oldProps)[keys[i]]!==newProps[keys[i]])) {
setProperty(dom, keys[i], newProps[keys[i]], oldProps[keys[i]], isSvg);
Object.keys(newProps).sort().some(k => {
if (k!=='children' && k!=='key' && (!oldProps || ((k==='value' || k==='checked') ? dom : oldProps)[k]!==newProps[k])) {
setProperty(dom, k, newProps[k], oldProps[k], isSvg);
}
}
});

for (let i in oldProps) {
if (i!=='children' && i!=='key' && (!newProps || !(i in newProps))) {
Expand All @@ -24,7 +23,8 @@ export function diffProps(dom, newProps, oldProps, isSvg) {
}
}

let CAMEL_REG = /-?(?=[A-Z])/g;
const CAMEL_REG = /-?(?=[A-Z])/g;
const XLINK_NS = 'http://www.w3.org/1999/xlink';

/**
* Set a property value on a DOM node
Expand All @@ -35,8 +35,7 @@ let CAMEL_REG = /-?(?=[A-Z])/g;
* @param {boolean} isSvg Whether or not this DOM node is an SVG node or not
*/
function setProperty(dom, name, value, oldValue, isSvg) {
let v;
if (name==='class' || name==='className') name = isSvg ? 'class' : 'className';
name = isSvg ? (name==='className' ? 'class' : name) : (name==='class' ? 'className' : name);

if (name==='style') {

Expand All @@ -59,7 +58,7 @@ function setProperty(dom, name, value, oldValue, isSvg) {
}
}
for (let i in value) {
v = value[i];
const v = value[i];
if (oldValue==null || v!==oldValue[i]) {
s.setProperty(i.replace(CAMEL_REG, '-'), typeof v==='number' && IS_NON_DIMENSIONAL.test(i)===false ? (v + 'px') : v);
}
Expand All @@ -86,13 +85,21 @@ function setProperty(dom, name, value, oldValue, isSvg) {
else if (name!=='list' && name!=='tagName' && !isSvg && (name in dom)) {
dom[name] = value==null ? '' : value;
}
else if (value==null || value===false) {
if (name!==(name = name.replace(/^xlink:?/, ''))) dom.removeAttributeNS('http://www.w3.org/1999/xlink', name.toLowerCase());
else dom.removeAttribute(name);
}
else if (typeof value!=='function') {
if (name!==(name = name.replace(/^xlink:?/, ''))) dom.setAttributeNS('http://www.w3.org/1999/xlink', name.toLowerCase(), value);
else dom.setAttribute(name, value);
if (name!==(name = name.replace(/^xlink:?/, ''))) {
if (value==null || value===false) {
dom.removeAttributeNS(XLINK_NS, name.toLowerCase());
}
else {
dom.setAttributeNS(XLINK_NS, name.toLowerCase(), value);
}
}
else if (value==null || value===false) {
dom.removeAttribute(name);
}
else {
dom.setAttribute(name, value);
}
}
}

Expand Down

0 comments on commit d1d76f5

Please sign in to comment.