import * as React from "react"; import { decorator_compatibility } from './utils'; // const BoundRenders = new WeakMap(); const enable_hooks_dec = decorator_compatibility({ stage3(value, context) { if (context.kind == "class") { class Wrapped extends value { @enable_hooks render(...params) { return super.render(...params); } } return Wrapped; } else if (context.kind == "method" && context.name == "render" && typeof value == "function") { context.addInitializer(function () { const f = this[context.name]; const boundFn = f.bind(this); boundFn.displayName = `WithHooks(${this.constructor.displayName})` const wrappedFn = () => React.createElement(boundFn, this.props); this[context.name] = wrappedFn; }) // function wrapped_render(...params) { // let br = BoundRenders.get(this); // if (!br) { // br = value.bind(this); // BoundRenders.set(this, br); // } // return React.createElement(br, this.props) // } // return wrapped_render; } else { throw new TypeError(`@enable_hooks decorator must be applied to the Component class or the render method - not '${context.name}'`); } }, legacy(target, key, descriptor?) { let fn = descriptor.value; if (key != 'render' || typeof fn !== 'function') { throw new TypeError(`@enable_hooks decorator must be applied to the Component class or the render method - not '${String(key)}'`); } // In IE11 calling Object.defineProperty has a side-effect of evaluating the // getter for the property which is being replaced. This causes infinite // recursion and an "Out of stack space" error. let definingProperty = false; return { configurable: true, get() { // eslint-disable-next-line no-prototype-builtins if (definingProperty || this === target.prototype || this.hasOwnProperty(key) || typeof fn !== 'function') { return fn; } const boundFn = fn.bind(this); boundFn.displayName = `WithHooks(${this.constructor.displayName})` const wrappedFn = () => React.createElement(boundFn, this.props); definingProperty = true; Object.defineProperty(this, key, { configurable: true, get() { return wrappedFn; }, set(value) { fn = value; delete this[key]; } }); definingProperty = false; return wrappedFn; }, set(value) { fn = value; } }; }, }) /** * Method/Class decorator to enable hooks for class-based Components */ export function enable_hooks(a, b?, c?) { if (!b) { return enable_hooks_dec(a, { kind: "class" }); } else { return enable_hooks_dec(a, b, c); } }