-
-
Save dmshvetsov/b74e16b9cf2dac1f38b3 to your computer and use it in GitHub Desktop.
Non-global react_ujs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*globals React, Turbolinks*/ | |
/* Modified react_ujs to prevent the components polluting global scope whenever possible. | |
* Since I use subdirs for my components, it also flattens the structure making | |
* _componentStore[className] possible. | |
* Creds for the react_ujs.js file to the people from react-rails (https://github.com/reactjs/react-rails) | |
*/ | |
var path = require('path'); | |
if (typeof require !== "undefined") { | |
var React = require('react'); | |
// Patches Object to have `.assign` since most browsers don't support this yet. | |
require('./lib/Assign'); | |
var _componentStore = {}; | |
Object.assign(_componentStore, require('./components/**/*.js', { | |
mode: 'hash', | |
resolve: function flatReduce (base, files, config) { | |
var filenames = Object.keys(files); | |
// contains map of stripped filenames | |
var conflicts = {}; | |
for (var i=0, l=filenames.length; i<l; i++) { | |
(function(file, key) { | |
var newKey = key.slice(key.lastIndexOf('/')+1, -path.extname(key).length); | |
// if already file with same stripping | |
if (conflicts.hasOwnProperty(newKey)) { | |
// check if first conflict | |
if (conflicts[newKey] !== false) { | |
// revert previous file stripping | |
files[conflicts[newKey][0]] = conflicts[newKey][1]; | |
conflicts[newKey] = false; | |
} | |
} else { | |
// strip key | |
files[file] = newKey; | |
// remember for possible later conflicts | |
conflicts[newKey] = [file, key]; | |
} | |
})(filenames[i], files[filenames[i]]); | |
} | |
return files; | |
} | |
})); | |
Object.assign(_componentStore, require('./containers/*.js', {mode: 'hash'})); | |
} | |
// Unobtrusive scripting adapter for React | |
;(function(document, window) { | |
// jQuery is optional. Use it to support legacy browsers. | |
var $ = (typeof window.jQuery !== 'undefined') && window.jQuery; | |
// create the namespace | |
window.ReactRailsUJS = { | |
CLASS_NAME_ATTR: 'data-react-class', | |
PROPS_ATTR: 'data-react-props', | |
RAILS_ENV_DEVELOPMENT: false, | |
// helper method for the mount and unmount methods to find the | |
// `data-react-class` DOM elements | |
findDOMNodes: function(searchSelector) { | |
// we will use fully qualified paths as we do not bind the callbacks | |
var selector; | |
if (typeof searchSelector === 'undefined') { | |
var selector = '[' + window.ReactRailsUJS.CLASS_NAME_ATTR + ']'; | |
} else { | |
var selector = searchSelector + ' [' + window.ReactRailsUJS.CLASS_NAME_ATTR + ']'; | |
} | |
if ($) { | |
return $(selector); | |
} else { | |
return document.querySelectorAll(selector); | |
} | |
}, | |
mountComponents: function(searchSelector) { | |
var nodes = window.ReactRailsUJS.findDOMNodes(searchSelector); | |
for (var i = 0; i < nodes.length; ++i) { | |
var node = nodes[i]; | |
var className = node.getAttribute(window.ReactRailsUJS.CLASS_NAME_ATTR); | |
// Assume className is simple and can be found at top-level (window). | |
// Fallback to eval to handle cases like 'My.React.ComponentName'. | |
const constructor = (typeof require === "undefined") | |
? window[className] || eval.call(window, className) | |
: _componentStore[className]; | |
var propsJson = node.getAttribute(window.ReactRailsUJS.PROPS_ATTR); | |
var props = propsJson && JSON.parse(propsJson); | |
React.render(React.createElement(constructor, props), node); | |
} | |
}, | |
unmountComponents: function(searchSelector) { | |
var nodes = window.ReactRailsUJS.findDOMNodes(searchSelector); | |
for (var i = 0; i < nodes.length; ++i) { | |
var node = nodes[i]; | |
React.unmountComponentAtNode(node); | |
} | |
} | |
}; | |
function handleNativeEvents() { | |
if ($) { | |
$(function() {window.ReactRailsUJS.mountComponents()}); | |
$(window).unload(function() {window.ReactRailsUJS.unmountComponents()}); | |
} else { | |
document.addEventListener('DOMContentLoaded', function() {window.ReactRailsUJS.mountComponents()}); | |
window.addEventListener('unload', function() {window.ReactRailsUJS.unmountComponents()}); | |
} | |
} | |
handleNativeEvents(); | |
})(document, window); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment