From 0e9e64c550eb867d720c8a8ec05c5cecea913f93 Mon Sep 17 00:00:00 2001 From: CommitSyncScript Date: Fri, 7 Jun 2013 22:04:14 -0700 Subject: [PATCH] Replace `persistentCloneOf` with `persist` There are to reasons to prefer a `persist` method on the event rather than a static method: - In open source, people do not have access to `AbstractEvent`. - This will allow people to persist events without requiring another module. - This will make refactors easier and more flexible. --- src/event/AbstractEvent.js | 47 +++++++++++-------------------------- src/event/EventPluginHub.js | 4 +++- 2 files changed, 17 insertions(+), 34 deletions(-) diff --git a/src/event/AbstractEvent.js b/src/event/AbstractEvent.js index 6930fdd8bf..ad14378a69 100644 --- a/src/event/AbstractEvent.js +++ b/src/event/AbstractEvent.js @@ -22,16 +22,8 @@ var BrowserEnv = require('BrowserEnv'); var PooledClass = require('PooledClass'); var TouchEventUtils = require('TouchEventUtils'); -var throwIf = require('throwIf'); +var emptyFunction = require('emptyFunction'); - -// Only accessed in __DEV__ -var CLONE_TYPE_ERR; -if (__DEV__) { - CLONE_TYPE_ERR = - 'You may only clone instances of AbstractEvent for ' + - 'persistent references. Check yourself.'; -} var MAX_POOL_SIZE = 20; /** @@ -68,6 +60,7 @@ function AbstractEvent( this._dispatchIDs = null; this.isPropagationStopped = false; + this.isPersistent = emptyFunction.thatReturnsFalse; } /** `PooledClass` looks for this. */ @@ -104,6 +97,15 @@ AbstractEvent.prototype.preventDefault = function() { AbstractEvent.preventDefaultOnNativeEvent(this.nativeEvent); }; +/** + * We clear out all dispatched `AbstractEvent`s after each event loop, adding + * them back into the pool. This allows a way to hold onto a reference that + * won't be added back into the pool. + */ +AbstractEvent.prototype.persist = function() { + this.isPersistent = emptyFunction.thatReturnsTrue; +}; + /** * Utility function for preventing default in cross browser manner. */ @@ -240,32 +242,11 @@ AbstractEvent.eventPageX = function(nativeEvent) { }; /** - * A semantic API around cloning an event for use in another event loop. We - * clear out all dispatched `AbstractEvent`s after each event loop, adding them - * back into the pool. This allows a way to hold onto a reference that won't be - * added back into the pool. Please note that `AbstractEvent.nativeEvent` is - * *not* cloned and you will run into problems in IE if you assume that it will - * be! The moral of that story is to always normalize any data you need into the - * `.data` field. The data field is not cloned either, but there won't be any - * issues related to use of `.data` in a future event cycle so long as no part - * of your application mutates it. We don't clone the private fields because - * your application should never be accessing them. - * - * - TODO: In __DEV__ when "releasing" events, don't put them back into the - * pool. Instead add ES5 getters on all their fields that throw errors so you - * can detect any application that's hanging onto events and reusing them. - * In prod - we can put them back into the pool for reuse. + * @deprecated */ AbstractEvent.persistentCloneOf = function(abstractEvent) { - if (__DEV__) { - throwIf(!(abstractEvent instanceof AbstractEvent), CLONE_TYPE_ERR); - } - return new AbstractEvent( - abstractEvent.reactEventType, - abstractEvent.reactTargetID, - abstractEvent.nativeEvent, - abstractEvent.data - ); + abstractEvent.persist(); + return abstractEvent; }; module.exports = AbstractEvent; diff --git a/src/event/EventPluginHub.js b/src/event/EventPluginHub.js index 52c3db0b61..99ce2b008b 100644 --- a/src/event/EventPluginHub.js +++ b/src/event/EventPluginHub.js @@ -277,7 +277,9 @@ var executeDispatchesAndRelease = function(abstractEvent) { abstractEvent, pluginExecuteDispatch || EventPluginUtils.executeDispatch ); - AbstractEvent.release(abstractEvent); + if (!abstractEvent.isPersistent()) { + AbstractEvent.release(abstractEvent); + } } };