'use strict';
exports.__esModule = true;
exports.ensureNodeData = ensureNodeData;
exports.getNodeData = getNodeData;
exports.getNodeType = getNodeType;
exports.appendChildren = appendChildren;
exports.removeNode = removeNode;
exports.getAccessor = getAccessor;
exports.setAccessor = setAccessor;
exports.getRawNodeAttributes = getRawNodeAttributes;
var _constants = require('../constants');
var _util = require('../util');
var _hooks = require('../hooks');
function ensureNodeData(node, data) {
return getNodeData(node) || (node[_constants.ATTR_KEY] = data || _util.createObject());
}
function getNodeData(node) {
if (node[_constants.ATTR_KEY] !== undefined) return node[_constants.ATTR_KEY];
}
function getNodeType(node) {
if (node instanceof Text) return 3;
Eif (node instanceof Element) return 1;
return 0;
}
/** Append multiple children to a Node.
* Uses a Document Fragment to batch when appending 2 or more children
* @private
*/
function appendChildren(parent, children) {
var len = children.length,
many = len > 2,
into = many ? document.createDocumentFragment() : parent;
for (var i = 0; i < len; i++) {
into.appendChild(children[i]);
}Iif (many) parent.appendChild(into);
}
/** Removes a given DOM Node from its parent. */
function removeNode(node) {
var p = node.parentNode;
if (p) p.removeChild(node);
}
/** Retrieve the value of a rendered attribute
* @private
*/
function getAccessor(node, name) {
if (name !== 'type' && name !== 'style' && name !== 'key' && name in node) return node[name];
var attrs = getNodeData(node);
if (attrs && name in attrs) return attrs[name];
if (name === 'class') return node.className || '';
if (name === 'style') return node.style.cssText || '';
}
/** Set a named attribute on the given Node, with special behavior for some names and event handlers.
* If `value` is `null`, the attribute/handler will be removed.
* @param {Element} node An element to mutate
* @param {string} name The name/key to set, such as an event or attribute name
* @param {any} value An attribute value, such as a function to be used as an event handler
* @param {any} previousValue The last value that was set for this name/node pair
* @private
*/
function setAccessor(node, name, value) {
if (name === 'class') {
node.className = value || '';
} else if (name === 'style') {
node.style.cssText = value || '';
} else if (name === 'dangerouslySetInnerHTML') {
if (value && value.__html) node.innerHTML = value.__html;
} else if (name !== 'key') {
// let valueIsFalsey = falsey(value);
if (name !== 'type' && name in node) {
node[name] = value;
if (_util.falsey(value)) node.removeAttribute(name);
} else if (name.substring(0, 2) === 'on') {
var type = normalizeEventName(name),
l = node._listeners || (node._listeners = _util.createObject());
if (!l[type]) node.addEventListener(type, eventProxy);else if (!value) node.removeEventListener(type, eventProxy);
l[type] = value;
} else if (_util.falsey(value)) {
node.removeAttribute(name);
} else if (typeof value !== 'object' && !_util.isFunction(value)) {
node.setAttribute(name, value);
}
}
ensureNodeData(node)[name] = value;
}
/** Proxy an event to hooked event handlers
* @private
*/
function eventProxy(e) {
return this._listeners[normalizeEventName(e.type)](_hooks.optionsHook('event', e) || e);
}
/** Convert an Event name/type to lowercase and strip any "on*" prefix.
* @function
* @private
*/
var normalizeEventName = _util.memoize(function (t) {
return _util.toLowerCase(t.replace(/^on/i, ''));
});
/** Get a node's attributes as a hashmap.
* @private
*/
function getRawNodeAttributes(node) {
var list = node.attributes,
attrs = _util.createObject(),
i = list.length;
while (i--) attrs[list[i].name] = list[i].value;
return attrs;
}
|