UNPKG

deku

Version:

Render interfaces using pure functions and virtual DOM

184 lines (150 loc) 4.62 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.create = create; exports.createTextElement = createTextElement; exports.createEmptyElement = createEmptyElement; exports.createThunkElement = createThunkElement; exports.isValidAttribute = isValidAttribute; function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } function _typeof(obj) { return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj; } /** * This function lets us create virtual nodes using a simple * syntax. It is compatible with JSX transforms so you can use * JSX to write nodes that will compile to this function. * * let node = element('div', { id: 'foo' }, [ * element('a', { href: 'http://google.com' }, * element('span', {}, 'Google'), * element('b', {}, 'Link') * ) * ]) */ function create(type, attributes) { for (var _len = arguments.length, children = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { children[_key - 2] = arguments[_key]; } if (!type) throw new TypeError('element() needs a type.'); attributes = attributes || {}; children = (children || []).reduce(reduceChildren, []); var key = typeof attributes.key === 'string' || typeof attributes.key === 'number' ? attributes.key : undefined; delete attributes.key; if ((typeof type === 'undefined' ? 'undefined' : _typeof(type)) === 'object' || typeof type === 'function') { return createThunkElement(type, key, attributes, children); } return { attributes: attributes, children: children, type: type, key: key }; } /** * Cleans up the array of child elements. * - Flattens nested arrays * - Converts raw strings and numbers into vnodes * - Filters out undefined elements */ function reduceChildren(children, vnode) { if (typeof vnode === 'string' || typeof vnode === 'number') { children.push(createTextElement(vnode)); } else if (vnode === null) { children.push(createEmptyElement()); } else if (Array.isArray(vnode)) { children = [].concat(_toConsumableArray(children), _toConsumableArray(vnode.reduce(reduceChildren, []))); } else if (typeof vnode === 'undefined') { throw new Error('vnode can\'t be undefined. Did you mean to use null?'); } else { children.push(vnode); } return children; } /** * Text nodes are stored as objects to keep things simple */ function createTextElement(text) { return { type: '#text', nodeValue: text }; } /** * Text nodes are stored as objects to keep things simple */ function createEmptyElement() { return { type: '#empty' }; } /** * Lazily-rendered virtual nodes */ function createThunkElement(component, key, props, children) { return { type: '#thunk', children: children, props: props, component: component, key: key }; } /** * Is a vnode a thunk? */ var isThunk = exports.isThunk = function isThunk(node) { return node.type === '#thunk'; }; /** * Is a vnode a text node? */ var isText = exports.isText = function isText(node) { return node.type === '#text'; }; /** * Is a vnode an empty placeholder? */ var isEmpty = exports.isEmpty = function isEmpty(node) { return node.type === '#empty'; }; /** * Determine if two virtual nodes are the same type */ var isSameThunk = exports.isSameThunk = function isSameThunk(left, right) { return isThunk(left) && isThunk(right) && left.component === right.component; }; /** * Group an array of virtual elements by their key, using index as a fallback. */ var groupByKey = exports.groupByKey = function groupByKey(children) { return children.reduce(function (acc, child, i) { if (child != null && child !== false) { acc.push({ key: String(child.key || i), item: child, index: i }); } return acc; }, []); }; /** * Check if an attribute should be rendered into the DOM. */ function isValidAttribute(value) { if (typeof value === 'boolean') return value; if (typeof value === 'function') return false; if (value === '') return true; if (value === undefined) return false; if (value === null) return false; return true; } /** * Create a node path, eg. (23,5,2,4) => '23.5.2.4' */ var createPath = exports.createPath = function createPath() { for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { args[_key2] = arguments[_key2]; } return args.join('.'); };