Skip to content

Commit 4bf8cc0

Browse files
committed
expose methods on React.ujs
1 parent 8c0e0b4 commit 4bf8cc0

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Unobtrusive scripting adapter for React
2+
(function(document, window, React) {
3+
4+
// jQuery is optional. Use it to support legacy browsers.
5+
var $ = (typeof window.jQuery !== 'undefined') && window.jQuery;
6+
7+
// rather than create another namespace just for the 3 methods and 2
8+
// propertios we expose just append them to the `React.ujs` object
9+
React.ujs = {
10+
11+
CLASS_NAME_ATTR: 'data-react-class',
12+
13+
PROPS_ATTR: 'data-react-props',
14+
15+
// helper method for the mount and unmount methods to find the
16+
// `data-react-class` DOM elements
17+
findDOMNodes: function() {
18+
19+
var selector = '[' + React.ujs.CLASS_NAME_ATTR + ']';
20+
21+
if ($) return $(selector);
22+
23+
else return document.querySelectorAll(selector);
24+
},
25+
26+
mountComponents: function() {
27+
28+
// we will use fully qualified paths as we do not bind the callbacks
29+
var nodes = React.ujs.findDOMNodes();
30+
31+
for (var i = 0; i < nodes.length; ++i) {
32+
var node = nodes[i];
33+
var className = node.getAttribute(React.ujs.CLASS_NAME_ATTR);
34+
35+
// Assume className is simple and can be found at top-level (window).
36+
// Fallback to eval to handle cases like 'My.React.ComponentName'.
37+
var constructor = window[className] || eval.call(window, className);
38+
var propsJson = node.getAttribute(React.ujs.PROPS_ATTR);
39+
var props = propsJson && JSON.parse(propsJson);
40+
41+
React.render(React.createElement(constructor, props), node);
42+
}
43+
},
44+
45+
unmountComponents: function() {
46+
var nodes = React.ujs.findDOMNodes();
47+
48+
for (var i = 0; i < nodes.length; ++i) {
49+
50+
React.unmountComponentAtNode(nodes[i]);
51+
52+
}
53+
}
54+
};
55+
56+
// functions not exposed publicly
57+
function handleTurbolinksEvents () {
58+
var handleEvent;
59+
60+
if ($) {
61+
62+
handleEvent = function(eventName, callback) {
63+
$(document).on(eventName, callback);
64+
};
65+
66+
} else {
67+
68+
handleEvent = function(eventName, callback) {
69+
document.addEventListener(eventName, callback);
70+
};
71+
72+
}
73+
handleEvent('page:change', React.ujs.mountComponents);
74+
handleEvent('page:receive', React.ujs.unmountComponents);
75+
}
76+
77+
function handleNativeEvents() {
78+
if ($) {
79+
80+
$(React.ujs.mountComponents);
81+
$(window).unload(React.ujs.unmountComponents);
82+
83+
} else {
84+
85+
document.addEventListener('DOMContentLoaded', React.ujs.mountComponents);
86+
window.addEventListener('unload', React.ujs.unmountComponents);
87+
}
88+
}
89+
90+
typeof Turbolinks !== 'undefined' ?
91+
handleTurbolinksEvents() : handleNativeEvents();
92+
93+
})(document, window, React);

0 commit comments

Comments
 (0)