├── .gitignore ├── README.md ├── src ├── index.html ├── index.mjs └── preact.mjs └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This just contains enough package.json and .babelrc to be able to convert JSX into calls to Preact's `h()` function. It shouldn't change much else, and relies on modern browsers supporting JavaScript Modules to handle module loading, using something like 2 | 3 | ```html 4 | 5 | ``` 6 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Page Title 7 | 8 | 9 | 10 | 11 | 12 |

Hello

13 | 14 | 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "p", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "keywords": [], 7 | "author": "", 8 | "license": "ISC", 9 | "devDependencies": { 10 | "@babel/cli": "^7.2.3", 11 | "@babel/core": "^7.3.4", 12 | "@babel/plugin-proposal-class-properties": "^7.3.4", 13 | "@babel/plugin-transform-react-jsx": "^7.3.0", 14 | "http-server": "^0.11.1" 15 | }, 16 | "scripts": { 17 | "build": "babel src -D --out-dir dist --extensions .mjs --keep-file-extension", 18 | "watch": "babel src -D --watch --out-dir dist --extensions .mjs --keep-file-extension", 19 | "start": "http-server dist" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/index.mjs: -------------------------------------------------------------------------------- 1 | import { Component, render, h } from './preact.mjs'; 2 | 3 | class TodoList extends Component { 4 | state = { todos: [], text: '' }; 5 | setText = e => { 6 | this.setState({ text: e.target.value }); 7 | }; 8 | addTodo = () => { 9 | let { todos, text } = this.state; 10 | todos = todos.concat({ text }); 11 | this.setState({ todos, text: '' }); 12 | }; 13 | render({ }, { todos, text }) { 14 | return ( 15 |
16 | 17 | 18 | 23 |
24 | ); 25 | } 26 | } 27 | 28 | render(, document.body); 29 | -------------------------------------------------------------------------------- /src/preact.mjs: -------------------------------------------------------------------------------- 1 | var VNode = function VNode() {}; 2 | 3 | var options = {}; 4 | 5 | var stack = []; 6 | 7 | var EMPTY_CHILDREN = []; 8 | 9 | function h(nodeName, attributes) { 10 | var children = EMPTY_CHILDREN, 11 | lastSimple, 12 | child, 13 | simple, 14 | i; 15 | for (i = arguments.length; i-- > 2;) { 16 | stack.push(arguments[i]); 17 | } 18 | if (attributes && attributes.children != null) { 19 | if (!stack.length) stack.push(attributes.children); 20 | delete attributes.children; 21 | } 22 | while (stack.length) { 23 | if ((child = stack.pop()) && child.pop !== undefined) { 24 | for (i = child.length; i--;) { 25 | stack.push(child[i]); 26 | } 27 | } else { 28 | if (typeof child === 'boolean') child = null; 29 | 30 | if (simple = typeof nodeName !== 'function') { 31 | if (child == null) child = '';else if (typeof child === 'number') child = String(child);else if (typeof child !== 'string') simple = false; 32 | } 33 | 34 | if (simple && lastSimple) { 35 | children[children.length - 1] += child; 36 | } else if (children === EMPTY_CHILDREN) { 37 | children = [child]; 38 | } else { 39 | children.push(child); 40 | } 41 | 42 | lastSimple = simple; 43 | } 44 | } 45 | 46 | var p = new VNode(); 47 | p.nodeName = nodeName; 48 | p.children = children; 49 | p.attributes = attributes == null ? undefined : attributes; 50 | p.key = attributes == null ? undefined : attributes.key; 51 | 52 | if (options.vnode !== undefined) options.vnode(p); 53 | 54 | return p; 55 | } 56 | 57 | function extend(obj, props) { 58 | for (var i in props) { 59 | obj[i] = props[i]; 60 | }return obj; 61 | } 62 | 63 | function applyRef(ref, value) { 64 | if (ref != null) { 65 | if (typeof ref == 'function') ref(value);else ref.current = value; 66 | } 67 | } 68 | 69 | var defer = typeof Promise == 'function' ? Promise.resolve().then.bind(Promise.resolve()) : setTimeout; 70 | 71 | function cloneElement(vnode, props) { 72 | return h(vnode.nodeName, extend(extend({}, vnode.attributes), props), arguments.length > 2 ? [].slice.call(arguments, 2) : vnode.children); 73 | } 74 | 75 | var IS_NON_DIMENSIONAL = /acit|ex(?:s|g|n|p|$)|rph|ows|mnc|ntw|ine[ch]|zoo|^ord/i; 76 | 77 | var items = []; 78 | 79 | function enqueueRender(component) { 80 | if (!component._dirty && (component._dirty = true) && items.push(component) == 1) { 81 | (options.debounceRendering || defer)(rerender); 82 | } 83 | } 84 | 85 | function rerender() { 86 | var p; 87 | while (p = items.pop()) { 88 | if (p._dirty) renderComponent(p); 89 | } 90 | } 91 | 92 | function isSameNodeType(node, vnode, hydrating) { 93 | if (typeof vnode === 'string' || typeof vnode === 'number') { 94 | return node.splitText !== undefined; 95 | } 96 | if (typeof vnode.nodeName === 'string') { 97 | return !node._componentConstructor && isNamedNode(node, vnode.nodeName); 98 | } 99 | return hydrating || node._componentConstructor === vnode.nodeName; 100 | } 101 | 102 | function isNamedNode(node, nodeName) { 103 | return node.normalizedNodeName === nodeName || node.nodeName.toLowerCase() === nodeName.toLowerCase(); 104 | } 105 | 106 | function getNodeProps(vnode) { 107 | var props = extend({}, vnode.attributes); 108 | props.children = vnode.children; 109 | 110 | var defaultProps = vnode.nodeName.defaultProps; 111 | if (defaultProps !== undefined) { 112 | for (var i in defaultProps) { 113 | if (props[i] === undefined) { 114 | props[i] = defaultProps[i]; 115 | } 116 | } 117 | } 118 | 119 | return props; 120 | } 121 | 122 | function createNode(nodeName, isSvg) { 123 | var node = isSvg ? document.createElementNS('http://www.w3.org/2000/svg', nodeName) : document.createElement(nodeName); 124 | node.normalizedNodeName = nodeName; 125 | return node; 126 | } 127 | 128 | function removeNode(node) { 129 | var parentNode = node.parentNode; 130 | if (parentNode) parentNode.removeChild(node); 131 | } 132 | 133 | function setAccessor(node, name, old, value, isSvg) { 134 | if (name === 'className') name = 'class'; 135 | 136 | if (name === 'key') {} else if (name === 'ref') { 137 | applyRef(old, null); 138 | applyRef(value, node); 139 | } else if (name === 'class' && !isSvg) { 140 | node.className = value || ''; 141 | } else if (name === 'style') { 142 | if (!value || typeof value === 'string' || typeof old === 'string') { 143 | node.style.cssText = value || ''; 144 | } 145 | if (value && typeof value === 'object') { 146 | if (typeof old !== 'string') { 147 | for (var i in old) { 148 | if (!(i in value)) node.style[i] = ''; 149 | } 150 | } 151 | for (var i in value) { 152 | node.style[i] = typeof value[i] === 'number' && IS_NON_DIMENSIONAL.test(i) === false ? value[i] + 'px' : value[i]; 153 | } 154 | } 155 | } else if (name === 'dangerouslySetInnerHTML') { 156 | if (value) node.innerHTML = value.__html || ''; 157 | } else if (name[0] == 'o' && name[1] == 'n') { 158 | var useCapture = name !== (name = name.replace(/Capture$/, '')); 159 | name = name.toLowerCase().substring(2); 160 | if (value) { 161 | if (!old) node.addEventListener(name, eventProxy, useCapture); 162 | } else { 163 | node.removeEventListener(name, eventProxy, useCapture); 164 | } 165 | (node._listeners || (node._listeners = {}))[name] = value; 166 | } else if (name !== 'list' && name !== 'type' && !isSvg && name in node) { 167 | try { 168 | node[name] = value == null ? '' : value; 169 | } catch (e) {} 170 | if ((value == null || value === false) && name != 'spellcheck') node.removeAttribute(name); 171 | } else { 172 | var ns = isSvg && name !== (name = name.replace(/^xlink:?/, '')); 173 | 174 | if (value == null || value === false) { 175 | if (ns) node.removeAttributeNS('http://www.w3.org/1999/xlink', name.toLowerCase());else node.removeAttribute(name); 176 | } else if (typeof value !== 'function') { 177 | if (ns) node.setAttributeNS('http://www.w3.org/1999/xlink', name.toLowerCase(), value);else node.setAttribute(name, value); 178 | } 179 | } 180 | } 181 | 182 | function eventProxy(e) { 183 | return this._listeners[e.type](options.event && options.event(e) || e); 184 | } 185 | 186 | var mounts = []; 187 | 188 | var diffLevel = 0; 189 | 190 | var isSvgMode = false; 191 | 192 | var hydrating = false; 193 | 194 | function flushMounts() { 195 | var c; 196 | while (c = mounts.shift()) { 197 | if (options.afterMount) options.afterMount(c); 198 | if (c.componentDidMount) c.componentDidMount(); 199 | } 200 | } 201 | 202 | function diff(dom, vnode, context, mountAll, parent, componentRoot) { 203 | if (!diffLevel++) { 204 | isSvgMode = parent != null && parent.ownerSVGElement !== undefined; 205 | 206 | hydrating = dom != null && !('__preactattr_' in dom); 207 | } 208 | 209 | var ret = idiff(dom, vnode, context, mountAll, componentRoot); 210 | 211 | if (parent && ret.parentNode !== parent) parent.appendChild(ret); 212 | 213 | if (! --diffLevel) { 214 | hydrating = false; 215 | 216 | if (!componentRoot) flushMounts(); 217 | } 218 | 219 | return ret; 220 | } 221 | 222 | function idiff(dom, vnode, context, mountAll, componentRoot) { 223 | var out = dom, 224 | prevSvgMode = isSvgMode; 225 | 226 | if (vnode == null || typeof vnode === 'boolean') vnode = ''; 227 | 228 | if (typeof vnode === 'string' || typeof vnode === 'number') { 229 | if (dom && dom.splitText !== undefined && dom.parentNode && (!dom._component || componentRoot)) { 230 | if (dom.nodeValue != vnode) { 231 | dom.nodeValue = vnode; 232 | } 233 | } else { 234 | out = document.createTextNode(vnode); 235 | if (dom) { 236 | if (dom.parentNode) dom.parentNode.replaceChild(out, dom); 237 | recollectNodeTree(dom, true); 238 | } 239 | } 240 | 241 | out['__preactattr_'] = true; 242 | 243 | return out; 244 | } 245 | 246 | var vnodeName = vnode.nodeName; 247 | if (typeof vnodeName === 'function') { 248 | return buildComponentFromVNode(dom, vnode, context, mountAll); 249 | } 250 | 251 | isSvgMode = vnodeName === 'svg' ? true : vnodeName === 'foreignObject' ? false : isSvgMode; 252 | 253 | vnodeName = String(vnodeName); 254 | if (!dom || !isNamedNode(dom, vnodeName)) { 255 | out = createNode(vnodeName, isSvgMode); 256 | 257 | if (dom) { 258 | while (dom.firstChild) { 259 | out.appendChild(dom.firstChild); 260 | } 261 | if (dom.parentNode) dom.parentNode.replaceChild(out, dom); 262 | 263 | recollectNodeTree(dom, true); 264 | } 265 | } 266 | 267 | var fc = out.firstChild, 268 | props = out['__preactattr_'], 269 | vchildren = vnode.children; 270 | 271 | if (props == null) { 272 | props = out['__preactattr_'] = {}; 273 | for (var a = out.attributes, i = a.length; i--;) { 274 | props[a[i].name] = a[i].value; 275 | } 276 | } 277 | 278 | if (!hydrating && vchildren && vchildren.length === 1 && typeof vchildren[0] === 'string' && fc != null && fc.splitText !== undefined && fc.nextSibling == null) { 279 | if (fc.nodeValue != vchildren[0]) { 280 | fc.nodeValue = vchildren[0]; 281 | } 282 | } else if (vchildren && vchildren.length || fc != null) { 283 | innerDiffNode(out, vchildren, context, mountAll, hydrating || props.dangerouslySetInnerHTML != null); 284 | } 285 | 286 | diffAttributes(out, vnode.attributes, props); 287 | 288 | isSvgMode = prevSvgMode; 289 | 290 | return out; 291 | } 292 | 293 | function innerDiffNode(dom, vchildren, context, mountAll, isHydrating) { 294 | var originalChildren = dom.childNodes, 295 | children = [], 296 | keyed = {}, 297 | keyedLen = 0, 298 | min = 0, 299 | len = originalChildren.length, 300 | childrenLen = 0, 301 | vlen = vchildren ? vchildren.length : 0, 302 | j, 303 | c, 304 | f, 305 | vchild, 306 | child; 307 | 308 | if (len !== 0) { 309 | for (var i = 0; i < len; i++) { 310 | var _child = originalChildren[i], 311 | props = _child['__preactattr_'], 312 | key = vlen && props ? _child._component ? _child._component.__key : props.key : null; 313 | if (key != null) { 314 | keyedLen++; 315 | keyed[key] = _child; 316 | } else if (props || (_child.splitText !== undefined ? isHydrating ? _child.nodeValue.trim() : true : isHydrating)) { 317 | children[childrenLen++] = _child; 318 | } 319 | } 320 | } 321 | 322 | if (vlen !== 0) { 323 | for (var i = 0; i < vlen; i++) { 324 | vchild = vchildren[i]; 325 | child = null; 326 | 327 | var key = vchild.key; 328 | if (key != null) { 329 | if (keyedLen && keyed[key] !== undefined) { 330 | child = keyed[key]; 331 | keyed[key] = undefined; 332 | keyedLen--; 333 | } 334 | } else if (min < childrenLen) { 335 | for (j = min; j < childrenLen; j++) { 336 | if (children[j] !== undefined && isSameNodeType(c = children[j], vchild, isHydrating)) { 337 | child = c; 338 | children[j] = undefined; 339 | if (j === childrenLen - 1) childrenLen--; 340 | if (j === min) min++; 341 | break; 342 | } 343 | } 344 | } 345 | 346 | child = idiff(child, vchild, context, mountAll); 347 | 348 | f = originalChildren[i]; 349 | if (child && child !== dom && child !== f) { 350 | if (f == null) { 351 | dom.appendChild(child); 352 | } else if (child === f.nextSibling) { 353 | removeNode(f); 354 | } else { 355 | dom.insertBefore(child, f); 356 | } 357 | } 358 | } 359 | } 360 | 361 | if (keyedLen) { 362 | for (var i in keyed) { 363 | if (keyed[i] !== undefined) recollectNodeTree(keyed[i], false); 364 | } 365 | } 366 | 367 | while (min <= childrenLen) { 368 | if ((child = children[childrenLen--]) !== undefined) recollectNodeTree(child, false); 369 | } 370 | } 371 | 372 | function recollectNodeTree(node, unmountOnly) { 373 | var component = node._component; 374 | if (component) { 375 | unmountComponent(component); 376 | } else { 377 | if (node['__preactattr_'] != null) applyRef(node['__preactattr_'].ref, null); 378 | 379 | if (unmountOnly === false || node['__preactattr_'] == null) { 380 | removeNode(node); 381 | } 382 | 383 | removeChildren(node); 384 | } 385 | } 386 | 387 | function removeChildren(node) { 388 | node = node.lastChild; 389 | while (node) { 390 | var next = node.previousSibling; 391 | recollectNodeTree(node, true); 392 | node = next; 393 | } 394 | } 395 | 396 | function diffAttributes(dom, attrs, old) { 397 | var name; 398 | 399 | for (name in old) { 400 | if (!(attrs && attrs[name] != null) && old[name] != null) { 401 | setAccessor(dom, name, old[name], old[name] = undefined, isSvgMode); 402 | } 403 | } 404 | 405 | for (name in attrs) { 406 | if (name !== 'children' && name !== 'innerHTML' && (!(name in old) || attrs[name] !== (name === 'value' || name === 'checked' ? dom[name] : old[name]))) { 407 | setAccessor(dom, name, old[name], old[name] = attrs[name], isSvgMode); 408 | } 409 | } 410 | } 411 | 412 | var recyclerComponents = []; 413 | 414 | function createComponent(Ctor, props, context) { 415 | var inst, 416 | i = recyclerComponents.length; 417 | 418 | if (Ctor.prototype && Ctor.prototype.render) { 419 | inst = new Ctor(props, context); 420 | Component.call(inst, props, context); 421 | } else { 422 | inst = new Component(props, context); 423 | inst.constructor = Ctor; 424 | inst.render = doRender; 425 | } 426 | 427 | while (i--) { 428 | if (recyclerComponents[i].constructor === Ctor) { 429 | inst.nextBase = recyclerComponents[i].nextBase; 430 | recyclerComponents.splice(i, 1); 431 | return inst; 432 | } 433 | } 434 | 435 | return inst; 436 | } 437 | 438 | function doRender(props, state, context) { 439 | return this.constructor(props, context); 440 | } 441 | 442 | function setComponentProps(component, props, renderMode, context, mountAll) { 443 | if (component._disable) return; 444 | component._disable = true; 445 | 446 | component.__ref = props.ref; 447 | component.__key = props.key; 448 | delete props.ref; 449 | delete props.key; 450 | 451 | if (typeof component.constructor.getDerivedStateFromProps === 'undefined') { 452 | if (!component.base || mountAll) { 453 | if (component.componentWillMount) component.componentWillMount(); 454 | } else if (component.componentWillReceiveProps) { 455 | component.componentWillReceiveProps(props, context); 456 | } 457 | } 458 | 459 | if (context && context !== component.context) { 460 | if (!component.prevContext) component.prevContext = component.context; 461 | component.context = context; 462 | } 463 | 464 | if (!component.prevProps) component.prevProps = component.props; 465 | component.props = props; 466 | 467 | component._disable = false; 468 | 469 | if (renderMode !== 0) { 470 | if (renderMode === 1 || options.syncComponentUpdates !== false || !component.base) { 471 | renderComponent(component, 1, mountAll); 472 | } else { 473 | enqueueRender(component); 474 | } 475 | } 476 | 477 | applyRef(component.__ref, component); 478 | } 479 | 480 | function renderComponent(component, renderMode, mountAll, isChild) { 481 | if (component._disable) return; 482 | 483 | var props = component.props, 484 | state = component.state, 485 | context = component.context, 486 | previousProps = component.prevProps || props, 487 | previousState = component.prevState || state, 488 | previousContext = component.prevContext || context, 489 | isUpdate = component.base, 490 | nextBase = component.nextBase, 491 | initialBase = isUpdate || nextBase, 492 | initialChildComponent = component._component, 493 | skip = false, 494 | snapshot = previousContext, 495 | rendered, 496 | inst, 497 | cbase; 498 | 499 | if (component.constructor.getDerivedStateFromProps) { 500 | state = extend(extend({}, state), component.constructor.getDerivedStateFromProps(props, state)); 501 | component.state = state; 502 | } 503 | 504 | if (isUpdate) { 505 | component.props = previousProps; 506 | component.state = previousState; 507 | component.context = previousContext; 508 | if (renderMode !== 2 && component.shouldComponentUpdate && component.shouldComponentUpdate(props, state, context) === false) { 509 | skip = true; 510 | } else if (component.componentWillUpdate) { 511 | component.componentWillUpdate(props, state, context); 512 | } 513 | component.props = props; 514 | component.state = state; 515 | component.context = context; 516 | } 517 | 518 | component.prevProps = component.prevState = component.prevContext = component.nextBase = null; 519 | component._dirty = false; 520 | 521 | if (!skip) { 522 | rendered = component.render(props, state, context); 523 | 524 | if (component.getChildContext) { 525 | context = extend(extend({}, context), component.getChildContext()); 526 | } 527 | 528 | if (isUpdate && component.getSnapshotBeforeUpdate) { 529 | snapshot = component.getSnapshotBeforeUpdate(previousProps, previousState); 530 | } 531 | 532 | var childComponent = rendered && rendered.nodeName, 533 | toUnmount, 534 | base; 535 | 536 | if (typeof childComponent === 'function') { 537 | 538 | var childProps = getNodeProps(rendered); 539 | inst = initialChildComponent; 540 | 541 | if (inst && inst.constructor === childComponent && childProps.key == inst.__key) { 542 | setComponentProps(inst, childProps, 1, context, false); 543 | } else { 544 | toUnmount = inst; 545 | 546 | component._component = inst = createComponent(childComponent, childProps, context); 547 | inst.nextBase = inst.nextBase || nextBase; 548 | inst._parentComponent = component; 549 | setComponentProps(inst, childProps, 0, context, false); 550 | renderComponent(inst, 1, mountAll, true); 551 | } 552 | 553 | base = inst.base; 554 | } else { 555 | cbase = initialBase; 556 | 557 | toUnmount = initialChildComponent; 558 | if (toUnmount) { 559 | cbase = component._component = null; 560 | } 561 | 562 | if (initialBase || renderMode === 1) { 563 | if (cbase) cbase._component = null; 564 | base = diff(cbase, rendered, context, mountAll || !isUpdate, initialBase && initialBase.parentNode, true); 565 | } 566 | } 567 | 568 | if (initialBase && base !== initialBase && inst !== initialChildComponent) { 569 | var baseParent = initialBase.parentNode; 570 | if (baseParent && base !== baseParent) { 571 | baseParent.replaceChild(base, initialBase); 572 | 573 | if (!toUnmount) { 574 | initialBase._component = null; 575 | recollectNodeTree(initialBase, false); 576 | } 577 | } 578 | } 579 | 580 | if (toUnmount) { 581 | unmountComponent(toUnmount); 582 | } 583 | 584 | component.base = base; 585 | if (base && !isChild) { 586 | var componentRef = component, 587 | t = component; 588 | while (t = t._parentComponent) { 589 | (componentRef = t).base = base; 590 | } 591 | base._component = componentRef; 592 | base._componentConstructor = componentRef.constructor; 593 | } 594 | } 595 | 596 | if (!isUpdate || mountAll) { 597 | mounts.push(component); 598 | } else if (!skip) { 599 | 600 | if (component.componentDidUpdate) { 601 | component.componentDidUpdate(previousProps, previousState, snapshot); 602 | } 603 | if (options.afterUpdate) options.afterUpdate(component); 604 | } 605 | 606 | while (component._renderCallbacks.length) { 607 | component._renderCallbacks.pop().call(component); 608 | }if (!diffLevel && !isChild) flushMounts(); 609 | } 610 | 611 | function buildComponentFromVNode(dom, vnode, context, mountAll) { 612 | var c = dom && dom._component, 613 | originalComponent = c, 614 | oldDom = dom, 615 | isDirectOwner = c && dom._componentConstructor === vnode.nodeName, 616 | isOwner = isDirectOwner, 617 | props = getNodeProps(vnode); 618 | while (c && !isOwner && (c = c._parentComponent)) { 619 | isOwner = c.constructor === vnode.nodeName; 620 | } 621 | 622 | if (c && isOwner && (!mountAll || c._component)) { 623 | setComponentProps(c, props, 3, context, mountAll); 624 | dom = c.base; 625 | } else { 626 | if (originalComponent && !isDirectOwner) { 627 | unmountComponent(originalComponent); 628 | dom = oldDom = null; 629 | } 630 | 631 | c = createComponent(vnode.nodeName, props, context); 632 | if (dom && !c.nextBase) { 633 | c.nextBase = dom; 634 | 635 | oldDom = null; 636 | } 637 | setComponentProps(c, props, 1, context, mountAll); 638 | dom = c.base; 639 | 640 | if (oldDom && dom !== oldDom) { 641 | oldDom._component = null; 642 | recollectNodeTree(oldDom, false); 643 | } 644 | } 645 | 646 | return dom; 647 | } 648 | 649 | function unmountComponent(component) { 650 | if (options.beforeUnmount) options.beforeUnmount(component); 651 | 652 | var base = component.base; 653 | 654 | component._disable = true; 655 | 656 | if (component.componentWillUnmount) component.componentWillUnmount(); 657 | 658 | component.base = null; 659 | 660 | var inner = component._component; 661 | if (inner) { 662 | unmountComponent(inner); 663 | } else if (base) { 664 | if (base['__preactattr_'] != null) applyRef(base['__preactattr_'].ref, null); 665 | 666 | component.nextBase = base; 667 | 668 | removeNode(base); 669 | recyclerComponents.push(component); 670 | 671 | removeChildren(base); 672 | } 673 | 674 | applyRef(component.__ref, null); 675 | } 676 | 677 | function Component(props, context) { 678 | this._dirty = true; 679 | 680 | this.context = context; 681 | 682 | this.props = props; 683 | 684 | this.state = this.state || {}; 685 | 686 | this._renderCallbacks = []; 687 | } 688 | 689 | extend(Component.prototype, { 690 | setState: function setState(state, callback) { 691 | if (!this.prevState) this.prevState = this.state; 692 | this.state = extend(extend({}, this.state), typeof state === 'function' ? state(this.state, this.props) : state); 693 | if (callback) this._renderCallbacks.push(callback); 694 | enqueueRender(this); 695 | }, 696 | forceUpdate: function forceUpdate(callback) { 697 | if (callback) this._renderCallbacks.push(callback); 698 | renderComponent(this, 2); 699 | }, 700 | render: function render() {} 701 | }); 702 | 703 | function render(vnode, parent, merge) { 704 | return diff(merge, vnode, {}, false, parent, false); 705 | } 706 | 707 | function createRef() { 708 | return {}; 709 | } 710 | 711 | var preact = { 712 | h: h, 713 | createElement: h, 714 | cloneElement: cloneElement, 715 | createRef: createRef, 716 | Component: Component, 717 | render: render, 718 | rerender: rerender, 719 | options: options 720 | }; 721 | 722 | export default preact; 723 | export { h, h as createElement, cloneElement, createRef, Component, render, rerender, options }; 724 | //# sourceMappingURL=preact.mjs.map 725 | --------------------------------------------------------------------------------