UNPKG

@builder.io/sdk

Version:

169 lines (168 loc) 4.63 kB
import VNode from 'virtual-dom/vnode/vnode'; import VText from 'virtual-dom/vnode/vtext'; // tslint:disable:no-increment-decrement // CREDIT: adopted from https://raw.githubusercontent.com/marcelklehr/vdom-virtualize/master/index.js export function createVNode(domNode, deep) { if (deep === void 0) { deep = false; } if (domNode.nodeType === 1) return createFromElement(domNode, deep); if (domNode.nodeType === 3) return createFromTextNode(domNode); return; } function createFromTextNode(tNode) { return new VText(tNode.nodeValue); } function createFromElement(el, deep) { if (deep === void 0) { deep = false; } var tagName = el.tagName; var namespace = el.namespaceURI === 'http://www.w3.org/1999/xhtml' ? null : el.namespaceURI; var properties = getElementProperties(el); var children = []; if (deep) { for (var i = 0; i < el.childNodes.length; i++) { children.push(createVNode(el.childNodes[i])); } } return new VNode(tagName, properties, children, null, namespace); } function getElementProperties(el) { var obj = {}; for (var i = 0; i < props.length; i++) { var propName = props[i]; if (!el[propName]) { continue; } if (propName === 'style') { var css = {}; if ('undefined' !== typeof el.style.length) { for (var j = 0; j < el.style.length; j++) { var styleProp = el.style[j]; css[styleProp] = el.style.getPropertyValue(styleProp); // TODO: add support for "!important" via getPropertyPriority()! } } if (Object.keys(css).length) { obj[propName] = css; } continue; } // https://msdn.microsoft.com/en-us/library/cc848861%28v=vs.85%29.aspx // The img element does not support the HREF content attribute. // In addition, the href property is read-only for the img Document Object Model (DOM) object if (el.tagName.toLowerCase() === 'img' && propName === 'href') { continue; } if (propName === 'attributes') { var atts = Array.prototype.slice.call(el[propName]); var hash = {}; for (var k = 0; k < atts.length; k++) { var name_1 = atts[k].name; if (obj[name_1] || obj[attrBlacklist[name_1]]) { continue; } hash[name_1] = el.getAttribute(name_1); } obj[propName] = hash; continue; } if (propName === 'tabIndex' && el.tabIndex === -1) { continue; } // Special case: contentEditable // browser use 'inherit' by default on all nodes, but does not allow setting it to '' // diffing virtualize dom will trigger error // ref: https://github.com/Matt-Esch/virtual-dom/issues/176 if (propName === 'contentEditable' && el[propName] === 'inherit') { continue; } if ('object' === typeof el[propName]) { continue; } // default: just copy the property obj[propName] = el[propName]; } return obj; } /** * DOMNode property white list * Taken from https://github.com/Raynos/react/blob/dom-property-config/src/browser/ui/dom/DefaultDOMPropertyConfig.js */ export var props = [ 'accept', 'accessKey', 'action', 'alt', 'async', 'autoComplete', 'autoPlay', 'cellPadding', 'cellSpacing', 'checked', 'className', 'colSpan', 'content', 'contentEditable', 'controls', 'crossOrigin', 'data', 'defer', 'dir', 'download', 'draggable', 'encType', 'formNoValidate', 'href', 'hrefLang', 'htmlFor', 'httpEquiv', 'icon', 'id', 'label', 'lang', 'list', 'loop', 'max', 'mediaGroup', 'method', 'min', 'multiple', 'muted', 'name', 'noValidate', 'pattern', 'placeholder', 'poster', 'preload', 'radioGroup', 'readOnly', 'rel', 'required', 'rowSpan', 'sandbox', 'scope', 'scrollLeft', 'scrolling', 'scrollTop', 'selected', 'span', 'spellCheck', 'src', 'srcDoc', 'srcSet', 'start', 'step', 'style', 'tabIndex', 'target', 'title', 'type', 'value', // Non-standard Properties 'autoCapitalize', 'autoCorrect', 'property', 'attributes', ]; export var attrBlacklist = { class: 'className', };