UNPKG

@skatejs/val

Version:

VirtualDOM abstraction layer - give yourself better integration and full control over the DOM with any virtual DOM library that uses a Hyperscript-like API such as React and Preact.

225 lines (176 loc) 6.06 kB
Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = val; exports.h = void 0; function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } var _window = window, customElements = _window.customElements; var cacheCtorLocalNames = new Map(); var cacheElementEventHandlers = new WeakMap(); // Override customElements.define() to cache constructor local names. This is // required for all virtual DOM implementations that don't natively support // custom element constructors as node names. if (customElements) { var define = customElements.define; customElements.define = function (name, Ctor) { cacheCtorLocalNames.set(Ctor, name); return define.call(customElements, name, Ctor); }; } // Applies attributes to the ref element. It doesn't traverse through // existing attributes and assumes that the supplied object will supply // all attributes that the applicator should care about, even ones that // should be removed. function applyAttrs(e, attrs) { if (!attrs) return; Object.keys(attrs).forEach(function (name) { var value = attrs[name]; if (value == null) { e.removeAttribute(name); } else { e.setAttribute(name, value); } }); } function applyEvents(e) { var events = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var handlers = cacheElementEventHandlers.get(e) || {}; cacheElementEventHandlers.set(e, events); // Remove any old listeners that are different - or aren't specified // in - the new set. Object.keys(handlers).forEach(function (name) { if (handlers[name] && handlers[name] !== events[name]) { e.removeEventListener(name, handlers[name]); } }); // Bind new listeners. Object.keys(events).forEach(function (name) { if (events[name] !== handlers[name]) { e.addEventListener(name, events[name]); } }); } // Sets props. Straight up. function applyProps(e, props) { Object.keys(props || {}).forEach(function (name) { e[name] = props[name]; }); } // Ensures that if a ref was specified that it's called as normal. function applyRef(e, ref) { if (ref) { ref(e); } } // Ensures attrs, events and props are all set as the consumer intended. function ensureProps(objs) { var _ref = objs || {}, attrs = _ref.attrs, events = _ref.events, props = _ref.props, ref = _ref.ref, pass = _objectWithoutProperties(_ref, ["attrs", "events", "props", "ref"]); var newRef = ensureRef(attrs, events, props, ref); return _objectSpread({}, pass, { ref: newRef }); } // Ensures a ref is supplied that set each member appropriately and that // the original ref is called. function ensureRef(attrs, events, props, ref) { return function (e) { if (e) { applyAttrs(e, attrs); applyEvents(e, events); applyProps(e, props); } applyRef(e, ref); }; } // Returns the custom element local name if it exists or the original // value. function ensureLocalName(lname) { var temp = cacheCtorLocalNames.get(lname); return temp || lname; } // Default adapter for rendering DOM. function defaultCreateElement(lname, _ref2) { var ref = _ref2.ref, props = _objectWithoutProperties(_ref2, ["ref"]); var node = typeof lname === "function" ? new lname() : document.createElement(lname); if (ref) { ref(node); } for (var name in props) { node[name] = props[name]; } for (var _len = arguments.length, chren = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { chren[_key - 2] = arguments[_key]; } chren.forEach(function (c) { return node.appendChild(typeof c === "string" ? document.createTextNode(c) : c); }); return node; } // Provides a function that takes the original createElement that is being // wrapped. It returns a function that you call like you normally would. // // It requires support for: // - `ref` function val() { var createElement = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultCreateElement; return function (lname, props) { lname = ensureLocalName(lname); props = ensureProps(props); for (var _len2 = arguments.length, chren = new Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { chren[_key2 - 2] = arguments[_key2]; } return createElement.apply(void 0, [lname, props].concat(chren)); }; } var h = val(); exports.h = h;