diff --git a/src/environment/ReactServerRendering.js b/src/environment/ReactServerRendering.js index e5046edbeb7..db2a33e045a 100644 --- a/src/environment/ReactServerRendering.js +++ b/src/environment/ReactServerRendering.js @@ -22,6 +22,7 @@ var ReactComponent = require('ReactComponent'); var ReactInstanceHandles = require('ReactInstanceHandles'); var ReactMarkupChecksum = require('ReactMarkupChecksum'); var ReactReconcileTransaction = require('ReactReconcileTransaction'); +var EventPluginHub = require('EventPluginHub'); var invariant = require('invariant'); @@ -48,7 +49,10 @@ function renderComponentToString(component, callback) { transaction.reinitializeTransaction(); try { transaction.perform(function() { + var registrationEnabled = EventPluginHub.isRegistrationEnabled(); + EventPluginHub.setRegistrationEnabled(false); var markup = component.mountComponent(id, transaction, 0); + EventPluginHub.setRegistrationEnabled(registrationEnabled); markup = ReactMarkupChecksum.addChecksumToMarkup(markup); callback(markup); }, null); diff --git a/src/environment/__tests__/ReactServerRendering-test.js b/src/environment/__tests__/ReactServerRendering-test.js index 85c62811a3b..babc0ecd375 100644 --- a/src/environment/__tests__/ReactServerRendering-test.js +++ b/src/environment/__tests__/ReactServerRendering-test.js @@ -27,7 +27,8 @@ require('mock-modules') .dontMock('ReactMount') .dontMock('ReactServerRendering') .dontMock('ReactTestUtils') - .dontMock('ReactMarkupChecksum'); + .dontMock('ReactMarkupChecksum') + .dontMock('EventPluginHub'); var mocks = require('mocks'); @@ -37,6 +38,7 @@ var ReactTestUtils; var ReactServerRendering; var ReactMarkupChecksum; var ExecutionEnvironment; +var EventPluginHub; var ID_ATTRIBUTE_NAME; @@ -50,6 +52,7 @@ describe('ReactServerRendering', function() { ExecutionEnvironment.canUseDOM = false; ReactServerRendering = require('ReactServerRendering'); ReactMarkupChecksum = require('ReactMarkupChecksum'); + EventPluginHub = require('EventPluginHub'); var DOMProperty = require('DOMProperty'); ID_ATTRIBUTE_NAME = DOMProperty.ID_ATTRIBUTE_NAME; @@ -234,6 +237,43 @@ describe('ReactServerRendering', function() { expect(numClicks).toEqual(1); }); + it('should not register listeners', function() { + var Link = React.createClass({ + handleClick: function() {}, + render: function() { + return link; + } + }); + var link = ; + ReactServerRendering.renderComponentToString(link, function(str) { + var listener = EventPluginHub.getListener(link._rootNodeID, 'onClick'); + expect(listener).not.toEqual(link.handleClick); + }); + }); + + // White box ReactServerRendering, black box EventPluginHub + describe('event listener registration', function() { + var cb; + beforeEach(function() { + cb = mocks.getMockFunction(); + }); + it('should preserve default', function() { + var def = EventPluginHub.isRegistrationEnabled(); + ReactServerRendering.renderComponentToString(, cb); + expect(EventPluginHub.isRegistrationEnabled()).toEqual(def); + }); + it('should preserve true', function() { + EventPluginHub.setRegistrationEnabled(false); + ReactServerRendering.renderComponentToString(, cb); + expect(EventPluginHub.isRegistrationEnabled()).toEqual(false); + }); + it('should preserve false', function() { + EventPluginHub.setRegistrationEnabled(true); + ReactServerRendering.renderComponentToString(, cb); + expect(EventPluginHub.isRegistrationEnabled()).toEqual(true); + }); + }); + it('should throw with silly args', function() { expect( ReactServerRendering.renderComponentToString.bind( diff --git a/src/event/EventPluginHub.js b/src/event/EventPluginHub.js index d42f3050e6f..4bd0c354489 100644 --- a/src/event/EventPluginHub.js +++ b/src/event/EventPluginHub.js @@ -31,6 +31,11 @@ var isEventSupported = require('isEventSupported'); */ var listenerBank = {}; +/** + * Allow disabling listener registration + */ +var registrationEnabled = true; + /** * Internal queue of events that have accumulated their dispatches and are * waiting to have their dispatches executed. @@ -98,6 +103,24 @@ function validateInstanceHandle() { */ var EventPluginHub = { + /** + * `setRegistrationEnabled` allows temporary disabling of event registration + * + * @param {boolean} enabled Enable or disable the registration of listeners + * @public + */ + setRegistrationEnabled: function(enabled) { + registrationEnabled = enabled; + }, + + /** + * @return {boolean} Returns whether or not registering listeners is enabled + * @public + */ + isRegistrationEnabled: function() { + return registrationEnabled; + }, + /** * Methods for injecting dependencies. */ @@ -158,9 +181,11 @@ var EventPluginHub = { console.warn('This browser doesn\'t support the `onScroll` event'); } } - var bankForRegistrationName = - listenerBank[registrationName] || (listenerBank[registrationName] = {}); - bankForRegistrationName[id] = listener; + if(registrationEnabled) { + var bankForRegistrationName = + listenerBank[registrationName] || (listenerBank[registrationName] = {}); + bankForRegistrationName[id] = listener; + } }, /** diff --git a/src/event/__tests__/EventPluginHub-test.js b/src/event/__tests__/EventPluginHub-test.js index 280e79728e6..a88a1c1d695 100644 --- a/src/event/__tests__/EventPluginHub-test.js +++ b/src/event/__tests__/EventPluginHub-test.js @@ -22,6 +22,9 @@ require('mock-modules') .dontMock('EventPluginHub') .mock('isEventSupported'); +var keyOf = require('keyOf'); +var mocks = require('mocks'); + describe('EventPluginHub', function() { var EventPluginHub; var isEventSupported; @@ -33,6 +36,45 @@ describe('EventPluginHub', function() { isEventSupported.mockReturnValue(false); }); + describe('event registration', function() { + var id, key, listener; + beforeEach(function() { + id = '.reactRoot.[0].[0].[0]'; + key = keyOf({onClick: null}); + listener = mocks.getMockFunction(); + }); + it('should be enabled by default', function() { + expect(EventPluginHub.isRegistrationEnabled()).toEqual(true); + }); + describe('disabled', function() { + beforeEach(function() { + EventPluginHub.setRegistrationEnabled(false); + }); + it('should not register listeners', function() { + EventPluginHub.setRegistrationEnabled(false); + EventPluginHub.putListener(id, key, listener); + var registeredListener = EventPluginHub.getListener(id, key); + expect(registeredListener).not.toEqual(listener); + }); + it('should report', function() { + expect(EventPluginHub.isRegistrationEnabled()).toEqual(false); + }); + }); + describe('enabled', function() { + beforeEach(function() { + EventPluginHub.setRegistrationEnabled(true); + }); + it('should register listeners', function() { + EventPluginHub.putListener(id, key, listener); + var registeredListener = EventPluginHub.getListener(id, key); + expect(registeredListener).toEqual(listener); + }); + it('should report', function() { + expect(EventPluginHub.isRegistrationEnabled()).toEqual(true); + }); + }); + }); + it('should warn about the `onScroll` issue on IE8', function() { spyOn(console, 'warn'); EventPluginHub.putListener(1, 'onScroll', function(){});