apisearch-autocomplete
Version:
Javascript User interface for a fully customized autocomplete search.
1,708 lines (1,449 loc) • 827 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["apisearchAutocomplete"] = factory();
else
root["apisearchAutocomplete"] = factory();
})(typeof self !== 'undefined' ? self : this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 38);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
var freeGlobal = __webpack_require__(22);
/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function('return this')();
module.exports = root;
/***/ }),
/* 1 */
/***/ (function(module, exports) {
/**
* Checks if `value` is classified as an `Array` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
* @example
*
* _.isArray([1, 2, 3]);
* // => true
*
* _.isArray(document.body.children);
* // => false
*
* _.isArray('abc');
* // => false
*
* _.isArray(_.noop);
* // => false
*/
var isArray = Array.isArray;
module.exports = isArray;
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
var baseIsNative = __webpack_require__(48),
getValue = __webpack_require__(53);
/**
* Gets the native function at `key` of `object`.
*
* @private
* @param {Object} object The object to query.
* @param {string} key The key of the method to get.
* @returns {*} Returns the function if it's native, else `undefined`.
*/
function getNative(object, key) {
var value = getValue(object, key);
return baseIsNative(value) ? value : undefined;
}
module.exports = getNative;
/***/ }),
/* 3 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "h", function() { return h; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "createElement", function() { return h; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "cloneElement", function() { return cloneElement; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Component", function() { return Component; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "render", function() { return render; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "rerender", function() { return rerender; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "options", function() { return options; });
/** Virtual DOM Node */
function VNode() {}
/** Global options
* @public
* @namespace options {Object}
*/
var options = {
/** If `true`, `prop` changes trigger synchronous component updates.
* @name syncComponentUpdates
* @type Boolean
* @default true
*/
//syncComponentUpdates: true,
/** Processes all created VNodes.
* @param {VNode} vnode A newly-created VNode to normalize/process
*/
//vnode(vnode) { }
/** Hook invoked after a component is mounted. */
// afterMount(component) { }
/** Hook invoked after the DOM is updated with a component's latest render. */
// afterUpdate(component) { }
/** Hook invoked immediately before a component is unmounted. */
// beforeUnmount(component) { }
};
var stack = [];
var EMPTY_CHILDREN = [];
/**
* JSX/hyperscript reviver.
* @see http://jasonformat.com/wtf-is-jsx
* Benchmarks: https://esbench.com/bench/57ee8f8e330ab09900a1a1a0
*
* Note: this is exported as both `h()` and `createElement()` for compatibility reasons.
*
* Creates a VNode (virtual DOM element). A tree of VNodes can be used as a lightweight representation
* of the structure of a DOM tree. This structure can be realized by recursively comparing it against
* the current _actual_ DOM structure, and applying only the differences.
*
* `h()`/`createElement()` accepts an element name, a list of attributes/props,
* and optionally children to append to the element.
*
* @example The following DOM tree
*
* `<div id="foo" name="bar">Hello!</div>`
*
* can be constructed using this function as:
*
* `h('div', { id: 'foo', name : 'bar' }, 'Hello!');`
*
* @param {string} nodeName An element name. Ex: `div`, `a`, `span`, etc.
* @param {Object} attributes Any attributes/props to set on the created element.
* @param rest Additional arguments are taken to be children to append. Can be infinitely nested Arrays.
*
* @public
*/
function h(nodeName, attributes) {
var children = EMPTY_CHILDREN,
lastSimple,
child,
simple,
i;
for (i = arguments.length; i-- > 2;) {
stack.push(arguments[i]);
}
if (attributes && attributes.children != null) {
if (!stack.length) stack.push(attributes.children);
delete attributes.children;
}
while (stack.length) {
if ((child = stack.pop()) && child.pop !== undefined) {
for (i = child.length; i--;) {
stack.push(child[i]);
}
} else {
if (typeof child === 'boolean') child = null;
if (simple = typeof nodeName !== 'function') {
if (child == null) child = '';else if (typeof child === 'number') child = String(child);else if (typeof child !== 'string') simple = false;
}
if (simple && lastSimple) {
children[children.length - 1] += child;
} else if (children === EMPTY_CHILDREN) {
children = [child];
} else {
children.push(child);
}
lastSimple = simple;
}
}
var p = new VNode();
p.nodeName = nodeName;
p.children = children;
p.attributes = attributes == null ? undefined : attributes;
p.key = attributes == null ? undefined : attributes.key;
// if a "vnode hook" is defined, pass every created VNode to it
if (options.vnode !== undefined) options.vnode(p);
return p;
}
/**
* Copy all properties from `props` onto `obj`.
* @param {Object} obj Object onto which properties should be copied.
* @param {Object} props Object from which to copy properties.
* @returns obj
* @private
*/
function extend(obj, props) {
for (var i in props) {
obj[i] = props[i];
}return obj;
}
/**
* Call a function asynchronously, as soon as possible. Makes
* use of HTML Promise to schedule the callback if available,
* otherwise falling back to `setTimeout` (mainly for IE<11).
*
* @param {Function} callback
*/
var defer = typeof Promise == 'function' ? Promise.resolve().then.bind(Promise.resolve()) : setTimeout;
/**
* Clones the given VNode, optionally adding attributes/props and replacing its children.
* @param {VNode} vnode The virutal DOM element to clone
* @param {Object} props Attributes/props to add when cloning
* @param {VNode} rest Any additional arguments will be used as replacement children.
*/
function cloneElement(vnode, props) {
return h(vnode.nodeName, extend(extend({}, vnode.attributes), props), arguments.length > 2 ? [].slice.call(arguments, 2) : vnode.children);
}
// DOM properties that should NOT have "px" added when numeric
var IS_NON_DIMENSIONAL = /acit|ex(?:s|g|n|p|$)|rph|ows|mnc|ntw|ine[ch]|zoo|^ord/i;
/** Managed queue of dirty components to be re-rendered */
var items = [];
function enqueueRender(component) {
if (!component._dirty && (component._dirty = true) && items.push(component) == 1) {
(options.debounceRendering || defer)(rerender);
}
}
function rerender() {
var p,
list = items;
items = [];
while (p = list.pop()) {
if (p._dirty) renderComponent(p);
}
}
/**
* Check if two nodes are equivalent.
*
* @param {Node} node DOM Node to compare
* @param {VNode} vnode Virtual DOM node to compare
* @param {boolean} [hyrdating=false] If true, ignores component constructors when comparing.
* @private
*/
function isSameNodeType(node, vnode, hydrating) {
if (typeof vnode === 'string' || typeof vnode === 'number') {
return node.splitText !== undefined;
}
if (typeof vnode.nodeName === 'string') {
return !node._componentConstructor && isNamedNode(node, vnode.nodeName);
}
return hydrating || node._componentConstructor === vnode.nodeName;
}
/**
* Check if an Element has a given nodeName, case-insensitively.
*
* @param {Element} node A DOM Element to inspect the name of.
* @param {String} nodeName Unnormalized name to compare against.
*/
function isNamedNode(node, nodeName) {
return node.normalizedNodeName === nodeName || node.nodeName.toLowerCase() === nodeName.toLowerCase();
}
/**
* Reconstruct Component-style `props` from a VNode.
* Ensures default/fallback values from `defaultProps`:
* Own-properties of `defaultProps` not present in `vnode.attributes` are added.
*
* @param {VNode} vnode
* @returns {Object} props
*/
function getNodeProps(vnode) {
var props = extend({}, vnode.attributes);
props.children = vnode.children;
var defaultProps = vnode.nodeName.defaultProps;
if (defaultProps !== undefined) {
for (var i in defaultProps) {
if (props[i] === undefined) {
props[i] = defaultProps[i];
}
}
}
return props;
}
/** Create an element with the given nodeName.
* @param {String} nodeName
* @param {Boolean} [isSvg=false] If `true`, creates an element within the SVG namespace.
* @returns {Element} node
*/
function createNode(nodeName, isSvg) {
var node = isSvg ? document.createElementNS('http://www.w3.org/2000/svg', nodeName) : document.createElement(nodeName);
node.normalizedNodeName = nodeName;
return node;
}
/** Remove a child node from its parent if attached.
* @param {Element} node The node to remove
*/
function removeNode(node) {
var parentNode = node.parentNode;
if (parentNode) parentNode.removeChild(node);
}
/** 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} old The last value that was set for this name/node pair
* @param {any} value An attribute value, such as a function to be used as an event handler
* @param {Boolean} isSvg Are we currently diffing inside an svg?
* @private
*/
function setAccessor(node, name, old, value, isSvg) {
if (name === 'className') name = 'class';
if (name === 'key') {
// ignore
} else if (name === 'ref') {
if (old) old(null);
if (value) value(node);
} else if (name === 'class' && !isSvg) {
node.className = value || '';
} else if (name === 'style') {
if (!value || typeof value === 'string' || typeof old === 'string') {
node.style.cssText = value || '';
}
if (value && typeof value === 'object') {
if (typeof old !== 'string') {
for (var i in old) {
if (!(i in value)) node.style[i] = '';
}
}
for (var i in value) {
node.style[i] = typeof value[i] === 'number' && IS_NON_DIMENSIONAL.test(i) === false ? value[i] + 'px' : value[i];
}
}
} else if (name === 'dangerouslySetInnerHTML') {
if (value) node.innerHTML = value.__html || '';
} else if (name[0] == 'o' && name[1] == 'n') {
var useCapture = name !== (name = name.replace(/Capture$/, ''));
name = name.toLowerCase().substring(2);
if (value) {
if (!old) node.addEventListener(name, eventProxy, useCapture);
} else {
node.removeEventListener(name, eventProxy, useCapture);
}
(node._listeners || (node._listeners = {}))[name] = value;
} else if (name !== 'list' && name !== 'type' && !isSvg && name in node) {
setProperty(node, name, value == null ? '' : value);
if (value == null || value === false) node.removeAttribute(name);
} else {
var ns = isSvg && name !== (name = name.replace(/^xlink\:?/, ''));
if (value == null || value === false) {
if (ns) node.removeAttributeNS('http://www.w3.org/1999/xlink', name.toLowerCase());else node.removeAttribute(name);
} else if (typeof value !== 'function') {
if (ns) node.setAttributeNS('http://www.w3.org/1999/xlink', name.toLowerCase(), value);else node.setAttribute(name, value);
}
}
}
/** Attempt to set a DOM property to the given value.
* IE & FF throw for certain property-value combinations.
*/
function setProperty(node, name, value) {
try {
node[name] = value;
} catch (e) {}
}
/** Proxy an event to hooked event handlers
* @private
*/
function eventProxy(e) {
return this._listeners[e.type](options.event && options.event(e) || e);
}
/** Queue of components that have been mounted and are awaiting componentDidMount */
var mounts = [];
/** Diff recursion count, used to track the end of the diff cycle. */
var diffLevel = 0;
/** Global flag indicating if the diff is currently within an SVG */
var isSvgMode = false;
/** Global flag indicating if the diff is performing hydration */
var hydrating = false;
/** Invoke queued componentDidMount lifecycle methods */
function flushMounts() {
var c;
while (c = mounts.pop()) {
if (options.afterMount) options.afterMount(c);
if (c.componentDidMount) c.componentDidMount();
}
}
/** Apply differences in a given vnode (and it's deep children) to a real DOM Node.
* @param {Element} [dom=null] A DOM node to mutate into the shape of the `vnode`
* @param {VNode} vnode A VNode (with descendants forming a tree) representing the desired DOM structure
* @returns {Element} dom The created/mutated element
* @private
*/
function diff(dom, vnode, context, mountAll, parent, componentRoot) {
// diffLevel having been 0 here indicates initial entry into the diff (not a subdiff)
if (!diffLevel++) {
// when first starting the diff, check if we're diffing an SVG or within an SVG
isSvgMode = parent != null && parent.ownerSVGElement !== undefined;
// hydration is indicated by the existing element to be diffed not having a prop cache
hydrating = dom != null && !('__preactattr_' in dom);
}
var ret = idiff(dom, vnode, context, mountAll, componentRoot);
// append the element if its a new parent
if (parent && ret.parentNode !== parent) parent.appendChild(ret);
// diffLevel being reduced to 0 means we're exiting the diff
if (! --diffLevel) {
hydrating = false;
// invoke queued componentDidMount lifecycle methods
if (!componentRoot) flushMounts();
}
return ret;
}
/** Internals of `diff()`, separated to allow bypassing diffLevel / mount flushing. */
function idiff(dom, vnode, context, mountAll, componentRoot) {
var out = dom,
prevSvgMode = isSvgMode;
// empty values (null, undefined, booleans) render as empty Text nodes
if (vnode == null || typeof vnode === 'boolean') vnode = '';
// Fast case: Strings & Numbers create/update Text nodes.
if (typeof vnode === 'string' || typeof vnode === 'number') {
// update if it's already a Text node:
if (dom && dom.splitText !== undefined && dom.parentNode && (!dom._component || componentRoot)) {
/* istanbul ignore if */ /* Browser quirk that can't be covered: https://github.com/developit/preact/commit/fd4f21f5c45dfd75151bd27b4c217d8003aa5eb9 */
if (dom.nodeValue != vnode) {
dom.nodeValue = vnode;
}
} else {
// it wasn't a Text node: replace it with one and recycle the old Element
out = document.createTextNode(vnode);
if (dom) {
if (dom.parentNode) dom.parentNode.replaceChild(out, dom);
recollectNodeTree(dom, true);
}
}
out['__preactattr_'] = true;
return out;
}
// If the VNode represents a Component, perform a component diff:
var vnodeName = vnode.nodeName;
if (typeof vnodeName === 'function') {
return buildComponentFromVNode(dom, vnode, context, mountAll);
}
// Tracks entering and exiting SVG namespace when descending through the tree.
isSvgMode = vnodeName === 'svg' ? true : vnodeName === 'foreignObject' ? false : isSvgMode;
// If there's no existing element or it's the wrong type, create a new one:
vnodeName = String(vnodeName);
if (!dom || !isNamedNode(dom, vnodeName)) {
out = createNode(vnodeName, isSvgMode);
if (dom) {
// move children into the replacement node
while (dom.firstChild) {
out.appendChild(dom.firstChild);
} // if the previous Element was mounted into the DOM, replace it inline
if (dom.parentNode) dom.parentNode.replaceChild(out, dom);
// recycle the old element (skips non-Element node types)
recollectNodeTree(dom, true);
}
}
var fc = out.firstChild,
props = out['__preactattr_'],
vchildren = vnode.children;
if (props == null) {
props = out['__preactattr_'] = {};
for (var a = out.attributes, i = a.length; i--;) {
props[a[i].name] = a[i].value;
}
}
// Optimization: fast-path for elements containing a single TextNode:
if (!hydrating && vchildren && vchildren.length === 1 && typeof vchildren[0] === 'string' && fc != null && fc.splitText !== undefined && fc.nextSibling == null) {
if (fc.nodeValue != vchildren[0]) {
fc.nodeValue = vchildren[0];
}
}
// otherwise, if there are existing or new children, diff them:
else if (vchildren && vchildren.length || fc != null) {
innerDiffNode(out, vchildren, context, mountAll, hydrating || props.dangerouslySetInnerHTML != null);
}
// Apply attributes/props from VNode to the DOM Element:
diffAttributes(out, vnode.attributes, props);
// restore previous SVG mode: (in case we're exiting an SVG namespace)
isSvgMode = prevSvgMode;
return out;
}
/** Apply child and attribute changes between a VNode and a DOM Node to the DOM.
* @param {Element} dom Element whose children should be compared & mutated
* @param {Array} vchildren Array of VNodes to compare to `dom.childNodes`
* @param {Object} context Implicitly descendant context object (from most recent `getChildContext()`)
* @param {Boolean} mountAll
* @param {Boolean} isHydrating If `true`, consumes externally created elements similar to hydration
*/
function innerDiffNode(dom, vchildren, context, mountAll, isHydrating) {
var originalChildren = dom.childNodes,
children = [],
keyed = {},
keyedLen = 0,
min = 0,
len = originalChildren.length,
childrenLen = 0,
vlen = vchildren ? vchildren.length : 0,
j,
c,
f,
vchild,
child;
// Build up a map of keyed children and an Array of unkeyed children:
if (len !== 0) {
for (var i = 0; i < len; i++) {
var _child = originalChildren[i],
props = _child['__preactattr_'],
key = vlen && props ? _child._component ? _child._component.__key : props.key : null;
if (key != null) {
keyedLen++;
keyed[key] = _child;
} else if (props || (_child.splitText !== undefined ? isHydrating ? _child.nodeValue.trim() : true : isHydrating)) {
children[childrenLen++] = _child;
}
}
}
if (vlen !== 0) {
for (var i = 0; i < vlen; i++) {
vchild = vchildren[i];
child = null;
// attempt to find a node based on key matching
var key = vchild.key;
if (key != null) {
if (keyedLen && keyed[key] !== undefined) {
child = keyed[key];
keyed[key] = undefined;
keyedLen--;
}
}
// attempt to pluck a node of the same type from the existing children
else if (!child && min < childrenLen) {
for (j = min; j < childrenLen; j++) {
if (children[j] !== undefined && isSameNodeType(c = children[j], vchild, isHydrating)) {
child = c;
children[j] = undefined;
if (j === childrenLen - 1) childrenLen--;
if (j === min) min++;
break;
}
}
}
// morph the matched/found/created DOM child to match vchild (deep)
child = idiff(child, vchild, context, mountAll);
f = originalChildren[i];
if (child && child !== dom && child !== f) {
if (f == null) {
dom.appendChild(child);
} else if (child === f.nextSibling) {
removeNode(f);
} else {
dom.insertBefore(child, f);
}
}
}
}
// remove unused keyed children:
if (keyedLen) {
for (var i in keyed) {
if (keyed[i] !== undefined) recollectNodeTree(keyed[i], false);
}
}
// remove orphaned unkeyed children:
while (min <= childrenLen) {
if ((child = children[childrenLen--]) !== undefined) recollectNodeTree(child, false);
}
}
/** Recursively recycle (or just unmount) a node and its descendants.
* @param {Node} node DOM node to start unmount/removal from
* @param {Boolean} [unmountOnly=false] If `true`, only triggers unmount lifecycle, skips removal
*/
function recollectNodeTree(node, unmountOnly) {
var component = node._component;
if (component) {
// if node is owned by a Component, unmount that component (ends up recursing back here)
unmountComponent(component);
} else {
// If the node's VNode had a ref function, invoke it with null here.
// (this is part of the React spec, and smart for unsetting references)
if (node['__preactattr_'] != null && node['__preactattr_'].ref) node['__preactattr_'].ref(null);
if (unmountOnly === false || node['__preactattr_'] == null) {
removeNode(node);
}
removeChildren(node);
}
}
/** Recollect/unmount all children.
* - we use .lastChild here because it causes less reflow than .firstChild
* - it's also cheaper than accessing the .childNodes Live NodeList
*/
function removeChildren(node) {
node = node.lastChild;
while (node) {
var next = node.previousSibling;
recollectNodeTree(node, true);
node = next;
}
}
/** Apply differences in attributes from a VNode to the given DOM Element.
* @param {Element} dom Element with attributes to diff `attrs` against
* @param {Object} attrs The desired end-state key-value attribute pairs
* @param {Object} old Current/previous attributes (from previous VNode or element's prop cache)
*/
function diffAttributes(dom, attrs, old) {
var name;
// remove attributes no longer present on the vnode by setting them to undefined
for (name in old) {
if (!(attrs && attrs[name] != null) && old[name] != null) {
setAccessor(dom, name, old[name], old[name] = undefined, isSvgMode);
}
}
// add new & update changed attributes
for (name in attrs) {
if (name !== 'children' && name !== 'innerHTML' && (!(name in old) || attrs[name] !== (name === 'value' || name === 'checked' ? dom[name] : old[name]))) {
setAccessor(dom, name, old[name], old[name] = attrs[name], isSvgMode);
}
}
}
/** Retains a pool of Components for re-use, keyed on component name.
* Note: since component names are not unique or even necessarily available, these are primarily a form of sharding.
* @private
*/
var components = {};
/** Reclaim a component for later re-use by the recycler. */
function collectComponent(component) {
var name = component.constructor.name;
(components[name] || (components[name] = [])).push(component);
}
/** Create a component. Normalizes differences between PFC's and classful Components. */
function createComponent(Ctor, props, context) {
var list = components[Ctor.name],
inst;
if (Ctor.prototype && Ctor.prototype.render) {
inst = new Ctor(props, context);
Component.call(inst, props, context);
} else {
inst = new Component(props, context);
inst.constructor = Ctor;
inst.render = doRender;
}
if (list) {
for (var i = list.length; i--;) {
if (list[i].constructor === Ctor) {
inst.nextBase = list[i].nextBase;
list.splice(i, 1);
break;
}
}
}
return inst;
}
/** The `.render()` method for a PFC backing instance. */
function doRender(props, state, context) {
return this.constructor(props, context);
}
/** Set a component's `props` (generally derived from JSX attributes).
* @param {Object} props
* @param {Object} [opts]
* @param {boolean} [opts.renderSync=false] If `true` and {@link options.syncComponentUpdates} is `true`, triggers synchronous rendering.
* @param {boolean} [opts.render=true] If `false`, no render will be triggered.
*/
function setComponentProps(component, props, opts, context, mountAll) {
if (component._disable) return;
component._disable = true;
if (component.__ref = props.ref) delete props.ref;
if (component.__key = props.key) delete props.key;
if (!component.base || mountAll) {
if (component.componentWillMount) component.componentWillMount();
} else if (component.componentWillReceiveProps) {
component.componentWillReceiveProps(props, context);
}
if (context && context !== component.context) {
if (!component.prevContext) component.prevContext = component.context;
component.context = context;
}
if (!component.prevProps) component.prevProps = component.props;
component.props = props;
component._disable = false;
if (opts !== 0) {
if (opts === 1 || options.syncComponentUpdates !== false || !component.base) {
renderComponent(component, 1, mountAll);
} else {
enqueueRender(component);
}
}
if (component.__ref) component.__ref(component);
}
/** Render a Component, triggering necessary lifecycle events and taking High-Order Components into account.
* @param {Component} component
* @param {Object} [opts]
* @param {boolean} [opts.build=false] If `true`, component will build and store a DOM node if not already associated with one.
* @private
*/
function renderComponent(component, opts, mountAll, isChild) {
if (component._disable) return;
var props = component.props,
state = component.state,
context = component.context,
previousProps = component.prevProps || props,
previousState = component.prevState || state,
previousContext = component.prevContext || context,
isUpdate = component.base,
nextBase = component.nextBase,
initialBase = isUpdate || nextBase,
initialChildComponent = component._component,
skip = false,
rendered,
inst,
cbase;
// if updating
if (isUpdate) {
component.props = previousProps;
component.state = previousState;
component.context = previousContext;
if (opts !== 2 && component.shouldComponentUpdate && component.shouldComponentUpdate(props, state, context) === false) {
skip = true;
} else if (component.componentWillUpdate) {
component.componentWillUpdate(props, state, context);
}
component.props = props;
component.state = state;
component.context = context;
}
component.prevProps = component.prevState = component.prevContext = component.nextBase = null;
component._dirty = false;
if (!skip) {
rendered = component.render(props, state, context);
// context to pass to the child, can be updated via (grand-)parent component
if (component.getChildContext) {
context = extend(extend({}, context), component.getChildContext());
}
var childComponent = rendered && rendered.nodeName,
toUnmount,
base;
if (typeof childComponent === 'function') {
// set up high order component link
var childProps = getNodeProps(rendered);
inst = initialChildComponent;
if (inst && inst.constructor === childComponent && childProps.key == inst.__key) {
setComponentProps(inst, childProps, 1, context, false);
} else {
toUnmount = inst;
component._component = inst = createComponent(childComponent, childProps, context);
inst.nextBase = inst.nextBase || nextBase;
inst._parentComponent = component;
setComponentProps(inst, childProps, 0, context, false);
renderComponent(inst, 1, mountAll, true);
}
base = inst.base;
} else {
cbase = initialBase;
// destroy high order component link
toUnmount = initialChildComponent;
if (toUnmount) {
cbase = component._component = null;
}
if (initialBase || opts === 1) {
if (cbase) cbase._component = null;
base = diff(cbase, rendered, context, mountAll || !isUpdate, initialBase && initialBase.parentNode, true);
}
}
if (initialBase && base !== initialBase && inst !== initialChildComponent) {
var baseParent = initialBase.parentNode;
if (baseParent && base !== baseParent) {
baseParent.replaceChild(base, initialBase);
if (!toUnmount) {
initialBase._component = null;
recollectNodeTree(initialBase, false);
}
}
}
if (toUnmount) {
unmountComponent(toUnmount);
}
component.base = base;
if (base && !isChild) {
var componentRef = component,
t = component;
while (t = t._parentComponent) {
(componentRef = t).base = base;
}
base._component = componentRef;
base._componentConstructor = componentRef.constructor;
}
}
if (!isUpdate || mountAll) {
mounts.unshift(component);
} else if (!skip) {
// Ensure that pending componentDidMount() hooks of child components
// are called before the componentDidUpdate() hook in the parent.
// Note: disabled as it causes duplicate hooks, see https://github.com/developit/preact/issues/750
// flushMounts();
if (component.componentDidUpdate) {
component.componentDidUpdate(previousProps, previousState, previousContext);
}
if (options.afterUpdate) options.afterUpdate(component);
}
if (component._renderCallbacks != null) {
while (component._renderCallbacks.length) {
component._renderCallbacks.pop().call(component);
}
}
if (!diffLevel && !isChild) flushMounts();
}
/** Apply the Component referenced by a VNode to the DOM.
* @param {Element} dom The DOM node to mutate
* @param {VNode} vnode A Component-referencing VNode
* @returns {Element} dom The created/mutated element
* @private
*/
function buildComponentFromVNode(dom, vnode, context, mountAll) {
var c = dom && dom._component,
originalComponent = c,
oldDom = dom,
isDirectOwner = c && dom._componentConstructor === vnode.nodeName,
isOwner = isDirectOwner,
props = getNodeProps(vnode);
while (c && !isOwner && (c = c._parentComponent)) {
isOwner = c.constructor === vnode.nodeName;
}
if (c && isOwner && (!mountAll || c._component)) {
setComponentProps(c, props, 3, context, mountAll);
dom = c.base;
} else {
if (originalComponent && !isDirectOwner) {
unmountComponent(originalComponent);
dom = oldDom = null;
}
c = createComponent(vnode.nodeName, props, context);
if (dom && !c.nextBase) {
c.nextBase = dom;
// passing dom/oldDom as nextBase will recycle it if unused, so bypass recycling on L229:
oldDom = null;
}
setComponentProps(c, props, 1, context, mountAll);
dom = c.base;
if (oldDom && dom !== oldDom) {
oldDom._component = null;
recollectNodeTree(oldDom, false);
}
}
return dom;
}
/** Remove a component from the DOM and recycle it.
* @param {Component} component The Component instance to unmount
* @private
*/
function unmountComponent(component) {
if (options.beforeUnmount) options.beforeUnmount(component);
var base = component.base;
component._disable = true;
if (component.componentWillUnmount) component.componentWillUnmount();
component.base = null;
// recursively tear down & recollect high-order component children:
var inner = component._component;
if (inner) {
unmountComponent(inner);
} else if (base) {
if (base['__preactattr_'] && base['__preactattr_'].ref) base['__preactattr_'].ref(null);
component.nextBase = base;
removeNode(base);
collectComponent(component);
removeChildren(base);
}
if (component.__ref) component.__ref(null);
}
/** Base Component class.
* Provides `setState()` and `forceUpdate()`, which trigger rendering.
* @public
*
* @example
* class MyFoo extends Component {
* render(props, state) {
* return <div />;
* }
* }
*/
function Component(props, context) {
this._dirty = true;
/** @public
* @type {object}
*/
this.context = context;
/** @public
* @type {object}
*/
this.props = props;
/** @public
* @type {object}
*/
this.state = this.state || {};
}
extend(Component.prototype, {
/** Returns a `boolean` indicating if the component should re-render when receiving the given `props` and `state`.
* @param {object} nextProps
* @param {object} nextState
* @param {object} nextContext
* @returns {Boolean} should the component re-render
* @name shouldComponentUpdate
* @function
*/
/** Update component state by copying properties from `state` to `this.state`.
* @param {object} state A hash of state properties to update with new values
* @param {function} callback A function to be called once component state is updated
*/
setState: function setState(state, callback) {
var s = this.state;
if (!this.prevState) this.prevState = extend({}, s);
extend(s, typeof state === 'function' ? state(s, this.props) : state);
if (callback) (this._renderCallbacks = this._renderCallbacks || []).push(callback);
enqueueRender(this);
},
/** Immediately perform a synchronous re-render of the component.
* @param {function} callback A function to be called after component is re-rendered.
* @private
*/
forceUpdate: function forceUpdate(callback) {
if (callback) (this._renderCallbacks = this._renderCallbacks || []).push(callback);
renderComponent(this, 2);
},
/** Accepts `props` and `state`, and returns a new Virtual DOM tree to build.
* Virtual DOM is generally constructed via [JSX](http://jasonformat.com/wtf-is-jsx).
* @param {object} props Props (eg: JSX attributes) received from parent element/component
* @param {object} state The component's current state
* @param {object} context Context object (if a parent component has provided context)
* @returns VNode
*/
render: function render() {}
});
/** Render JSX into a `parent` Element.
* @param {VNode} vnode A (JSX) VNode to render
* @param {Element} parent DOM element to render into
* @param {Element} [merge] Attempt to re-use an existing DOM tree rooted at `merge`
* @public
*
* @example
* // render a div into <body>:
* render(<div id="hello">hello!</div>, document.body);
*
* @example
* // render a "Thing" component into #foo:
* const Thing = ({ name }) => <span>{ name }</span>;
* render(<Thing name="one" />, document.querySelector('#foo'));
*/
function render(vnode, parent, merge) {
return diff(merge, vnode, {}, false, parent, false);
}
var preact = {
h: h,
createElement: h,
cloneElement: cloneElement,
Component: Component,
render: render,
rerender: rerender,
options: options
};
/* harmony default export */ __webpack_exports__["default"] = (preact);
//# sourceMappingURL=preact.esm.js.map
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
var Symbol = __webpack_require__(6),
getRawTag = __webpack_require__(49),
objectToString = __webpack_require__(50);
/** `Object#toString` result references. */
var nullTag = '[object Null]',
undefinedTag = '[object Undefined]';
/** Built-in value references. */
var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
/**
* The base implementation of `getTag` without fallbacks for buggy environments.
*
* @private
* @param {*} value The value to query.
* @returns {string} Returns the `toStringTag`.
*/
function baseGetTag(value) {
if (value == null) {
return value === undefined ? undefinedTag : nullTag;
}
return (symToStringTag && symToStringTag in Object(value))
? getRawTag(value)
: objectToString(value);
}
module.exports = baseGetTag;
/***/ }),
/* 5 */
/***/ (function(module, exports) {
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return value != null && typeof value == 'object';
}
module.exports = isObjectLike;
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
var root = __webpack_require__(0);
/** Built-in value references. */
var Symbol = root.Symbol;
module.exports = Symbol;
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
var listCacheClear = __webpack_require__(76),
listCacheDelete = __webpack_require__(77),
listCacheGet = __webpack_require__(78),
listCacheHas = __webpack_require__(79),
listCacheSet = __webpack_require__(80);
/**
* Creates an list cache object.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function ListCache(entries) {
var index = -1,
length = entries == null ? 0 : entries.length;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
// Add methods to `ListCache`.
ListCache.prototype.clear = listCacheClear;
ListCache.prototype['delete'] = listCacheDelete;
ListCache.prototype.get = listCacheGet;
ListCache.prototype.has = listCacheHas;
ListCache.prototype.set = listCacheSet;
module.exports = ListCache;
/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {
var eq = __webpack_require__(31);
/**
* Gets the index at which the `key` is found in `array` of key-value pairs.
*
* @private
* @param {Array} array The array to inspect.
* @param {*} key The key to search for.
* @returns {number} Returns the index of the matched value, else `-1`.
*/
function assocIndexOf(array, key) {
var length = array.length;
while (length--) {
if (eq(array[length][0], key)) {
return length;
}
}
return -1;
}
module.exports = assocIndexOf;
/***/ }),
/* 9 */
/***/ (function(module, exports, __webpack_require__) {
var getNative = __webpack_require__(2);
/* Built-in method references that are verified to be native. */
var nativeCreate = getNative(Object, 'create');
module.exports = nativeCreate;
/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {
var isKeyable = __webpack_require__(94);
/**
* Gets the data for `map`.
*
* @private
* @param {Object} map The map to query.
* @param {string} key The reference key.
* @returns {*} Returns the map data.
*/
function getMapData(map, key) {
var data = map.__data__;
return isKeyable(key)
? data[typeof key == 'string' ? 'string' : 'hash']
: data.map;
}
module.exports = getMapData;
/***/ }),
/* 11 */
/***/ (function(module, exports, __webpack_require__) {
var isSymbol = __webpack_require__(20);
/** Used as references for various `Number` constants. */
var INFINITY = 1 / 0;
/**
* Converts `value` to a string key if it's not a string or symbol.
*
* @private
* @param {*} value The value to inspect.
* @returns {string|symbol} Returns the key.
*/
function toKey(value) {
if (typeof value == 'string' || isSymbol(value)) {
return value;
}
var result = (value + '');
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
}
module.exports = toKey;
/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {
var t=__webpack_require__(3);function n(t,n){"function"==typeof t&&(t=t(n));var r={};for(var e in t)r[e]=n.action(t[e]);return r}function r(t){return"string"==typeof t&&(t=t.split(/\s*,\s*/)),function(n){for(var r={},e=0;e<t.length;e++)r[t[e]]=n[t[e]];return r}}function e(t,n){for(var r in n)t[r]=n[r];return t}function o(o,i){return"function"!=typeof o&&(o=r(o||[])),function(r){function u(u,c){var f=this,s=c.store,p=o(s?s.getState():{},u),a=i?n(i,s):{store:s},l=function(){var t=o(s?s.getState():{},f.props);for(var n in t)if(t[n]!==p[n])return p=t,f.setState(null);for(var r in p)if(!(r in t))return p=t,f.setState(null)};this.componentDidMount=function(){l(),s.subscribe(l)},this.componentWillUnmount=function(){s.unsubscribe(l)},this.render=function(n){return t.h(r,e(e(e({},a),n),p))}}return(u.prototype=new t.Component).constructor=u}}function i(t){this.getChildContext=function(){return{store:t.store}}}i.prototype.render=function(t){return t.children[0]},exports.connect=o,exports.Provider=i;
//# sourceMappingURL=preact.js.map
/***/ }),
/* 13 */
/***/ (function(module, exports) {
/**
* Checks if `value` is the
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* _.isObject({});
* // => true
*
* _.isObject([1, 2, 3]);
* // => true
*
* _.isObject(_.noop);
* // => true
*
* _.isObject(null);
* // => false
*/
function isObject(value) {
var type = typeof value;
return value != null && (type == 'object' || type == 'function');
}
module.exports = isObject;
/***/ }),
/* 14 */
/***/ (function(module, exports, __webpack_require__) {
var arrayLikeKeys = __webpack_require__(61),
baseKeys = __webpack_require__(68),
isArrayLike = __webpack_require__(29);
/**
* Creates an array of the own enumerable property names of `object`.
*
* **Note:** Non-object values are coerced to objects. See the
* [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
* for more details.
*
* @static
* @since 0.1.0
* @memberOf _
* @category Object
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property names.
* @example
*
* function Foo() {
* this.a = 1;
* this.b = 2;
* }
*
* Foo.prototype.c = 3;
*
* _.keys(new Foo);
* // => ['a', 'b'] (iteration order is not guaranteed)
*
* _.keys('hi');
* // => ['0', '1']
*/
function keys(object) {
return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
}
module.exports = keys;
/***/ }),
/* 15 */
/***/ (function(module, exports) {
module.exports = function(module) {
if(!module.webpackPolyfill) {
module.deprecate = function() {};
module.paths = [];
// module.parent = undefined by default
if(!module.children) module.children = [];
Object.defineProperty(module, "loaded", {
enumerable: true,
get: function() {
return module.l;
}
});
Object.defineProperty(module, "id", {
enumerable: true,
get: function() {
return module.i;
}
});
module.webpackPolyfill = 1;
}
return module;
};
/***/ }),
/* 16 */
/***/ (function(module, exports) {
/** Used as references for various `Number` constants. */
var MAX_SAFE_INTEGER = 9007199254740991;
/**
* Checks if `value` is a valid array-like length.
*
* **Note:** This method is loosely based on
* [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
* @example
*
* _.isLength(3);
* // => true
*
* _.isLength(Number.MIN_VALUE);
* // => false
*
* _.isLength(Infinity);
* // => false
*
* _.isLength('3');
* // => false
*/
function isLength(value) {
return typeof value == 'number' &&
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
}
module.exports = isLength;
/***/ }),
/* 17 */
/***/ (function(module, exports, __webpack_require__) {
var getNative = __webpack_require__(2),
root = __webpack_require__(0);
/* Built-in method references that are verified to be native. */
var Map = getNative(root, 'Map');
module.exports = Map;
/***/ }),
/* 18 */
/***/ (function(module, exports, __webpack_require__) {
var mapCacheClear = __webpack_require__(86),
mapCacheDelete = __webpack_require__(93),
mapCacheGet = __webpack_require__(95),
mapCacheHas = __webpack_require__(96),
mapCacheSet = __webpack_require__(97);
/**
* Creates a map cache object to store key-value pairs.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function MapCache(entries) {
var index = -1,
length = entries == null ? 0 : entries.length;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
// Add methods to `MapCache`.
MapCache.prototype.clear = mapCacheClear;
MapCache.prototype['delete'] = mapCacheDelete;
MapCache.prototype.get = mapCacheGet;
MapCache.prototype.has = mapCacheHas;
MapCache.prototype.set = mapCacheSet;
module.exports = MapCache;
/***/ }),
/* 19 */
/***/ (function(module, exports, __webpack_require__) {
var isArray = __webpack_require__(1),
isSymbol = __webpack_require__(20);
/** Used to match property names within property paths. */
var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
reIsPlainProp = /^\w*$/;
/**
* Checks if `value` is a property name and not a property path.
*
* @private
* @param {*} value The value to check.
* @param {Object} [object] The object to query keys on.
* @returns {boolean} Returns `true` if `value` is a property name, else `false`.
*/
function isKey(value, object) {
if (isArray(value)) {
return false;
}
var type = typeof value;
if (type == 'number' || type == 'symbol' || type == 'boolean' ||
value == null || isSymbol(value)) {
return true;
}
return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
(object != null && value in Object(object));
}
module.exports = isKey;
/***/ }),
/* 20 */
/***/ (function(module, exports, __webpack_require__) {
var baseGetTag = __webpack_require__(4),
isObjectLike = __webpack_require__(5);
/** `Object#toString` result references. */
var symbolTag = '[object Symbol]';
/**
* Checks if `value` is classified as a `Symbol` primitive or object.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
* @example
*
* _.isSymbol(Symbol.iterator);
* // => true
*
* _.isSymbol('abc');
* // => false
*/
function isSymbol(value) {
return typeof value == 'symbol' ||
(isObjectLike(value) && baseGetTag(value) == symbolTag);
}
module.exports = isSymbol;
/***/ }),
/* 21 */
/***/ (function(module, exports, __webpack_require__) {
var baseGetTag = __webpack_require__(4),
isObject = __webpack_require__(13);
/** `Object#toString` result references. */
var asyncTag = '[object AsyncFunction]',
funcTag = '[object Function]',
genTag = '[object GeneratorFunction]',
proxyTag = '[object Proxy]';
/**
* Checks if `value` is classified as a `Function` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
* @example
*
* _.isFunction(_);
* // => true
*
* _.isFunction(/abc/);
* // => false
*/
function isFunction(value) {
if (!isObject(value)) {
return false;
}
// The use of `Object#toString` avoids issues with the `typeof` operator
// in Safari 9 which returns 'object' for typed arrays and other constructors.
var tag = baseGetTag(value);
return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
}
module.exports = isFunction;
/***/ }),
/* 22 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(global) {/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
module.exports = freeGlobal;
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(23)))
/***/ })