From 97552da77f1bd7166fc9151ea7efe5beeb7d89d2 Mon Sep 17 00:00:00 2001 From: Marks Polakovs Date: Mon, 15 Mar 2021 13:50:23 +0000 Subject: [PATCH 01/14] Initial support for (P)react form fields --- src/Classes/MyRadio/MyRadioForm.php | 14 +++++++++++++- src/Classes/MyRadio/MyRadioFormField.php | 9 +++++++++ src/Public/js/vendor/htm.min.js | 1 + src/Public/js/vendor/preact.module.js | 2 ++ src/Public/js/vendor/preact.module.js.map | 1 + src/Templates/FormFields/FieldType_23.twig | 18 ++++++++++++++++++ src/Templates/form.twig | 11 +++++++++++ 7 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/Public/js/vendor/htm.min.js create mode 100644 src/Public/js/vendor/preact.module.js create mode 100644 src/Public/js/vendor/preact.module.js.map create mode 100644 src/Templates/FormFields/FieldType_23.twig diff --git a/src/Classes/MyRadio/MyRadioForm.php b/src/Classes/MyRadio/MyRadioForm.php index 702b94e81..63153b55c 100644 --- a/src/Classes/MyRadio/MyRadioForm.php +++ b/src/Classes/MyRadio/MyRadioForm.php @@ -318,6 +318,16 @@ public function render($frmcustom = []) $captcha = null; } + // If we're using a React field, load in the prerequisites + $hasReact = !empty(array_filter(/** + * @param MyRadioFormField $field + * @return boolean + */ $this->fields, + function ($field) { + return $field->getType() === MyRadioFormField::TYPE_REACT; + } + )); + $fields = []; $redact = []; foreach ($this->fields as $field) { @@ -345,7 +355,9 @@ public function render($frmcustom = []) ->addVariable('frm_fields', $fields) ->addVariable('redact', $redact) ->addVariable('captcha', $captcha) - ->addVariable('frm_custom', $frmcustom); + ->addVariable('frm_custom', $frmcustom) + ->addVariable('react', $hasReact); + $twig->render(); } diff --git a/src/Classes/MyRadio/MyRadioFormField.php b/src/Classes/MyRadio/MyRadioFormField.php index e531ec1ab..91294a4a5 100644 --- a/src/Classes/MyRadio/MyRadioFormField.php +++ b/src/Classes/MyRadio/MyRadioFormField.php @@ -252,6 +252,15 @@ class MyRadioFormField */ const TYPE_SECTION_CLOSE = 0x16; + /** + * The constant used to specify this MyRadioFormField is a custom React component. + * + * It takes the following options: + * * component - the name of the component to render + * (must be default export of a file called "Public/js/myradio.form.react.{component}.js) + */ + const TYPE_REACT = 0x17; + /** * The name/id of the Form Field. * diff --git a/src/Public/js/vendor/htm.min.js b/src/Public/js/vendor/htm.min.js new file mode 100644 index 000000000..ca651c699 --- /dev/null +++ b/src/Public/js/vendor/htm.min.js @@ -0,0 +1 @@ +var n = function (t, s, r, e) {var u;s[0] = 0;for (var h = 1; h < s.length; h++) {var p = s[h++],a = s[h] ? (s[0] |= p ? 1 : 2, r[s[h++]]) : s[++h];3 === p ? e[0] = a : 4 === p ? e[1] = Object.assign(e[1] || {}, a) : 5 === p ? (e[1] = e[1] || {})[s[++h]] = a : 6 === p ? e[1][s[++h]] += a + "" : p ? (u = t.apply(a, n(t, a, r, ["", null])), e.push(u), a[0] ? s[0] |= 2 : (s[h - 2] = 0, s[h] = u)) : e.push(a);}return e;},t = new Map();export default function (s) {var r = t.get(this);return r || (r = new Map(), t.set(this, r)), (r = n(this, r.get(s) || (r.set(s, r = function (n) {for (var t, s, r = 1, e = "", u = "", h = [0], p = function (n) {1 === r && (n || (e = e.replace(/^\s*\n\s*|\s*\n\s*$/g, ""))) ? h.push(0, n, e) : 3 === r && (n || e) ? (h.push(3, n, e), r = 2) : 2 === r && "..." === e && n ? h.push(4, n, 0) : 2 === r && e && !n ? h.push(5, 0, !0, e) : r >= 5 && ((e || !n && 5 === r) && (h.push(r, 0, e, s), r = 6), n && (h.push(r, n, 0, s), r = 6)), e = "";}, a = 0; a < n.length; a++) {a && (1 === r && p(), p(a));for (var l = 0; l < n[a].length; l++) t = n[a][l], 1 === r ? "<" === t ? (p(), h = [h], r = 3) : e += t : 4 === r ? "--" === e && ">" === t ? (r = 1, e = "") : e = t + e[0] : u ? t === u ? u = "" : e += t : '"' === t || "'" === t ? u = t : ">" === t ? (p(), r = 1) : r && ("=" === t ? (r = 5, s = e, e = "") : "/" === t && (r < 5 || ">" === n[a][l + 1]) ? (p(), 3 === r && (h = h[0]), r = h, (h = h[0]).push(2, 0, r), r = 0) : " " === t || "\t" === t || "\n" === t || "\r" === t ? (p(), r = 2) : e += t), 3 === r && "!--" === e && (r = 4, h = h[0]);}return p(), h;}(s)), r), arguments, [])).length > 1 ? r : r[0];} \ No newline at end of file diff --git a/src/Public/js/vendor/preact.module.js b/src/Public/js/vendor/preact.module.js new file mode 100644 index 000000000..a9feb0cc3 --- /dev/null +++ b/src/Public/js/vendor/preact.module.js @@ -0,0 +1,2 @@ +var n,l,u,i,t,o,r={},f=[],e=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function c(n,l){for(var u in l)n[u]=l[u];return n}function s(n){var l=n.parentNode;l&&l.removeChild(n)}function a(n,l,u){var i,t,o,r=arguments,f={};for(o in l)"key"==o?i=l[o]:"ref"==o?t=l[o]:f[o]=l[o];if(arguments.length>3)for(u=[u],o=3;o0?v(k.type,k.props,k.key,null,k.__v):k)){if(k.__=u,k.__b=u.__b+1,null===(_=A[h])||_&&k.key==_.key&&k.type===_.type)A[h]=void 0;else for(p=0;p3)for(u=[u],o=3;o} [children] The children of the virtual node\n * @returns {import('./internal').VNode}\n */\nexport function createElement(type, props, children) {\n\tlet normalizedProps = {},\n\t\tkey,\n\t\tref,\n\t\ti;\n\tfor (i in props) {\n\t\tif (i == 'key') key = props[i];\n\t\telse if (i == 'ref') ref = props[i];\n\t\telse normalizedProps[i] = props[i];\n\t}\n\n\tif (arguments.length > 3) {\n\t\tchildren = [children];\n\t\t// https://github.com/preactjs/preact/issues/1916\n\t\tfor (i = 3; i < arguments.length; i++) {\n\t\t\tchildren.push(arguments[i]);\n\t\t}\n\t}\n\tif (children != null) {\n\t\tnormalizedProps.children = children;\n\t}\n\n\t// If a Component VNode, check for and apply defaultProps\n\t// Note: type may be undefined in development, must never error here.\n\tif (typeof type == 'function' && type.defaultProps != null) {\n\t\tfor (i in type.defaultProps) {\n\t\t\tif (normalizedProps[i] === undefined) {\n\t\t\t\tnormalizedProps[i] = type.defaultProps[i];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn createVNode(type, normalizedProps, key, ref, null);\n}\n\n/**\n * Create a VNode (used internally by Preact)\n * @param {import('./internal').VNode[\"type\"]} type The node name or Component\n * Constructor for this virtual node\n * @param {object | string | number | null} props The properties of this virtual node.\n * If this virtual node represents a text node, this is the text of the node (string or number).\n * @param {string | number | null} key The key for this virtual node, used when\n * diffing it against its children\n * @param {import('./internal').VNode[\"ref\"]} ref The ref property that will\n * receive a reference to its created child\n * @returns {import('./internal').VNode}\n */\nexport function createVNode(type, props, key, ref, original) {\n\t// V8 seems to be better at detecting type shapes if the object is allocated from the same call site\n\t// Do not inline into createElement and coerceToVNode!\n\tconst vnode = {\n\t\ttype,\n\t\tprops,\n\t\tkey,\n\t\tref,\n\t\t_children: null,\n\t\t_parent: null,\n\t\t_depth: 0,\n\t\t_dom: null,\n\t\t// _nextDom must be initialized to undefined b/c it will eventually\n\t\t// be set to dom.nextSibling which can return `null` and it is important\n\t\t// to be able to distinguish between an uninitialized _nextDom and\n\t\t// a _nextDom that has been set to `null`\n\t\t_nextDom: undefined,\n\t\t_component: null,\n\t\t_hydrating: null,\n\t\tconstructor: undefined,\n\t\t_original: original == null ? ++options._vnodeId : original\n\t};\n\n\tif (options.vnode != null) options.vnode(vnode);\n\n\treturn vnode;\n}\n\nexport function createRef() {\n\treturn { current: null };\n}\n\nexport function Fragment(props) {\n\treturn props.children;\n}\n\n/**\n * Check if a the argument is a valid Preact VNode.\n * @param {*} vnode\n * @returns {vnode is import('./internal').VNode}\n */\nexport const isValidElement = vnode =>\n\tvnode != null && vnode.constructor === undefined;\n","import { assign } from './util';\nimport { diff, commitRoot } from './diff/index';\nimport options from './options';\nimport { Fragment } from './create-element';\n\n/**\n * Base Component class. Provides `setState()` and `forceUpdate()`, which\n * trigger rendering\n * @param {object} props The initial component props\n * @param {object} context The initial context from parent components'\n * getChildContext\n */\nexport function Component(props, context) {\n\tthis.props = props;\n\tthis.context = context;\n}\n\n/**\n * Update component state and schedule a re-render.\n * @this {import('./internal').Component}\n * @param {object | ((s: object, p: object) => object)} update A hash of state\n * properties to update with new values or a function that given the current\n * state and props returns a new partial state\n * @param {() => void} [callback] A function to be called once component state is\n * updated\n */\nComponent.prototype.setState = function(update, callback) {\n\t// only clone state when copying to nextState the first time.\n\tlet s;\n\tif (this._nextState != null && this._nextState !== this.state) {\n\t\ts = this._nextState;\n\t} else {\n\t\ts = this._nextState = assign({}, this.state);\n\t}\n\n\tif (typeof update == 'function') {\n\t\t// Some libraries like `immer` mark the current state as readonly,\n\t\t// preventing us from mutating it, so we need to clone it. See #2716\n\t\tupdate = update(assign({}, s), this.props);\n\t}\n\n\tif (update) {\n\t\tassign(s, update);\n\t}\n\n\t// Skip update if updater function returned null\n\tif (update == null) return;\n\n\tif (this._vnode) {\n\t\tif (callback) this._renderCallbacks.push(callback);\n\t\tenqueueRender(this);\n\t}\n};\n\n/**\n * Immediately perform a synchronous re-render of the component\n * @this {import('./internal').Component}\n * @param {() => void} [callback] A function to be called after component is\n * re-rendered\n */\nComponent.prototype.forceUpdate = function(callback) {\n\tif (this._vnode) {\n\t\t// Set render mode so that we can differentiate where the render request\n\t\t// is coming from. We need this because forceUpdate should never call\n\t\t// shouldComponentUpdate\n\t\tthis._force = true;\n\t\tif (callback) this._renderCallbacks.push(callback);\n\t\tenqueueRender(this);\n\t}\n};\n\n/**\n * Accepts `props` and `state`, and returns a new Virtual DOM tree to build.\n * Virtual DOM is generally constructed via [JSX](http://jasonformat.com/wtf-is-jsx).\n * @param {object} props Props (eg: JSX attributes) received from parent\n * element/component\n * @param {object} state The component's current state\n * @param {object} context Context object, as returned by the nearest\n * ancestor's `getChildContext()`\n * @returns {import('./index').ComponentChildren | void}\n */\nComponent.prototype.render = Fragment;\n\n/**\n * @param {import('./internal').VNode} vnode\n * @param {number | null} [childIndex]\n */\nexport function getDomSibling(vnode, childIndex) {\n\tif (childIndex == null) {\n\t\t// Use childIndex==null as a signal to resume the search from the vnode's sibling\n\t\treturn vnode._parent\n\t\t\t? getDomSibling(vnode._parent, vnode._parent._children.indexOf(vnode) + 1)\n\t\t\t: null;\n\t}\n\n\tlet sibling;\n\tfor (; childIndex < vnode._children.length; childIndex++) {\n\t\tsibling = vnode._children[childIndex];\n\n\t\tif (sibling != null && sibling._dom != null) {\n\t\t\t// Since updateParentDomPointers keeps _dom pointer correct,\n\t\t\t// we can rely on _dom to tell us if this subtree contains a\n\t\t\t// rendered DOM node, and what the first rendered DOM node is\n\t\t\treturn sibling._dom;\n\t\t}\n\t}\n\n\t// If we get here, we have not found a DOM node in this vnode's children.\n\t// We must resume from this vnode's sibling (in it's parent _children array)\n\t// Only climb up and search the parent if we aren't searching through a DOM\n\t// VNode (meaning we reached the DOM parent of the original vnode that began\n\t// the search)\n\treturn typeof vnode.type == 'function' ? getDomSibling(vnode) : null;\n}\n\n/**\n * Trigger in-place re-rendering of a component.\n * @param {import('./internal').Component} component The component to rerender\n */\nfunction renderComponent(component) {\n\tlet vnode = component._vnode,\n\t\toldDom = vnode._dom,\n\t\tparentDom = component._parentDom;\n\n\tif (parentDom) {\n\t\tlet commitQueue = [];\n\t\tconst oldVNode = assign({}, vnode);\n\t\toldVNode._original = vnode._original + 1;\n\n\t\tdiff(\n\t\t\tparentDom,\n\t\t\tvnode,\n\t\t\toldVNode,\n\t\t\tcomponent._globalContext,\n\t\t\tparentDom.ownerSVGElement !== undefined,\n\t\t\tvnode._hydrating != null ? [oldDom] : null,\n\t\t\tcommitQueue,\n\t\t\toldDom == null ? getDomSibling(vnode) : oldDom,\n\t\t\tvnode._hydrating\n\t\t);\n\t\tcommitRoot(commitQueue, vnode);\n\n\t\tif (vnode._dom != oldDom) {\n\t\t\tupdateParentDomPointers(vnode);\n\t\t}\n\t}\n}\n\n/**\n * @param {import('./internal').VNode} vnode\n */\nfunction updateParentDomPointers(vnode) {\n\tif ((vnode = vnode._parent) != null && vnode._component != null) {\n\t\tvnode._dom = vnode._component.base = null;\n\t\tfor (let i = 0; i < vnode._children.length; i++) {\n\t\t\tlet child = vnode._children[i];\n\t\t\tif (child != null && child._dom != null) {\n\t\t\t\tvnode._dom = vnode._component.base = child._dom;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn updateParentDomPointers(vnode);\n\t}\n}\n\n/**\n * The render queue\n * @type {Array}\n */\nlet rerenderQueue = [];\n\n/**\n * Asynchronously schedule a callback\n * @type {(cb: () => void) => void}\n */\n/* istanbul ignore next */\n// Note the following line isn't tree-shaken by rollup cuz of rollup/rollup#2566\nconst defer =\n\ttypeof Promise == 'function'\n\t\t? Promise.prototype.then.bind(Promise.resolve())\n\t\t: setTimeout;\n\n/*\n * The value of `Component.debounce` must asynchronously invoke the passed in callback. It is\n * important that contributors to Preact can consistently reason about what calls to `setState`, etc.\n * do, and when their effects will be applied. See the links below for some further reading on designing\n * asynchronous APIs.\n * * [Designing APIs for Asynchrony](https://blog.izs.me/2013/08/designing-apis-for-asynchrony)\n * * [Callbacks synchronous and asynchronous](https://blog.ometer.com/2011/07/24/callbacks-synchronous-and-asynchronous/)\n */\n\nlet prevDebounce;\n\n/**\n * Enqueue a rerender of a component\n * @param {import('./internal').Component} c The component to rerender\n */\nexport function enqueueRender(c) {\n\tif (\n\t\t(!c._dirty &&\n\t\t\t(c._dirty = true) &&\n\t\t\trerenderQueue.push(c) &&\n\t\t\t!process._rerenderCount++) ||\n\t\tprevDebounce !== options.debounceRendering\n\t) {\n\t\tprevDebounce = options.debounceRendering;\n\t\t(prevDebounce || defer)(process);\n\t}\n}\n\n/** Flush the render queue by rerendering all queued components */\nfunction process() {\n\tlet queue;\n\twhile ((process._rerenderCount = rerenderQueue.length)) {\n\t\tqueue = rerenderQueue.sort((a, b) => a._vnode._depth - b._vnode._depth);\n\t\trerenderQueue = [];\n\t\t// Don't update `renderCount` yet. Keep its value non-zero to prevent unnecessary\n\t\t// process() calls from getting scheduled while `queue` is still being consumed.\n\t\tqueue.some(c => {\n\t\t\tif (c._dirty) renderComponent(c);\n\t\t});\n\t}\n}\nprocess._rerenderCount = 0;\n","import { enqueueRender } from './component';\n\nexport let i = 0;\n\nexport function createContext(defaultValue, contextId) {\n\tcontextId = '__cC' + i++;\n\n\tconst context = {\n\t\t_id: contextId,\n\t\t_defaultValue: defaultValue,\n\t\t/** @type {import('./internal').FunctionComponent} */\n\t\tConsumer(props, contextValue) {\n\t\t\t// return props.children(\n\t\t\t// \tcontext[contextId] ? context[contextId].props.value : defaultValue\n\t\t\t// );\n\t\t\treturn props.children(contextValue);\n\t\t},\n\t\t/** @type {import('./internal').FunctionComponent} */\n\t\tProvider(props) {\n\t\t\tif (!this.getChildContext) {\n\t\t\t\tlet subs = [];\n\t\t\t\tlet ctx = {};\n\t\t\t\tctx[contextId] = this;\n\n\t\t\t\tthis.getChildContext = () => ctx;\n\n\t\t\t\tthis.shouldComponentUpdate = function(_props) {\n\t\t\t\t\tif (this.props.value !== _props.value) {\n\t\t\t\t\t\t// I think the forced value propagation here was only needed when `options.debounceRendering` was being bypassed:\n\t\t\t\t\t\t// https://github.com/preactjs/preact/commit/4d339fb803bea09e9f198abf38ca1bf8ea4b7771#diff-54682ce380935a717e41b8bfc54737f6R358\n\t\t\t\t\t\t// In those cases though, even with the value corrected, we're double-rendering all nodes.\n\t\t\t\t\t\t// It might be better to just tell folks not to use force-sync mode.\n\t\t\t\t\t\t// Currently, using `useContext()` in a class component will overwrite its `this.context` value.\n\t\t\t\t\t\t// subs.some(c => {\n\t\t\t\t\t\t// \tc.context = _props.value;\n\t\t\t\t\t\t// \tenqueueRender(c);\n\t\t\t\t\t\t// });\n\n\t\t\t\t\t\t// subs.some(c => {\n\t\t\t\t\t\t// \tc.context[contextId] = _props.value;\n\t\t\t\t\t\t// \tenqueueRender(c);\n\t\t\t\t\t\t// });\n\t\t\t\t\t\tsubs.some(enqueueRender);\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tthis.sub = c => {\n\t\t\t\t\tsubs.push(c);\n\t\t\t\t\tlet old = c.componentWillUnmount;\n\t\t\t\t\tc.componentWillUnmount = () => {\n\t\t\t\t\t\tsubs.splice(subs.indexOf(c), 1);\n\t\t\t\t\t\tif (old) old.call(c);\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn props.children;\n\t\t}\n\t};\n\n\t// Devtools needs access to the context object when it\n\t// encounters a Provider. This is necessary to support\n\t// setting `displayName` on the context object instead\n\t// of on the component itself. See:\n\t// https://reactjs.org/docs/context.html#contextdisplayname\n\n\treturn (context.Provider._contextRef = context.Consumer.contextType = context);\n}\n","/**\n * Assign properties from `props` to `obj`\n * @template O, P The obj and props types\n * @param {O} obj The object to copy properties to\n * @param {P} props The object to copy properties from\n * @returns {O & P}\n */\nexport function assign(obj, props) {\n\t// @ts-ignore We change the type of `obj` to be `O & P`\n\tfor (let i in props) obj[i] = props[i];\n\treturn /** @type {O & P} */ (obj);\n}\n\n/**\n * Remove a child node from its parent if attached. This is a workaround for\n * IE11 which doesn't support `Element.prototype.remove()`. Using this function\n * is smaller than including a dedicated polyfill.\n * @param {Node} node The node to remove\n */\nexport function removeNode(node) {\n\tlet parentNode = node.parentNode;\n\tif (parentNode) parentNode.removeChild(node);\n}\n","import { diff, unmount, applyRef } from './index';\nimport { createVNode, Fragment } from '../create-element';\nimport { EMPTY_OBJ, EMPTY_ARR } from '../constants';\nimport { getDomSibling } from '../component';\n\n/**\n * Diff the children of a virtual node\n * @param {import('../internal').PreactElement} parentDom The DOM element whose\n * children are being diffed\n * @param {import('../internal').ComponentChildren[]} renderResult\n * @param {import('../internal').VNode} newParentVNode The new virtual\n * node whose children should be diff'ed against oldParentVNode\n * @param {import('../internal').VNode} oldParentVNode The old virtual\n * node whose children should be diff'ed against newParentVNode\n * @param {object} globalContext The current context object - modified by getChildContext\n * @param {boolean} isSvg Whether or not this DOM node is an SVG node\n * @param {Array} excessDomChildren\n * @param {Array} commitQueue List of components\n * which have callbacks to invoke in commitRoot\n * @param {import('../internal').PreactElement} oldDom The current attached DOM\n * element any new dom elements should be placed around. Likely `null` on first\n * render (except when hydrating). Can be a sibling DOM element when diffing\n * Fragments that have siblings. In most cases, it starts out as `oldChildren[0]._dom`.\n * @param {boolean} isHydrating Whether or not we are in hydration\n */\nexport function diffChildren(\n\tparentDom,\n\trenderResult,\n\tnewParentVNode,\n\toldParentVNode,\n\tglobalContext,\n\tisSvg,\n\texcessDomChildren,\n\tcommitQueue,\n\toldDom,\n\tisHydrating\n) {\n\tlet i, j, oldVNode, childVNode, newDom, firstChildDom, refs;\n\n\t// This is a compression of oldParentVNode!=null && oldParentVNode != EMPTY_OBJ && oldParentVNode._children || EMPTY_ARR\n\t// as EMPTY_OBJ._children should be `undefined`.\n\tlet oldChildren = (oldParentVNode && oldParentVNode._children) || EMPTY_ARR;\n\n\tlet oldChildrenLength = oldChildren.length;\n\n\tnewParentVNode._children = [];\n\tfor (i = 0; i < renderResult.length; i++) {\n\t\tchildVNode = renderResult[i];\n\n\t\tif (childVNode == null || typeof childVNode == 'boolean') {\n\t\t\tchildVNode = newParentVNode._children[i] = null;\n\t\t}\n\t\t// If this newVNode is being reused (e.g.
{reuse}{reuse}
) in the same diff,\n\t\t// or we are rendering a component (e.g. setState) copy the oldVNodes so it can have\n\t\t// it's own DOM & etc. pointers\n\t\telse if (\n\t\t\ttypeof childVNode == 'string' ||\n\t\t\ttypeof childVNode == 'number' ||\n\t\t\t// eslint-disable-next-line valid-typeof\n\t\t\ttypeof childVNode == 'bigint'\n\t\t) {\n\t\t\tchildVNode = newParentVNode._children[i] = createVNode(\n\t\t\t\tnull,\n\t\t\t\tchildVNode,\n\t\t\t\tnull,\n\t\t\t\tnull,\n\t\t\t\tchildVNode\n\t\t\t);\n\t\t} else if (Array.isArray(childVNode)) {\n\t\t\tchildVNode = newParentVNode._children[i] = createVNode(\n\t\t\t\tFragment,\n\t\t\t\t{ children: childVNode },\n\t\t\t\tnull,\n\t\t\t\tnull,\n\t\t\t\tnull\n\t\t\t);\n\t\t} else if (childVNode._depth > 0) {\n\t\t\t// VNode is already in use, clone it. This can happen in the following\n\t\t\t// scenario:\n\t\t\t// const reuse =
\n\t\t\t//
{reuse}{reuse}
\n\t\t\tchildVNode = newParentVNode._children[i] = createVNode(\n\t\t\t\tchildVNode.type,\n\t\t\t\tchildVNode.props,\n\t\t\t\tchildVNode.key,\n\t\t\t\tnull,\n\t\t\t\tchildVNode._original\n\t\t\t);\n\t\t} else {\n\t\t\tchildVNode = newParentVNode._children[i] = childVNode;\n\t\t}\n\n\t\t// Terser removes the `continue` here and wraps the loop body\n\t\t// in a `if (childVNode) { ... } condition\n\t\tif (childVNode == null) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tchildVNode._parent = newParentVNode;\n\t\tchildVNode._depth = newParentVNode._depth + 1;\n\n\t\t// Check if we find a corresponding element in oldChildren.\n\t\t// If found, delete the array item by setting to `undefined`.\n\t\t// We use `undefined`, as `null` is reserved for empty placeholders\n\t\t// (holes).\n\t\toldVNode = oldChildren[i];\n\n\t\tif (\n\t\t\toldVNode === null ||\n\t\t\t(oldVNode &&\n\t\t\t\tchildVNode.key == oldVNode.key &&\n\t\t\t\tchildVNode.type === oldVNode.type)\n\t\t) {\n\t\t\toldChildren[i] = undefined;\n\t\t} else {\n\t\t\t// Either oldVNode === undefined or oldChildrenLength > 0,\n\t\t\t// so after this loop oldVNode == null or oldVNode is a valid value.\n\t\t\tfor (j = 0; j < oldChildrenLength; j++) {\n\t\t\t\toldVNode = oldChildren[j];\n\t\t\t\t// If childVNode is unkeyed, we only match similarly unkeyed nodes, otherwise we match by key.\n\t\t\t\t// We always match by type (in either case).\n\t\t\t\tif (\n\t\t\t\t\toldVNode &&\n\t\t\t\t\tchildVNode.key == oldVNode.key &&\n\t\t\t\t\tchildVNode.type === oldVNode.type\n\t\t\t\t) {\n\t\t\t\t\toldChildren[j] = undefined;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\toldVNode = null;\n\t\t\t}\n\t\t}\n\n\t\toldVNode = oldVNode || EMPTY_OBJ;\n\n\t\t// Morph the old element into the new one, but don't append it to the dom yet\n\t\tdiff(\n\t\t\tparentDom,\n\t\t\tchildVNode,\n\t\t\toldVNode,\n\t\t\tglobalContext,\n\t\t\tisSvg,\n\t\t\texcessDomChildren,\n\t\t\tcommitQueue,\n\t\t\toldDom,\n\t\t\tisHydrating\n\t\t);\n\n\t\tnewDom = childVNode._dom;\n\n\t\tif ((j = childVNode.ref) && oldVNode.ref != j) {\n\t\t\tif (!refs) refs = [];\n\t\t\tif (oldVNode.ref) refs.push(oldVNode.ref, null, childVNode);\n\t\t\trefs.push(j, childVNode._component || newDom, childVNode);\n\t\t}\n\n\t\tif (newDom != null) {\n\t\t\tif (firstChildDom == null) {\n\t\t\t\tfirstChildDom = newDom;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\ttypeof childVNode.type == 'function' &&\n\t\t\t\tchildVNode._children != null && // Can be null if childVNode suspended\n\t\t\t\tchildVNode._children === oldVNode._children\n\t\t\t) {\n\t\t\t\tchildVNode._nextDom = oldDom = reorderChildren(\n\t\t\t\t\tchildVNode,\n\t\t\t\t\toldDom,\n\t\t\t\t\tparentDom\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\toldDom = placeChild(\n\t\t\t\t\tparentDom,\n\t\t\t\t\tchildVNode,\n\t\t\t\t\toldVNode,\n\t\t\t\t\toldChildren,\n\t\t\t\t\tnewDom,\n\t\t\t\t\toldDom\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Browsers will infer an option's `value` from `textContent` when\n\t\t\t// no value is present. This essentially bypasses our code to set it\n\t\t\t// later in `diff()`. It works fine in all browsers except for IE11\n\t\t\t// where it breaks setting `select.value`. There it will be always set\n\t\t\t// to an empty string. Re-applying an options value will fix that, so\n\t\t\t// there are probably some internal data structures that aren't\n\t\t\t// updated properly.\n\t\t\t//\n\t\t\t// To fix it we make sure to reset the inferred value, so that our own\n\t\t\t// value check in `diff()` won't be skipped.\n\t\t\tif (!isHydrating && newParentVNode.type === 'option') {\n\t\t\t\t// @ts-ignore We have validated that the type of parentDOM is 'option'\n\t\t\t\t// in the above check\n\t\t\t\tparentDom.value = '';\n\t\t\t} else if (typeof newParentVNode.type == 'function') {\n\t\t\t\t// Because the newParentVNode is Fragment-like, we need to set it's\n\t\t\t\t// _nextDom property to the nextSibling of its last child DOM node.\n\t\t\t\t//\n\t\t\t\t// `oldDom` contains the correct value here because if the last child\n\t\t\t\t// is a Fragment-like, then oldDom has already been set to that child's _nextDom.\n\t\t\t\t// If the last child is a DOM VNode, then oldDom will be set to that DOM\n\t\t\t\t// node's nextSibling.\n\t\t\t\tnewParentVNode._nextDom = oldDom;\n\t\t\t}\n\t\t} else if (\n\t\t\toldDom &&\n\t\t\toldVNode._dom == oldDom &&\n\t\t\toldDom.parentNode != parentDom\n\t\t) {\n\t\t\t// The above condition is to handle null placeholders. See test in placeholder.test.js:\n\t\t\t// `efficiently replace null placeholders in parent rerenders`\n\t\t\toldDom = getDomSibling(oldVNode);\n\t\t}\n\t}\n\n\tnewParentVNode._dom = firstChildDom;\n\n\t// Remove remaining oldChildren if there are any.\n\tfor (i = oldChildrenLength; i--; ) {\n\t\tif (oldChildren[i] != null) {\n\t\t\tif (\n\t\t\t\ttypeof newParentVNode.type == 'function' &&\n\t\t\t\toldChildren[i]._dom != null &&\n\t\t\t\toldChildren[i]._dom == newParentVNode._nextDom\n\t\t\t) {\n\t\t\t\t// If the newParentVNode.__nextDom points to a dom node that is about to\n\t\t\t\t// be unmounted, then get the next sibling of that vnode and set\n\t\t\t\t// _nextDom to it\n\t\t\t\tnewParentVNode._nextDom = getDomSibling(oldParentVNode, i + 1);\n\t\t\t}\n\n\t\t\tunmount(oldChildren[i], oldChildren[i]);\n\t\t}\n\t}\n\n\t// Set refs only after unmount\n\tif (refs) {\n\t\tfor (i = 0; i < refs.length; i++) {\n\t\t\tapplyRef(refs[i], refs[++i], refs[++i]);\n\t\t}\n\t}\n}\n\nfunction reorderChildren(childVNode, oldDom, parentDom) {\n\tfor (let tmp = 0; tmp < childVNode._children.length; tmp++) {\n\t\tlet vnode = childVNode._children[tmp];\n\t\tif (vnode) {\n\t\t\t// We typically enter this code path on sCU bailout, where we copy\n\t\t\t// oldVNode._children to newVNode._children. If that is the case, we need\n\t\t\t// to update the old children's _parent pointer to point to the newVNode\n\t\t\t// (childVNode here).\n\t\t\tvnode._parent = childVNode;\n\n\t\t\tif (typeof vnode.type == 'function') {\n\t\t\t\toldDom = reorderChildren(vnode, oldDom, parentDom);\n\t\t\t} else {\n\t\t\t\toldDom = placeChild(\n\t\t\t\t\tparentDom,\n\t\t\t\t\tvnode,\n\t\t\t\t\tvnode,\n\t\t\t\t\tchildVNode._children,\n\t\t\t\t\tvnode._dom,\n\t\t\t\t\toldDom\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn oldDom;\n}\n\n/**\n * Flatten and loop through the children of a virtual node\n * @param {import('../index').ComponentChildren} children The unflattened\n * children of a virtual node\n * @returns {import('../internal').VNode[]}\n */\nexport function toChildArray(children, out) {\n\tout = out || [];\n\tif (children == null || typeof children == 'boolean') {\n\t} else if (Array.isArray(children)) {\n\t\tchildren.some(child => {\n\t\t\ttoChildArray(child, out);\n\t\t});\n\t} else {\n\t\tout.push(children);\n\t}\n\treturn out;\n}\n\nfunction placeChild(\n\tparentDom,\n\tchildVNode,\n\toldVNode,\n\toldChildren,\n\tnewDom,\n\toldDom\n) {\n\tlet nextDom;\n\tif (childVNode._nextDom !== undefined) {\n\t\t// Only Fragments or components that return Fragment like VNodes will\n\t\t// have a non-undefined _nextDom. Continue the diff from the sibling\n\t\t// of last DOM child of this child VNode\n\t\tnextDom = childVNode._nextDom;\n\n\t\t// Eagerly cleanup _nextDom. We don't need to persist the value because\n\t\t// it is only used by `diffChildren` to determine where to resume the diff after\n\t\t// diffing Components and Fragments. Once we store it the nextDOM local var, we\n\t\t// can clean up the property\n\t\tchildVNode._nextDom = undefined;\n\t} else if (\n\t\toldVNode == null ||\n\t\tnewDom != oldDom ||\n\t\tnewDom.parentNode == null\n\t) {\n\t\touter: if (oldDom == null || oldDom.parentNode !== parentDom) {\n\t\t\tparentDom.appendChild(newDom);\n\t\t\tnextDom = null;\n\t\t} else {\n\t\t\t// `j href (xlink:href was removed from SVG and isn't needed)\n\t\t\t// - className --> class\n\t\t\tname = name.replace(/xlink[H:h]/, 'h').replace(/sName$/, 's');\n\t\t} else if (\n\t\t\tname !== 'href' &&\n\t\t\tname !== 'list' &&\n\t\t\tname !== 'form' &&\n\t\t\t// Default value in browsers is `-1` and an empty string is\n\t\t\t// cast to `0` instead\n\t\t\tname !== 'tabIndex' &&\n\t\t\tname !== 'download' &&\n\t\t\tname in dom\n\t\t) {\n\t\t\ttry {\n\t\t\t\tdom[name] = value == null ? '' : value;\n\t\t\t\t// labelled break is 1b smaller here than a return statement (sorry)\n\t\t\t\tbreak o;\n\t\t\t} catch (e) {}\n\t\t}\n\n\t\t// ARIA-attributes have a different notion of boolean values.\n\t\t// The value `false` is different from the attribute not\n\t\t// existing on the DOM, so we can't remove it. For non-boolean\n\t\t// ARIA-attributes we could treat false as a removal, but the\n\t\t// amount of exceptions would cost us too many bytes. On top of\n\t\t// that other VDOM frameworks also always stringify `false`.\n\n\t\tif (typeof value === 'function') {\n\t\t\t// never serialize functions as attribute values\n\t\t} else if (\n\t\t\tvalue != null &&\n\t\t\t(value !== false || (name[0] === 'a' && name[1] === 'r'))\n\t\t) {\n\t\t\tdom.setAttribute(name, value);\n\t\t} else {\n\t\t\tdom.removeAttribute(name);\n\t\t}\n\t}\n}\n\n/**\n * Proxy an event to hooked event handlers\n * @param {Event} e The event object from the browser\n * @private\n */\nfunction eventProxy(e) {\n\tthis._listeners[e.type + false](options.event ? options.event(e) : e);\n}\n\nfunction eventProxyCapture(e) {\n\tthis._listeners[e.type + true](options.event ? options.event(e) : e);\n}\n","import { EMPTY_OBJ, EMPTY_ARR } from '../constants';\nimport { Component } from '../component';\nimport { Fragment } from '../create-element';\nimport { diffChildren } from './children';\nimport { diffProps, setProperty } from './props';\nimport { assign, removeNode } from '../util';\nimport options from '../options';\n\n/**\n * Diff two virtual nodes and apply proper changes to the DOM\n * @param {import('../internal').PreactElement} parentDom The parent of the DOM element\n * @param {import('../internal').VNode} newVNode The new virtual node\n * @param {import('../internal').VNode} oldVNode The old virtual node\n * @param {object} globalContext The current context object. Modified by getChildContext\n * @param {boolean} isSvg Whether or not this element is an SVG node\n * @param {Array} excessDomChildren\n * @param {Array} commitQueue List of components\n * which have callbacks to invoke in commitRoot\n * @param {import('../internal').PreactElement} oldDom The current attached DOM\n * element any new dom elements should be placed around. Likely `null` on first\n * render (except when hydrating). Can be a sibling DOM element when diffing\n * Fragments that have siblings. In most cases, it starts out as `oldChildren[0]._dom`.\n * @param {boolean} [isHydrating] Whether or not we are in hydration\n */\nexport function diff(\n\tparentDom,\n\tnewVNode,\n\toldVNode,\n\tglobalContext,\n\tisSvg,\n\texcessDomChildren,\n\tcommitQueue,\n\toldDom,\n\tisHydrating\n) {\n\tlet tmp,\n\t\tnewType = newVNode.type;\n\n\t// When passing through createElement it assigns the object\n\t// constructor as undefined. This to prevent JSON-injection.\n\tif (newVNode.constructor !== undefined) return null;\n\n\t// If the previous diff bailed out, resume creating/hydrating.\n\tif (oldVNode._hydrating != null) {\n\t\tisHydrating = oldVNode._hydrating;\n\t\toldDom = newVNode._dom = oldVNode._dom;\n\t\t// if we resume, we want the tree to be \"unlocked\"\n\t\tnewVNode._hydrating = null;\n\t\texcessDomChildren = [oldDom];\n\t}\n\n\tif ((tmp = options._diff)) tmp(newVNode);\n\n\ttry {\n\t\touter: if (typeof newType == 'function') {\n\t\t\tlet c, isNew, oldProps, oldState, snapshot, clearProcessingException;\n\t\t\tlet newProps = newVNode.props;\n\n\t\t\t// Necessary for createContext api. Setting this property will pass\n\t\t\t// the context value as `this.context` just for this component.\n\t\t\ttmp = newType.contextType;\n\t\t\tlet provider = tmp && globalContext[tmp._id];\n\t\t\tlet componentContext = tmp\n\t\t\t\t? provider\n\t\t\t\t\t? provider.props.value\n\t\t\t\t\t: tmp._defaultValue\n\t\t\t\t: globalContext;\n\n\t\t\t// Get component and set it to `c`\n\t\t\tif (oldVNode._component) {\n\t\t\t\tc = newVNode._component = oldVNode._component;\n\t\t\t\tclearProcessingException = c._processingException = c._pendingError;\n\t\t\t} else {\n\t\t\t\t// Instantiate the new component\n\t\t\t\tif ('prototype' in newType && newType.prototype.render) {\n\t\t\t\t\t// @ts-ignore The check above verifies that newType is suppose to be constructed\n\t\t\t\t\tnewVNode._component = c = new newType(newProps, componentContext); // eslint-disable-line new-cap\n\t\t\t\t} else {\n\t\t\t\t\t// @ts-ignore Trust me, Component implements the interface we want\n\t\t\t\t\tnewVNode._component = c = new Component(newProps, componentContext);\n\t\t\t\t\tc.constructor = newType;\n\t\t\t\t\tc.render = doRender;\n\t\t\t\t}\n\t\t\t\tif (provider) provider.sub(c);\n\n\t\t\t\tc.props = newProps;\n\t\t\t\tif (!c.state) c.state = {};\n\t\t\t\tc.context = componentContext;\n\t\t\t\tc._globalContext = globalContext;\n\t\t\t\tisNew = c._dirty = true;\n\t\t\t\tc._renderCallbacks = [];\n\t\t\t}\n\n\t\t\t// Invoke getDerivedStateFromProps\n\t\t\tif (c._nextState == null) {\n\t\t\t\tc._nextState = c.state;\n\t\t\t}\n\t\t\tif (newType.getDerivedStateFromProps != null) {\n\t\t\t\tif (c._nextState == c.state) {\n\t\t\t\t\tc._nextState = assign({}, c._nextState);\n\t\t\t\t}\n\n\t\t\t\tassign(\n\t\t\t\t\tc._nextState,\n\t\t\t\t\tnewType.getDerivedStateFromProps(newProps, c._nextState)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\toldProps = c.props;\n\t\t\toldState = c.state;\n\n\t\t\t// Invoke pre-render lifecycle methods\n\t\t\tif (isNew) {\n\t\t\t\tif (\n\t\t\t\t\tnewType.getDerivedStateFromProps == null &&\n\t\t\t\t\tc.componentWillMount != null\n\t\t\t\t) {\n\t\t\t\t\tc.componentWillMount();\n\t\t\t\t}\n\n\t\t\t\tif (c.componentDidMount != null) {\n\t\t\t\t\tc._renderCallbacks.push(c.componentDidMount);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (\n\t\t\t\t\tnewType.getDerivedStateFromProps == null &&\n\t\t\t\t\tnewProps !== oldProps &&\n\t\t\t\t\tc.componentWillReceiveProps != null\n\t\t\t\t) {\n\t\t\t\t\tc.componentWillReceiveProps(newProps, componentContext);\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\t(!c._force &&\n\t\t\t\t\t\tc.shouldComponentUpdate != null &&\n\t\t\t\t\t\tc.shouldComponentUpdate(\n\t\t\t\t\t\t\tnewProps,\n\t\t\t\t\t\t\tc._nextState,\n\t\t\t\t\t\t\tcomponentContext\n\t\t\t\t\t\t) === false) ||\n\t\t\t\t\tnewVNode._original === oldVNode._original\n\t\t\t\t) {\n\t\t\t\t\tc.props = newProps;\n\t\t\t\t\tc.state = c._nextState;\n\t\t\t\t\t// More info about this here: https://gist.github.com/JoviDeCroock/bec5f2ce93544d2e6070ef8e0036e4e8\n\t\t\t\t\tif (newVNode._original !== oldVNode._original) c._dirty = false;\n\t\t\t\t\tc._vnode = newVNode;\n\t\t\t\t\tnewVNode._dom = oldVNode._dom;\n\t\t\t\t\tnewVNode._children = oldVNode._children;\n\t\t\t\t\tnewVNode._children.forEach(vnode => {\n\t\t\t\t\t\tif (vnode) vnode._parent = newVNode;\n\t\t\t\t\t});\n\t\t\t\t\tif (c._renderCallbacks.length) {\n\t\t\t\t\t\tcommitQueue.push(c);\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak outer;\n\t\t\t\t}\n\n\t\t\t\tif (c.componentWillUpdate != null) {\n\t\t\t\t\tc.componentWillUpdate(newProps, c._nextState, componentContext);\n\t\t\t\t}\n\n\t\t\t\tif (c.componentDidUpdate != null) {\n\t\t\t\t\tc._renderCallbacks.push(() => {\n\t\t\t\t\t\tc.componentDidUpdate(oldProps, oldState, snapshot);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tc.context = componentContext;\n\t\t\tc.props = newProps;\n\t\t\tc.state = c._nextState;\n\n\t\t\tif ((tmp = options._render)) tmp(newVNode);\n\n\t\t\tc._dirty = false;\n\t\t\tc._vnode = newVNode;\n\t\t\tc._parentDom = parentDom;\n\n\t\t\ttmp = c.render(c.props, c.state, c.context);\n\n\t\t\t// Handle setState called in render, see #2553\n\t\t\tc.state = c._nextState;\n\n\t\t\tif (c.getChildContext != null) {\n\t\t\t\tglobalContext = assign(assign({}, globalContext), c.getChildContext());\n\t\t\t}\n\n\t\t\tif (!isNew && c.getSnapshotBeforeUpdate != null) {\n\t\t\t\tsnapshot = c.getSnapshotBeforeUpdate(oldProps, oldState);\n\t\t\t}\n\n\t\t\tlet isTopLevelFragment =\n\t\t\t\ttmp != null && tmp.type === Fragment && tmp.key == null;\n\t\t\tlet renderResult = isTopLevelFragment ? tmp.props.children : tmp;\n\n\t\t\tdiffChildren(\n\t\t\t\tparentDom,\n\t\t\t\tArray.isArray(renderResult) ? renderResult : [renderResult],\n\t\t\t\tnewVNode,\n\t\t\t\toldVNode,\n\t\t\t\tglobalContext,\n\t\t\t\tisSvg,\n\t\t\t\texcessDomChildren,\n\t\t\t\tcommitQueue,\n\t\t\t\toldDom,\n\t\t\t\tisHydrating\n\t\t\t);\n\n\t\t\tc.base = newVNode._dom;\n\n\t\t\t// We successfully rendered this VNode, unset any stored hydration/bailout state:\n\t\t\tnewVNode._hydrating = null;\n\n\t\t\tif (c._renderCallbacks.length) {\n\t\t\t\tcommitQueue.push(c);\n\t\t\t}\n\n\t\t\tif (clearProcessingException) {\n\t\t\t\tc._pendingError = c._processingException = null;\n\t\t\t}\n\n\t\t\tc._force = false;\n\t\t} else if (\n\t\t\texcessDomChildren == null &&\n\t\t\tnewVNode._original === oldVNode._original\n\t\t) {\n\t\t\tnewVNode._children = oldVNode._children;\n\t\t\tnewVNode._dom = oldVNode._dom;\n\t\t} else {\n\t\t\tnewVNode._dom = diffElementNodes(\n\t\t\t\toldVNode._dom,\n\t\t\t\tnewVNode,\n\t\t\t\toldVNode,\n\t\t\t\tglobalContext,\n\t\t\t\tisSvg,\n\t\t\t\texcessDomChildren,\n\t\t\t\tcommitQueue,\n\t\t\t\tisHydrating\n\t\t\t);\n\t\t}\n\n\t\tif ((tmp = options.diffed)) tmp(newVNode);\n\t} catch (e) {\n\t\tnewVNode._original = null;\n\t\t// if hydrating or creating initial tree, bailout preserves DOM:\n\t\tif (isHydrating || excessDomChildren != null) {\n\t\t\tnewVNode._dom = oldDom;\n\t\t\tnewVNode._hydrating = !!isHydrating;\n\t\t\texcessDomChildren[excessDomChildren.indexOf(oldDom)] = null;\n\t\t\t// ^ could possibly be simplified to:\n\t\t\t// excessDomChildren.length = 0;\n\t\t}\n\t\toptions._catchError(e, newVNode, oldVNode);\n\t}\n}\n\n/**\n * @param {Array} commitQueue List of components\n * which have callbacks to invoke in commitRoot\n * @param {import('../internal').VNode} root\n */\nexport function commitRoot(commitQueue, root) {\n\tif (options._commit) options._commit(root, commitQueue);\n\n\tcommitQueue.some(c => {\n\t\ttry {\n\t\t\t// @ts-ignore Reuse the commitQueue variable here so the type changes\n\t\t\tcommitQueue = c._renderCallbacks;\n\t\t\tc._renderCallbacks = [];\n\t\t\tcommitQueue.some(cb => {\n\t\t\t\t// @ts-ignore See above ts-ignore on commitQueue\n\t\t\t\tcb.call(c);\n\t\t\t});\n\t\t} catch (e) {\n\t\t\toptions._catchError(e, c._vnode);\n\t\t}\n\t});\n}\n\n/**\n * Diff two virtual nodes representing DOM element\n * @param {import('../internal').PreactElement} dom The DOM element representing\n * the virtual nodes being diffed\n * @param {import('../internal').VNode} newVNode The new virtual node\n * @param {import('../internal').VNode} oldVNode The old virtual node\n * @param {object} globalContext The current context object\n * @param {boolean} isSvg Whether or not this DOM node is an SVG node\n * @param {*} excessDomChildren\n * @param {Array} commitQueue List of components\n * which have callbacks to invoke in commitRoot\n * @param {boolean} isHydrating Whether or not we are in hydration\n * @returns {import('../internal').PreactElement}\n */\nfunction diffElementNodes(\n\tdom,\n\tnewVNode,\n\toldVNode,\n\tglobalContext,\n\tisSvg,\n\texcessDomChildren,\n\tcommitQueue,\n\tisHydrating\n) {\n\tlet oldProps = oldVNode.props;\n\tlet newProps = newVNode.props;\n\tlet nodeType = newVNode.type;\n\tlet i = 0;\n\n\t// Tracks entering and exiting SVG namespace when descending through the tree.\n\tif (nodeType === 'svg') isSvg = true;\n\n\tif (excessDomChildren != null) {\n\t\tfor (; i < excessDomChildren.length; i++) {\n\t\t\tconst child = excessDomChildren[i];\n\n\t\t\t// if newVNode matches an element in excessDomChildren or the `dom`\n\t\t\t// argument matches an element in excessDomChildren, remove it from\n\t\t\t// excessDomChildren so it isn't later removed in diffChildren\n\t\t\tif (\n\t\t\t\tchild &&\n\t\t\t\t(child === dom ||\n\t\t\t\t\t(nodeType ? child.localName == nodeType : child.nodeType == 3))\n\t\t\t) {\n\t\t\t\tdom = child;\n\t\t\t\texcessDomChildren[i] = null;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (dom == null) {\n\t\tif (nodeType === null) {\n\t\t\t// @ts-ignore createTextNode returns Text, we expect PreactElement\n\t\t\treturn document.createTextNode(newProps);\n\t\t}\n\n\t\tif (isSvg) {\n\t\t\tdom = document.createElementNS(\n\t\t\t\t'http://www.w3.org/2000/svg',\n\t\t\t\t// @ts-ignore We know `newVNode.type` is a string\n\t\t\t\tnodeType\n\t\t\t);\n\t\t} else {\n\t\t\tdom = document.createElement(\n\t\t\t\t// @ts-ignore We know `newVNode.type` is a string\n\t\t\t\tnodeType,\n\t\t\t\tnewProps.is && newProps\n\t\t\t);\n\t\t}\n\n\t\t// we created a new parent, so none of the previously attached children can be reused:\n\t\texcessDomChildren = null;\n\t\t// we are creating a new node, so we can assume this is a new subtree (in case we are hydrating), this deopts the hydrate\n\t\tisHydrating = false;\n\t}\n\n\tif (nodeType === null) {\n\t\t// During hydration, we still have to split merged text from SSR'd HTML.\n\t\tif (oldProps !== newProps && (!isHydrating || dom.data !== newProps)) {\n\t\t\tdom.data = newProps;\n\t\t}\n\t} else {\n\t\t// If excessDomChildren was not null, repopulate it with the current element's children:\n\t\texcessDomChildren =\n\t\t\texcessDomChildren && EMPTY_ARR.slice.call(dom.childNodes);\n\n\t\toldProps = oldVNode.props || EMPTY_OBJ;\n\n\t\tlet oldHtml = oldProps.dangerouslySetInnerHTML;\n\t\tlet newHtml = newProps.dangerouslySetInnerHTML;\n\n\t\t// During hydration, props are not diffed at all (including dangerouslySetInnerHTML)\n\t\t// @TODO we should warn in debug mode when props don't match here.\n\t\tif (!isHydrating) {\n\t\t\t// But, if we are in a situation where we are using existing DOM (e.g. replaceNode)\n\t\t\t// we should read the existing DOM attributes to diff them\n\t\t\tif (excessDomChildren != null) {\n\t\t\t\toldProps = {};\n\t\t\t\tfor (let i = 0; i < dom.attributes.length; i++) {\n\t\t\t\t\toldProps[dom.attributes[i].name] = dom.attributes[i].value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (newHtml || oldHtml) {\n\t\t\t\t// Avoid re-applying the same '__html' if it did not changed between re-render\n\t\t\t\tif (\n\t\t\t\t\t!newHtml ||\n\t\t\t\t\t((!oldHtml || newHtml.__html != oldHtml.__html) &&\n\t\t\t\t\t\tnewHtml.__html !== dom.innerHTML)\n\t\t\t\t) {\n\t\t\t\t\tdom.innerHTML = (newHtml && newHtml.__html) || '';\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdiffProps(dom, newProps, oldProps, isSvg, isHydrating);\n\n\t\t// If the new vnode didn't have dangerouslySetInnerHTML, diff its children\n\t\tif (newHtml) {\n\t\t\tnewVNode._children = [];\n\t\t} else {\n\t\t\ti = newVNode.props.children;\n\t\t\tdiffChildren(\n\t\t\t\tdom,\n\t\t\t\tArray.isArray(i) ? i : [i],\n\t\t\t\tnewVNode,\n\t\t\t\toldVNode,\n\t\t\t\tglobalContext,\n\t\t\t\tisSvg && nodeType !== 'foreignObject',\n\t\t\t\texcessDomChildren,\n\t\t\t\tcommitQueue,\n\t\t\t\tdom.firstChild,\n\t\t\t\tisHydrating\n\t\t\t);\n\n\t\t\t// Remove children that are not part of any vnode.\n\t\t\tif (excessDomChildren != null) {\n\t\t\t\tfor (i = excessDomChildren.length; i--; ) {\n\t\t\t\t\tif (excessDomChildren[i] != null) removeNode(excessDomChildren[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// (as above, don't diff props during hydration)\n\t\tif (!isHydrating) {\n\t\t\tif (\n\t\t\t\t'value' in newProps &&\n\t\t\t\t(i = newProps.value) !== undefined &&\n\t\t\t\t// #2756 For the -element the initial value is 0,\n\t\t\t\t// despite the attribute not being present. When the attribute\n\t\t\t\t// is missing the progress bar is treated as indeterminate.\n\t\t\t\t// To fix that we'll always update it when it is 0 for progress elements\n\t\t\t\t(i !== dom.value || (nodeType === 'progress' && !i))\n\t\t\t) {\n\t\t\t\tsetProperty(dom, 'value', i, oldProps.value, false);\n\t\t\t}\n\t\t\tif (\n\t\t\t\t'checked' in newProps &&\n\t\t\t\t(i = newProps.checked) !== undefined &&\n\t\t\t\ti !== dom.checked\n\t\t\t) {\n\t\t\t\tsetProperty(dom, 'checked', i, oldProps.checked, false);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn dom;\n}\n\n/**\n * Invoke or update a ref, depending on whether it is a function or object ref.\n * @param {object|function} ref\n * @param {any} value\n * @param {import('../internal').VNode} vnode\n */\nexport function applyRef(ref, value, vnode) {\n\ttry {\n\t\tif (typeof ref == 'function') ref(value);\n\t\telse ref.current = value;\n\t} catch (e) {\n\t\toptions._catchError(e, vnode);\n\t}\n}\n\n/**\n * Unmount a virtual node from the tree and apply DOM changes\n * @param {import('../internal').VNode} vnode The virtual node to unmount\n * @param {import('../internal').VNode} parentVNode The parent of the VNode that\n * initiated the unmount\n * @param {boolean} [skipRemove] Flag that indicates that a parent node of the\n * current element is already detached from the DOM.\n */\nexport function unmount(vnode, parentVNode, skipRemove) {\n\tlet r;\n\tif (options.unmount) options.unmount(vnode);\n\n\tif ((r = vnode.ref)) {\n\t\tif (!r.current || r.current === vnode._dom) applyRef(r, null, parentVNode);\n\t}\n\n\tlet dom;\n\tif (!skipRemove && typeof vnode.type != 'function') {\n\t\tskipRemove = (dom = vnode._dom) != null;\n\t}\n\n\t// Must be set to `undefined` to properly clean up `_nextDom`\n\t// for which `null` is a valid value. See comment in `create-element.js`\n\tvnode._dom = vnode._nextDom = undefined;\n\n\tif ((r = vnode._component) != null) {\n\t\tif (r.componentWillUnmount) {\n\t\t\ttry {\n\t\t\t\tr.componentWillUnmount();\n\t\t\t} catch (e) {\n\t\t\t\toptions._catchError(e, parentVNode);\n\t\t\t}\n\t\t}\n\n\t\tr.base = r._parentDom = null;\n\t}\n\n\tif ((r = vnode._children)) {\n\t\tfor (let i = 0; i < r.length; i++) {\n\t\t\tif (r[i]) unmount(r[i], parentVNode, skipRemove);\n\t\t}\n\t}\n\n\tif (dom != null) removeNode(dom);\n}\n\n/** The `.render()` method for a PFC backing instance. */\nfunction doRender(props, state, context) {\n\treturn this.constructor(props, context);\n}\n","import { EMPTY_OBJ, EMPTY_ARR } from './constants';\nimport { commitRoot, diff } from './diff/index';\nimport { createElement, Fragment } from './create-element';\nimport options from './options';\n\n/**\n * Render a Preact virtual node into a DOM element\n * @param {import('./internal').ComponentChild} vnode The virtual node to render\n * @param {import('./internal').PreactElement} parentDom The DOM element to\n * render into\n * @param {import('./internal').PreactElement | object} [replaceNode] Optional: Attempt to re-use an\n * existing DOM tree rooted at `replaceNode`\n */\nexport function render(vnode, parentDom, replaceNode) {\n\tif (options._root) options._root(vnode, parentDom);\n\n\t// We abuse the `replaceNode` parameter in `hydrate()` to signal if we are in\n\t// hydration mode or not by passing the `hydrate` function instead of a DOM\n\t// element..\n\tlet isHydrating = typeof replaceNode === 'function';\n\n\t// To be able to support calling `render()` multiple times on the same\n\t// DOM node, we need to obtain a reference to the previous tree. We do\n\t// this by assigning a new `_children` property to DOM nodes which points\n\t// to the last rendered tree. By default this property is not present, which\n\t// means that we are mounting a new tree for the first time.\n\tlet oldVNode = isHydrating\n\t\t? null\n\t\t: (replaceNode && replaceNode._children) || parentDom._children;\n\n\tvnode = (\n\t\t(!isHydrating && replaceNode) ||\n\t\tparentDom\n\t)._children = createElement(Fragment, null, [vnode]);\n\n\t// List of effects that need to be called after diffing.\n\tlet commitQueue = [];\n\tdiff(\n\t\tparentDom,\n\t\t// Determine the new vnode tree and store it on the DOM element on\n\t\t// our custom `_children` property.\n\t\tvnode,\n\t\toldVNode || EMPTY_OBJ,\n\t\tEMPTY_OBJ,\n\t\tparentDom.ownerSVGElement !== undefined,\n\t\t!isHydrating && replaceNode\n\t\t\t? [replaceNode]\n\t\t\t: oldVNode\n\t\t\t? null\n\t\t\t: parentDom.firstChild\n\t\t\t? EMPTY_ARR.slice.call(parentDom.childNodes)\n\t\t\t: null,\n\t\tcommitQueue,\n\t\t!isHydrating && replaceNode\n\t\t\t? replaceNode\n\t\t\t: oldVNode\n\t\t\t? oldVNode._dom\n\t\t\t: parentDom.firstChild,\n\t\tisHydrating\n\t);\n\n\t// Flush all queued effects\n\tcommitRoot(commitQueue, vnode);\n}\n\n/**\n * Update an existing DOM element with data from a Preact virtual node\n * @param {import('./internal').ComponentChild} vnode The virtual node to render\n * @param {import('./internal').PreactElement} parentDom The DOM element to\n * update\n */\nexport function hydrate(vnode, parentDom) {\n\trender(vnode, parentDom, hydrate);\n}\n","import { assign } from './util';\nimport { createVNode } from './create-element';\n\n/**\n * Clones the given VNode, optionally adding attributes/props and replacing its children.\n * @param {import('./internal').VNode} vnode The virtual DOM element to clone\n * @param {object} props Attributes/props to add when cloning\n * @param {Array} rest Any additional arguments will be used as replacement children.\n * @returns {import('./internal').VNode}\n */\nexport function cloneElement(vnode, props, children) {\n\tlet normalizedProps = assign({}, vnode.props),\n\t\tkey,\n\t\tref,\n\t\ti;\n\tfor (i in props) {\n\t\tif (i == 'key') key = props[i];\n\t\telse if (i == 'ref') ref = props[i];\n\t\telse normalizedProps[i] = props[i];\n\t}\n\n\tif (arguments.length > 3) {\n\t\tchildren = [children];\n\t\tfor (i = 3; i < arguments.length; i++) {\n\t\t\tchildren.push(arguments[i]);\n\t\t}\n\t}\n\tif (children != null) {\n\t\tnormalizedProps.children = children;\n\t}\n\n\treturn createVNode(\n\t\tvnode.type,\n\t\tnormalizedProps,\n\t\tkey || vnode.key,\n\t\tref || vnode.ref,\n\t\tnull\n\t);\n}\n","/**\n * Find the closest error boundary to a thrown error and call it\n * @param {object} error The thrown value\n * @param {import('../internal').VNode} vnode The vnode that threw\n * the error that was caught (except for unmounting when this parameter\n * is the highest parent that was being unmounted)\n */\nexport function _catchError(error, vnode) {\n\t/** @type {import('../internal').Component} */\n\tlet component, ctor, handled;\n\n\tfor (; (vnode = vnode._parent); ) {\n\t\tif ((component = vnode._component) && !component._processingException) {\n\t\t\ttry {\n\t\t\t\tctor = component.constructor;\n\n\t\t\t\tif (ctor && ctor.getDerivedStateFromError != null) {\n\t\t\t\t\tcomponent.setState(ctor.getDerivedStateFromError(error));\n\t\t\t\t\thandled = component._dirty;\n\t\t\t\t}\n\n\t\t\t\tif (component.componentDidCatch != null) {\n\t\t\t\t\tcomponent.componentDidCatch(error);\n\t\t\t\t\thandled = component._dirty;\n\t\t\t\t}\n\n\t\t\t\t// This is an error boundary. Mark it as having bailed out, and whether it was mid-hydration.\n\t\t\t\tif (handled) {\n\t\t\t\t\treturn (component._pendingError = component);\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\terror = e;\n\t\t\t}\n\t\t}\n\t}\n\n\tthrow error;\n}\n"],"names":["options","isValidElement","rerenderQueue","defer","prevDebounce","i","EMPTY_OBJ","EMPTY_ARR","IS_NON_DIMENSIONAL","assign","obj","props","removeNode","node","parentNode","removeChild","createElement","type","children","key","ref","normalizedProps","arguments","length","push","defaultProps","undefined","createVNode","original","vnode","constructor","createRef","current","Fragment","Component","context","getDomSibling","childIndex","indexOf","sibling","updateParentDomPointers","child","base","enqueueRender","c","process","debounceRendering","queue","sort","a","b","some","component","commitQueue","oldVNode","oldDom","parentDom","diff","ownerSVGElement","commitRoot","diffChildren","renderResult","newParentVNode","oldParentVNode","globalContext","isSvg","excessDomChildren","isHydrating","j","childVNode","newDom","firstChildDom","refs","oldChildren","oldChildrenLength","Array","isArray","reorderChildren","placeChild","value","unmount","applyRef","tmp","toChildArray","out","nextDom","sibDom","outer","appendChild","nextSibling","insertBefore","diffProps","dom","newProps","oldProps","hydrate","setProperty","setStyle","style","test","name","oldValue","useCapture","o","cssText","replace","toLowerCase","slice","_listeners","addEventListener","eventProxyCapture","eventProxy","removeEventListener","e","setAttribute","removeAttribute","event","newVNode","isNew","oldState","snapshot","clearProcessingException","provider","componentContext","newType","contextType","prototype","render","doRender","sub","state","getDerivedStateFromProps","componentWillMount","componentDidMount","componentWillReceiveProps","shouldComponentUpdate","forEach","componentWillUpdate","componentDidUpdate","getChildContext","getSnapshotBeforeUpdate","diffElementNodes","diffed","root","cb","call","oldHtml","newHtml","nodeType","localName","document","createTextNode","createElementNS","is","data","childNodes","dangerouslySetInnerHTML","attributes","innerHTML","firstChild","checked","parentVNode","skipRemove","r","componentWillUnmount","this","replaceNode","cloneElement","createContext","defaultValue","contextId","Consumer","contextValue","Provider","subs","ctx","_props","old","splice","error","ctor","handled","getDerivedStateFromError","setState","componentDidCatch","update","callback","s","forceUpdate","Promise","then","bind","resolve","setTimeout"],"mappings":"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"} \ No newline at end of file diff --git a/src/Templates/FormFields/FieldType_23.twig b/src/Templates/FormFields/FieldType_23.twig new file mode 100644 index 000000000..178e26fcf --- /dev/null +++ b/src/Templates/FormFields/FieldType_23.twig @@ -0,0 +1,18 @@ +
+ Loading, please wait... +
+ + diff --git a/src/Templates/form.twig b/src/Templates/form.twig index 624ccecd6..1f54c14a1 100644 --- a/src/Templates/form.twig +++ b/src/Templates/form.twig @@ -42,4 +42,15 @@ +{% if react %} + + +{% endif %} {% endblock %} From f2180c1a6c6a9a69c03aa5e8f6cc6b668bcccddf Mon Sep 17 00:00:00 2001 From: Marks Polakovs Date: Mon, 15 Mar 2021 13:50:59 +0000 Subject: [PATCH 02/14] Add test field --- src/Classes/ServiceAPI/MyRadio_Event.php | 8 ++++++++ src/Public/js/myradio.form.react.sample.js | 11 +++++++++++ 2 files changed, 19 insertions(+) create mode 100644 src/Public/js/myradio.form.react.sample.js diff --git a/src/Classes/ServiceAPI/MyRadio_Event.php b/src/Classes/ServiceAPI/MyRadio_Event.php index c2ae2fac6..f20a077e2 100644 --- a/src/Classes/ServiceAPI/MyRadio_Event.php +++ b/src/Classes/ServiceAPI/MyRadio_Event.php @@ -410,6 +410,14 @@ public static function getForm() 'label' => 'End Time', ] ) + )->addField( + new MyRadioFormField( + 'react_test', + MyRadioFormField::TYPE_REACT, + [ + 'component' => 'Sample' + ] + ) ); } diff --git a/src/Public/js/myradio.form.react.sample.js b/src/Public/js/myradio.form.react.sample.js new file mode 100644 index 000000000..e065482e1 --- /dev/null +++ b/src/Public/js/myradio.form.react.sample.js @@ -0,0 +1,11 @@ +import { h } from "preact"; +import htm from "htm"; + +const html = htm.bind(h); + +export default function Sample({ initialValue }) +{ + return html` + Hello React! Initial value is ${initialValue} + `; +} From 8c017c23b3858452b78d423844cc8850cbde0128 Mon Sep 17 00:00:00 2001 From: Marks Polakovs Date: Mon, 15 Mar 2021 13:52:57 +0000 Subject: [PATCH 03/14] Whoops --- src/Public/js/vendor/es-module-shims.min.js | 2 ++ src/Public/js/vendor/es-module-shims.min.js.map | 1 + src/Templates/form.twig | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 src/Public/js/vendor/es-module-shims.min.js create mode 100644 src/Public/js/vendor/es-module-shims.min.js.map diff --git a/src/Public/js/vendor/es-module-shims.min.js b/src/Public/js/vendor/es-module-shims.min.js new file mode 100644 index 000000000..71ceb7a60 --- /dev/null +++ b/src/Public/js/vendor/es-module-shims.min.js @@ -0,0 +1,2 @@ +/* ES Module Shims 0.10.1 */ +!function(){"use strict";const A=Promise.resolve();let Q;function C(A,Q="text/javascript"){return URL.createObjectURL(new Blob([A],{type:Q}))}const B="undefined"!=typeof document;let E,g=!1;try{E=(0,eval)("u=>import(u)"),g=!0}catch(A){if(B){let A;self.addEventListener("error",Q=>A=Q.error),E=B=>{const E=C(`import*as m from'${B}';self._esmsm=m`),g=document.createElement("script");return g.type="module",g.src=E,document.head.appendChild(g),new Promise((C,B)=>{g.addEventListener("load",()=>{document.head.removeChild(g),"_esmsm"in self?(C(self._esmsm,Q),delete self._esmsm):B(A)})})}}}let I=!1,e=!1;const t=Promise.all([E(C("import.meta")).then(()=>I=!0),g&&B&&new Promise(A=>{self._$s=C=>{document.body.removeChild(Q),C&&(e=!0),delete self._$s,A()};const Q=document.createElement("iframe");Q.style.display="none",Q.src=C(' - + {% endif %} {% endblock %} From 80e1290bfbd86b6baef2e5593cf279ab90bd5e68 Mon Sep 17 00:00:00 2001 From: Marks Polakovs Date: Mon, 15 Mar 2021 13:56:04 +0000 Subject: [PATCH 04/14] Debug nonsense --- src/Templates/FormFields/FieldType_23.twig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Templates/FormFields/FieldType_23.twig b/src/Templates/FormFields/FieldType_23.twig index 178e26fcf..faf53f2dd 100644 --- a/src/Templates/FormFields/FieldType_23.twig +++ b/src/Templates/FormFields/FieldType_23.twig @@ -1,6 +1,9 @@
Loading, please wait...
+ - +{# We can't instantiate the component yet, since we have to do it after the import map #} +{# This is done in form.twig. #} diff --git a/src/Templates/form.twig b/src/Templates/form.twig index f2ea9b959..c6718ec78 100644 --- a/src/Templates/form.twig +++ b/src/Templates/form.twig @@ -42,7 +42,7 @@ -{% if react %} +{% if react is defined %} + {# We can't instantiate the component until after the importmap, hence we have to do it now #} + {% for type, fields in react %} + + {% endfor %} {% endif %} {% endblock %} From 1c0ed0821b2786d4164d70f9625da4ffaa78f289 Mon Sep 17 00:00:00 2001 From: Marks Polakovs Date: Mon, 15 Mar 2021 14:06:13 +0000 Subject: [PATCH 07/14] Don't use shim mode --- src/Templates/form.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Templates/form.twig b/src/Templates/form.twig index c6718ec78..b17dd525b 100644 --- a/src/Templates/form.twig +++ b/src/Templates/form.twig @@ -43,7 +43,7 @@ {% if react is defined %} - From 8be06c8dff44025ffea869ca5c059e5e305490f7 Mon Sep 17 00:00:00 2001 From: Marks Polakovs Date: Mon, 15 Mar 2021 14:09:46 +0000 Subject: [PATCH 09/14] Remove silly samples, and improve documentation --- src/Classes/MyRadio/MyRadioFormField.php | 7 +++++-- src/Classes/ServiceAPI/MyRadio_Event.php | 10 ---------- src/Public/js/myradio.form.react.sample.js | 11 ----------- 3 files changed, 5 insertions(+), 23 deletions(-) delete mode 100644 src/Public/js/myradio.form.react.sample.js diff --git a/src/Classes/MyRadio/MyRadioFormField.php b/src/Classes/MyRadio/MyRadioFormField.php index 91294a4a5..7f9b767df 100644 --- a/src/Classes/MyRadio/MyRadioFormField.php +++ b/src/Classes/MyRadio/MyRadioFormField.php @@ -255,9 +255,12 @@ class MyRadioFormField /** * The constant used to specify this MyRadioFormField is a custom React component. * - * It takes the following options: + * It takes the following custom options: * * component - the name of the component to render - * (must be default export of a file called "Public/js/myradio.form.react.{component}.js) + * (must be default export of a file called "Public/js/myradio.form.react.{component|lowercase}.js) + * + * The component is imported from the above file, and rendered with the following props: + * * initialValue: the field's initial value, or `null` if it doesn't have one */ const TYPE_REACT = 0x17; diff --git a/src/Classes/ServiceAPI/MyRadio_Event.php b/src/Classes/ServiceAPI/MyRadio_Event.php index d33a98527..c2ae2fac6 100644 --- a/src/Classes/ServiceAPI/MyRadio_Event.php +++ b/src/Classes/ServiceAPI/MyRadio_Event.php @@ -410,16 +410,6 @@ public static function getForm() 'label' => 'End Time', ] ) - )->addField( - new MyRadioFormField( - 'react_test', - MyRadioFormField::TYPE_REACT, - [ - 'options' => [ - 'component' => 'Sample' - ] - ] - ) ); } diff --git a/src/Public/js/myradio.form.react.sample.js b/src/Public/js/myradio.form.react.sample.js deleted file mode 100644 index e065482e1..000000000 --- a/src/Public/js/myradio.form.react.sample.js +++ /dev/null @@ -1,11 +0,0 @@ -import { h } from "preact"; -import htm from "htm"; - -const html = htm.bind(h); - -export default function Sample({ initialValue }) -{ - return html` - Hello React! Initial value is ${initialValue} - `; -} From 4536cef0acfe194a10590439b9379e5bdbf0c7e3 Mon Sep 17 00:00:00 2001 From: Marks Polakovs Date: Mon, 15 Mar 2021 14:17:42 +0000 Subject: [PATCH 10/14] Support readValues lol --- src/Classes/MyRadio/MyRadioFormField.php | 9 +++++++++ src/Templates/form.twig | 4 +++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Classes/MyRadio/MyRadioFormField.php b/src/Classes/MyRadio/MyRadioFormField.php index 7f9b767df..fa0be7e58 100644 --- a/src/Classes/MyRadio/MyRadioFormField.php +++ b/src/Classes/MyRadio/MyRadioFormField.php @@ -261,6 +261,11 @@ class MyRadioFormField * * The component is imported from the above file, and rendered with the following props: * * initialValue: the field's initial value, or `null` if it doesn't have one + * * formName: the name of the form + * * fieldName: the name of the field + * + * It should render an + * (in other words, a input named the same as all other field inputs, with the field's value JSON-encoded). */ const TYPE_REACT = 0x17; @@ -614,6 +619,7 @@ public function render() * @return mixed The submitted field value * * @throws MyRadioException if the field type does not have a valid read handler + * @throws \JsonException if the React field type returns invalid JSON * * @todo Verify all returns deal with repeated elements correctly */ @@ -855,6 +861,9 @@ public function readValue($prefix) return $times; break; + case self::TYPE_REACT: + // React fields should dump in JSON + return json_decode($_REQUEST[$name], true, 512, JSON_THROW_ON_ERROR); default: throw new MyRadioException( 'Field type ' . $this->type . ' does not have a valid value interpreter definition.' diff --git a/src/Templates/form.twig b/src/Templates/form.twig index 3dda45f96..f837381b4 100644 --- a/src/Templates/form.twig +++ b/src/Templates/form.twig @@ -62,7 +62,9 @@ render(h( {{ type }}, { - initialValue: {{ field.value | json_encode }} + initialValue: {{ field.value | json_encode }}, + formName: "{{ frm_name }}", + fieldName: "{{ field.name }}" } ), document.getElementById("{{ frm_name }}-{{ field.name }}")); From 3d0a71434329d79e99a0be9cbf4f2d814d081933 Mon Sep 17 00:00:00 2001 From: Marks Polakovs Date: Mon, 15 Mar 2021 14:19:38 +0000 Subject: [PATCH 11/14] Fix mistake in doc-comment --- src/Classes/MyRadio/MyRadioFormField.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Classes/MyRadio/MyRadioFormField.php b/src/Classes/MyRadio/MyRadioFormField.php index fa0be7e58..aff088483 100644 --- a/src/Classes/MyRadio/MyRadioFormField.php +++ b/src/Classes/MyRadio/MyRadioFormField.php @@ -264,7 +264,7 @@ class MyRadioFormField * * formName: the name of the form * * fieldName: the name of the field * - * It should render an + * It should render an * (in other words, a input named the same as all other field inputs, with the field's value JSON-encoded). */ const TYPE_REACT = 0x17; From bcae6d76d65f2690704b2f471283b30620ab7fd7 Mon Sep 17 00:00:00 2001 From: Marks Polakovs Date: Mon, 15 Mar 2021 14:23:42 +0000 Subject: [PATCH 12/14] Pass in the whole field --- src/Classes/MyRadio/MyRadioFormField.php | 4 ++-- src/Templates/form.twig | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Classes/MyRadio/MyRadioFormField.php b/src/Classes/MyRadio/MyRadioFormField.php index aff088483..20f021c7f 100644 --- a/src/Classes/MyRadio/MyRadioFormField.php +++ b/src/Classes/MyRadio/MyRadioFormField.php @@ -262,9 +262,9 @@ class MyRadioFormField * The component is imported from the above file, and rendered with the following props: * * initialValue: the field's initial value, or `null` if it doesn't have one * * formName: the name of the form - * * fieldName: the name of the field + * * field: the output of $this->render(), JSON-encoded * - * It should render an + * It should render an * (in other words, a input named the same as all other field inputs, with the field's value JSON-encoded). */ const TYPE_REACT = 0x17; diff --git a/src/Templates/form.twig b/src/Templates/form.twig index f837381b4..26e819f5a 100644 --- a/src/Templates/form.twig +++ b/src/Templates/form.twig @@ -62,9 +62,9 @@ render(h( {{ type }}, { - initialValue: {{ field.value | json_encode }}, + initialValue: {{ field.value | json_encode | raw }}, formName: "{{ frm_name }}", - fieldName: "{{ field.name }}" + field: "{{ field | json_encode | raw }}" } ), document.getElementById("{{ frm_name }}-{{ field.name }}")); From 8a999dd1ac4b49bec405fd8f222ad5ec18b41e1b Mon Sep 17 00:00:00 2001 From: Marks Polakovs Date: Mon, 15 Mar 2021 14:24:07 +0000 Subject: [PATCH 13/14] In fact, if we do that, we don't need initialValue --- src/Classes/MyRadio/MyRadioFormField.php | 1 - src/Templates/form.twig | 1 - 2 files changed, 2 deletions(-) diff --git a/src/Classes/MyRadio/MyRadioFormField.php b/src/Classes/MyRadio/MyRadioFormField.php index 20f021c7f..ce582c88d 100644 --- a/src/Classes/MyRadio/MyRadioFormField.php +++ b/src/Classes/MyRadio/MyRadioFormField.php @@ -260,7 +260,6 @@ class MyRadioFormField * (must be default export of a file called "Public/js/myradio.form.react.{component|lowercase}.js) * * The component is imported from the above file, and rendered with the following props: - * * initialValue: the field's initial value, or `null` if it doesn't have one * * formName: the name of the form * * field: the output of $this->render(), JSON-encoded * diff --git a/src/Templates/form.twig b/src/Templates/form.twig index 26e819f5a..ee0b0209d 100644 --- a/src/Templates/form.twig +++ b/src/Templates/form.twig @@ -62,7 +62,6 @@ render(h( {{ type }}, { - initialValue: {{ field.value | json_encode | raw }}, formName: "{{ frm_name }}", field: "{{ field | json_encode | raw }}" } From 61ffe68806c6a91f7d4eb283786a521a48398624 Mon Sep 17 00:00:00 2001 From: Marks Polakovs Date: Tue, 16 Mar 2021 08:21:34 +0000 Subject: [PATCH 14/14] Add preact/compat for full React compat --- src/Public/js/vendor/preact.compat.module.js | 2 ++ src/Public/js/vendor/preact.compat.module.js.map | 1 + src/Templates/form.twig | 4 +++- 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 src/Public/js/vendor/preact.compat.module.js create mode 100644 src/Public/js/vendor/preact.compat.module.js.map diff --git a/src/Public/js/vendor/preact.compat.module.js b/src/Public/js/vendor/preact.compat.module.js new file mode 100644 index 000000000..ea00bdec9 --- /dev/null +++ b/src/Public/js/vendor/preact.compat.module.js @@ -0,0 +1,2 @@ +import{useState as n,useReducer as t,useEffect as e,useLayoutEffect as r,useRef as u,useImperativeHandle as o,useMemo as i,useCallback as l,useContext as f,useDebugValue as c}from"preact/hooks";export*from"preact/hooks";import{Component as a,createElement as s,options as h,toChildArray as p,Fragment as v,render as d,hydrate as m,cloneElement as y,createRef as b,createContext as _}from"preact";export{createElement,createContext,createRef,Fragment,Component}from"preact";function C(n,t){for(var e in t)n[e]=t[e];return n}function S(n,t){for(var e in n)if("__source"!==e&&!(e in t))return!0;for(var r in t)if("__source"!==r&&n[r]!==t[r])return!0;return!1}function E(n){this.props=n}function g(n,t){function e(n){var e=this.props.ref,r=e==n.ref;return!r&&e&&(e.call?e(null):e.current=null),t?!t(this.props,n)||!r:S(this.props,n)}function r(t){return this.shouldComponentUpdate=e,s(n,t)}return r.displayName="Memo("+(n.displayName||n.name)+")",r.prototype.isReactComponent=!0,r.__f=!0,r}(E.prototype=new a).isPureReactComponent=!0,E.prototype.shouldComponentUpdate=function(n,t){return S(this.props,n)||S(this.state,t)};var w=h.__b;h.__b=function(n){n.type&&n.type.__f&&n.ref&&(n.props.ref=n.ref,n.ref=null),w&&w(n)};var R="undefined"!=typeof Symbol&&Symbol.for&&Symbol.for("react.forward_ref")||3911;function x(n){function t(t,e){var r=C({},t);return delete r.ref,n(r,(e=t.ref||e)&&("object"!=typeof e||"current"in e)?e:null)}return t.$$typeof=R,t.render=t,t.prototype.isReactComponent=t.__f=!0,t.displayName="ForwardRef("+(n.displayName||n.name)+")",t}var N=function(n,t){return null==n?null:p(p(n).map(t))},k={map:N,forEach:N,count:function(n){return n?p(n).length:0},only:function(n){var t=p(n);if(1!==t.length)throw"Children.only";return t[0]},toArray:p},A=h.__e;h.__e=function(n,t,e){if(n.then)for(var r,u=t;u=u.__;)if((r=u.__c)&&r.__c)return null==t.__e&&(t.__e=e.__e,t.__k=e.__k),r.__c(n,t);A(n,t,e)};var O=h.unmount;function L(){this.__u=0,this.t=null,this.__b=null}function U(n){var t=n.__.__c;return t&&t.__e&&t.__e(n)}function D(n){var t,e,r;function u(u){if(t||(t=n()).then(function(n){e=n.default||n},function(n){r=n}),r)throw r;if(!e)throw t;return s(e,u)}return u.displayName="Lazy",u.__f=!0,u}function F(){this.u=null,this.o=null}h.unmount=function(n){var t=n.__c;t&&t.__R&&t.__R(),t&&!0===n.__h&&(n.type=null),O&&O(n)},(L.prototype=new a).__c=function(n,t){var e=t.__c,r=this;null==r.t&&(r.t=[]),r.t.push(e);var u=U(r.__v),o=!1,i=function(){o||(o=!0,e.__R=null,u?u(l):l())};e.__R=i;var l=function(){if(!--r.__u){if(r.state.__e){var n=r.state.__e;r.__v.__k[0]=function n(t,e,r){return t&&(t.__v=null,t.__k=t.__k&&t.__k.map(function(t){return n(t,e,r)}),t.__c&&t.__c.__P===e&&(t.__e&&r.insertBefore(t.__e,t.__d),t.__c.__e=!0,t.__c.__P=r)),t}(n,n.__c.__P,n.__c.__O)}var t;for(r.setState({__e:r.__b=null});t=r.t.pop();)t.forceUpdate()}},f=!0===t.__h;r.__u++||f||r.setState({__e:r.__b=r.__v.__k[0]}),n.then(i,i)},L.prototype.componentWillUnmount=function(){this.t=[]},L.prototype.render=function(n,t){if(this.__b){if(this.__v.__k){var e=document.createElement("div"),r=this.__v.__k[0].__c;this.__v.__k[0]=function n(t,e,r){return t&&(t.__c&&t.__c.__H&&(t.__c.__H.__.forEach(function(n){"function"==typeof n.__c&&n.__c()}),t.__c.__H=null),null!=(t=C({},t)).__c&&(t.__c.__P===r&&(t.__c.__P=e),t.__c=null),t.__k=t.__k&&t.__k.map(function(t){return n(t,e,r)})),t}(this.__b,e,r.__O=r.__P)}this.__b=null}var u=t.__e&&s(v,null,n.fallback);return u&&(u.__h=null),[s(v,null,t.__e?null:n.children),u]};var M=function(n,t,e){if(++e[1]===e[0]&&n.o.delete(t),n.props.revealOrder&&("t"!==n.props.revealOrder[0]||!n.o.size))for(e=n.u;e;){for(;e.length>3;)e.pop()();if(e[1]>>1,1),t.i.removeChild(n)}}),d(s(T,{context:t.context},n.__v),t.l)):t.l&&t.componentWillUnmount()}function I(n,t){return s(j,{__v:n,i:t})}(F.prototype=new a).__e=function(n){var t=this,e=U(t.__v),r=t.o.get(n);return r[0]++,function(u){var o=function(){t.props.revealOrder?(r.push(u),M(t,n,r)):u()};e?e(o):o()}},F.prototype.render=function(n){this.u=null,this.o=new Map;var t=p(n.children);n.revealOrder&&"b"===n.revealOrder[0]&&t.reverse();for(var e=t.length;e--;)this.o.set(t[e],this.u=[1,0,this.u]);return n.children},F.prototype.componentDidUpdate=F.prototype.componentDidMount=function(){var n=this;this.o.forEach(function(t,e){M(n,e,t)})};var W="undefined"!=typeof Symbol&&Symbol.for&&Symbol.for("react.element")||60103,P=/^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|fill|flood|font|glyph(?!R)|horiz|marker(?!H|W|U)|overline|paint|stop|strikethrough|stroke|text(?!L)|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/,V=function(n){return("undefined"!=typeof Symbol&&"symbol"==typeof Symbol()?/fil|che|rad/i:/fil|che|ra/i).test(n)};function z(n,t,e){return null==t.__k&&(t.textContent=""),d(n,t),"function"==typeof e&&e(),n?n.__c:null}function B(n,t,e){return m(n,t),"function"==typeof e&&e(),n?n.__c:null}a.prototype.isReactComponent={},["componentWillMount","componentWillReceiveProps","componentWillUpdate"].forEach(function(n){Object.defineProperty(a.prototype,n,{configurable:!0,get:function(){return this["UNSAFE_"+n]},set:function(t){Object.defineProperty(this,n,{configurable:!0,writable:!0,value:t})}})});var H=h.event;function Z(){}function Y(){return this.cancelBubble}function $(){return this.defaultPrevented}h.event=function(n){return H&&(n=H(n)),n.persist=Z,n.isPropagationStopped=Y,n.isDefaultPrevented=$,n.nativeEvent=n};var q,G={configurable:!0,get:function(){return this.class}},J=h.vnode;h.vnode=function(n){var t=n.type,e=n.props,r=e;if("string"==typeof t){for(var u in r={},e){var o=e[u];"value"===u&&"defaultValue"in e&&null==o||("defaultValue"===u&&"value"in e&&null==e.value?u="value":"download"===u&&!0===o?o="":/ondoubleclick/i.test(u)?u="ondblclick":/^onchange(textarea|input)/i.test(u+t)&&!V(e.type)?u="oninput":/^on(Ani|Tra|Tou|BeforeInp)/.test(u)?u=u.toLowerCase():P.test(u)?u=u.replace(/[A-Z0-9]/,"-$&").toLowerCase():null===o&&(o=void 0),r[u]=o)}"select"==t&&r.multiple&&Array.isArray(r.value)&&(r.value=p(e.children).forEach(function(n){n.props.selected=-1!=r.value.indexOf(n.props.value)})),"select"==t&&null!=r.defaultValue&&(r.value=p(e.children).forEach(function(n){n.props.selected=r.multiple?-1!=r.defaultValue.indexOf(n.props.value):r.defaultValue==n.props.value})),n.props=r}t&&e.class!=e.className&&(G.enumerable="className"in e,null!=e.className&&(r.class=e.className),Object.defineProperty(r,"className",G)),n.$$typeof=W,J&&J(n)};var K=h.__r;h.__r=function(n){K&&K(n),q=n.__c};var Q={ReactCurrentDispatcher:{current:{readContext:function(n){return q.__n[n.__c].props.value}}}},X=1,nn=2,tn=3,en=4,rn=5;function un(n,t){return t()}var on="object"==typeof performance&&"function"==typeof performance.now?performance.now.bind(performance):function(){return Date.now()},ln="16.8.0";function fn(n){return s.bind(null,n)}function cn(n){return!!n&&n.$$typeof===W}function an(n){return cn(n)?y.apply(null,arguments):n}function sn(n){return!!n.__k&&(d(null,n),!0)}function hn(n){return n&&(n.base||1===n.nodeType&&n)||null}var pn=function(n,t){return n(t)},vn=v;export default{useState:n,useReducer:t,useEffect:e,useLayoutEffect:r,useRef:u,useImperativeHandle:o,useMemo:i,useCallback:l,useContext:f,useDebugValue:c,version:"16.8.0",Children:k,render:z,hydrate:B,unmountComponentAtNode:sn,createPortal:I,createElement:s,createContext:_,createFactory:fn,cloneElement:an,createRef:b,Fragment:v,isValidElement:cn,findDOMNode:hn,Component:a,PureComponent:E,memo:g,forwardRef:x,unstable_batchedUpdates:pn,StrictMode:v,Suspense:L,SuspenseList:F,lazy:D,__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:Q};export{ln as version,k as Children,z as render,B as hydrate,sn as unmountComponentAtNode,I as createPortal,fn as createFactory,an as cloneElement,cn as isValidElement,hn as findDOMNode,E as PureComponent,g as memo,x as forwardRef,pn as unstable_batchedUpdates,vn as StrictMode,L as Suspense,F as SuspenseList,D as lazy,Q as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,X as unstable_ImmediatePriority,nn as unstable_UserBlockingPriority,tn as unstable_NormalPriority,en as unstable_LowPriority,rn as unstable_IdlePriority,un as unstable_runWithPriority,on as unstable_now}; +//# sourceMappingURL=preact.compat.module.js.map diff --git a/src/Public/js/vendor/preact.compat.module.js.map b/src/Public/js/vendor/preact.compat.module.js.map new file mode 100644 index 000000000..d06fbba43 --- /dev/null +++ b/src/Public/js/vendor/preact.compat.module.js.map @@ -0,0 +1 @@ +{"version":3,"file":"preact.compat.module.js","sources":["../src/util.js","../src/PureComponent.js","../src/memo.js","../src/forwardRef.js","../src/Children.js","../src/suspense.js","../src/suspense-list.js","../src/portals.js","../src/render.js","../src/scheduler.js","../src/index.js"],"sourcesContent":["/**\n * Assign properties from `props` to `obj`\n * @template O, P The obj and props types\n * @param {O} obj The object to copy properties to\n * @param {P} props The object to copy properties from\n * @returns {O & P}\n */\nexport function assign(obj, props) {\n\tfor (let i in props) obj[i] = props[i];\n\treturn /** @type {O & P} */ (obj);\n}\n\n/**\n * Check if two objects have a different shape\n * @param {object} a\n * @param {object} b\n * @returns {boolean}\n */\nexport function shallowDiffers(a, b) {\n\tfor (let i in a) if (i !== '__source' && !(i in b)) return true;\n\tfor (let i in b) if (i !== '__source' && a[i] !== b[i]) return true;\n\treturn false;\n}\n\nexport function removeNode(node) {\n\tlet parentNode = node.parentNode;\n\tif (parentNode) parentNode.removeChild(node);\n}\n","import { Component } from 'preact';\nimport { shallowDiffers } from './util';\n\n/**\n * Component class with a predefined `shouldComponentUpdate` implementation\n */\nexport function PureComponent(p) {\n\tthis.props = p;\n}\nPureComponent.prototype = new Component();\n// Some third-party libraries check if this property is present\nPureComponent.prototype.isPureReactComponent = true;\nPureComponent.prototype.shouldComponentUpdate = function(props, state) {\n\treturn shallowDiffers(this.props, props) || shallowDiffers(this.state, state);\n};\n","import { createElement } from 'preact';\nimport { shallowDiffers } from './util';\n\n/**\n * Memoize a component, so that it only updates when the props actually have\n * changed. This was previously known as `React.pure`.\n * @param {import('./internal').FunctionComponent} c functional component\n * @param {(prev: object, next: object) => boolean} [comparer] Custom equality function\n * @returns {import('./internal').FunctionComponent}\n */\nexport function memo(c, comparer) {\n\tfunction shouldUpdate(nextProps) {\n\t\tlet ref = this.props.ref;\n\t\tlet updateRef = ref == nextProps.ref;\n\t\tif (!updateRef && ref) {\n\t\t\tref.call ? ref(null) : (ref.current = null);\n\t\t}\n\n\t\tif (!comparer) {\n\t\t\treturn shallowDiffers(this.props, nextProps);\n\t\t}\n\n\t\treturn !comparer(this.props, nextProps) || !updateRef;\n\t}\n\n\tfunction Memoed(props) {\n\t\tthis.shouldComponentUpdate = shouldUpdate;\n\t\treturn createElement(c, props);\n\t}\n\tMemoed.displayName = 'Memo(' + (c.displayName || c.name) + ')';\n\tMemoed.prototype.isReactComponent = true;\n\tMemoed._forwarded = true;\n\treturn Memoed;\n}\n","import { options } from 'preact';\nimport { assign } from './util';\n\nlet oldDiffHook = options._diff;\noptions._diff = vnode => {\n\tif (vnode.type && vnode.type._forwarded && vnode.ref) {\n\t\tvnode.props.ref = vnode.ref;\n\t\tvnode.ref = null;\n\t}\n\tif (oldDiffHook) oldDiffHook(vnode);\n};\n\nexport const REACT_FORWARD_SYMBOL =\n\t(typeof Symbol != 'undefined' &&\n\t\tSymbol.for &&\n\t\tSymbol.for('react.forward_ref')) ||\n\t0xf47;\n\n/**\n * Pass ref down to a child. This is mainly used in libraries with HOCs that\n * wrap components. Using `forwardRef` there is an easy way to get a reference\n * of the wrapped component instead of one of the wrapper itself.\n * @param {import('./index').ForwardFn} fn\n * @returns {import('./internal').FunctionComponent}\n */\nexport function forwardRef(fn) {\n\t// We always have ref in props.ref, except for\n\t// mobx-react. It will call this function directly\n\t// and always pass ref as the second argument.\n\tfunction Forwarded(props, ref) {\n\t\tlet clone = assign({}, props);\n\t\tdelete clone.ref;\n\t\tref = props.ref || ref;\n\t\treturn fn(\n\t\t\tclone,\n\t\t\t!ref || (typeof ref === 'object' && !('current' in ref)) ? null : ref\n\t\t);\n\t}\n\n\t// mobx-react checks for this being present\n\tForwarded.$$typeof = REACT_FORWARD_SYMBOL;\n\t// mobx-react heavily relies on implementation details.\n\t// It expects an object here with a `render` property,\n\t// and prototype.render will fail. Without this\n\t// mobx-react throws.\n\tForwarded.render = Forwarded;\n\n\tForwarded.prototype.isReactComponent = Forwarded._forwarded = true;\n\tForwarded.displayName = 'ForwardRef(' + (fn.displayName || fn.name) + ')';\n\treturn Forwarded;\n}\n","import { toChildArray } from 'preact';\n\nconst mapFn = (children, fn) => {\n\tif (children == null) return null;\n\treturn toChildArray(toChildArray(children).map(fn));\n};\n\n// This API is completely unnecessary for Preact, so it's basically passthrough.\nexport const Children = {\n\tmap: mapFn,\n\tforEach: mapFn,\n\tcount(children) {\n\t\treturn children ? toChildArray(children).length : 0;\n\t},\n\tonly(children) {\n\t\tconst normalized = toChildArray(children);\n\t\tif (normalized.length !== 1) throw 'Children.only';\n\t\treturn normalized[0];\n\t},\n\ttoArray: toChildArray\n};\n","import { Component, createElement, options, Fragment } from 'preact';\nimport { assign } from './util';\n\nconst oldCatchError = options._catchError;\noptions._catchError = function(error, newVNode, oldVNode) {\n\tif (error.then) {\n\t\t/** @type {import('./internal').Component} */\n\t\tlet component;\n\t\tlet vnode = newVNode;\n\n\t\tfor (; (vnode = vnode._parent); ) {\n\t\t\tif ((component = vnode._component) && component._childDidSuspend) {\n\t\t\t\tif (newVNode._dom == null) {\n\t\t\t\t\tnewVNode._dom = oldVNode._dom;\n\t\t\t\t\tnewVNode._children = oldVNode._children;\n\t\t\t\t}\n\t\t\t\t// Don't call oldCatchError if we found a Suspense\n\t\t\t\treturn component._childDidSuspend(error, newVNode);\n\t\t\t}\n\t\t}\n\t}\n\toldCatchError(error, newVNode, oldVNode);\n};\n\nconst oldUnmount = options.unmount;\noptions.unmount = function(vnode) {\n\t/** @type {import('./internal').Component} */\n\tconst component = vnode._component;\n\tif (component && component._onResolve) {\n\t\tcomponent._onResolve();\n\t}\n\n\t// if the component is still hydrating\n\t// most likely it is because the component is suspended\n\t// we set the vnode.type as `null` so that it is not a typeof function\n\t// so the unmount will remove the vnode._dom\n\tif (component && vnode._hydrating === true) {\n\t\tvnode.type = null;\n\t}\n\n\tif (oldUnmount) oldUnmount(vnode);\n};\n\nfunction detachedClone(vnode, detachedParent, parentDom) {\n\tif (vnode) {\n\t\tif (vnode._component && vnode._component.__hooks) {\n\t\t\tvnode._component.__hooks._list.forEach(effect => {\n\t\t\t\tif (typeof effect._cleanup == 'function') effect._cleanup();\n\t\t\t});\n\n\t\t\tvnode._component.__hooks = null;\n\t\t}\n\n\t\tvnode = assign({}, vnode);\n\t\tif (vnode._component != null) {\n\t\t\tif (vnode._component._parentDom === parentDom) {\n\t\t\t\tvnode._component._parentDom = detachedParent;\n\t\t\t}\n\t\t\tvnode._component = null;\n\t\t}\n\n\t\tvnode._children =\n\t\t\tvnode._children &&\n\t\t\tvnode._children.map(child =>\n\t\t\t\tdetachedClone(child, detachedParent, parentDom)\n\t\t\t);\n\t}\n\n\treturn vnode;\n}\n\nfunction removeOriginal(vnode, detachedParent, originalParent) {\n\tif (vnode) {\n\t\tvnode._original = null;\n\t\tvnode._children =\n\t\t\tvnode._children &&\n\t\t\tvnode._children.map(child =>\n\t\t\t\tremoveOriginal(child, detachedParent, originalParent)\n\t\t\t);\n\n\t\tif (vnode._component) {\n\t\t\tif (vnode._component._parentDom === detachedParent) {\n\t\t\t\tif (vnode._dom) {\n\t\t\t\t\toriginalParent.insertBefore(vnode._dom, vnode._nextDom);\n\t\t\t\t}\n\t\t\t\tvnode._component._force = true;\n\t\t\t\tvnode._component._parentDom = originalParent;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn vnode;\n}\n\n// having custom inheritance instead of a class here saves a lot of bytes\nexport function Suspense() {\n\t// we do not call super here to golf some bytes...\n\tthis._pendingSuspensionCount = 0;\n\tthis._suspenders = null;\n\tthis._detachOnNextRender = null;\n}\n\n// Things we do here to save some bytes but are not proper JS inheritance:\n// - call `new Component()` as the prototype\n// - do not set `Suspense.prototype.constructor` to `Suspense`\nSuspense.prototype = new Component();\n\n/**\n * @this {import('./internal').SuspenseComponent}\n * @param {Promise} promise The thrown promise\n * @param {import('./internal').VNode} suspendingVNode The suspending component\n */\nSuspense.prototype._childDidSuspend = function(promise, suspendingVNode) {\n\tconst suspendingComponent = suspendingVNode._component;\n\n\t/** @type {import('./internal').SuspenseComponent} */\n\tconst c = this;\n\n\tif (c._suspenders == null) {\n\t\tc._suspenders = [];\n\t}\n\tc._suspenders.push(suspendingComponent);\n\n\tconst resolve = suspended(c._vnode);\n\n\tlet resolved = false;\n\tconst onResolved = () => {\n\t\tif (resolved) return;\n\n\t\tresolved = true;\n\t\tsuspendingComponent._onResolve = null;\n\n\t\tif (resolve) {\n\t\t\tresolve(onSuspensionComplete);\n\t\t} else {\n\t\t\tonSuspensionComplete();\n\t\t}\n\t};\n\n\tsuspendingComponent._onResolve = onResolved;\n\n\tconst onSuspensionComplete = () => {\n\t\tif (!--c._pendingSuspensionCount) {\n\t\t\t// If the suspension was during hydration we don't need to restore the\n\t\t\t// suspended children into the _children array\n\t\t\tif (c.state._suspended) {\n\t\t\t\tconst suspendedVNode = c.state._suspended;\n\t\t\t\tc._vnode._children[0] = removeOriginal(\n\t\t\t\t\tsuspendedVNode,\n\t\t\t\t\tsuspendedVNode._component._parentDom,\n\t\t\t\t\tsuspendedVNode._component._originalParentDom\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tc.setState({ _suspended: (c._detachOnNextRender = null) });\n\n\t\t\tlet suspended;\n\t\t\twhile ((suspended = c._suspenders.pop())) {\n\t\t\t\tsuspended.forceUpdate();\n\t\t\t}\n\t\t}\n\t};\n\n\t/**\n\t * We do not set `suspended: true` during hydration because we want the actual markup\n\t * to remain on screen and hydrate it when the suspense actually gets resolved.\n\t * While in non-hydration cases the usual fallback -> component flow would occour.\n\t */\n\tconst wasHydrating = suspendingVNode._hydrating === true;\n\tif (!c._pendingSuspensionCount++ && !wasHydrating) {\n\t\tc.setState({ _suspended: (c._detachOnNextRender = c._vnode._children[0]) });\n\t}\n\tpromise.then(onResolved, onResolved);\n};\n\nSuspense.prototype.componentWillUnmount = function() {\n\tthis._suspenders = [];\n};\n\n/**\n * @this {import('./internal').SuspenseComponent}\n * @param {import('./internal').SuspenseComponent[\"props\"]} props\n * @param {import('./internal').SuspenseState} state\n */\nSuspense.prototype.render = function(props, state) {\n\tif (this._detachOnNextRender) {\n\t\t// When the Suspense's _vnode was created by a call to createVNode\n\t\t// (i.e. due to a setState further up in the tree)\n\t\t// it's _children prop is null, in this case we \"forget\" about the parked vnodes to detach\n\t\tif (this._vnode._children) {\n\t\t\tconst detachedParent = document.createElement('div');\n\t\t\tconst detachedComponent = this._vnode._children[0]._component;\n\t\t\tthis._vnode._children[0] = detachedClone(\n\t\t\t\tthis._detachOnNextRender,\n\t\t\t\tdetachedParent,\n\t\t\t\t(detachedComponent._originalParentDom = detachedComponent._parentDom)\n\t\t\t);\n\t\t}\n\n\t\tthis._detachOnNextRender = null;\n\t}\n\n\t// Wrap fallback tree in a VNode that prevents itself from being marked as aborting mid-hydration:\n\t/** @type {import('./internal').VNode} */\n\tconst fallback =\n\t\tstate._suspended && createElement(Fragment, null, props.fallback);\n\tif (fallback) fallback._hydrating = null;\n\n\treturn [\n\t\tcreateElement(Fragment, null, state._suspended ? null : props.children),\n\t\tfallback\n\t];\n};\n\n/**\n * Checks and calls the parent component's _suspended method, passing in the\n * suspended vnode. This is a way for a parent (e.g. SuspenseList) to get notified\n * that one of its children/descendants suspended.\n *\n * The parent MAY return a callback. The callback will get called when the\n * suspension resolves, notifying the parent of the fact.\n * Moreover, the callback gets function `unsuspend` as a parameter. The resolved\n * child descendant will not actually get unsuspended until `unsuspend` gets called.\n * This is a way for the parent to delay unsuspending.\n *\n * If the parent does not return a callback then the resolved vnode\n * gets unsuspended immediately when it resolves.\n *\n * @param {import('./internal').VNode} vnode\n * @returns {((unsuspend: () => void) => void)?}\n */\nexport function suspended(vnode) {\n\t/** @type {import('./internal').Component} */\n\tlet component = vnode._parent._component;\n\treturn component && component._suspended && component._suspended(vnode);\n}\n\nexport function lazy(loader) {\n\tlet prom;\n\tlet component;\n\tlet error;\n\n\tfunction Lazy(props) {\n\t\tif (!prom) {\n\t\t\tprom = loader();\n\t\t\tprom.then(\n\t\t\t\texports => {\n\t\t\t\t\tcomponent = exports.default || exports;\n\t\t\t\t},\n\t\t\t\te => {\n\t\t\t\t\terror = e;\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\n\t\tif (error) {\n\t\t\tthrow error;\n\t\t}\n\n\t\tif (!component) {\n\t\t\tthrow prom;\n\t\t}\n\n\t\treturn createElement(component, props);\n\t}\n\n\tLazy.displayName = 'Lazy';\n\tLazy._forwarded = true;\n\treturn Lazy;\n}\n","import { Component, toChildArray } from 'preact';\nimport { suspended } from './suspense.js';\n\n// Indexes to linked list nodes (nodes are stored as arrays to save bytes).\nconst SUSPENDED_COUNT = 0;\nconst RESOLVED_COUNT = 1;\nconst NEXT_NODE = 2;\n\n// Having custom inheritance instead of a class here saves a lot of bytes.\nexport function SuspenseList() {\n\tthis._next = null;\n\tthis._map = null;\n}\n\n// Mark one of child's earlier suspensions as resolved.\n// Some pending callbacks may become callable due to this\n// (e.g. the last suspended descendant gets resolved when\n// revealOrder === 'together'). Process those callbacks as well.\nconst resolve = (list, child, node) => {\n\tif (++node[RESOLVED_COUNT] === node[SUSPENDED_COUNT]) {\n\t\t// The number a child (or any of its descendants) has been suspended\n\t\t// matches the number of times it's been resolved. Therefore we\n\t\t// mark the child as completely resolved by deleting it from ._map.\n\t\t// This is used to figure out when *all* children have been completely\n\t\t// resolved when revealOrder is 'together'.\n\t\tlist._map.delete(child);\n\t}\n\n\t// If revealOrder is falsy then we can do an early exit, as the\n\t// callbacks won't get queued in the node anyway.\n\t// If revealOrder is 'together' then also do an early exit\n\t// if all suspended descendants have not yet been resolved.\n\tif (\n\t\t!list.props.revealOrder ||\n\t\t(list.props.revealOrder[0] === 't' && list._map.size)\n\t) {\n\t\treturn;\n\t}\n\n\t// Walk the currently suspended children in order, calling their\n\t// stored callbacks on the way. Stop if we encounter a child that\n\t// has not been completely resolved yet.\n\tnode = list._next;\n\twhile (node) {\n\t\twhile (node.length > 3) {\n\t\t\tnode.pop()();\n\t\t}\n\t\tif (node[RESOLVED_COUNT] < node[SUSPENDED_COUNT]) {\n\t\t\tbreak;\n\t\t}\n\t\tlist._next = node = node[NEXT_NODE];\n\t}\n};\n\n// Things we do here to save some bytes but are not proper JS inheritance:\n// - call `new Component()` as the prototype\n// - do not set `Suspense.prototype.constructor` to `Suspense`\nSuspenseList.prototype = new Component();\n\nSuspenseList.prototype._suspended = function(child) {\n\tconst list = this;\n\tconst delegated = suspended(list._vnode);\n\n\tlet node = list._map.get(child);\n\tnode[SUSPENDED_COUNT]++;\n\n\treturn unsuspend => {\n\t\tconst wrappedUnsuspend = () => {\n\t\t\tif (!list.props.revealOrder) {\n\t\t\t\t// Special case the undefined (falsy) revealOrder, as there\n\t\t\t\t// is no need to coordinate a specific order or unsuspends.\n\t\t\t\tunsuspend();\n\t\t\t} else {\n\t\t\t\tnode.push(unsuspend);\n\t\t\t\tresolve(list, child, node);\n\t\t\t}\n\t\t};\n\t\tif (delegated) {\n\t\t\tdelegated(wrappedUnsuspend);\n\t\t} else {\n\t\t\twrappedUnsuspend();\n\t\t}\n\t};\n};\n\nSuspenseList.prototype.render = function(props) {\n\tthis._next = null;\n\tthis._map = new Map();\n\n\tconst children = toChildArray(props.children);\n\tif (props.revealOrder && props.revealOrder[0] === 'b') {\n\t\t// If order === 'backwards' (or, well, anything starting with a 'b')\n\t\t// then flip the child list around so that the last child will be\n\t\t// the first in the linked list.\n\t\tchildren.reverse();\n\t}\n\t// Build the linked list. Iterate through the children in reverse order\n\t// so that `_next` points to the first linked list node to be resolved.\n\tfor (let i = children.length; i--; ) {\n\t\t// Create a new linked list node as an array of form:\n\t\t// \t[suspended_count, resolved_count, next_node]\n\t\t// where suspended_count and resolved_count are numeric counters for\n\t\t// keeping track how many times a node has been suspended and resolved.\n\t\t//\n\t\t// Note that suspended_count starts from 1 instead of 0, so we can block\n\t\t// processing callbacks until componentDidMount has been called. In a sense\n\t\t// node is suspended at least until componentDidMount gets called!\n\t\t//\n\t\t// Pending callbacks are added to the end of the node:\n\t\t// \t[suspended_count, resolved_count, next_node, callback_0, callback_1, ...]\n\t\tthis._map.set(children[i], (this._next = [1, 0, this._next]));\n\t}\n\treturn props.children;\n};\n\nSuspenseList.prototype.componentDidUpdate = SuspenseList.prototype.componentDidMount = function() {\n\t// Iterate through all children after mounting for two reasons:\n\t// 1. As each node[SUSPENDED_COUNT] starts from 1, this iteration increases\n\t// each node[RELEASED_COUNT] by 1, therefore balancing the counters.\n\t// The nodes can now be completely consumed from the linked list.\n\t// 2. Handle nodes that might have gotten resolved between render and\n\t// componentDidMount.\n\tthis._map.forEach((node, child) => {\n\t\tresolve(this, child, node);\n\t});\n};\n","import { createElement, render } from 'preact';\n\n/**\n * @param {import('../../src/index').RenderableProps<{ context: any }>} props\n */\nfunction ContextProvider(props) {\n\tthis.getChildContext = () => props.context;\n\treturn props.children;\n}\n\n/**\n * Portal component\n * @this {import('./internal').Component}\n * @param {object | null | undefined} props\n *\n * TODO: use createRoot() instead of fake root\n */\nfunction Portal(props) {\n\tconst _this = this;\n\tlet container = props._container;\n\n\t_this.componentWillUnmount = function() {\n\t\trender(null, _this._temp);\n\t\t_this._temp = null;\n\t\t_this._container = null;\n\t};\n\n\t// When we change container we should clear our old container and\n\t// indicate a new mount.\n\tif (_this._container && _this._container !== container) {\n\t\t_this.componentWillUnmount();\n\t}\n\n\t// When props.vnode is undefined/false/null we are dealing with some kind of\n\t// conditional vnode. This should not trigger a render.\n\tif (props._vnode) {\n\t\tif (!_this._temp) {\n\t\t\t_this._container = container;\n\n\t\t\t// Create a fake DOM parent node that manages a subset of `container`'s children:\n\t\t\t_this._temp = {\n\t\t\t\tnodeType: 1,\n\t\t\t\tparentNode: container,\n\t\t\t\tchildNodes: [],\n\t\t\t\tappendChild(child) {\n\t\t\t\t\tthis.childNodes.push(child);\n\t\t\t\t\t_this._container.appendChild(child);\n\t\t\t\t},\n\t\t\t\tinsertBefore(child, before) {\n\t\t\t\t\tthis.childNodes.push(child);\n\t\t\t\t\t_this._container.appendChild(child);\n\t\t\t\t},\n\t\t\t\tremoveChild(child) {\n\t\t\t\t\tthis.childNodes.splice(this.childNodes.indexOf(child) >>> 1, 1);\n\t\t\t\t\t_this._container.removeChild(child);\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\t// Render our wrapping element into temp.\n\t\trender(\n\t\t\tcreateElement(ContextProvider, { context: _this.context }, props._vnode),\n\t\t\t_this._temp\n\t\t);\n\t}\n\t// When we come from a conditional render, on a mounted\n\t// portal we should clear the DOM.\n\telse if (_this._temp) {\n\t\t_this.componentWillUnmount();\n\t}\n}\n\n/**\n * Create a `Portal` to continue rendering the vnode tree at a different DOM node\n * @param {import('./internal').VNode} vnode The vnode to render\n * @param {import('./internal').PreactElement} container The DOM node to continue rendering in to.\n */\nexport function createPortal(vnode, container) {\n\treturn createElement(Portal, { _vnode: vnode, _container: container });\n}\n","import {\n\trender as preactRender,\n\thydrate as preactHydrate,\n\toptions,\n\ttoChildArray,\n\tComponent\n} from 'preact';\n\nexport const REACT_ELEMENT_TYPE =\n\t(typeof Symbol != 'undefined' && Symbol.for && Symbol.for('react.element')) ||\n\t0xeac7;\n\nconst CAMEL_PROPS = /^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|fill|flood|font|glyph(?!R)|horiz|marker(?!H|W|U)|overline|paint|stop|strikethrough|stroke|text(?!L)|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/;\n\n// Input types for which onchange should not be converted to oninput.\n// type=\"file|checkbox|radio\", plus \"range\" in IE11.\n// (IE11 doesn't support Symbol, which we use here to turn `rad` into `ra` which matches \"range\")\nconst onChangeInputType = type =>\n\t(typeof Symbol != 'undefined' && typeof Symbol() == 'symbol'\n\t\t? /fil|che|rad/i\n\t\t: /fil|che|ra/i\n\t).test(type);\n\n// Some libraries like `react-virtualized` explicitly check for this.\nComponent.prototype.isReactComponent = {};\n\n// `UNSAFE_*` lifecycle hooks\n// Preact only ever invokes the unprefixed methods.\n// Here we provide a base \"fallback\" implementation that calls any defined UNSAFE_ prefixed method.\n// - If a component defines its own `componentDidMount()` (including via defineProperty), use that.\n// - If a component defines `UNSAFE_componentDidMount()`, `componentDidMount` is the alias getter/setter.\n// - If anything assigns to an `UNSAFE_*` property, the assignment is forwarded to the unprefixed property.\n// See https://github.com/preactjs/preact/issues/1941\n[\n\t'componentWillMount',\n\t'componentWillReceiveProps',\n\t'componentWillUpdate'\n].forEach(key => {\n\tObject.defineProperty(Component.prototype, key, {\n\t\tconfigurable: true,\n\t\tget() {\n\t\t\treturn this['UNSAFE_' + key];\n\t\t},\n\t\tset(v) {\n\t\t\tObject.defineProperty(this, key, {\n\t\t\t\tconfigurable: true,\n\t\t\t\twritable: true,\n\t\t\t\tvalue: v\n\t\t\t});\n\t\t}\n\t});\n});\n\n/**\n * Proxy render() since React returns a Component reference.\n * @param {import('./internal').VNode} vnode VNode tree to render\n * @param {import('./internal').PreactElement} parent DOM node to render vnode tree into\n * @param {() => void} [callback] Optional callback that will be called after rendering\n * @returns {import('./internal').Component | null} The root component reference or null\n */\nexport function render(vnode, parent, callback) {\n\t// React destroys any existing DOM nodes, see #1727\n\t// ...but only on the first render, see #1828\n\tif (parent._children == null) {\n\t\tparent.textContent = '';\n\t}\n\n\tpreactRender(vnode, parent);\n\tif (typeof callback == 'function') callback();\n\n\treturn vnode ? vnode._component : null;\n}\n\nexport function hydrate(vnode, parent, callback) {\n\tpreactHydrate(vnode, parent);\n\tif (typeof callback == 'function') callback();\n\n\treturn vnode ? vnode._component : null;\n}\n\nlet oldEventHook = options.event;\noptions.event = e => {\n\tif (oldEventHook) e = oldEventHook(e);\n\te.persist = empty;\n\te.isPropagationStopped = isPropagationStopped;\n\te.isDefaultPrevented = isDefaultPrevented;\n\treturn (e.nativeEvent = e);\n};\n\nfunction empty() {}\n\nfunction isPropagationStopped() {\n\treturn this.cancelBubble;\n}\n\nfunction isDefaultPrevented() {\n\treturn this.defaultPrevented;\n}\n\nlet classNameDescriptor = {\n\tconfigurable: true,\n\tget() {\n\t\treturn this.class;\n\t}\n};\n\nlet oldVNodeHook = options.vnode;\noptions.vnode = vnode => {\n\tlet type = vnode.type;\n\tlet props = vnode.props;\n\tlet normalizedProps = props;\n\n\t// only normalize props on Element nodes\n\tif (typeof type === 'string') {\n\t\tnormalizedProps = {};\n\n\t\tfor (let i in props) {\n\t\t\tlet value = props[i];\n\n\t\t\tif (i === 'value' && 'defaultValue' in props && value == null) {\n\t\t\t\t// Skip applying value if it is null/undefined and we already set\n\t\t\t\t// a default value\n\t\t\t\tcontinue;\n\t\t\t} else if (\n\t\t\t\ti === 'defaultValue' &&\n\t\t\t\t'value' in props &&\n\t\t\t\tprops.value == null\n\t\t\t) {\n\t\t\t\t// `defaultValue` is treated as a fallback `value` when a value prop is present but null/undefined.\n\t\t\t\t// `defaultValue` for Elements with no value prop is the same as the DOM defaultValue property.\n\t\t\t\ti = 'value';\n\t\t\t} else if (i === 'download' && value === true) {\n\t\t\t\t// Calling `setAttribute` with a truthy value will lead to it being\n\t\t\t\t// passed as a stringified value, e.g. `download=\"true\"`. React\n\t\t\t\t// converts it to an empty string instead, otherwise the attribute\n\t\t\t\t// value will be used as the file name and the file will be called\n\t\t\t\t// \"true\" upon downloading it.\n\t\t\t\tvalue = '';\n\t\t\t} else if (/ondoubleclick/i.test(i)) {\n\t\t\t\ti = 'ondblclick';\n\t\t\t} else if (\n\t\t\t\t/^onchange(textarea|input)/i.test(i + type) &&\n\t\t\t\t!onChangeInputType(props.type)\n\t\t\t) {\n\t\t\t\ti = 'oninput';\n\t\t\t} else if (/^on(Ani|Tra|Tou|BeforeInp)/.test(i)) {\n\t\t\t\ti = i.toLowerCase();\n\t\t\t} else if (CAMEL_PROPS.test(i)) {\n\t\t\t\ti = i.replace(/[A-Z0-9]/, '-$&').toLowerCase();\n\t\t\t} else if (value === null) {\n\t\t\t\tvalue = undefined;\n\t\t\t}\n\n\t\t\tnormalizedProps[i] = value;\n\t\t}\n\n\t\t// Add support for array select values: