mirror of
https://github.com/status-im/reagent.git
synced 2025-01-14 13:54:08 +00:00
115 lines
3.4 KiB
JavaScript
115 lines
3.4 KiB
JavaScript
|
#! /usr/bin/env node
|
||
|
|
||
|
/*
|
||
|
This is a huge hack: convert React from js to cljs by embedding
|
||
|
in (js* ), and making it safe for Closure advanced optimization
|
||
|
by adding a lot of @expose annotations.
|
||
|
*/
|
||
|
|
||
|
var fs = require('fs');
|
||
|
|
||
|
var ns = "cloact.react";
|
||
|
var destFile = "src/cloact/React.cljs";
|
||
|
|
||
|
var srcfile = "bower_components/react/react-with-addons.js";
|
||
|
var React = require("../" + srcfile);
|
||
|
var src = "" + fs.readFileSync(srcfile);
|
||
|
|
||
|
// Names that might clash with module names
|
||
|
// XXX: meta might be broken now
|
||
|
var skipNames = ['var', 'object', 'base', 'map', 'meta', 'source', 'time'];
|
||
|
|
||
|
// Property names from DefaultDOMPropertyConfig.js
|
||
|
// https://github.com/facebook/react/blob/master/src/dom/DefaultDOMPropertyConfig.js
|
||
|
var propNames = ['allowFullScreen', 'autoComplete', 'autoFocus', 'autoPlay',
|
||
|
'charSet', 'encType', 'icon', 'preload', 'radioGroup', 'role',
|
||
|
'spellCheck', 'wmode',
|
||
|
'autoCapitalize',
|
||
|
'cx', 'cy', 'd', 'fx', 'fy', 'gradientTransform',
|
||
|
'gradientUnits', 'points', 'r', 'rx', 'ry', 'spreadMethod',
|
||
|
'stopColor', 'stopOpacity', 'strokeLinecap', 'strokeWidth',
|
||
|
'viewBox', 'x1', 'x2', 'x', 'y1', 'y2', 'y',
|
||
|
'componentConstructor', 'displayName'
|
||
|
];
|
||
|
|
||
|
var getNames = function (obj) {
|
||
|
var res = [];
|
||
|
for (var x in obj) {
|
||
|
res.push(x);
|
||
|
}
|
||
|
return res;
|
||
|
};
|
||
|
|
||
|
var stripAnnotations = function (src) {
|
||
|
// Stop bloody google closure complaining about jsdoc tags
|
||
|
// by removing "@" in block comments.
|
||
|
return src.replace(/\/\*([^*]|\*(?!\/))*\*\//gm, function (s) {
|
||
|
return s.replace(/@/g, '');
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var quote = function (src) {
|
||
|
return src.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
||
|
}
|
||
|
|
||
|
var getLiteralKeys = function (src) {
|
||
|
var res = {};
|
||
|
src.replace(/([a-zA-Z$_][a-zA-Z0-9$_]*):/gm, function (s, key) {
|
||
|
res[key] = true;
|
||
|
});
|
||
|
return getNames(res);
|
||
|
}
|
||
|
|
||
|
var eventNames = function (keys) {
|
||
|
return keys.filter(function (x) {
|
||
|
return x.match(/^on[A-Z]/);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
var ReactCompositeComponentInterface = {
|
||
|
mixins: null,
|
||
|
propTypes: null,
|
||
|
getDefaultProps: null,
|
||
|
getInitialState: null,
|
||
|
render: null,
|
||
|
componentWillMount: null,
|
||
|
componentDidMount: null,
|
||
|
componentWillReceiveProps: null,
|
||
|
shouldComponentUpdate: null,
|
||
|
componentWillUpdate: null,
|
||
|
componentDidUpdate: null,
|
||
|
componentWillUnmount: null,
|
||
|
updateComponent: null
|
||
|
}
|
||
|
|
||
|
var printCljs = function () {
|
||
|
var stripped = stripAnnotations(src);
|
||
|
var quoted = quote(stripped);
|
||
|
var domNames = getNames(React.DOM);
|
||
|
var evNames = eventNames(getLiteralKeys(src));
|
||
|
var iNames = getNames(ReactCompositeComponentInterface);
|
||
|
var names = [].concat(domNames, evNames, iNames, propNames);
|
||
|
var fnames = names.filter(function (n) {
|
||
|
return skipNames.indexOf(n) == -1;
|
||
|
});
|
||
|
|
||
|
res = ["(ns " + ns + ")",
|
||
|
'(js* "',
|
||
|
'/**',
|
||
|
' * @fileoverview React.js packaged for clojurescript',
|
||
|
' * @suppress {nonStandardJsDocs|checkRegExp}',
|
||
|
' */',
|
||
|
quoted,
|
||
|
'(function () {',
|
||
|
'var X = {};'].concat(fnames.map(function (x) {
|
||
|
return '/** @expose */\nX.' + x + " = true;"
|
||
|
})).concat([
|
||
|
'})();',
|
||
|
ns + ".React = (typeof(window) != 'undefined' ? window.React : global.React);",
|
||
|
'")',
|
||
|
]);
|
||
|
return res.join('\n');
|
||
|
}
|
||
|
|
||
|
fs.writeFileSync(destFile, printCljs());
|