mirror of
https://github.com/bobwen-dev/react-templates
synced 2025-04-12 00:56:39 +02:00
Merge branch 'nippur72-virtual-node' into gh-pages
This commit is contained in:
commit
ea4729dafe
@ -16,6 +16,7 @@ web/**
|
|||||||
|
|
||||||
playground/sample/**
|
playground/sample/**
|
||||||
test/data/**
|
test/data/**
|
||||||
|
dist
|
||||||
|
|
||||||
internalTasks/release.js
|
internalTasks/release.js
|
||||||
playground.config.js
|
playground.config.js
|
||||||
|
27
.eslintrc
27
.eslintrc
@ -1,18 +1,24 @@
|
|||||||
{
|
{
|
||||||
"extends": "wix-editor",
|
"extends": "wix-editor/node",
|
||||||
"plugins": ["lodash3", "wix-editor"],
|
"plugins": ["lodash3", "wix-editor"],
|
||||||
"rules": {
|
"rules": {
|
||||||
"strict": [2, "global"],
|
"no-var": 0,
|
||||||
"no-restricted-syntax": [2, "WithStatement"],
|
"object-shorthand": 0,
|
||||||
|
"prefer-arrow-callback": 0,
|
||||||
|
"prefer-const": 0,
|
||||||
|
"prefer-spread": 0,
|
||||||
|
"prefer-template": 0,
|
||||||
|
|
||||||
|
"no-restricted-syntax": [2, "WithStatement", "ContinueStatement", "ForStatement"],
|
||||||
"no-negated-condition": 1,
|
"no-negated-condition": 1,
|
||||||
"lodash3/prop-shorthand": 2,
|
"lodash3/prop-shorthand": 2,
|
||||||
"lodash3/matches-shorthand": 2,
|
"lodash3/matches-shorthand": [2, "always", 3],
|
||||||
"lodash3/matches-prop-shorthand": 2,
|
"lodash3/matches-prop-shorthand": 2,
|
||||||
"lodash3/prefer-chain": 2,
|
"lodash3/prefer-chain": 2,
|
||||||
"lodash3/preferred-alias": 2,
|
"lodash3/preferred-alias": 2,
|
||||||
"lodash3/no-single-chain": 2,
|
"lodash3/no-single-chain": 2,
|
||||||
"lodash3/prefer-reject": 2,
|
"lodash3/prefer-reject": [2, 3],
|
||||||
"lodash3/prefer-filter": 2,
|
"lodash3/prefer-filter": [2, 3],
|
||||||
"lodash3/no-unnecessary-bind": 2,
|
"lodash3/no-unnecessary-bind": 2,
|
||||||
"lodash3/unwrap": 2,
|
"lodash3/unwrap": 2,
|
||||||
"lodash3/prefer-compact": 2,
|
"lodash3/prefer-compact": 2,
|
||||||
@ -21,6 +27,7 @@
|
|||||||
"lodash3/prefer-wrapper-method": 2,
|
"lodash3/prefer-wrapper-method": 2,
|
||||||
"lodash3/prefer-invoke": 2,
|
"lodash3/prefer-invoke": 2,
|
||||||
"lodash3/prefer-thru": 2,
|
"lodash3/prefer-thru": 2,
|
||||||
|
"lodash3/prefer-lodash-chain": 2,
|
||||||
"lodash3/prefer-lodash-method": 0,
|
"lodash3/prefer-lodash-method": 0,
|
||||||
"lodash3/prefer-lodash-typecheck": 2,
|
"lodash3/prefer-lodash-typecheck": 2,
|
||||||
"lodash3/no-commit": 2,
|
"lodash3/no-commit": 2,
|
||||||
@ -36,13 +43,5 @@
|
|||||||
"wix-editor/prefer-ternary": 1,
|
"wix-editor/prefer-ternary": 1,
|
||||||
"wix-editor/return-boolean": 1,
|
"wix-editor/return-boolean": 1,
|
||||||
"wix-editor/simplify-boolean-expression": 1
|
"wix-editor/simplify-boolean-expression": 1
|
||||||
},
|
|
||||||
"env": {
|
|
||||||
"browser": false,
|
|
||||||
"node": true,
|
|
||||||
"amd": true
|
|
||||||
},
|
|
||||||
"globals": {
|
|
||||||
"requirejs": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -16,6 +16,9 @@ npm-debug.log
|
|||||||
### bower ###
|
### bower ###
|
||||||
/bower_components/*
|
/bower_components/*
|
||||||
|
|
||||||
|
### babel ###
|
||||||
|
/dist
|
||||||
|
|
||||||
/web
|
/web
|
||||||
/target
|
/target
|
||||||
/coverage
|
/coverage
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
'use strict';
|
'use strict';
|
||||||
var cli = require('../src/cli');
|
var cli = require('../dist/cli');
|
||||||
var exitCode = cli.execute(process.argv);
|
var exitCode = cli.execute(process.argv);
|
||||||
/*eslint no-process-exit:0*/
|
/*eslint no-process-exit:0*/
|
||||||
process.exit(exitCode);
|
process.exit(exitCode);
|
28
package.json
28
package.json
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "react-templates",
|
"name": "react-templates",
|
||||||
"version": "0.3.2",
|
"version": "0.4.1",
|
||||||
"description": "Light weight templates for react -> write html get valid react code",
|
"description": "Light weight templates for react -> write html get valid react code",
|
||||||
"main": "./src/cli.js",
|
"main": "./dist/cli.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
"rt": "./bin/rt.js"
|
"rt": "./bin/rt.js"
|
||||||
},
|
},
|
||||||
@ -15,7 +15,8 @@
|
|||||||
"minor": "npm version minor -m\"update version to %s\" && git push && git push --tags",
|
"minor": "npm version minor -m\"update version to %s\" && git push && git push --tags",
|
||||||
"major": "npm version major -m\"update version to %s\" && git push && git push --tags",
|
"major": "npm version major -m\"update version to %s\" && git push && git push --tags",
|
||||||
"buildwp": "webpack --config webpack-production.config.js --progress --profile --colors",
|
"buildwp": "webpack --config webpack-production.config.js --progress --profile --colors",
|
||||||
"babel": "rm -rf dist; babel src/ --out-dir dist/"
|
"babel": "rm -rf dist && babel src/ --out-dir dist/",
|
||||||
|
"all": "npm run lint && npm run test && npm run babel"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -31,20 +32,21 @@
|
|||||||
"chalk": "^1.1.1",
|
"chalk": "^1.1.1",
|
||||||
"cheerio": "^0.19.0",
|
"cheerio": "^0.19.0",
|
||||||
"css": "^2.2.1",
|
"css": "^2.2.1",
|
||||||
"escodegen": "^1.7.0",
|
"escodegen": "1.7.1",
|
||||||
"esprima-fb": "^15001.1001.0-dev-harmony-fb",
|
"esprima-fb": "^15001.1001.0-dev-harmony-fb",
|
||||||
"lodash": "^3.10.1",
|
"lodash": "^3.10.1",
|
||||||
"optionator": "^0.6.0",
|
"optionator": "^0.8.0",
|
||||||
"text-table": "^0.2.0"
|
"text-table": "^0.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"brace": "^0.5.1",
|
"babel-cli": "^6.3.17",
|
||||||
|
"brace": "0.7.0",
|
||||||
"brfs": "^1.4.1",
|
"brfs": "^1.4.1",
|
||||||
"coveralls": "^2.11.4",
|
"coveralls": "2.11.6",
|
||||||
"eslint": "^1.10.1",
|
"eslint": "1.10.3",
|
||||||
"eslint-config-wix-editor": "^0.1.1",
|
"eslint-config-wix-editor": "^0.1.1",
|
||||||
"eslint-plugin-lodash3": "^0.2.1",
|
"eslint-plugin-lodash3": "^0.5.0",
|
||||||
"eslint-plugin-react": "^3.10.0",
|
"eslint-plugin-react": "^3.13.1",
|
||||||
"eslint-plugin-wix-editor": "^1.0.1",
|
"eslint-plugin-wix-editor": "^1.0.1",
|
||||||
"grunt": "^0.4.5",
|
"grunt": "^0.4.5",
|
||||||
"grunt-browserify": "^4.0.0",
|
"grunt-browserify": "^4.0.0",
|
||||||
@ -53,11 +55,11 @@
|
|||||||
"grunt-contrib-watch": "^0.6.1",
|
"grunt-contrib-watch": "^0.6.1",
|
||||||
"grunt-eslint": "^17.3.1",
|
"grunt-eslint": "^17.3.1",
|
||||||
"grunt-tape": "0.0.2",
|
"grunt-tape": "0.0.2",
|
||||||
"istanbul": "^0.4.0",
|
"istanbul": "0.4.1",
|
||||||
"react": "^0.14.2",
|
"react": "^0.14.2",
|
||||||
"react-dom": "^0.14.2",
|
"react-dom": "^0.14.2",
|
||||||
"react-native": "^0.11.4",
|
"react-native": "^0.17.0",
|
||||||
"tape": "^4.2.1"
|
"tape": "^4.4.0"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"templates",
|
"templates",
|
||||||
|
@ -95,7 +95,7 @@ define(['react', 'lodash', 'jquery', './libs/codemirror-4.8/lib/codemirror'], fu
|
|||||||
}
|
}
|
||||||
var poll = setInterval(function () {
|
var poll = setInterval(function () {
|
||||||
if (tooltip) {
|
if (tooltip) {
|
||||||
for (var n = node; ; n = n.parentNode) {
|
for (var n = node; ; n = n.parentNode) { //eslint-disable-line no-restricted-syntax
|
||||||
if (n === document.body) {
|
if (n === document.body) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -45,8 +45,8 @@ function getLine(html, node) {
|
|||||||
|
|
||||||
// Redefine properties on Error to be enumerable
|
// Redefine properties on Error to be enumerable
|
||||||
/*eslint no-extend-native:0*/
|
/*eslint no-extend-native:0*/
|
||||||
Object.defineProperty(Error.prototype, 'message', {configurable: true, enumerable: true});
|
//Object.defineProperty(Error.prototype, 'message', {configurable: true, enumerable: true});
|
||||||
Object.defineProperty(Error.prototype, 'stack', {configurable: true, enumerable: true});
|
//Object.defineProperty(Error.prototype, 'stack', {configurable: true, enumerable: true});
|
||||||
//Object.defineProperty(Error.prototype, 'line', { configurable: true, enumerable: true });
|
//Object.defineProperty(Error.prototype, 'line', { configurable: true, enumerable: true });
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -57,31 +57,42 @@ Object.defineProperty(Error.prototype, 'stack', {configurable: true, enumerable:
|
|||||||
* @param {number=} column
|
* @param {number=} column
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function RTCodeError(message, startOffset, endOffset, line, column) {
|
class RTCodeError extends Error {
|
||||||
Error.captureStackTrace(this, RTCodeError);
|
constructor(message, startOffset, endOffset, line, column) {
|
||||||
this.name = 'RTCodeError';
|
super();
|
||||||
this.message = message || '';
|
Error.captureStackTrace(this, RTCodeError);
|
||||||
this.index = norm(startOffset);
|
this.name = 'RTCodeError';
|
||||||
this.startOffset = norm(startOffset);
|
this.message = message || '';
|
||||||
this.endOffset = norm(endOffset);
|
this.index = norm(startOffset);
|
||||||
this.line = norm(line);
|
this.startOffset = norm(startOffset);
|
||||||
this.column = norm(column);
|
this.endOffset = norm(endOffset);
|
||||||
|
this.line = norm(line);
|
||||||
|
this.column = norm(column);
|
||||||
|
}
|
||||||
|
//build buildError
|
||||||
}
|
}
|
||||||
|
|
||||||
function norm(n) {
|
function norm(n) {
|
||||||
return n === undefined ? -1 : n;
|
return n === undefined ? -1 : n;
|
||||||
}
|
}
|
||||||
|
|
||||||
RTCodeError.prototype = Object.create(Error.prototype);
|
//const norm = n => n === undefined ? -1 : n;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {buildError}
|
||||||
|
*/
|
||||||
RTCodeError.build = buildError;
|
RTCodeError.build = buildError;
|
||||||
RTCodeError.norm = norm;
|
RTCodeError.norm = norm;
|
||||||
|
|
||||||
RTCodeError.prototype.toIssue = function () {
|
/**
|
||||||
};
|
* @param {*} context
|
||||||
|
* @param {*} node
|
||||||
|
* @param {string} msg
|
||||||
|
* @param args
|
||||||
|
* @return {RTCodeError}
|
||||||
|
*/
|
||||||
function buildFormat(context, node, msg, args) {
|
function buildFormat(context, node, msg, args) {
|
||||||
return buildError(util.format.apply(this, [msg].concat(args)), context, node);
|
return buildError(context, node, util.format.apply(this, [msg].concat(args)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,12 +105,12 @@ function buildFormat(context, node, msg, args) {
|
|||||||
RTCodeError.buildFormat = _.restParam(buildFormat, 3);
|
RTCodeError.buildFormat = _.restParam(buildFormat, 3);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} msg
|
|
||||||
* @param {*} context
|
* @param {*} context
|
||||||
* @param {*} node
|
* @param {*} node
|
||||||
|
* @param {string} msg
|
||||||
* @return {RTCodeError}
|
* @return {RTCodeError}
|
||||||
*/
|
*/
|
||||||
function buildError(msg, context, node) {
|
function buildError(context, node, msg) {
|
||||||
var loc = getNodeLoc(context, node);
|
var loc = getNodeLoc(context, node);
|
||||||
return new RTCodeError(msg, loc.start, loc.end, loc.pos.line, loc.pos.col);
|
return new RTCodeError(msg, loc.start, loc.end, loc.pos.line, loc.pos.col);
|
||||||
}
|
}
|
||||||
|
@ -5,13 +5,14 @@ var path = require('path');
|
|||||||
var util = require('util');
|
var util = require('util');
|
||||||
var chalk = require('chalk');
|
var chalk = require('chalk');
|
||||||
var reactTemplates = require('./reactTemplates');
|
var reactTemplates = require('./reactTemplates');
|
||||||
|
var fsUtil = require('./fsUtil');
|
||||||
var convertRT = reactTemplates.convertRT;
|
var convertRT = reactTemplates.convertRT;
|
||||||
var convertJSRTToJS = reactTemplates.convertJSRTToJS;
|
var convertJSRTToJS = reactTemplates.convertJSRTToJS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} source
|
* @param {string} source
|
||||||
* @param {string} target
|
* @param {string} target
|
||||||
* @param {{modules:string, dryRun:boolean}?} options
|
* @param {Options} options
|
||||||
* @param {CONTEXT} context
|
* @param {CONTEXT} context
|
||||||
*/
|
*/
|
||||||
function convertFile(source, target, options, context) {
|
function convertFile(source, target, options, context) {
|
||||||
@ -21,10 +22,9 @@ function convertFile(source, target, options, context) {
|
|||||||
// }
|
// }
|
||||||
options = options || {};
|
options = options || {};
|
||||||
options.fileName = source;
|
options.fileName = source;
|
||||||
var fsUtil = require('./fsUtil');
|
|
||||||
|
|
||||||
if (!options.force && !fsUtil.isStale(source, target)) {
|
if (!options.force && !fsUtil.isStale(source, target)) {
|
||||||
context.verbose(util.format('target file %s is up to date, skipping', chalk.cyan(target)));
|
context.verbose(`target file ${chalk.cyan(target)} is up to date, skipping`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
src/cli.js
10
src/cli.js
@ -11,13 +11,17 @@ var reactDOMSupport = require('./reactDOMSupport');
|
|||||||
var reactTemplates = require('./reactTemplates');
|
var reactTemplates = require('./reactTemplates');
|
||||||
var rtStyle = require('./rtStyle');
|
var rtStyle = require('./rtStyle');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Options} currentOptions
|
||||||
|
* @return {number}
|
||||||
|
*/
|
||||||
function executeOptions(currentOptions) {
|
function executeOptions(currentOptions) {
|
||||||
var ret = 0;
|
var ret = 0;
|
||||||
var files = currentOptions._;
|
var files = currentOptions._;
|
||||||
context.options.format = currentOptions.format || 'stylish';
|
context.options.format = currentOptions.format || 'stylish';
|
||||||
|
|
||||||
if (currentOptions.version) {
|
if (currentOptions.version) {
|
||||||
console.log('v' + pkg.version);
|
console.log(`v${pkg.version}`);
|
||||||
} else if (currentOptions.help) {
|
} else if (currentOptions.help) {
|
||||||
if (files.length) {
|
if (files.length) {
|
||||||
console.log(options.generateHelpForOption(files[0]));
|
console.log(options.generateHelpForOption(files[0]));
|
||||||
@ -37,6 +41,8 @@ function executeOptions(currentOptions) {
|
|||||||
|
|
||||||
function printVersions(currentOptions) {
|
function printVersions(currentOptions) {
|
||||||
var ret = Object.keys(reactDOMSupport);
|
var ret = Object.keys(reactDOMSupport);
|
||||||
|
//const out = currentOptions.format === 'json' ? JSON.stringify(ret, undefined, 2) : ret.join(', ');
|
||||||
|
//console.log(out);
|
||||||
if (currentOptions.format === 'json') {
|
if (currentOptions.format === 'json') {
|
||||||
console.log(JSON.stringify(ret, undefined, 2));
|
console.log(JSON.stringify(ret, undefined, 2));
|
||||||
} else {
|
} else {
|
||||||
@ -45,7 +51,7 @@ function printVersions(currentOptions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {*} currentOptions
|
* @param {Options} currentOptions
|
||||||
* @param {string} filename file name to process
|
* @param {string} filename file name to process
|
||||||
*/
|
*/
|
||||||
function handleSingleFile(currentOptions, filename) {
|
function handleSingleFile(currentOptions, filename) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
/**
|
/**
|
||||||
* @typedef {{color: boolean, cwd: string, report: function(string), warn: function(string), getMessages: function():Array.<MESSAGE>}} CONTEXT
|
* @typedef {{color: boolean, cwd: string, report: function(string), issue: function(string, string,string,number,number,number=,number=), warn: function(string), verbose: function(string), getMessages: function():Array.<MESSAGE>, options:Options, messages: Array.<MESSAGE>}} CONTEXT
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* @typedef {{msg: string, level: MESSAGE_LEVEL, file: string,line:number,column:number,startOffset:number,endOffset:number}} MESSAGE
|
* @typedef {{msg: string, level: MESSAGE_LEVEL, file: string,line:number,column:number,startOffset:number,endOffset:number}} MESSAGE
|
||||||
@ -58,7 +58,7 @@ var context = {
|
|||||||
* @param {number=} endOffset
|
* @param {number=} endOffset
|
||||||
*/
|
*/
|
||||||
issue: function (level, msg, file, line, column, startOffset, endOffset) {
|
issue: function (level, msg, file, line, column, startOffset, endOffset) {
|
||||||
context.messages.push({level: level, msg: msg, file: file || null, line: norm(line), column: norm(column), index: norm(startOffset), startOffset: norm(startOffset), endOffset: norm(endOffset)});
|
context.messages.push({level, msg, file: file || null, line: norm(line), column: norm(column), index: norm(startOffset), startOffset: norm(startOffset), endOffset: norm(endOffset)});
|
||||||
},
|
},
|
||||||
getMessages: function () {
|
getMessages: function () {
|
||||||
return context.messages;
|
return context.messages;
|
||||||
|
@ -19,13 +19,12 @@ var reactNativeSupport = require('./reactNativeSupport');
|
|||||||
|
|
||||||
// exports 'parse(args)', 'generateHelp()', and 'generateHelpForOption(optionName)'
|
// exports 'parse(args)', 'generateHelp()', and 'generateHelpForOption(optionName)'
|
||||||
module.exports = optionator({
|
module.exports = optionator({
|
||||||
prepend: [
|
prepend:
|
||||||
pkg.name + ' v' + pkg.version,
|
`${pkg.name} v${pkg.version}
|
||||||
pkg.description,
|
${pkg.description}
|
||||||
'',
|
|
||||||
'Usage:',
|
Usage:
|
||||||
'$ rt <filename> [<filename> ...] [<args>]'
|
$ rt <filename> [<filename> ...] [<args>]`,
|
||||||
].join('\n'),
|
|
||||||
concatRepeatedArrays: true,
|
concatRepeatedArrays: true,
|
||||||
mergeRepeatedObjects: true,
|
mergeRepeatedObjects: true,
|
||||||
options: [{
|
options: [{
|
||||||
@ -76,7 +75,7 @@ module.exports = optionator({
|
|||||||
alias: 't',
|
alias: 't',
|
||||||
type: 'String',
|
type: 'String',
|
||||||
default: reactDOMSupport.default,
|
default: reactDOMSupport.default,
|
||||||
description: 'React version to generate code for (' + Object.keys(reactDOMSupport).join(', ') + ')'
|
description: `'React version to generate code for (${Object.keys(reactDOMSupport).join(', ')})'`
|
||||||
}, {
|
}, {
|
||||||
option: 'list-target-version',
|
option: 'list-target-version',
|
||||||
type: 'Boolean',
|
type: 'Boolean',
|
||||||
@ -116,6 +115,6 @@ module.exports = optionator({
|
|||||||
alias: 'rnv',
|
alias: 'rnv',
|
||||||
type: 'String',
|
type: 'String',
|
||||||
default: reactNativeSupport.default,
|
default: reactNativeSupport.default,
|
||||||
description: 'React native version to generate code for (' + Object.keys(reactNativeSupport).join(', ') + ')'
|
description: `'React native version to generate code for (${Object.keys(reactNativeSupport).join(', ')})'`
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
|
@ -18,6 +18,6 @@ var versions = {
|
|||||||
'0.11.1': ver0_11_0,
|
'0.11.1': ver0_11_0,
|
||||||
'0.11.0': ver0_11_0,
|
'0.11.0': ver0_11_0,
|
||||||
'0.10.0': ver0_10_0,
|
'0.10.0': ver0_10_0,
|
||||||
default: '0.13.1'
|
default: '0.14.0'
|
||||||
};
|
};
|
||||||
module.exports = versions;
|
module.exports = versions;
|
||||||
|
@ -38,10 +38,11 @@ var htmlSelfClosingTags = ['area', 'base', 'br', 'col', 'command', 'embed', 'hr'
|
|||||||
var templateAMDTemplate = _.template("define(<%= name ? '\"'+name + '\", ' : '' %>[<%= requirePaths %>], function (<%= requireNames %>) {\n'use strict';\n <%= injectedFunctions %>\nreturn function(){ return <%= body %>};\n});");
|
var templateAMDTemplate = _.template("define(<%= name ? '\"'+name + '\", ' : '' %>[<%= requirePaths %>], function (<%= requireNames %>) {\n'use strict';\n <%= injectedFunctions %>\nreturn function(){ return <%= body %>};\n});");
|
||||||
var templateCommonJSTemplate = _.template("'use strict';\n<%= vars %>\n\n<%= injectedFunctions %>\nmodule.exports = function(){ return <%= body %>};\n");
|
var templateCommonJSTemplate = _.template("'use strict';\n<%= vars %>\n\n<%= injectedFunctions %>\nmodule.exports = function(){ return <%= body %>};\n");
|
||||||
var templateES6Template = _.template('<%= vars %>\n\n<%= injectedFunctions %>\nexport default function(){ return <%= body %>}\n');
|
var templateES6Template = _.template('<%= vars %>\n\n<%= injectedFunctions %>\nexport default function(){ return <%= body %>}\n');
|
||||||
var templatePJSTemplate = _.template('var <%= name %> = function () {\n' +
|
var templatePJSTemplate = _.template(`var <%= name %> = function () {
|
||||||
'<%= injectedFunctions %>\n' +
|
<%= injectedFunctions %>
|
||||||
'return <%= body %>\n' +
|
return <%= body %>
|
||||||
'};\n');
|
};
|
||||||
|
`);
|
||||||
var templateTypescriptTemplate = _.template('<%= vars %>\n\n<%= injectedFunctions %>\nvar fn = function() { return <%= body %> };\nexport = fn\n');
|
var templateTypescriptTemplate = _.template('<%= vars %>\n\n<%= injectedFunctions %>\nvar fn = function() { return <%= body %> };\nexport = fn\n');
|
||||||
var templateJSRTTemplate = _.template('(function () {\n <%= injectedFunctions %>\n return function(){\nreturn <%= body %>}}\n)()');
|
var templateJSRTTemplate = _.template('(function () {\n <%= injectedFunctions %>\n return function(){\nreturn <%= body %>}}\n)()');
|
||||||
|
|
||||||
|
@ -20,18 +20,17 @@ var ifTemplate = _.template('((<%= condition %>)?(<%= body %>):null)');
|
|||||||
var propsTemplateSimple = _.template('_.assign({}, <%= generatedProps %>, <%= rtProps %>)');
|
var propsTemplateSimple = _.template('_.assign({}, <%= generatedProps %>, <%= rtProps %>)');
|
||||||
var propsTemplate = _.template('mergeProps( <%= generatedProps %>, <%= rtProps %>)');
|
var propsTemplate = _.template('mergeProps( <%= generatedProps %>, <%= rtProps %>)');
|
||||||
|
|
||||||
var propsMergeFunction = [
|
const propsMergeFunction = `function mergeProps(inline,external) {
|
||||||
'function mergeProps(inline,external) {',
|
var res = _.assign({},inline,external)
|
||||||
' var res = _.assign({},inline,external)',
|
if (inline.hasOwnProperty('style')) {
|
||||||
'if (inline.hasOwnProperty(\'style\')) {',
|
res.style = _.defaults(res.style, inline.style);
|
||||||
' res.style = _.defaults(res.style, inline.style);',
|
}
|
||||||
'}',
|
if (inline.hasOwnProperty('className') && external.hasOwnProperty('className')) {
|
||||||
' if (inline.hasOwnProperty(\'className\') && external.hasOwnProperty(\'className\')) {',
|
res.className = external.className + ' ' + inline.className;
|
||||||
' res.className = external.className + \' \' + inline.className;',
|
}
|
||||||
'} return res;',
|
return res;
|
||||||
'}',
|
}
|
||||||
''
|
`
|
||||||
].join('\n');
|
|
||||||
|
|
||||||
var classSetTemplate = _.template('_.keys(_.pick(<%= classSet %>, _.identity)).join(" ")');
|
var classSetTemplate = _.template('_.keys(_.pick(<%= classSet %>, _.identity)).join(" ")');
|
||||||
|
|
||||||
@ -52,7 +51,12 @@ var classAttr = 'class';
|
|||||||
var scopeAttr = 'rt-scope';
|
var scopeAttr = 'rt-scope';
|
||||||
var propsAttr = 'rt-props';
|
var propsAttr = 'rt-props';
|
||||||
var templateNode = 'rt-template';
|
var templateNode = 'rt-template';
|
||||||
|
var virtualNode = 'rt-virtual';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Options} options
|
||||||
|
* @return {Options}
|
||||||
|
*/
|
||||||
function getOptions(options) {
|
function getOptions(options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var defaultOptions = {
|
var defaultOptions = {
|
||||||
@ -91,16 +95,19 @@ function reactImport(options) {
|
|||||||
/**
|
/**
|
||||||
* @const
|
* @const
|
||||||
*/
|
*/
|
||||||
var curlyMap = {'{': 1, '}': -1};
|
const curlyMap = {'{': 1, '}': -1};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {{boundParams: Array.<string>, injectedFunctions: Array.<string>, html: string, options: *}} Context
|
* @typedef {{boundParams: Array.<string>, injectedFunctions: Array.<string>, html: string, options: *}} Context
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {{fileName:string,force:boolean,modules:string,defines:*,reactImportPath:string=,lodashImportPath:string=,flow:boolean,name:string,native:boolean,propTemplates:*,format:string,_:*,version:boolean,help:boolean,listTargetVersion:boolean,modules:string, dryRun:boolean}} Options
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @param context
|
* @param {Context} context
|
||||||
* @param {string} txt
|
* @param {string} txt
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
@ -117,7 +124,7 @@ function convertText(node, context, txt) {
|
|||||||
}
|
}
|
||||||
var curlyCounter = 1;
|
var curlyCounter = 1;
|
||||||
var end;
|
var end;
|
||||||
for (end = start + 1; end < txt.length && curlyCounter > 0; end++) {
|
for (end = start + 1; end < txt.length && curlyCounter > 0; end++) { //eslint-disable-line no-restricted-syntax
|
||||||
curlyCounter += curlyMap[txt.charAt(end)] || 0;
|
curlyCounter += curlyMap[txt.charAt(end)] || 0;
|
||||||
}
|
}
|
||||||
if (curlyCounter === 0) {
|
if (curlyCounter === 0) {
|
||||||
@ -126,7 +133,7 @@ function convertText(node, context, txt) {
|
|||||||
first = false;
|
first = false;
|
||||||
txt = txt.substr(end);
|
txt = txt.substr(end);
|
||||||
} else {
|
} else {
|
||||||
throw RTCodeError.buildFormat(context, node, "Failed to parse text '%s'", txt);
|
throw RTCodeError.build(context, node, `Failed to parse text '${txt}'`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (txt) {
|
if (txt) {
|
||||||
@ -135,7 +142,6 @@ function convertText(node, context, txt) {
|
|||||||
if (res === '') {
|
if (res === '') {
|
||||||
res = 'true';
|
res = 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,10 +154,13 @@ function convertText(node, context, txt) {
|
|||||||
*/
|
*/
|
||||||
function generateInjectedFunc(context, namePrefix, body, params) {
|
function generateInjectedFunc(context, namePrefix, body, params) {
|
||||||
params = params || context.boundParams;
|
params = params || context.boundParams;
|
||||||
var generatedFuncName = namePrefix.replace(',', '') + (context.injectedFunctions.length + 1);
|
var funcName = namePrefix.replace(',', '') + (context.injectedFunctions.length + 1);
|
||||||
var funcText = util.format('function %s(%s) {\n%s\n}\n', generatedFuncName, params.join(','), body);
|
var funcText = `function ${funcName}(${params.join(',')}) {
|
||||||
|
${body}
|
||||||
|
}
|
||||||
|
`;
|
||||||
context.injectedFunctions.push(funcText);
|
context.injectedFunctions.push(funcText);
|
||||||
return generatedFuncName;
|
return funcName;
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateTemplateProps(node, context) {
|
function generateTemplateProps(node, context) {
|
||||||
@ -161,7 +170,7 @@ function generateTemplateProps(node, context) {
|
|||||||
var templateProp = null;
|
var templateProp = null;
|
||||||
if (child.name === templateNode) { // Generic explicit template tag
|
if (child.name === templateNode) { // Generic explicit template tag
|
||||||
if (!_.has(child.attribs, 'prop')) {
|
if (!_.has(child.attribs, 'prop')) {
|
||||||
throw RTCodeError.build('rt-template must have a prop attribute', context, child);
|
throw RTCodeError.build(context, child, 'rt-template must have a prop attribute');
|
||||||
}
|
}
|
||||||
|
|
||||||
var childTemplate = _.find(context.options.propTemplates, {prop: child.attribs.prop}) || {arguments: []};
|
var childTemplate = _.find(context.options.propTemplates, {prop: child.attribs.prop}) || {arguments: []};
|
||||||
@ -212,7 +221,7 @@ function generateProps(node, context) {
|
|||||||
_.forOwn(node.attribs, function (val, key) {
|
_.forOwn(node.attribs, function (val, key) {
|
||||||
var propKey = reactSupport.attributesMapping[key.toLowerCase()] || key;
|
var propKey = reactSupport.attributesMapping[key.toLowerCase()] || key;
|
||||||
if (props.hasOwnProperty(propKey) && propKey !== reactSupport.classNameProp) {
|
if (props.hasOwnProperty(propKey) && propKey !== reactSupport.classNameProp) {
|
||||||
throw RTCodeError.buildFormat(context, node, 'duplicate definition of %s %s', propKey, JSON.stringify(node.attribs));
|
throw RTCodeError.build(context, node, `duplicate definition of ${propKey} ${JSON.stringify(node.attribs)}`);
|
||||||
}
|
}
|
||||||
if (key.indexOf('on') === 0 && !utils.isStringOnlyCode(val)) {
|
if (key.indexOf('on') === 0 && !utils.isStringOnlyCode(val)) {
|
||||||
props[propKey] = handleEventHandler(val, context, node, key);
|
props[propKey] = handleEventHandler(val, context, node, key);
|
||||||
@ -222,7 +231,7 @@ function generateProps(node, context) {
|
|||||||
// Processing for both class and rt-class conveniently return strings that
|
// Processing for both class and rt-class conveniently return strings that
|
||||||
// represent JS expressions, each evaluating to a space-separated set of class names.
|
// represent JS expressions, each evaluating to a space-separated set of class names.
|
||||||
// We can just join them with another space here.
|
// We can just join them with another space here.
|
||||||
var existing = props[propKey] ? props[propKey] + ' + " " + ' : '';
|
var existing = props[propKey] ? `${props[propKey]} + " " + ` : '';
|
||||||
if (key === classSetAttr) {
|
if (key === classSetAttr) {
|
||||||
props[propKey] = existing + classSetTemplate({classSet: val});
|
props[propKey] = existing + classSetTemplate({classSet: val});
|
||||||
} else if (key === classAttr || key === reactSupport.classNameProp) {
|
} else if (key === classAttr || key === reactSupport.classNameProp) {
|
||||||
@ -234,15 +243,14 @@ function generateProps(node, context) {
|
|||||||
});
|
});
|
||||||
_.assign(props, generateTemplateProps(node, context));
|
_.assign(props, generateTemplateProps(node, context));
|
||||||
|
|
||||||
return '{' + _.map(props, function (val, key) {
|
const propStr = _.map(props, (v, k) => `${JSON.stringify(k)} : ${v}`).join(',');
|
||||||
return JSON.stringify(key) + ' : ' + val;
|
return `{${propStr}}`;
|
||||||
}).join(',') + '}';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleEventHandler(val, context, node, key) {
|
function handleEventHandler(val, context, node, key) {
|
||||||
var funcParts = val.split('=>');
|
var funcParts = val.split('=>');
|
||||||
if (funcParts.length !== 2) {
|
if (funcParts.length !== 2) {
|
||||||
throw RTCodeError.buildFormat(context, node, "when using 'on' events, use lambda '(p1,p2)=>body' notation or use {} to return a callback function. error: [%s='%s']", key, val);
|
throw RTCodeError.build(context, node, `when using 'on' events, use lambda '(p1,p2)=>body' notation or use {} to return a callback function. error: [${key}='${val}']`);
|
||||||
}
|
}
|
||||||
var evtParams = funcParts[0].replace('(', '').replace(')', '').trim();
|
var evtParams = funcParts[0].replace('(', '').replace(')', '').trim();
|
||||||
var funcBody = funcParts[1].trim();
|
var funcBody = funcParts[1].trim();
|
||||||
@ -259,21 +267,19 @@ function genBind(func, args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleStyleProp(val, node, context) {
|
function handleStyleProp(val, node, context) {
|
||||||
var styleParts = val.trim().split(';');
|
const styleStr = _(val)
|
||||||
styleParts = _.compact(_.map(styleParts, function (str) {
|
.split(';')
|
||||||
str = str.trim();
|
.map(_.trim)
|
||||||
if (!str || str.indexOf(':') === -1) {
|
.filter(i => _.includes(i, ':'))
|
||||||
return null;
|
.map(i => {
|
||||||
}
|
const pair = i.split(':');
|
||||||
var res = str.split(':');
|
//const val = pair[1];
|
||||||
res[0] = res[0].trim();
|
const val = pair.slice(1).join(':').trim();
|
||||||
res[1] = res.slice(1).join(':').trim();
|
return _.camelCase(pair[0].trim()) + ' : ' + convertText(node, context, val.trim())
|
||||||
return res;
|
//return stringUtils.convertToCamelCase(pair[0].trim()) + ' : ' + convertText(node, context, val.trim())
|
||||||
}));
|
})
|
||||||
var styleArray = _.map(styleParts, function (stylePart) {
|
.join(',');
|
||||||
return stringUtils.convertToCamelCase(stylePart[0]) + ' : ' + convertText(node, context, stylePart[1].trim());
|
return `{${styleStr}}`;
|
||||||
});
|
|
||||||
return '{' + styleArray.join(',') + '}';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -288,7 +294,7 @@ function convertTagNameToConstructor(tagName, context) {
|
|||||||
var isHtmlTag = _.includes(reactDOMSupport[context.options.targetVersion], tagName);
|
var isHtmlTag = _.includes(reactDOMSupport[context.options.targetVersion], tagName);
|
||||||
if (reactSupport.shouldUseCreateElement(context)) {
|
if (reactSupport.shouldUseCreateElement(context)) {
|
||||||
isHtmlTag = isHtmlTag || tagName.match(/^\w+(-\w+)$/);
|
isHtmlTag = isHtmlTag || tagName.match(/^\w+(-\w+)$/);
|
||||||
return isHtmlTag ? "'" + tagName + "'" : tagName;
|
return isHtmlTag ? `'${tagName}'` : tagName;
|
||||||
}
|
}
|
||||||
return isHtmlTag ? 'React.DOM.' + tagName : tagName;
|
return isHtmlTag ? 'React.DOM.' + tagName : tagName;
|
||||||
}
|
}
|
||||||
@ -312,9 +318,7 @@ function defaultContext(html, options) {
|
|||||||
* @return {boolean}
|
* @return {boolean}
|
||||||
*/
|
*/
|
||||||
function hasNonSimpleChildren(node) {
|
function hasNonSimpleChildren(node) {
|
||||||
return _.some(node.children, function (child) {
|
return _.some(node.children, child => child.type === 'tag' && child.attribs[repeatAttr]);
|
||||||
return child.type === 'tag' && child.attribs[repeatAttr];
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -338,14 +342,14 @@ function convertHtmlToReact(node, context) {
|
|||||||
if (node.attribs[repeatAttr]) {
|
if (node.attribs[repeatAttr]) {
|
||||||
var arr = node.attribs[repeatAttr].split(' in ');
|
var arr = node.attribs[repeatAttr].split(' in ');
|
||||||
if (arr.length !== 2) {
|
if (arr.length !== 2) {
|
||||||
throw RTCodeError.buildFormat(context, node, "rt-repeat invalid 'in' expression '%s'", node.attribs[repeatAttr]);
|
throw RTCodeError.build(context, node, `rt-repeat invalid 'in' expression '${node.attribs[repeatAttr]}'`);
|
||||||
}
|
}
|
||||||
data.item = arr[0].trim();
|
data.item = arr[0].trim();
|
||||||
data.collection = arr[1].trim();
|
data.collection = arr[1].trim();
|
||||||
validateJS(data.item, node, context);
|
validateJS(data.item, node, context);
|
||||||
validateJS(data.collection, node, context);
|
validateJS(data.collection, node, context);
|
||||||
stringUtils.addIfMissing(context.boundParams, data.item);
|
stringUtils.addIfMissing(context.boundParams, data.item);
|
||||||
stringUtils.addIfMissing(context.boundParams, data.item + 'Index');
|
stringUtils.addIfMissing(context.boundParams, `${data.item}Index`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.attribs[scopeAttr]) {
|
if (node.attribs[scopeAttr]) {
|
||||||
@ -371,27 +375,32 @@ function convertHtmlToReact(node, context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data.children = utils.concatChildren(_.map(node.children, function (child) {
|
var children = _.map(node.children, function (child) {
|
||||||
var code = convertHtmlToReact(child, context);
|
var code = convertHtmlToReact(child, context);
|
||||||
validateJS(code, child, context);
|
validateJS(code, child, context);
|
||||||
return code;
|
return code;
|
||||||
}));
|
});
|
||||||
|
|
||||||
data.body = _.template(getTagTemplateString(!hasNonSimpleChildren(node), reactSupport.shouldUseCreateElement(context)))(data);
|
data.children = utils.concatChildren(children);
|
||||||
|
|
||||||
|
if (node.name === virtualNode) { //eslint-disable-line wix-editor/prefer-ternary
|
||||||
|
data.body = "[" + _.compact(children).join(',') + "]"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data.body = _.template(getTagTemplateString(!hasNonSimpleChildren(node), reactSupport.shouldUseCreateElement(context)))(data);
|
||||||
|
}
|
||||||
|
|
||||||
if (node.attribs[scopeAttr]) {
|
if (node.attribs[scopeAttr]) {
|
||||||
var functionBody = _.values(data.innerScope.innerMapping).join('\n') + 'return ' + data.body;
|
var functionBody = _.values(data.innerScope.innerMapping).join('\n') + `return ${data.body}`;
|
||||||
var generatedFuncName = generateInjectedFunc(context, 'scope' + data.innerScope.scopeName, functionBody, _.keys(data.innerScope.outerMapping));
|
var generatedFuncName = generateInjectedFunc(context, 'scope' + data.innerScope.scopeName, functionBody, _.keys(data.innerScope.outerMapping));
|
||||||
data.body = util.format('%s.apply(this, [%s])', generatedFuncName, _.values(data.innerScope.outerMapping).join(','));
|
data.body = `${generatedFuncName}.apply(this, [${_.values(data.innerScope.outerMapping).join(',')}])`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Order matters here. Each rt-repeat iteration wraps over the rt-scope, so
|
// Order matters here. Each rt-repeat iteration wraps over the rt-scope, so
|
||||||
// the scope variables are evaluated in context of the current iteration.
|
// the scope variables are evaluated in context of the current iteration.
|
||||||
if (node.attribs[repeatAttr]) {
|
if (node.attribs[repeatAttr]) {
|
||||||
data.repeatFunction = generateInjectedFunc(context, 'repeat' + stringUtils.capitalize(data.item), 'return ' + data.body);
|
data.repeatFunction = generateInjectedFunc(context, 'repeat' + _.capitalize(data.item), 'return ' + data.body);
|
||||||
data.repeatBinds = ['this'].concat(_.reject(context.boundParams, function (param) {
|
data.repeatBinds = ['this'].concat(_.reject(context.boundParams, p => p === data.item || p === data.item + 'Index' || data.innerScope && p in data.innerScope.innerMapping));
|
||||||
return param === data.item || param === data.item + 'Index' || data.innerScope && param in data.innerScope.innerMapping;
|
|
||||||
}));
|
|
||||||
data.body = repeatTemplate(data);
|
data.body = repeatTemplate(data);
|
||||||
}
|
}
|
||||||
if (node.attribs[ifAttr]) {
|
if (node.attribs[ifAttr]) {
|
||||||
@ -401,10 +410,7 @@ function convertHtmlToReact(node, context) {
|
|||||||
} else if (node.type === 'comment') {
|
} else if (node.type === 'comment') {
|
||||||
return commentTemplate(node);
|
return commentTemplate(node);
|
||||||
} else if (node.type === 'text') {
|
} else if (node.type === 'text') {
|
||||||
if (node.data.trim()) {
|
return node.data.trim() ? convertText(node, context, node.data) : '';
|
||||||
return convertText(node, context, node.data);
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -417,10 +423,10 @@ function handleScopeAttribute(node, context, data) {
|
|||||||
|
|
||||||
data.innerScope.outerMapping = _.zipObject(context.boundParams, context.boundParams);
|
data.innerScope.outerMapping = _.zipObject(context.boundParams, context.boundParams);
|
||||||
|
|
||||||
_(node.attribs[scopeAttr]).split(';').invoke('trim').compact().forEach(function (scopePart) {
|
_(node.attribs[scopeAttr]).split(';').invoke('trim').compact().forEach(scopePart => { //eslint-disable-line lodash3/collection-return
|
||||||
var scopeSubParts = _(scopePart).split(' as ').invoke('trim').value();
|
var scopeSubParts = _(scopePart).split(' as ').invoke('trim').value();
|
||||||
if (scopeSubParts.length < 2) {
|
if (scopeSubParts.length < 2) {
|
||||||
throw RTCodeError.buildFormat(context, node, "invalid scope part '%s'", scopePart);
|
throw RTCodeError.build(context, node, `invalid scope part '${scopePart}'`);
|
||||||
}
|
}
|
||||||
var alias = scopeSubParts[1];
|
var alias = scopeSubParts[1];
|
||||||
var value = scopeSubParts[0];
|
var value = scopeSubParts[0];
|
||||||
@ -431,8 +437,8 @@ function handleScopeAttribute(node, context, data) {
|
|||||||
// function call, as with the ones we generate for rt-scope.
|
// function call, as with the ones we generate for rt-scope.
|
||||||
stringUtils.addIfMissing(context.boundParams, alias);
|
stringUtils.addIfMissing(context.boundParams, alias);
|
||||||
|
|
||||||
data.innerScope.scopeName += stringUtils.capitalize(alias);
|
data.innerScope.scopeName += _.capitalize(alias);
|
||||||
data.innerScope.innerMapping[alias] = 'var ' + alias + ' = ' + value + ';';
|
data.innerScope.innerMapping[alias] = `var ${alias} = ${value};`;
|
||||||
validateJS(data.innerScope.innerMapping[alias], node, context);
|
validateJS(data.innerScope.innerMapping[alias], node, context);
|
||||||
}).value();
|
}).value();
|
||||||
}
|
}
|
||||||
@ -445,8 +451,7 @@ function validateIfAttribute(node, context, data) {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new RTCodeError(e.message, e.index, -1);
|
throw new RTCodeError(e.message, e.index, -1);
|
||||||
}
|
}
|
||||||
if (ifAttributeTree && ifAttributeTree.body && ifAttributeTree.body.length === 1 &&
|
if (ifAttributeTree && ifAttributeTree.body && ifAttributeTree.body.length === 1 && ifAttributeTree.body[0].type === 'ExpressionStatement') {
|
||||||
ifAttributeTree.body[0].type === 'ExpressionStatement') {
|
|
||||||
// make sure that rt-if does not use an inner mapping
|
// make sure that rt-if does not use an inner mapping
|
||||||
if (ifAttributeTree.body[0].expression && utils.usesScopeName(innerMappingKeys, ifAttributeTree.body[0].expression)) {
|
if (ifAttributeTree.body[0].expression && utils.usesScopeName(innerMappingKeys, ifAttributeTree.body[0].expression)) {
|
||||||
throw RTCodeError.buildFormat(context, node, "invalid scope mapping used in if part '%s'", node.attribs[ifAttr]);
|
throw RTCodeError.buildFormat(context, node, "invalid scope mapping used in if part '%s'", node.attribs[ifAttr]);
|
||||||
@ -471,9 +476,7 @@ function handleSelfClosingHtmlTags(nodes) {
|
|||||||
node.children = handleSelfClosingHtmlTags(node.children);
|
node.children = handleSelfClosingHtmlTags(node.children);
|
||||||
if (node.type === 'tag' && _.includes(reactSupport.htmlSelfClosingTags, node.name)) {
|
if (node.type === 'tag' && _.includes(reactSupport.htmlSelfClosingTags, node.name)) {
|
||||||
externalNodes = _.filter(node.children, isTag);
|
externalNodes = _.filter(node.children, isTag);
|
||||||
_.forEach(externalNodes, function (child) {
|
_.forEach(externalNodes, i => i.parent = node);
|
||||||
child.parent = node;
|
|
||||||
});
|
|
||||||
node.children = _.reject(node.children, isTag);
|
node.children = _.reject(node.children, isTag);
|
||||||
}
|
}
|
||||||
return [node].concat(externalNodes);
|
return [node].concat(externalNodes);
|
||||||
@ -490,7 +493,7 @@ function convertTemplateToReact(html, options) {
|
|||||||
/**
|
/**
|
||||||
* @param {string} html
|
* @param {string} html
|
||||||
* @param {CONTEXT} reportContext
|
* @param {CONTEXT} reportContext
|
||||||
* @param {{modules:string,defines:*}?} options
|
* @param {Options?} options
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
function convertRT(html, reportContext, options) {
|
function convertRT(html, reportContext, options) {
|
||||||
@ -511,46 +514,41 @@ function convertRT(html, reportContext, options) {
|
|||||||
throw new RTCodeError('Document should have a root element');
|
throw new RTCodeError('Document should have a root element');
|
||||||
}
|
}
|
||||||
var firstTag = null;
|
var firstTag = null;
|
||||||
_.forEach(rootTags, function (tag) {
|
_.forEach(rootTags, function (tag) { //eslint-disable-line lodash3/collection-return
|
||||||
if (tag.name === 'rt-require') {
|
if (tag.name === 'rt-require') {
|
||||||
if (!tag.attribs.dependency || !tag.attribs.as) {
|
if (!tag.attribs.dependency || !tag.attribs.as) {
|
||||||
throw RTCodeError.build("rt-require needs 'dependency' and 'as' attributes", context, tag);
|
throw RTCodeError.build(context, tag, "rt-require needs 'dependency' and 'as' attributes");
|
||||||
} else if (tag.children.length) {
|
} else if (tag.children.length) {
|
||||||
throw RTCodeError.build('rt-require may have no children', context, tag);
|
throw RTCodeError.build(context, tag, 'rt-require may have no children');
|
||||||
}
|
}
|
||||||
defines[tag.attribs.dependency] = tag.attribs.as;
|
defines[tag.attribs.dependency] = tag.attribs.as;
|
||||||
} else if (firstTag === null) {
|
} else if (firstTag === null) {
|
||||||
firstTag = tag;
|
firstTag = tag;
|
||||||
} else {
|
} else {
|
||||||
throw RTCodeError.build('Document should have no more than a single root element', context, tag);
|
throw RTCodeError.build(context, tag, 'Document should have no more than a single root element');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (firstTag === null) {
|
if (firstTag === null) {
|
||||||
throw RTCodeError.build('Document should have a single root element', context, rootNode.root()[0]);
|
throw RTCodeError.build(context, rootNode.root()[0], 'Document should have a single root element');
|
||||||
|
} else if (firstTag.name === virtualNode) {
|
||||||
|
throw RTCodeError.build(context, firstTag, `Document should not have <${virtualNode}> as root element`);
|
||||||
}
|
}
|
||||||
var body = convertHtmlToReact(firstTag, context);
|
var body = convertHtmlToReact(firstTag, context);
|
||||||
var requirePaths = _(defines)
|
var requirePaths = _(defines)
|
||||||
.keys()
|
.keys()
|
||||||
.map(function (reqName) { return '"' + reqName + '"'; })
|
.map(def => `"${def}"`)
|
||||||
.join(',');
|
.join(',');
|
||||||
var requireVars = _.values(defines).join(',');
|
var buildImport;
|
||||||
var buildImportString;
|
|
||||||
if (options.modules === 'typescript') {
|
if (options.modules === 'typescript') {
|
||||||
buildImportString = "import %s = require('%s');";
|
buildImport = (v, p) => `import ${v} = require('${p}');`;
|
||||||
} else if (options.modules === 'es6') { // eslint-disable-line
|
} else if (options.modules === 'es6') { // eslint-disable-line
|
||||||
buildImportString = "import %s from '%s';";
|
buildImport = (v, p) => `import ${v} from '${p}';`
|
||||||
} else {
|
} else {
|
||||||
buildImportString = "var %s = require('%s');";
|
buildImport = (v, p) => `var ${v} = require('${p}');`
|
||||||
}
|
}
|
||||||
var vars = _(defines).map(function (reqVar, reqPath) {
|
const header = options.flow ? '/* @flow */\n' : '';
|
||||||
return util.format(buildImportString, reqVar, reqPath);
|
const vars = header + _(defines).map(buildImport).join('\n');
|
||||||
}).join('\n');
|
var data = {body, injectedFunctions: context.injectedFunctions.join('\n'), requireNames: _.values(defines).join(','), requirePaths, vars, name: options.name};
|
||||||
|
|
||||||
if (options.flow) {
|
|
||||||
vars = '/* @flow */\n' + vars;
|
|
||||||
}
|
|
||||||
var data = {body: body, injectedFunctions: '', requireNames: requireVars, requirePaths: requirePaths, vars: vars, name: options.name};
|
|
||||||
data.injectedFunctions = context.injectedFunctions.join('\n');
|
|
||||||
var code = generate(data, options);
|
var code = generate(data, options);
|
||||||
if (options.modules !== 'typescript' && options.modules !== 'jsrt') {
|
if (options.modules !== 'typescript' && options.modules !== 'jsrt') {
|
||||||
code = parseJS(code);
|
code = parseJS(code);
|
||||||
@ -572,9 +570,7 @@ function convertJSRTToJS(text, reportContext, options) {
|
|||||||
options = getOptions(options);
|
options = getOptions(options);
|
||||||
options.modules = 'jsrt';
|
options.modules = 'jsrt';
|
||||||
var templateMatcherJSRT = /<template>([^]*?)<\/template>/gm;
|
var templateMatcherJSRT = /<template>([^]*?)<\/template>/gm;
|
||||||
var code = text.replace(templateMatcherJSRT, function (template, html) {
|
var code = text.replace(templateMatcherJSRT, (template, html) => convertRT(html, reportContext, options).replace(/;$/, ''));
|
||||||
return convertRT(html, reportContext, options).replace(/;$/, '');
|
|
||||||
});
|
|
||||||
code = parseJS(code);
|
code = parseJS(code);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,10 @@ var rtnData = require('./rt-style-support-data.js');
|
|||||||
|
|
||||||
|
|
||||||
var templateCommonJSTemplate = _.template(
|
var templateCommonJSTemplate = _.template(
|
||||||
"'use strict';\n" +
|
`'use strict';
|
||||||
'var style = <%= body %>;\n' +
|
var style = <%= body %>;
|
||||||
'module.exports = style;\n'
|
module.exports = style;
|
||||||
);
|
`);
|
||||||
|
|
||||||
function convert(text) {
|
function convert(text) {
|
||||||
return templateCommonJSTemplate({body: convertBody(text)});
|
return templateCommonJSTemplate({body: convertBody(text)});
|
||||||
@ -31,7 +31,7 @@ function processRule2(result, rule) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function processDeclaration(result, dec) {
|
function processDeclaration(result, dec) {
|
||||||
var prop = stringUtils.convertToCamelCase(dec.property);
|
var prop = _.camelCase(dec.property);
|
||||||
result[prop] = convertValue(prop, dec.value);
|
result[prop] = convertValue(prop, dec.value);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
16
src/shell.js
16
src/shell.js
@ -1,22 +1,16 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param {CONTEXT} context
|
||||||
* @return {number}
|
* @return {number}
|
||||||
*/
|
*/
|
||||||
function printResults(context) {
|
function printResults(context) {
|
||||||
var _ = require('lodash');
|
|
||||||
// var wfs = require('./wfs');
|
|
||||||
var warnings = context.getMessages();
|
var warnings = context.getMessages();
|
||||||
var out = require('./formatters/' + context.options.format)(warnings);
|
var out = require(`./formatters/${context.options.format}`)(warnings);
|
||||||
// if (context.options.outFile) {
|
|
||||||
// wfs.file.write(context.options.outFile, out);
|
|
||||||
// } else {
|
|
||||||
// context.report(out);
|
|
||||||
// }
|
|
||||||
context.report(out);
|
context.report(out);
|
||||||
var grouped = _.groupBy(warnings, 'level');
|
var grouped = _.groupBy(warnings, 'level');
|
||||||
return grouped.ERROR ? grouped.ERROR.length : 0;
|
return grouped.ERROR ? grouped.ERROR.length : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {printResults};
|
||||||
printResults: printResults
|
|
||||||
};
|
|
||||||
|
@ -1,22 +1,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} str
|
|
||||||
* @return {string}
|
|
||||||
*/
|
|
||||||
function convertToCamelCase(str) {
|
|
||||||
return str.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} str
|
|
||||||
* @return {string}
|
|
||||||
*/
|
|
||||||
function capitalize(str) {
|
|
||||||
return str[0].toUpperCase() + str.slice(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Array.<*>} array
|
* @param {Array.<*>} array
|
||||||
* @param {*} obj
|
* @param {*} obj
|
||||||
@ -27,8 +11,4 @@ function addIfMissing(array, obj) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {addIfMissing};
|
||||||
convertToCamelCase: convertToCamelCase,
|
|
||||||
capitalize: capitalize,
|
|
||||||
addIfMissing: addIfMissing
|
|
||||||
};
|
|
||||||
|
25
src/utils.js
25
src/utils.js
@ -13,7 +13,7 @@ function validateJS(code, node, context) {
|
|||||||
try {
|
try {
|
||||||
esprima.parse(code);
|
esprima.parse(code);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw RTCodeError.build(e.description, context, node);
|
throw RTCodeError.build(context, node, e.description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,6 +35,16 @@ function isStringOnlyCode(txt) {
|
|||||||
//return txt.length && txt.charAt(0) === '{' && txt.charAt(txt.length - 1) === '}';
|
//return txt.length && txt.charAt(0) === '{' && txt.charAt(txt.length - 1) === '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Array.<*>} array
|
||||||
|
* @param {*} obj
|
||||||
|
*/
|
||||||
|
function addIfMissing(array, obj) {
|
||||||
|
if (!_.includes(array, obj)) {
|
||||||
|
array.push(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Array.<string>} children
|
* @param {Array.<string>} children
|
||||||
* @return {string}
|
* @return {string}
|
||||||
@ -115,10 +125,11 @@ function usesScopeName(scopeNames, node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
usesScopeName: usesScopeName,
|
usesScopeName,
|
||||||
normalizeName: normalizeName,
|
normalizeName,
|
||||||
validateJS: validateJS,
|
validateJS,
|
||||||
isStringOnlyCode: isStringOnlyCode,
|
isStringOnlyCode,
|
||||||
concatChildren: concatChildren,
|
concatChildren,
|
||||||
validate: validate
|
validate,
|
||||||
|
addIfMissing
|
||||||
};
|
};
|
||||||
|
3
test/data/invalid-virtual.rt
Normal file
3
test/data/invalid-virtual.rt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<rt-virtual>
|
||||||
|
<div>This is not allowed</div>
|
||||||
|
</rt-virtual>
|
14
test/data/virtual.rt
Normal file
14
test/data/virtual.rt
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<div>
|
||||||
|
<rt-virtual rt-scope="'rendered' as verb">
|
||||||
|
<rt-virtual rt-if="1<0">
|
||||||
|
<div>this is not {verb}</div>
|
||||||
|
</rt-virtual>
|
||||||
|
<rt-virtual rt-if="1>0">
|
||||||
|
<div>this is {verb}</div>
|
||||||
|
</rt-virtual>
|
||||||
|
<rt-virtual rt-repeat="n in [1,2]">
|
||||||
|
<div>{verb} {n}-a</div>
|
||||||
|
<div>{verb} {n}-b</div>
|
||||||
|
</rt-virtual>
|
||||||
|
</rt-virtual>
|
||||||
|
</div>
|
1
test/data/virtual.rt.html
Normal file
1
test/data/virtual.rt.html
Normal file
@ -0,0 +1 @@
|
|||||||
|
<div><div>this is rendered</div><div>rendered 1-a</div><div>rendered 1-b</div><div>rendered 2-a</div><div>rendered 2-b</div></div>
|
@ -26,7 +26,8 @@ var invalidFiles = [
|
|||||||
{file: 'invalid-repeat.rt', issue: new RTCodeError('rt-repeat invalid \'in\' expression \'a in b in c\'', 0, 35, 1, 1)},
|
{file: 'invalid-repeat.rt', issue: new RTCodeError('rt-repeat invalid \'in\' expression \'a in b in c\'', 0, 35, 1, 1)},
|
||||||
{file: 'invalid-rt-require.rt', issue: new RTCodeError("rt-require needs 'dependency' and 'as' attributes", 0, 14, 1, 1)},
|
{file: 'invalid-rt-require.rt', issue: new RTCodeError("rt-require needs 'dependency' and 'as' attributes", 0, 14, 1, 1)},
|
||||||
{file: 'invalid-brace.rt', issue: new RTCodeError('Unexpected end of input', 128, 163, 5, 11)},
|
{file: 'invalid-brace.rt', issue: new RTCodeError('Unexpected end of input', 128, 163, 5, 11)},
|
||||||
{file: 'invalid-style.rt', issue: new RTCodeError('Unexpected token ILLEGAL', 10, 39, 2, 5)}
|
{file: 'invalid-style.rt', issue: new RTCodeError('Unexpected token ILLEGAL', 10, 39, 2, 5)},
|
||||||
|
{file: 'invalid-virtual.rt', issue: new RTCodeError('Document should not have <rt-virtual> as root element', 0, 60, 1, 1)}
|
||||||
];
|
];
|
||||||
|
|
||||||
test('invalid tests', function (t) {
|
test('invalid tests', function (t) {
|
||||||
@ -183,7 +184,7 @@ test('convert jsrt and test source results', function (t) {
|
|||||||
|
|
||||||
test('html tests', function (t) {
|
test('html tests', function (t) {
|
||||||
var files = ['scope.rt', 'scope-trailing-semicolon.rt', 'scope-variable-references.rt', 'lambda.rt', 'eval.rt', 'props.rt', 'custom-element.rt', 'style.rt', 'concat.rt',
|
var files = ['scope.rt', 'scope-trailing-semicolon.rt', 'scope-variable-references.rt', 'lambda.rt', 'eval.rt', 'props.rt', 'custom-element.rt', 'style.rt', 'concat.rt',
|
||||||
'js-in-attr.rt', 'props-class.rt', 'rt-class.rt', 'className.rt', 'svg.rt',
|
'js-in-attr.rt', 'props-class.rt', 'rt-class.rt', 'className.rt', 'svg.rt', 'virtual.rt',
|
||||||
'scope-evaluated-after-repeat.rt', 'scope-evaluated-after-repeat2.rt', 'scope-evaluated-after-if.rt', 'scope-obj.rt'
|
'scope-evaluated-after-repeat.rt', 'scope-evaluated-after-repeat2.rt', 'scope-evaluated-after-if.rt', 'scope-obj.rt'
|
||||||
];
|
];
|
||||||
t.plan(files.length);
|
t.plan(files.length);
|
||||||
@ -228,9 +229,7 @@ test('test shell', function (t) {
|
|||||||
var newContext = _.cloneDeep(context);
|
var newContext = _.cloneDeep(context);
|
||||||
var outputJSON = '';
|
var outputJSON = '';
|
||||||
newContext.options.format = 'json';
|
newContext.options.format = 'json';
|
||||||
newContext.report = function (text) {
|
newContext.report = function (text) { outputJSON = text; };
|
||||||
outputJSON = text;
|
|
||||||
};
|
|
||||||
var r = shell.printResults(newContext);
|
var r = shell.printResults(newContext);
|
||||||
t.equal(r, 0);
|
t.equal(r, 0);
|
||||||
context.error('hi', '', 1, 1);
|
context.error('hi', '', 1, 1);
|
||||||
@ -245,7 +244,7 @@ test('test shell', function (t) {
|
|||||||
test('test shell', function (t) {
|
test('test shell', function (t) {
|
||||||
var filename = path.join(dataPath, 'div.rt');
|
var filename = path.join(dataPath, 'div.rt');
|
||||||
var cli = require('../../src/cli');
|
var cli = require('../../src/cli');
|
||||||
var r = cli.execute(filename + ' -r --dry-run');
|
var r = cli.execute(`${filename} -r --dry-run`);
|
||||||
t.equal(r, 0);
|
t.equal(r, 0);
|
||||||
t.end();
|
t.end();
|
||||||
});
|
});
|
||||||
|
@ -65,9 +65,7 @@ function codeToHtml(code) {
|
|||||||
var defineMap = {'react/addons': React, lodash: _};
|
var defineMap = {'react/addons': React, lodash: _};
|
||||||
//noinspection JSUnusedLocalSymbols
|
//noinspection JSUnusedLocalSymbols
|
||||||
var define = function (requirementsNames, content) { //eslint-disable-line no-unused-vars,func-style
|
var define = function (requirementsNames, content) { //eslint-disable-line no-unused-vars,func-style
|
||||||
var requirements = _.map(requirementsNames, function (reqName) {
|
var requirements = _.map(requirementsNames, reqName => defineMap[reqName]);
|
||||||
return defineMap[reqName];
|
|
||||||
});
|
|
||||||
return content.apply(this, requirements);
|
return content.apply(this, requirements);
|
||||||
};
|
};
|
||||||
var comp = React.createFactory(React.createClass({
|
var comp = React.createFactory(React.createClass({
|
||||||
|
Loading…
x
Reference in New Issue
Block a user