{"version":3,"file":"preact-compat.js","sources":["../src/index.js"],"sourcesContent":["import PropTypes from 'proptypes';\nimport { render as preactRender, cloneElement as preactCloneElement, h, Component as PreactComponent, options } from 'preact';\n\nconst version = '15.1.0'; // trick libraries to think we are react\n\nconst ELEMENTS = 'a abbr address area article aside audio b base bdi bdo big blockquote body br button canvas caption cite code col colgroup data datalist dd del details dfn dialog div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 head header hgroup hr html i iframe img input ins kbd keygen label legend li link main map mark menu menuitem meta meter nav noscript object ol optgroup option output p param picture pre progress q rp rt ruby s samp script section select small source span strong style sub summary sup table tbody td textarea tfoot th thead time title tr track u ul var video wbr circle clipPath defs ellipse g image line linearGradient mask path pattern polygon polyline radialGradient rect stop svg text tspan'.split(' ');\n\nconst REACT_ELEMENT_TYPE = (typeof Symbol!=='undefined' && Symbol.for && Symbol.for('react.element')) || 0xeac7;\n\nconst COMPONENT_WRAPPER_KEY = typeof Symbol!=='undefined' ? Symbol.for('__preactCompatWrapper') : '__preactCompatWrapper';\n\n// don't autobind these methods since they already have guaranteed context.\nconst AUTOBIND_BLACKLIST = {\n\tconstructor: 1,\n\trender: 1,\n\tshouldComponentUpdate: 1,\n\tcomponentWillReceiveProps: 1,\n\tcomponentWillUpdate: 1,\n\tcomponentDidUpdate: 1,\n\tcomponentWillMount: 1,\n\tcomponentDidMount: 1,\n\tcomponentWillUnmount: 1,\n\tcomponentDidUnmount: 1\n};\n\n\nconst CAMEL_PROPS = /^(?:accent|alignment|arabic|baseline|cap|clip|color|fill|flood|font|glyph|horiz|marker|overline|paint|stop|strikethrough|stroke|text|underline|unicode|units|v|vert|word|writing|x)[A-Z]/;\n\n\nconst BYPASS_HOOK = {};\n\n/*global process*/\nconst DEV = typeof process==='undefined' || !process.env || process.env.NODE_ENV!=='production';\n\n// a component that renders nothing. Used to replace components for unmountComponentAtNode.\nfunction EmptyComponent() { return null; }\n\n\n\n// make react think we're react.\nlet VNode = h('a', null).constructor;\nVNode.prototype.$$typeof = REACT_ELEMENT_TYPE;\nVNode.prototype.preactCompatUpgraded = false;\nVNode.prototype.preactCompatNormalized = false;\n\nObject.defineProperty(VNode.prototype, 'type', {\n\tget() { return this.nodeName; },\n\tset(v) { this.nodeName = v; },\n\tconfigurable:true\n});\n\nObject.defineProperty(VNode.prototype, 'props', {\n\tget() { return this.attributes; },\n\tset(v) { this.attributes = v; },\n\tconfigurable:true\n});\n\n\n\nlet oldEventHook = options.event;\noptions.event = e => {\n\tif (oldEventHook) e = oldEventHook(e);\n\te.persist = Object;\n\te.nativeEvent = e;\n\treturn e;\n};\n\n\nlet oldVnodeHook = options.vnode;\noptions.vnode = vnode => {\n\tif (!vnode.preactCompatUpgraded) {\n\t\tvnode.preactCompatUpgraded = true;\n\n\t\tlet tag = vnode.nodeName,\n\t\t\tattrs = vnode.attributes = extend({}, vnode.attributes);\n\n\t\tif (typeof tag==='function') {\n\t\t\tif (tag[COMPONENT_WRAPPER_KEY]===true || (tag.prototype && 'isReactComponent' in tag.prototype)) {\n\t\t\t\tif (vnode.children && !vnode.children.length) vnode.children = undefined;\n\t\t\t\tif (vnode.children) attrs.children = vnode.children;\n\n\t\t\t\tif (!vnode.preactCompatNormalized) {\n\t\t\t\t\tnormalizeVNode(vnode);\n\t\t\t\t}\n\t\t\t\thandleComponentVNode(vnode);\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tif (vnode.children && !vnode.children.length) vnode.children = undefined;\n\t\t\tif (vnode.children) attrs.children = vnode.children;\n\n\t\t\tif (attrs.defaultValue) {\n\t\t\t\tif (!attrs.value && attrs.value!==0) {\n\t\t\t\t\tattrs.value = attrs.defaultValue;\n\t\t\t\t}\n\t\t\t\tdelete attrs.defaultValue;\n\t\t\t}\n\n\t\t\thandleElementVNode(vnode, attrs);\n\t\t}\n\t}\n\n\tif (oldVnodeHook) oldVnodeHook(vnode);\n};\n\nfunction handleComponentVNode(vnode) {\n\tlet tag = vnode.nodeName,\n\t\ta = vnode.attributes;\n\n\tvnode.attributes = {};\n\tif (tag.defaultProps) extend(vnode.attributes, tag.defaultProps);\n\tif (a) extend(vnode.attributes, a);\n}\n\nfunction handleElementVNode(vnode, a) {\n\tlet shouldSanitize, attrs, i;\n\tif (a) {\n\t\tfor (i in a) if ((shouldSanitize = CAMEL_PROPS.test(i))) break;\n\t\tif (shouldSanitize) {\n\t\t\tattrs = vnode.attributes = {};\n\t\t\tfor (i in a) {\n\t\t\t\tif (a.hasOwnProperty(i)) {\n\t\t\t\t\tattrs[ CAMEL_PROPS.test(i) ? i.replace(/([A-Z0-9])/, '-$1').toLowerCase() : i ] = a[i];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n\n\n// proxy render() since React returns a Component reference.\nfunction render(vnode, parent, callback) {\n\tlet prev = parent && parent._preactCompatRendered && parent._preactCompatRendered.base;\n\n\t// ignore impossible previous renders\n\tif (prev && prev.parentNode!==parent) prev = null;\n\n\t// default to first Element child\n\tif (!prev) prev = parent.children[0];\n\n\t// remove unaffected siblings\n\tfor (let i=parent.childNodes.length; i--; ) {\n\t\tif (parent.childNodes[i]!==prev) {\n\t\t\tparent.removeChild(parent.childNodes[i]);\n\t\t}\n\t}\n\n\tlet out = preactRender(vnode, parent, prev);\n\tif (parent) parent._preactCompatRendered = out && (out._component || { base: out });\n\tif (typeof callback==='function') callback();\n\treturn out && out._component || out;\n}\n\n\nclass ContextProvider {\n\tgetChildContext() {\n\t\treturn this.props.context;\n\t}\n\trender(props) {\n\t\treturn props.children[0];\n\t}\n}\n\nfunction renderSubtreeIntoContainer(parentComponent, vnode, container, callback) {\n\tlet wrap = h(ContextProvider, { context: parentComponent.context }, vnode);\n\tlet c = render(wrap, container);\n\tif (callback) callback(c);\n\treturn c._component || c.base;\n}\n\n\nfunction unmountComponentAtNode(container) {\n\tlet existing = container._preactCompatRendered && container._preactCompatRendered.base;\n\tif (existing && existing.parentNode===container) {\n\t\tpreactRender(h(EmptyComponent), container, existing);\n\t\treturn true;\n\t}\n\treturn false;\n}\n\n\n\nconst ARR = [];\n\n// This API is completely unnecessary for Preact, so it's basically passthrough.\nlet Children = {\n\tmap(children, fn, ctx) {\n\t\tif (children == null) return null;\n\t\tchildren = Children.toArray(children);\n\t\tif (ctx && ctx!==children) fn = fn.bind(ctx);\n\t\treturn children.map(fn);\n\t},\n\tforEach(children, fn, ctx) {\n\t\tif (children == null) return null;\n\t\tchildren = Children.toArray(children);\n\t\tif (ctx && ctx!==children) fn = fn.bind(ctx);\n\t\tchildren.forEach(fn);\n\t},\n\tcount(children) {\n\t\treturn children && children.length || 0;\n\t},\n\tonly(children) {\n\t\tchildren = Children.toArray(children);\n\t\tif (children.length!==1) throw new Error('Children.only() expects only one child.');\n\t\treturn children[0];\n\t},\n\ttoArray(children) {\n\t\treturn Array.isArray && Array.isArray(children) ? children : ARR.concat(children);\n\t}\n};\n\n\n/** Track current render() component for ref assignment */\nlet currentComponent;\n\n\nfunction createFactory(type) {\n\treturn createElement.bind(null, type);\n}\n\n\nlet DOM = {};\nfor (let i=ELEMENTS.length; i--; ) {\n\tDOM[ELEMENTS[i]] = createFactory(ELEMENTS[i]);\n}\n\nfunction upgradeToVNodes(arr, offset) {\n\tfor (let i=offset || 0; i {\n\t\tif (component && component.refs) {\n\t\t\tcomponent.refs[name] = resolved;\n\t\t\tif (resolved===null) {\n\t\t\t\tdelete component._refProxies[name];\n\t\t\t\tcomponent = null;\n\t\t\t}\n\t\t}\n\t});\n}\n\n\nfunction applyEventNormalization({ nodeName, attributes }) {\n\tif (!attributes || typeof nodeName!=='string') return;\n\tlet props = {};\n\tfor (let i in attributes) {\n\t\tprops[i.toLowerCase()] = i;\n\t}\n\tif (props.ondoubleclick) {\n\t\tattributes.ondblclick = attributes[props.ondoubleclick];\n\t\tdelete attributes[props.ondoubleclick];\n\t}\n\t// for *textual inputs* (incl textarea), normalize `onChange` -> `onInput`:\n\tif (props.onchange && (nodeName==='textarea' || (nodeName.toLowerCase()==='input' && !/^fil|che|rad/i.test(attributes.type)))) {\n\t\tlet normalized = props.oninput || 'oninput';\n\t\tif (!attributes[normalized]) {\n\t\t\tattributes[normalized] = multihook([attributes[normalized], attributes[props.onchange]]);\n\t\t\tdelete attributes[props.onchange];\n\t\t}\n\t}\n}\n\n\nfunction applyClassName({ attributes }) {\n\tif (!attributes) return;\n\tlet cl = attributes.className || attributes.class;\n\tif (cl) attributes.className = cl;\n}\n\n\nfunction extend(base, props) {\n\tfor (let key in props) {\n\t\tif (props.hasOwnProperty(key)) {\n\t\t\tbase[key] = props[key];\n\t\t}\n\t}\n\treturn base;\n}\n\n\nfunction shallowDiffers(a, b) {\n\tfor (let i in a) if (!(i in b)) return true;\n\tfor (let i in b) if (a[i]!==b[i]) return true;\n\treturn false;\n}\n\n\nfunction findDOMNode(component) {\n\treturn component && component.base || component;\n}\n\n\nfunction F(){}\n\nfunction createClass(obj) {\n\tfunction cl(props, context) {\n\t\tbindAll(this);\n\t\tComponent.call(this, props, context, BYPASS_HOOK);\n\t\tnewComponentHook.call(this, props, context);\n\t}\n\n\tobj = extend({ constructor: cl }, obj);\n\n\t// We need to apply mixins here so that getDefaultProps is correctly mixed\n\tif (obj.mixins) {\n\t\tapplyMixins(obj, collateMixins(obj.mixins));\n\t}\n\tif (obj.statics) {\n\t\textend(cl, obj.statics);\n\t}\n\tif (obj.propTypes) {\n\t\tcl.propTypes = obj.propTypes;\n\t}\n\tif (obj.defaultProps) {\n\t\tcl.defaultProps = obj.defaultProps;\n\t}\n\tif (obj.getDefaultProps) {\n\t\tcl.defaultProps = obj.getDefaultProps();\n\t}\n\n\tF.prototype = Component.prototype;\n\tcl.prototype = extend(new F(), obj);\n\n\tcl.displayName = obj.displayName || 'Component';\n\n\treturn cl;\n}\n\n\n// Flatten an Array of mixins to a map of method name to mixin implementations\nfunction collateMixins(mixins) {\n\tlet keyed = {};\n\tfor (let i=0; i