@@ -117,14 +117,37 @@ var turbolinksClassicEvents = __webpack_require__(10)
117117// see what things are globally available
118118// and setup event handlers to those things
119119module . exports = function ( ujs ) {
120+
121+ if ( ujs . handleEvent ) {
122+ // We're calling this a second time -- remove previous handlers
123+ turbolinksClassicEvents . teardown ( ujs )
124+ turbolinksEvents . teardown ( ujs ) ;
125+ turbolinksClassicDeprecatedEvents . teardown ( ujs ) ;
126+ pjaxEvents . teardown ( ujs ) ;
127+ nativeEvents . teardown ( ujs ) ;
128+ }
129+
120130 if ( ujs . jQuery ) {
121131 ujs . handleEvent = function ( eventName , callback ) {
122132 ujs . jQuery ( document ) . on ( eventName , callback ) ;
123133 } ;
124- } else {
134+ ujs . removeEvent = function ( eventName , callback ) {
135+ ujs . jQuery ( document ) . off ( eventName , callback ) ;
136+ }
137+ } else if ( 'addEventListener' in window ) {
125138 ujs . handleEvent = function ( eventName , callback ) {
126139 document . addEventListener ( eventName , callback ) ;
127140 } ;
141+ ujs . removeEvent = function ( eventName , callback ) {
142+ document . removeEventListener ( eventName , callback ) ;
143+ } ;
144+ } else {
145+ ujs . handleEvent = function ( eventName , callback ) {
146+ window . attachEvent ( eventName , callback ) ;
147+ } ;
148+ ujs . removeEvent = function ( eventName , callback ) {
149+ window . detachEvent ( eventName , callback ) ;
150+ } ;
128151 }
129152
130153 // Detect which kind of events to set up:
@@ -251,8 +274,11 @@ var ReactRailsUJS = {
251274 // the default is ReactRailsUJS.ComponentGlobal
252275 getConstructor : constructorFromGlobal ,
253276
254- useContext : function ( req ) {
255- this . getConstructor = constructorFromRequireContextWithGlobalFallback ( req )
277+ // Given a Webpack `require.context`,
278+ // try finding components with `require`,
279+ // then falling back to global lookup.
280+ useContext : function ( requireContext ) {
281+ this . getConstructor = constructorFromRequireContextWithGlobalFallback ( requireContext )
256282 } ,
257283
258284 // Render `componentName` with `props` to a string,
@@ -298,11 +324,36 @@ var ReactRailsUJS = {
298324 ReactDOM . unmountComponentAtNode ( node ) ;
299325 }
300326 } ,
327+
328+ // Check the global context for installed libraries
329+ // and figure out which library to hook up to (pjax, Turbolinks, jQuery)
330+ // This is called on load, but you can call it again if needed
331+ // (It will unmount itself)
332+ detectEvents : function ( ) {
333+ detectEvents ( this )
334+ } ,
335+ }
336+
337+ // These stable references are so that handlers can be added and removed:
338+ ReactRailsUJS . handleMount = function ( e ) {
339+ var target = undefined ;
340+ if ( e && e . target ) {
341+ target = e . target ;
342+ }
343+ ReactRailsUJS . mountComponents ( target ) ;
344+ }
345+ ReactRailsUJS . handleUnmount = function ( e ) {
346+ var target = undefined ;
347+ if ( e && e . target ) {
348+ target = e . target ;
349+ }
350+ ReactRailsUJS . unmountComponents ( target ) ;
301351}
302352
353+
303354if ( typeof window !== "undefined" ) {
304355 // Only setup events for browser (not server-rendering)
305- detectEvents ( ReactRailsUJS )
356+ ReactRailsUJS . detectEvents ( )
306357}
307358
308359// It's a bit of a no-no to populate the global namespace,
@@ -324,12 +375,22 @@ module.exports = {
324375 setup : function ( ujs ) {
325376 if ( ujs . jQuery ) {
326377 // Use jQuery if it's present:
327- ujs . jQuery ( function ( ) { ujs . mountComponents ( ) } ) ;
378+ ujs . handleEvent ( "ready" , ujs . handleMount ) ;
328379 } else if ( 'addEventListener' in window ) {
329- document . addEventListener ( 'DOMContentLoaded' , function ( ) { ujs . mountComponents ( ) } ) ;
380+ ujs . handleEvent ( 'DOMContentLoaded' , ujs . handleMount ) ;
330381 } else {
331382 // add support to IE8 without jQuery
332- window . attachEvent ( 'onload' , function ( ) { ujs . mountComponents ( ) } ) ;
383+ ujs . handleEvent ( 'onload' , ujs . handleMount ) ;
384+ }
385+ } ,
386+
387+ teardown : function ( ujs ) {
388+ if ( ujs . jQuery ) {
389+ ujs . removeEvent ( "ready" , ujs . handleMount ) ;
390+ } else if ( 'addEventListener' in window ) {
391+ ujs . removeEvent ( 'DOMContentLoaded' , ujs . handleMount ) ;
392+ } else {
393+ ujs . removeEvent ( 'onload' , ujs . handleMount ) ;
333394 }
334395 }
335396}
@@ -342,10 +403,16 @@ module.exports = {
342403module . exports = {
343404 // pjax support
344405 setup : function ( ujs ) {
345- ujs . handleEvent ( 'ready' , function ( ) { ujs . mountComponents ( ) } ) ;
346- ujs . handleEvent ( 'pjax:end' , function ( e ) { ujs . mountComponents ( e . target ) } ) ;
347- ujs . handleEvent ( 'pjax:beforeReplace' , function ( e ) { ujs . unmountComponents ( e . target ) } ) ;
348- }
406+ ujs . handleEvent ( 'ready' , ujs . handleMount ) ;
407+ ujs . handleEvent ( 'pjax:end' , ujs . handleMount ) ;
408+ ujs . handleEvent ( 'pjax:beforeReplace' , ujs . handleUnmount ) ;
409+ } ,
410+
411+ teardown : function ( ) {
412+ ujs . removeEvent ( 'ready' , ujs . handleMount ) ;
413+ ujs . removeEvent ( 'pjax:end' , ujs . handleMount ) ;
414+ ujs . removeEvent ( 'pjax:beforeReplace' , ujs . handleUnmount ) ;
415+ } ,
349416}
350417
351418
@@ -356,9 +423,15 @@ module.exports = {
356423module . exports = {
357424 // Turbolinks 5+ got rid of named events (?!)
358425 setup : function ( ujs ) {
359- ujs . handleEvent ( 'DOMContentLoaded' , function ( ) { ujs . mountComponents ( ) } )
360- ujs . handleEvent ( 'turbolinks:render' , function ( ) { ujs . mountComponents ( ) } )
361- ujs . handleEvent ( 'turbolinks:before-render' , function ( ) { ujs . unmountComponents ( ) } )
426+ ujs . handleEvent ( 'DOMContentLoaded' , ujs . handleMount )
427+ ujs . handleEvent ( 'turbolinks:render' , ujs . handleMount )
428+ ujs . handleEvent ( 'turbolinks:before-render' , ujs . handleUnmount )
429+ } ,
430+
431+ teardown : function ( ujs ) {
432+ ujs . removeEvent ( 'DOMContentLoaded' , ujs . handleMount )
433+ ujs . removeEvent ( 'turbolinks:render' , ujs . handleMount )
434+ ujs . removeEvent ( 'turbolinks:before-render' , ujs . handleUnmount )
362435 } ,
363436}
364437
@@ -371,8 +444,12 @@ module.exports = {
371444 // Attach handlers to Turbolinks-Classic events
372445 // for mounting and unmounting components
373446 setup : function ( ujs ) {
374- ujs . handleEvent ( Turbolinks . EVENTS . CHANGE , function ( ) { ujs . mountComponents ( ) } ) ;
375- ujs . handleEvent ( Turbolinks . EVENTS . BEFORE_UNLOAD , function ( ) { ujs . unmountComponents ( ) } ) ;
447+ ujs . handleEvent ( Turbolinks . EVENTS . CHANGE , ujs . handleMount ) ;
448+ ujs . handleEvent ( Turbolinks . EVENTS . BEFORE_UNLOAD , ujs . handleUnmount ) ;
449+ } ,
450+ teardown : function ( ujs ) {
451+ ujs . removeEvent ( Turbolinks . EVENTS . CHANGE , ujs . handleMount ) ;
452+ ujs . removeEvent ( Turbolinks . EVENTS . BEFORE_UNLOAD , ujs . handleUnmount ) ;
376453 }
377454}
378455
@@ -388,8 +465,12 @@ module.exports = {
388465 // https://github.com/reactjs/react-rails/issues/87
389466 setup : function ( ujs ) {
390467 Turbolinks . pagesCached ( 0 )
391- ujs . handleEvent ( 'page:change' , function ( ) { ujs . mountComponents ( ) } ) ;
392- ujs . handleEvent ( 'page:receive' , function ( ) { ujs . unmountComponents ( ) } ) ;
468+ ujs . handleEvent ( 'page:change' , ujs . handleMount ) ;
469+ ujs . handleEvent ( 'page:receive' , ujs . handleUnmount ) ;
470+ } ,
471+ teardown : function ( ujs ) {
472+ ujs . removeEvent ( 'page:change' , ujs . handleMount ) ;
473+ ujs . removeEvent ( 'page:receive' , ujs . handleUnmount ) ;
393474 }
394475}
395476
0 commit comments