diff --git a/src/clone-element.js b/src/clone-element.js index 9998095344..d97384d613 100644 --- a/src/clone-element.js +++ b/src/clone-element.js @@ -1,6 +1,6 @@ import { assign, slice } from './util'; import { createVNode } from './create-element'; -import { UNDEFINED } from './constants'; +import { NULL, UNDEFINED } from './constants'; /** * Clones the given VNode, optionally adding attributes/props and replacing its @@ -43,6 +43,6 @@ export function cloneElement(vnode, props, children) { normalizedProps, key || vnode.key, ref || vnode.ref, - null + NULL ); } diff --git a/src/component.js b/src/component.js index 90f0855244..967ebcac66 100644 --- a/src/component.js +++ b/src/component.js @@ -2,7 +2,7 @@ import { assign } from './util'; import { diff, commitRoot } from './diff/index'; import options from './options'; import { Fragment } from './create-element'; -import { MODE_HYDRATE } from './constants'; +import { MODE_HYDRATE, NULL } from './constants'; /** * Base Component class. Provides `setState()` and `forceUpdate()`, which @@ -28,7 +28,7 @@ export function BaseComponent(props, context) { BaseComponent.prototype.setState = function (update, callback) { // only clone state when copying to nextState the first time. let s; - if (this._nextState != null && this._nextState !== this.state) { + if (this._nextState != NULL && this._nextState !== this.state) { s = this._nextState; } else { s = this._nextState = assign({}, this.state); @@ -45,7 +45,7 @@ BaseComponent.prototype.setState = function (update, callback) { } // Skip update if updater function returned null - if (update == null) return; + if (update == NULL) return; if (this._vnode) { if (callback) { @@ -89,18 +89,18 @@ BaseComponent.prototype.render = Fragment; * @param {number | null} [childIndex] */ export function getDomSibling(vnode, childIndex) { - if (childIndex == null) { + 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._index + 1) - : null; + : NULL; } let sibling; for (; childIndex < vnode._children.length; childIndex++) { sibling = vnode._children[childIndex]; - if (sibling != null && sibling._dom != null) { + if (sibling != NULL && sibling._dom != NULL) { // Since updateParentDomPointers keeps _dom pointer correct, // we can rely on _dom to tell us if this subtree contains a // rendered DOM node, and what the first rendered DOM node is @@ -113,7 +113,7 @@ export function getDomSibling(vnode, childIndex) { // 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; + return typeof vnode.type == 'function' ? getDomSibling(vnode) : NULL; } /** @@ -137,9 +137,9 @@ function renderComponent(component) { oldVNode, component._globalContext, component._parentDom.namespaceURI, - oldVNode._flags & MODE_HYDRATE ? [oldDom] : null, + oldVNode._flags & MODE_HYDRATE ? [oldDom] : NULL, commitQueue, - oldDom == null ? getDomSibling(oldVNode) : oldDom, + oldDom == NULL ? getDomSibling(oldVNode) : oldDom, !!(oldVNode._flags & MODE_HYDRATE), refQueue ); @@ -158,11 +158,11 @@ function renderComponent(component) { * @param {import('./internal').VNode} vnode */ function updateParentDomPointers(vnode) { - if ((vnode = vnode._parent) != null && vnode._component != null) { - vnode._dom = vnode._component.base = null; + if ((vnode = vnode._parent) != NULL && vnode._component != NULL) { + vnode._dom = vnode._component.base = NULL; for (let i = 0; i < vnode._children.length; i++) { let child = vnode._children[i]; - if (child != null && child._dom != null) { + if (child != NULL && child._dom != NULL) { vnode._dom = vnode._component.base = child._dom; break; } diff --git a/src/constants.js b/src/constants.js index 197783b081..c60df07b93 100644 --- a/src/constants.js +++ b/src/constants.js @@ -14,6 +14,7 @@ export const SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; export const XHTML_NAMESPACE = 'http://www.w3.org/1999/xhtml'; export const MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML'; +export const NULL = null; export const UNDEFINED = undefined; export const EMPTY_OBJ = /** @type {any} */ ({}); export const EMPTY_ARR = []; diff --git a/src/create-context.js b/src/create-context.js index 8ecaec9ea5..7961e56d7c 100644 --- a/src/create-context.js +++ b/src/create-context.js @@ -1,4 +1,5 @@ import { enqueueRender } from './component'; +import { NULL } from './constants'; export let i = 0; @@ -13,7 +14,7 @@ export function createContext(defaultValue) { this.getChildContext = () => ctx; this.componentWillUnmount = () => { - subs = null; + subs = NULL; }; this.shouldComponentUpdate = function (_props) { diff --git a/src/create-element.js b/src/create-element.js index c843e0dc51..d4ea2dd935 100644 --- a/src/create-element.js +++ b/src/create-element.js @@ -1,6 +1,6 @@ import { slice } from './util'; import options from './options'; -import { UNDEFINED } from './constants'; +import { NULL, UNDEFINED } from './constants'; let vnodeId = 0; @@ -31,7 +31,7 @@ export function createElement(type, props, children) { // If a Component VNode, check for and apply defaultProps // Note: type may be undefined in development, must never error here. - if (typeof type == 'function' && type.defaultProps != null) { + if (typeof type == 'function' && type.defaultProps != NULL) { for (i in type.defaultProps) { if (normalizedProps[i] === UNDEFINED) { normalizedProps[i] = type.defaultProps[i]; @@ -39,7 +39,7 @@ export function createElement(type, props, children) { } } - return createVNode(type, normalizedProps, key, ref, null); + return createVNode(type, normalizedProps, key, ref, NULL); } /** @@ -63,25 +63,25 @@ export function createVNode(type, props, key, ref, original) { props, key, ref, - _children: null, - _parent: null, + _children: NULL, + _parent: NULL, _depth: 0, - _dom: null, - _component: null, + _dom: NULL, + _component: NULL, constructor: UNDEFINED, - _original: original == null ? ++vnodeId : original, + _original: original == NULL ? ++vnodeId : original, _index: -1, _flags: 0 }; // Only invoke the vnode hook if this was *not* a direct copy: - if (original == null && options.vnode != null) options.vnode(vnode); + if (original == NULL && options.vnode != NULL) options.vnode(vnode); return vnode; } export function createRef() { - return { current: null }; + return { current: NULL }; } export function Fragment(props) { @@ -94,4 +94,4 @@ export function Fragment(props) { * @returns {vnode is VNode} */ export const isValidElement = vnode => - vnode != null && vnode.constructor == UNDEFINED; + vnode != NULL && vnode.constructor == UNDEFINED; diff --git a/src/diff/catch-error.js b/src/diff/catch-error.js index 2bd607f797..ada46f1942 100644 --- a/src/diff/catch-error.js +++ b/src/diff/catch-error.js @@ -1,3 +1,5 @@ +import { NULL } from '../constants'; + /** * Find the closest error boundary to a thrown error and call it * @param {object} error The thrown value @@ -20,12 +22,12 @@ export function _catchError(error, vnode, oldVNode, errorInfo) { try { ctor = component.constructor; - if (ctor && ctor.getDerivedStateFromError != null) { + if (ctor && ctor.getDerivedStateFromError != NULL) { component.setState(ctor.getDerivedStateFromError(error)); handled = component._dirty; } - if (component.componentDidCatch != null) { + if (component.componentDidCatch != NULL) { component.componentDidCatch(error, errorInfo || {}); handled = component._dirty; } diff --git a/src/diff/children.js b/src/diff/children.js index 5053a51174..c40b4d5b1e 100644 --- a/src/diff/children.js +++ b/src/diff/children.js @@ -5,7 +5,8 @@ import { EMPTY_ARR, INSERT_VNODE, MATCHED, - UNDEFINED + UNDEFINED, + NULL } from '../constants'; import { isArray } from '../util'; import { getDomSibling } from '../component'; @@ -79,7 +80,7 @@ export function diffChildren( for (i = 0; i < newChildrenLength; i++) { childVNode = newParentVNode._children[i]; - if (childVNode == null) continue; + if (childVNode == NULL) continue; // At this point, constructNewChildrenArray has assigned _index to be the // matchingIndex for this VNode's oldVNode (or -1 if there is no oldVNode). @@ -110,7 +111,7 @@ export function diffChildren( newDom = childVNode._dom; if (childVNode.ref && oldVNode.ref != childVNode.ref) { if (oldVNode.ref) { - applyRef(oldVNode.ref, null, childVNode); + applyRef(oldVNode.ref, NULL, childVNode); } refQueue.push( childVNode.ref, @@ -119,7 +120,7 @@ export function diffChildren( ); } - if (firstChildDom == null && newDom != null) { + if (firstChildDom == NULL && newDom != NULL) { firstChildDom = newDom; } @@ -174,11 +175,11 @@ function constructNewChildrenArray( childVNode = renderResult[i]; if ( - childVNode == null || + childVNode == NULL || typeof childVNode == 'boolean' || typeof childVNode == 'function' ) { - newParentVNode._children[i] = null; + newParentVNode._children[i] = NULL; continue; } // If this newVNode is being reused (e.g.
{reuse}{reuse}
) in the same diff, @@ -192,19 +193,19 @@ function constructNewChildrenArray( childVNode.constructor == String ) { childVNode = newParentVNode._children[i] = createVNode( - null, + NULL, childVNode, - null, - null, - null + NULL, + NULL, + NULL ); } else if (isArray(childVNode)) { childVNode = newParentVNode._children[i] = createVNode( Fragment, { children: childVNode }, - null, - null, - null + NULL, + NULL, + NULL ); } else if (childVNode.constructor === UNDEFINED && childVNode._depth > 0) { // VNode is already in use, clone it. This can happen in the following @@ -215,7 +216,7 @@ function constructNewChildrenArray( childVNode.type, childVNode.props, childVNode.key, - childVNode.ref ? childVNode.ref : null, + childVNode.ref ? childVNode.ref : NULL, childVNode._original ); } else { @@ -236,7 +237,7 @@ function constructNewChildrenArray( remainingOldChildren )); - oldVNode = null; + oldVNode = NULL; if (matchingIndex !== -1) { oldVNode = oldChildren[matchingIndex]; remainingOldChildren--; @@ -248,7 +249,7 @@ function constructNewChildrenArray( // Here, we define isMounting for the purposes of the skew diffing // algorithm. Nodes that are unsuspending are considered mounting and we detect // this by checking if oldVNode._original === null - const isMounting = oldVNode == null || oldVNode._original === null; + const isMounting = oldVNode == NULL || oldVNode._original === NULL; if (isMounting) { if (matchingIndex == -1) { @@ -302,7 +303,7 @@ function constructNewChildrenArray( if (remainingOldChildren) { for (i = 0; i < oldChildrenLength; i++) { oldVNode = oldChildren[i]; - if (oldVNode != null && (oldVNode._flags & MATCHED) == 0) { + if (oldVNode != NULL && (oldVNode._flags & MATCHED) == 0) { if (oldVNode._dom == oldDom) { oldDom = getDomSibling(oldVNode); } @@ -342,13 +343,13 @@ function insert(parentVNode, oldDom, parentDom) { if (oldDom && parentVNode.type && !parentDom.contains(oldDom)) { oldDom = getDomSibling(parentVNode); } - parentDom.insertBefore(parentVNode._dom, oldDom || null); + parentDom.insertBefore(parentVNode._dom, oldDom || NULL); oldDom = parentVNode._dom; } do { oldDom = oldDom && oldDom.nextSibling; - } while (oldDom != null && oldDom.nodeType == 8); + } while (oldDom != NULL && oldDom.nodeType == 8); return oldDom; } @@ -361,7 +362,7 @@ function insert(parentVNode, oldDom, parentDom) { */ export function toChildArray(children, out) { out = out || []; - if (children == null || typeof children == 'boolean') { + if (children == NULL || typeof children == 'boolean') { } else if (isArray(children)) { children.some(child => { toChildArray(child, out); @@ -403,10 +404,10 @@ function findMatchingIndex( let shouldSearch = // (typeof type != 'function' || type === Fragment || key) && remainingOldChildren > - (oldVNode != null && (oldVNode._flags & MATCHED) == 0 ? 1 : 0); + (oldVNode != NULL && (oldVNode._flags & MATCHED) == 0 ? 1 : 0); if ( - oldVNode === null || + oldVNode === NULL || (oldVNode && key == oldVNode.key && type === oldVNode.type && diff --git a/src/diff/index.js b/src/diff/index.js index 7d94813596..9d98bdf582 100644 --- a/src/diff/index.js +++ b/src/diff/index.js @@ -3,6 +3,7 @@ import { MATH_NAMESPACE, MODE_HYDRATE, MODE_SUSPENDED, + NULL, RESET_MODE, SVG_NAMESPACE, UNDEFINED, @@ -63,7 +64,7 @@ export function diff( // When passing through createElement it assigns the object // constructor as undefined. This to prevent JSON-injection. - if (newVNode.constructor !== UNDEFINED) return null; + if (newVNode.constructor !== UNDEFINED) return NULL; // If the previous diff bailed out, resume creating/hydrating. if (oldVNode._flags & MODE_SUSPENDED) { @@ -121,11 +122,11 @@ export function diff( } // Invoke getDerivedStateFromProps - if (isClassComponent && c._nextState == null) { + if (isClassComponent && c._nextState == NULL) { c._nextState = c.state; } - if (isClassComponent && newType.getDerivedStateFromProps != null) { + if (isClassComponent && newType.getDerivedStateFromProps != NULL) { if (c._nextState == c.state) { c._nextState = assign({}, c._nextState); } @@ -144,28 +145,28 @@ export function diff( if (isNew) { if ( isClassComponent && - newType.getDerivedStateFromProps == null && - c.componentWillMount != null + newType.getDerivedStateFromProps == NULL && + c.componentWillMount != NULL ) { c.componentWillMount(); } - if (isClassComponent && c.componentDidMount != null) { + if (isClassComponent && c.componentDidMount != NULL) { c._renderCallbacks.push(c.componentDidMount); } } else { if ( isClassComponent && - newType.getDerivedStateFromProps == null && + newType.getDerivedStateFromProps == NULL && newProps !== oldProps && - c.componentWillReceiveProps != null + c.componentWillReceiveProps != NULL ) { c.componentWillReceiveProps(newProps, componentContext); } if ( !c._force && - ((c.shouldComponentUpdate != null && + ((c.shouldComponentUpdate != NULL && c.shouldComponentUpdate( newProps, c._nextState, @@ -202,11 +203,11 @@ export function diff( break outer; } - if (c.componentWillUpdate != null) { + if (c.componentWillUpdate != NULL) { c.componentWillUpdate(newProps, c._nextState, componentContext); } - if (isClassComponent && c.componentDidUpdate != null) { + if (isClassComponent && c.componentDidUpdate != NULL) { c._renderCallbacks.push(() => { c.componentDidUpdate(oldProps, oldState, snapshot); }); @@ -247,16 +248,16 @@ export function diff( // Handle setState called in render, see #2553 c.state = c._nextState; - if (c.getChildContext != null) { + if (c.getChildContext != NULL) { globalContext = assign(assign({}, globalContext), c.getChildContext()); } - if (isClassComponent && !isNew && c.getSnapshotBeforeUpdate != null) { + if (isClassComponent && !isNew && c.getSnapshotBeforeUpdate != NULL) { snapshot = c.getSnapshotBeforeUpdate(oldProps, oldState); } let isTopLevelFragment = - tmp != null && tmp.type === Fragment && tmp.key == null; + tmp != NULL && tmp.type === Fragment && tmp.key == NULL; let renderResult = isTopLevelFragment ? tmp.props.children : tmp; oldDom = diffChildren( @@ -283,12 +284,12 @@ export function diff( } if (clearProcessingException) { - c._pendingError = c._processingException = null; + c._pendingError = c._processingException = NULL; } } catch (e) { - newVNode._original = null; + newVNode._original = NULL; // if hydrating or creating initial tree, bailout preserves DOM: - if (isHydrating || excessDomChildren != null) { + if (isHydrating || excessDomChildren != NULL) { if (e.then) { newVNode._flags |= isHydrating ? MODE_HYDRATE | MODE_SUSPENDED @@ -298,7 +299,7 @@ export function diff( oldDom = oldDom.nextSibling; } - excessDomChildren[excessDomChildren.indexOf(oldDom)] = null; + excessDomChildren[excessDomChildren.indexOf(oldDom)] = NULL; newVNode._dom = oldDom; } else { for (let i = excessDomChildren.length; i--; ) { @@ -312,7 +313,7 @@ export function diff( options._catchError(e, newVNode, oldVNode); } } else if ( - excessDomChildren == null && + excessDomChildren == NULL && newVNode._original == oldVNode._original ) { newVNode._children = oldVNode._children; @@ -409,7 +410,7 @@ function diffElementNodes( else if (nodeType == 'math') namespace = MATH_NAMESPACE; else if (!namespace) namespace = XHTML_NAMESPACE; - if (excessDomChildren != null) { + if (excessDomChildren != NULL) { for (i = 0; i < excessDomChildren.length; i++) { value = excessDomChildren[i]; @@ -422,14 +423,14 @@ function diffElementNodes( (nodeType ? value.localName == nodeType : value.nodeType == 3) ) { dom = value; - excessDomChildren[i] = null; + excessDomChildren[i] = NULL; break; } } } - if (dom == null) { - if (nodeType == null) { + if (dom == NULL) { + if (nodeType == NULL) { return document.createTextNode(newProps); } @@ -447,10 +448,10 @@ function diffElementNodes( isHydrating = false; } // we created a new parent, so none of the previously attached children can be reused: - excessDomChildren = null; + excessDomChildren = NULL; } - if (nodeType === null) { + if (nodeType === NULL) { // During hydration, we still have to split merged text from SSR'd HTML. if (oldProps !== newProps && (!isHydrating || dom.data !== newProps)) { dom.data = newProps; @@ -464,7 +465,7 @@ function diffElementNodes( // If we are in a situation where we are not hydrating but are using // existing DOM (e.g. replaceNode) we should read the existing DOM // attributes to diff them - if (!isHydrating && excessDomChildren != null) { + if (!isHydrating && excessDomChildren != NULL) { oldProps = {}; for (i = 0; i < dom.attributes.length; i++) { value = dom.attributes[i]; @@ -484,7 +485,7 @@ function diffElementNodes( ) { continue; } - setProperty(dom, i, null, value, namespace); + setProperty(dom, i, NULL, value, namespace); } } @@ -542,7 +543,7 @@ function diffElementNodes( ); // Remove children that are not part of any vnode. - if (excessDomChildren != null) { + if (excessDomChildren != NULL) { for (i = excessDomChildren.length; i--; ) { removeNode(excessDomChildren[i]); } @@ -552,7 +553,7 @@ function diffElementNodes( // As above, don't diff props during hydration if (!isHydrating) { i = 'value'; - if (nodeType == 'progress' && inputValue == null) { + if (nodeType == 'progress' && inputValue == NULL) { dom.removeAttribute('value'); } else if ( inputValue !== UNDEFINED && @@ -595,7 +596,7 @@ export function applyRef(ref, value, vnode) { ref._unmount(); } - if (!hasRefUnmount || value != null) { + if (!hasRefUnmount || value != NULL) { // Store the cleanup function on the function // instance object itself to avoid shape // transitioning vnode @@ -620,11 +621,11 @@ export function unmount(vnode, parentVNode, skipRemove) { if ((r = vnode.ref)) { if (!r.current || r.current === vnode._dom) { - applyRef(r, null, parentVNode); + applyRef(r, NULL, parentVNode); } } - if ((r = vnode._component) != null) { + if ((r = vnode._component) != NULL) { if (r.componentWillUnmount) { try { r.componentWillUnmount(); @@ -633,7 +634,7 @@ export function unmount(vnode, parentVNode, skipRemove) { } } - r.base = r._parentDom = null; + r.base = r._parentDom = NULL; } if ((r = vnode._children)) { diff --git a/src/diff/props.js b/src/diff/props.js index df362863a8..3338d909eb 100644 --- a/src/diff/props.js +++ b/src/diff/props.js @@ -1,10 +1,10 @@ -import { IS_NON_DIMENSIONAL, SVG_NAMESPACE } from '../constants'; +import { IS_NON_DIMENSIONAL, NULL, SVG_NAMESPACE } from '../constants'; import options from '../options'; function setStyle(style, key, value) { if (key[0] == '-') { - style.setProperty(key, value == null ? '' : value); - } else if (value == null) { + style.setProperty(key, value == NULL ? '' : value); + } else if (value == NULL) { style[key] = ''; } else if (typeof value != 'number' || IS_NON_DIMENSIONAL.test(key)) { style[key] = value; @@ -121,7 +121,7 @@ export function setProperty(dom, name, value, oldValue, namespace) { name in dom ) { try { - dom[name] = value == null ? '' : value; + dom[name] = value == NULL ? '' : value; // labelled break is 1b smaller here than a return statement (sorry) break o; } catch (e) {} @@ -136,7 +136,7 @@ export function setProperty(dom, name, value, oldValue, namespace) { if (typeof value == 'function') { // never serialize functions as attribute values - } else if (value != null && (value !== false || name[4] == '-')) { + } else if (value != NULL && (value !== false || name[4] == '-')) { dom.setAttribute(name, name == 'popover' && value == true ? '' : value); } else { dom.removeAttribute(name); @@ -158,7 +158,7 @@ function createEventProxy(useCapture) { return function (e) { if (this._listeners) { const eventHandler = this._listeners[e.type + useCapture]; - if (e._dispatched == null) { + if (e._dispatched == NULL) { e._dispatched = eventClock++; // When `e._dispatched` is smaller than the time when the targeted event diff --git a/src/render.js b/src/render.js index e8c507d7db..5080853a47 100644 --- a/src/render.js +++ b/src/render.js @@ -1,4 +1,4 @@ -import { EMPTY_OBJ } from './constants'; +import { EMPTY_OBJ, NULL } from './constants'; import { commitRoot, diff } from './diff/index'; import { createElement, Fragment } from './create-element'; import options from './options'; @@ -30,11 +30,11 @@ export function render(vnode, parentDom, replaceNode) { // to the last rendered tree. By default this property is not present, which // means that we are mounting a new tree for the first time. let oldVNode = isHydrating - ? null + ? NULL : (replaceNode && replaceNode._children) || parentDom._children; vnode = ((!isHydrating && replaceNode) || parentDom)._children = - createElement(Fragment, null, [vnode]); + createElement(Fragment, NULL, [vnode]); // List of effects that need to be called after diffing. let commitQueue = [], @@ -50,10 +50,10 @@ export function render(vnode, parentDom, replaceNode) { !isHydrating && replaceNode ? [replaceNode] : oldVNode - ? null + ? NULL : parentDom.firstChild ? slice.call(parentDom.childNodes) - : null, + : NULL, commitQueue, !isHydrating && replaceNode ? replaceNode