UNPKG

23.3 kBJavaScriptView Raw
1!function(global, factory) {
2 'object' == typeof exports && 'undefined' != typeof module ? factory(exports) : 'function' == typeof define && define.amd ? define([ 'exports' ], factory) : factory(global.preact = global.preact || {});
3}(this, function(exports) {
4 function VNode(nodeName, attributes, children) {
5 this.nodeName = nodeName;
6 this.attributes = attributes;
7 this.children = children;
8 this.key = attributes && attributes.key;
9 }
10 function h(nodeName, attributes) {
11 var lastSimple, child, simple, i, children = [];
12 for (i = arguments.length; i-- > 2; ) stack.push(arguments[i]);
13 if (attributes && attributes.children) {
14 if (!stack.length) stack.push(attributes.children);
15 delete attributes.children;
16 }
17 while (stack.length) if ((child = stack.pop()) instanceof Array) for (i = child.length; i--; ) stack.push(child[i]); else if (null != child && child !== !1) {
18 if ('number' == typeof child || child === !0) child = String(child);
19 simple = 'string' == typeof child;
20 if (simple && lastSimple) children[children.length - 1] += child; else {
21 children.push(child);
22 lastSimple = simple;
23 }
24 }
25 var p = new VNode(nodeName, attributes || void 0, children);
26 if (options.vnode) options.vnode(p);
27 return p;
28 }
29 function extend(obj, props) {
30 if (props) for (var i in props) obj[i] = props[i];
31 return obj;
32 }
33 function clone(obj) {
34 return extend({}, obj);
35 }
36 function delve(obj, key) {
37 for (var p = key.split('.'), i = 0; i < p.length && obj; i++) obj = obj[p[i]];
38 return obj;
39 }
40 function isFunction(obj) {
41 return 'function' == typeof obj;
42 }
43 function isString(obj) {
44 return 'string' == typeof obj;
45 }
46 function hashToClassName(c) {
47 var str = '';
48 for (var prop in c) if (c[prop]) {
49 if (str) str += ' ';
50 str += prop;
51 }
52 return str;
53 }
54 function cloneElement(vnode, props) {
55 return h(vnode.nodeName, extend(clone(vnode.attributes), props), arguments.length > 2 ? [].slice.call(arguments, 2) : vnode.children);
56 }
57 function createLinkedState(component, key, eventPath) {
58 var path = key.split('.');
59 return function(e) {
60 var t = e && e.target || this, state = {}, obj = state, v = isString(eventPath) ? delve(e, eventPath) : t.nodeName ? t.type.match(/^che|rad/) ? t.checked : t.value : e, i = 0;
61 for (;i < path.length - 1; i++) obj = obj[path[i]] || (obj[path[i]] = !i && component.state[path[i]] || {});
62 obj[path[i]] = v;
63 component.setState(state);
64 };
65 }
66 function enqueueRender(component) {
67 if (!component._dirty && (component._dirty = !0) && 1 == items.push(component)) (options.debounceRendering || defer)(rerender);
68 }
69 function rerender() {
70 var p, list = items;
71 items = [];
72 while (p = list.pop()) if (p._dirty) renderComponent(p);
73 }
74 function isFunctionalComponent(vnode) {
75 var nodeName = vnode && vnode.nodeName;
76 return nodeName && isFunction(nodeName) && !(nodeName.prototype && nodeName.prototype.render);
77 }
78 function buildFunctionalComponent(vnode, context) {
79 return vnode.nodeName(getNodeProps(vnode), context || EMPTY);
80 }
81 function isSameNodeType(node, vnode) {
82 if (isString(vnode)) return node instanceof Text;
83 if (isString(vnode.nodeName)) return isNamedNode(node, vnode.nodeName);
84 if (isFunction(vnode.nodeName)) return node._componentConstructor === vnode.nodeName || isFunctionalComponent(vnode); else ;
85 }
86 function isNamedNode(node, nodeName) {
87 return node.normalizedNodeName === nodeName || toLowerCase(node.nodeName) === toLowerCase(nodeName);
88 }
89 function getNodeProps(vnode) {
90 var props = clone(vnode.attributes);
91 props.children = vnode.children;
92 var defaultProps = vnode.nodeName.defaultProps;
93 if (defaultProps) for (var i in defaultProps) if (void 0 === props[i]) props[i] = defaultProps[i];
94 return props;
95 }
96 function removeNode(node) {
97 var p = node.parentNode;
98 if (p) p.removeChild(node);
99 }
100 function setAccessor(node, name, old, value, isSvg) {
101 if ('className' === name) name = 'class';
102 if ('class' === name && value && 'object' == typeof value) value = hashToClassName(value);
103 if ('key' === name) ; else if ('class' === name && !isSvg) node.className = value || ''; else if ('style' === name) {
104 if (!value || isString(value) || isString(old)) node.style.cssText = value || '';
105 if (value && 'object' == typeof value) {
106 if (!isString(old)) for (var i in old) if (!(i in value)) node.style[i] = '';
107 for (var i in value) node.style[i] = 'number' == typeof value[i] && !NON_DIMENSION_PROPS[i] ? value[i] + 'px' : value[i];
108 }
109 } else if ('dangerouslySetInnerHTML' === name) {
110 if (value) node.innerHTML = value.__html;
111 } else if ('o' == name[0] && 'n' == name[1]) {
112 var l = node._listeners || (node._listeners = {});
113 name = toLowerCase(name.substring(2));
114 if (value) {
115 if (!l[name]) node.addEventListener(name, eventProxy, !!NON_BUBBLING_EVENTS[name]);
116 } else if (l[name]) node.removeEventListener(name, eventProxy, !!NON_BUBBLING_EVENTS[name]);
117 l[name] = value;
118 } else if ('list' !== name && 'type' !== name && !isSvg && name in node) {
119 setProperty(node, name, null == value ? '' : value);
120 if (null == value || value === !1) node.removeAttribute(name);
121 } else {
122 var ns = isSvg && name.match(/^xlink\:?(.+)/);
123 if (null == value || value === !1) if (ns) node.removeAttributeNS('http://www.w3.org/1999/xlink', toLowerCase(ns[1])); else node.removeAttribute(name); else if ('object' != typeof value && !isFunction(value)) if (ns) node.setAttributeNS('http://www.w3.org/1999/xlink', toLowerCase(ns[1]), value); else node.setAttribute(name, value);
124 }
125 }
126 function setProperty(node, name, value) {
127 try {
128 node[name] = value;
129 } catch (e) {}
130 }
131 function eventProxy(e) {
132 return this._listeners[e.type](options.event && options.event(e) || e);
133 }
134 function collectNode(node) {
135 removeNode(node);
136 if (node instanceof Element) {
137 node._component = node._componentConstructor = null;
138 var _name = node.normalizedNodeName || toLowerCase(node.nodeName);
139 (nodes[_name] || (nodes[_name] = [])).push(node);
140 }
141 }
142 function createNode(nodeName, isSvg) {
143 var name = toLowerCase(nodeName), node = nodes[name] && nodes[name].pop() || (isSvg ? document.createElementNS('http://www.w3.org/2000/svg', nodeName) : document.createElement(nodeName));
144 node.normalizedNodeName = name;
145 return node;
146 }
147 function flushMounts() {
148 var c;
149 while (c = mounts.pop()) {
150 if (options.afterMount) options.afterMount(c);
151 if (c.componentDidMount) c.componentDidMount();
152 }
153 }
154 function diff(dom, vnode, context, mountAll, parent, componentRoot) {
155 if (!diffLevel++) isSvgMode = parent instanceof SVGElement;
156 var ret = idiff(dom, vnode, context, mountAll);
157 if (parent && ret.parentNode !== parent) parent.appendChild(ret);
158 if (!--diffLevel && !componentRoot) flushMounts();
159 return ret;
160 }
161 function idiff(dom, vnode, context, mountAll) {
162 var originalAttributes = vnode && vnode.attributes;
163 while (isFunctionalComponent(vnode)) vnode = buildFunctionalComponent(vnode, context);
164 if (null == vnode) vnode = '';
165 if (isString(vnode)) {
166 if (dom) {
167 if (dom instanceof Text && dom.parentNode) {
168 if (dom.nodeValue != vnode) dom.nodeValue = vnode;
169 return dom;
170 }
171 recollectNodeTree(dom);
172 }
173 return document.createTextNode(vnode);
174 }
175 if (isFunction(vnode.nodeName)) return buildComponentFromVNode(dom, vnode, context, mountAll);
176 var out = dom, nodeName = vnode.nodeName, prevSvgMode = isSvgMode, vchildren = vnode.children;
177 if (!isString(nodeName)) nodeName = String(nodeName);
178 isSvgMode = 'svg' === nodeName ? !0 : 'foreignObject' === nodeName ? !1 : isSvgMode;
179 if (!dom) out = createNode(nodeName, isSvgMode); else if (!isNamedNode(dom, nodeName)) {
180 out = createNode(nodeName, isSvgMode);
181 while (dom.firstChild) out.appendChild(dom.firstChild);
182 recollectNodeTree(dom);
183 }
184 if (vchildren && 1 === vchildren.length && 'string' == typeof vchildren[0] && 1 === out.childNodes.length && out.firstChild instanceof Text) {
185 if (out.firstChild.nodeValue != vchildren[0]) out.firstChild.nodeValue = vchildren[0];
186 } else if (vchildren && vchildren.length || out.firstChild) innerDiffNode(out, vchildren, context, mountAll);
187 var props = out[ATTR_KEY];
188 if (!props) {
189 out[ATTR_KEY] = props = {};
190 for (var a = out.attributes, i = a.length; i--; ) props[a[i].name] = a[i].value;
191 }
192 diffAttributes(out, vnode.attributes, props);
193 if (originalAttributes && 'function' == typeof originalAttributes.ref) (props.ref = originalAttributes.ref)(out);
194 isSvgMode = prevSvgMode;
195 return out;
196 }
197 function innerDiffNode(dom, vchildren, context, mountAll) {
198 var j, c, vchild, child, originalChildren = dom.childNodes, children = [], keyed = {}, keyedLen = 0, min = 0, len = originalChildren.length, childrenLen = 0, vlen = vchildren && vchildren.length;
199 if (len) for (var i = 0; i < len; i++) {
200 var _child = originalChildren[i], key = vlen ? (c = _child._component) ? c.__key : (c = _child[ATTR_KEY]) ? c.key : null : null;
201 if (key || 0 === key) {
202 keyedLen++;
203 keyed[key] = _child;
204 } else children[childrenLen++] = _child;
205 }
206 if (vlen) for (var i = 0; i < vlen; i++) {
207 vchild = vchildren[i];
208 child = null;
209 var key = vchild.key;
210 if (null != key) {
211 if (keyedLen && key in keyed) {
212 child = keyed[key];
213 keyed[key] = void 0;
214 keyedLen--;
215 }
216 } else if (!child && min < childrenLen) {
217 for (j = min; j < childrenLen; j++) {
218 c = children[j];
219 if (c && isSameNodeType(c, vchild)) {
220 child = c;
221 children[j] = void 0;
222 if (j === childrenLen - 1) childrenLen--;
223 if (j === min) min++;
224 break;
225 }
226 }
227 if (!child && min < childrenLen && isFunction(vchild.nodeName) && mountAll) {
228 child = children[min];
229 children[min++] = void 0;
230 }
231 }
232 child = idiff(child, vchild, context, mountAll);
233 if (child && child !== dom && child !== originalChildren[i]) dom.insertBefore(child, originalChildren[i] || null);
234 }
235 if (keyedLen) for (var i in keyed) if (keyed[i]) recollectNodeTree(keyed[i]);
236 if (min < childrenLen) removeOrphanedChildren(children);
237 }
238 function removeOrphanedChildren(children, unmountOnly) {
239 for (var i = children.length; i--; ) if (children[i]) recollectNodeTree(children[i], unmountOnly);
240 }
241 function recollectNodeTree(node, unmountOnly) {
242 var component = node._component;
243 if (component) unmountComponent(component, !unmountOnly); else {
244 if (node[ATTR_KEY] && node[ATTR_KEY].ref) node[ATTR_KEY].ref(null);
245 if (!unmountOnly) collectNode(node);
246 if (node.childNodes && node.childNodes.length) removeOrphanedChildren(node.childNodes, unmountOnly);
247 }
248 }
249 function diffAttributes(dom, attrs, old) {
250 for (var _name in old) if (!(attrs && _name in attrs) && null != old[_name]) setAccessor(dom, _name, old[_name], old[_name] = void 0, isSvgMode);
251 if (attrs) for (var _name2 in attrs) if (!('children' === _name2 || 'innerHTML' === _name2 || _name2 in old && attrs[_name2] === ('value' === _name2 || 'checked' === _name2 ? dom[_name2] : old[_name2]))) setAccessor(dom, _name2, old[_name2], old[_name2] = attrs[_name2], isSvgMode);
252 }
253 function collectComponent(component) {
254 var name = component.constructor.name, list = components[name];
255 if (list) list.push(component); else components[name] = [ component ];
256 }
257 function createComponent(Ctor, props, context) {
258 var inst = new Ctor(props, context), list = components[Ctor.name];
259 Component.call(inst, props, context);
260 if (list) for (var i = list.length; i--; ) if (list[i].constructor === Ctor) {
261 inst.nextBase = list[i].nextBase;
262 list.splice(i, 1);
263 break;
264 }
265 return inst;
266 }
267 function setComponentProps(component, props, opts, context, mountAll) {
268 if (!component._disable) {
269 component._disable = !0;
270 if (component.__ref = props.ref) delete props.ref;
271 if (component.__key = props.key) delete props.key;
272 if (!component.base || mountAll) {
273 if (component.componentWillMount) component.componentWillMount();
274 } else if (component.componentWillReceiveProps) component.componentWillReceiveProps(props, context);
275 if (context && context !== component.context) {
276 if (!component.prevContext) component.prevContext = component.context;
277 component.context = context;
278 }
279 if (!component.prevProps) component.prevProps = component.props;
280 component.props = props;
281 component._disable = !1;
282 if (0 !== opts) if (1 === opts || options.syncComponentUpdates !== !1 || !component.base) renderComponent(component, 1, mountAll); else enqueueRender(component);
283 if (component.__ref) component.__ref(component);
284 }
285 }
286 function renderComponent(component, opts, mountAll, isChild) {
287 if (!component._disable) {
288 var skip, rendered, inst, cbase, 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;
289 if (isUpdate) {
290 component.props = previousProps;
291 component.state = previousState;
292 component.context = previousContext;
293 if (2 !== opts && component.shouldComponentUpdate && component.shouldComponentUpdate(props, state, context) === !1) skip = !0; else if (component.componentWillUpdate) component.componentWillUpdate(props, state, context);
294 component.props = props;
295 component.state = state;
296 component.context = context;
297 }
298 component.prevProps = component.prevState = component.prevContext = component.nextBase = null;
299 component._dirty = !1;
300 if (!skip) {
301 if (component.render) rendered = component.render(props, state, context);
302 if (component.getChildContext) context = extend(clone(context), component.getChildContext());
303 while (isFunctionalComponent(rendered)) rendered = buildFunctionalComponent(rendered, context);
304 var toUnmount, base, childComponent = rendered && rendered.nodeName;
305 if (isFunction(childComponent)) {
306 inst = initialChildComponent;
307 var childProps = getNodeProps(rendered);
308 if (inst && inst.constructor === childComponent) setComponentProps(inst, childProps, 1, context); else {
309 toUnmount = inst;
310 inst = createComponent(childComponent, childProps, context);
311 inst.nextBase = inst.nextBase || nextBase;
312 inst._parentComponent = component;
313 component._component = inst;
314 setComponentProps(inst, childProps, 0, context);
315 renderComponent(inst, 1, mountAll, !0);
316 }
317 base = inst.base;
318 } else {
319 cbase = initialBase;
320 toUnmount = initialChildComponent;
321 if (toUnmount) cbase = component._component = null;
322 if (initialBase || 1 === opts) {
323 if (cbase) cbase._component = null;
324 base = diff(cbase, rendered, context, mountAll || !isUpdate, initialBase && initialBase.parentNode, !0);
325 }
326 }
327 if (initialBase && base !== initialBase && inst !== initialChildComponent) {
328 var baseParent = initialBase.parentNode;
329 if (baseParent && base !== baseParent) {
330 baseParent.replaceChild(base, initialBase);
331 if (!toUnmount) {
332 initialBase._component = null;
333 recollectNodeTree(initialBase);
334 }
335 }
336 }
337 if (toUnmount) unmountComponent(toUnmount, base !== initialBase);
338 component.base = base;
339 if (base && !isChild) {
340 var componentRef = component, t = component;
341 while (t = t._parentComponent) (componentRef = t).base = base;
342 base._component = componentRef;
343 base._componentConstructor = componentRef.constructor;
344 }
345 }
346 if (!isUpdate || mountAll) mounts.unshift(component); else if (!skip) {
347 if (component.componentDidUpdate) component.componentDidUpdate(previousProps, previousState, previousContext);
348 if (options.afterUpdate) options.afterUpdate(component);
349 }
350 var fn, cb = component._renderCallbacks;
351 if (cb) while (fn = cb.pop()) fn.call(component);
352 if (!diffLevel && !isChild) flushMounts();
353 }
354 }
355 function buildComponentFromVNode(dom, vnode, context, mountAll) {
356 var c = dom && dom._component, oldDom = dom, isDirectOwner = c && dom._componentConstructor === vnode.nodeName, isOwner = isDirectOwner, props = getNodeProps(vnode);
357 while (c && !isOwner && (c = c._parentComponent)) isOwner = c.constructor === vnode.nodeName;
358 if (c && isOwner && (!mountAll || c._component)) {
359 setComponentProps(c, props, 3, context, mountAll);
360 dom = c.base;
361 } else {
362 if (c && !isDirectOwner) {
363 unmountComponent(c, !0);
364 dom = oldDom = null;
365 }
366 c = createComponent(vnode.nodeName, props, context);
367 if (dom && !c.nextBase) {
368 c.nextBase = dom;
369 oldDom = null;
370 }
371 setComponentProps(c, props, 1, context, mountAll);
372 dom = c.base;
373 if (oldDom && dom !== oldDom) {
374 oldDom._component = null;
375 recollectNodeTree(oldDom);
376 }
377 }
378 return dom;
379 }
380 function unmountComponent(component, remove) {
381 if (options.beforeUnmount) options.beforeUnmount(component);
382 var base = component.base;
383 component._disable = !0;
384 if (component.componentWillUnmount) component.componentWillUnmount();
385 component.base = null;
386 var inner = component._component;
387 if (inner) unmountComponent(inner, remove); else if (base) {
388 if (base[ATTR_KEY] && base[ATTR_KEY].ref) base[ATTR_KEY].ref(null);
389 component.nextBase = base;
390 if (remove) {
391 removeNode(base);
392 collectComponent(component);
393 }
394 removeOrphanedChildren(base.childNodes, !remove);
395 }
396 if (component.__ref) component.__ref(null);
397 if (component.componentDidUnmount) component.componentDidUnmount();
398 }
399 function Component(props, context) {
400 this._dirty = !0;
401 this.context = context;
402 this.props = props;
403 if (!this.state) this.state = {};
404 }
405 function render(vnode, parent, merge) {
406 return diff(merge, vnode, {}, !1, parent);
407 }
408 var options = {};
409 var stack = [];
410 var lcCache = {};
411 var toLowerCase = function(s) {
412 return lcCache[s] || (lcCache[s] = s.toLowerCase());
413 };
414 var resolved = 'undefined' != typeof Promise && Promise.resolve();
415 var defer = resolved ? function(f) {
416 resolved.then(f);
417 } : setTimeout;
418 var EMPTY = {};
419 var ATTR_KEY = 'undefined' != typeof Symbol ? Symbol.for('preactattr') : '__preactattr_';
420 var NON_DIMENSION_PROPS = {
421 boxFlex: 1,
422 boxFlexGroup: 1,
423 columnCount: 1,
424 fillOpacity: 1,
425 flex: 1,
426 flexGrow: 1,
427 flexPositive: 1,
428 flexShrink: 1,
429 flexNegative: 1,
430 fontWeight: 1,
431 lineClamp: 1,
432 lineHeight: 1,
433 opacity: 1,
434 order: 1,
435 orphans: 1,
436 strokeOpacity: 1,
437 widows: 1,
438 zIndex: 1,
439 zoom: 1
440 };
441 var NON_BUBBLING_EVENTS = {
442 blur: 1,
443 error: 1,
444 focus: 1,
445 load: 1,
446 resize: 1,
447 scroll: 1
448 };
449 var items = [];
450 var nodes = {};
451 var mounts = [];
452 var diffLevel = 0;
453 var isSvgMode = !1;
454 var components = {};
455 extend(Component.prototype, {
456 linkState: function(key, eventPath) {
457 var c = this._linkedStates || (this._linkedStates = {});
458 return c[key + eventPath] || (c[key + eventPath] = createLinkedState(this, key, eventPath));
459 },
460 setState: function(state, callback) {
461 var s = this.state;
462 if (!this.prevState) this.prevState = clone(s);
463 extend(s, isFunction(state) ? state(s, this.props) : state);
464 if (callback) (this._renderCallbacks = this._renderCallbacks || []).push(callback);
465 enqueueRender(this);
466 },
467 forceUpdate: function() {
468 renderComponent(this, 2);
469 },
470 render: function() {}
471 });
472 exports.h = h;
473 exports.cloneElement = cloneElement;
474 exports.Component = Component;
475 exports.render = render;
476 exports.rerender = rerender;
477 exports.options = options;
478});
479//# sourceMappingURL=preact.js.map
\No newline at end of file