Skip to content

Instantly share code, notes, and snippets.

@rescribet
Created July 20, 2015 23:38
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save rescribet/3b74abccf6a01e08f79e to your computer and use it in GitHub Desktop.
Save rescribet/3b74abccf6a01e08f79e to your computer and use it in GitHub Desktop.
Non-global react_ujs
/*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