From c303cb2221cd453afb23f0c96aec8587630cc0df Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Mon, 14 Jul 2014 06:16:06 +0400 Subject: [PATCH] Performance and bugfixes. 0.1.6 --- example/b.jsx | 2 +- hot.js | 90 +++++++++++++++++++++++++++------------------------ package.json | 2 +- 3 files changed, 50 insertions(+), 44 deletions(-) diff --git a/example/b.jsx b/example/b.jsx index ca9d2ce96..2fbdade5c 100644 --- a/example/b.jsx +++ b/example/b.jsx @@ -5,7 +5,7 @@ var React = require('react'); var B = React.createClass({ render: function() { return ( -
+

I am example/b.jsx, feel free to edit me.

diff --git a/hot.js b/hot.js index 4a8e0bbe5..0f76764a3 100644 --- a/hot.js +++ b/hot.js @@ -1,11 +1,5 @@ 'use strict'; -var setPrototypeOf = Object.setPrototypeOf || function (obj, proto) { - /* jshint proto:true */ - obj.__proto__ = proto; - return obj; -}; - module.exports = function (React) { var mounted = []; var Mixin = { @@ -19,63 +13,75 @@ module.exports = function (React) { }; var assimilatePrototype = (function () { - var storedPrototype; - - function assimilateProperty(freshPrototype, key) { - function get() { - if (typeof storedPrototype[key] !== 'function' || - key === 'type' || - key === 'constructor') { + var storedPrototype, + knownPrototypes = []; - return storedPrototype[key]; + function wrapFunction(key) { + return function () { + if (storedPrototype[key]) { + return storedPrototype[key].apply(this, arguments); } + }; + } - return function () { - var value = storedPrototype[key]; - if (typeof value === 'function') { - return value.apply(this, arguments); - } else { - console.warn('A call to ' + key + ' was made after it was deleted. Acting as no-op.'); - } - }; - } + function patchProperty(proto, key) { + proto[key] = storedPrototype[key]; - function set(value) { - storedPrototype[key] = value; + if (typeof proto[key] !== 'function' || + key === 'type' || + key === 'constructor') { + return; } - storedPrototype[key] = freshPrototype[key]; - Object.defineProperty(freshPrototype, key, { - configurable: false, - enumerable: true, - get: get, - set: set - }); + proto[key] = wrapFunction(key); + + if (proto.__reactAutoBindMap[key]) { + proto.__reactAutoBindMap[key] = proto[key]; + } } - return function assimilatePrototype(freshPrototype) { + function updateStoredPrototype(freshPrototype) { storedPrototype = {}; + for (var key in freshPrototype) { - assimilateProperty(freshPrototype, key); + if (freshPrototype.hasOwnProperty(key)) { + storedPrototype[key] = freshPrototype[key]; + } } + } + + function reconcileWithStoredPrototypes(freshPrototype) { + knownPrototypes.push(freshPrototype); + knownPrototypes.forEach(function (proto) { + for (var key in storedPrototype) { + patchProperty(proto, key); + } + }); + } + + return function (freshPrototype) { + updateStoredPrototype(freshPrototype); + reconcileWithStoredPrototypes(freshPrototype); }; })(); + function injectMixinAndAssimilatePrototype(spec) { + spec.mixins = spec.mixins || []; + spec.mixins.push(Mixin); + var Component = React.createClass(spec); + assimilatePrototype(Component.type.prototype); + return Component; + } + var Component; return { createClass: function (spec) { - spec.mixins = spec.mixins || []; - spec.mixins.push(Mixin); - - Component = React.createClass(spec); - assimilatePrototype(Component.componentConstructor.prototype); - + Component = injectMixinAndAssimilatePrototype(spec); return Component; }, updateClass: function (spec) { - var UpdatedComponent = React.createClass(spec); - assimilatePrototype(UpdatedComponent.componentConstructor.prototype); + injectMixinAndAssimilatePrototype(spec); mounted.forEach(function (instance) { instance._bindAutoBindMethods(); diff --git a/package.json b/package.json index db56f96b7..d5611ffd4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-hot-loader", - "version": "0.1.5", + "version": "0.1.6", "description": "Webpack loader that enables live-editing React components without unmounting or losing their state", "main": "index.js", "directories": {