From 979cc0ddb80283eb7e5b17588a87fbaa854df390 Mon Sep 17 00:00:00 2001 From: Avi Marcus Date: Wed, 12 Nov 2014 10:48:22 +0200 Subject: [PATCH] removed superfluous flattens, made generated code look almost like what hand crafted code would look like --- src/reactTemplates.js | 21 ++++++++++++----- test/data/div.rt.js | 4 ++-- test/data/repeat.rt.js | 19 ++++++++------- test/data/test.rt.js | 52 +++++++++++++++++++----------------------- test/src/test.js | 10 ++++---- 5 files changed, 57 insertions(+), 49 deletions(-) diff --git a/src/reactTemplates.js b/src/reactTemplates.js index a7de380..1b8da03 100644 --- a/src/reactTemplates.js +++ b/src/reactTemplates.js @@ -13,7 +13,8 @@ var fs = require('fs'); var repeatTemplate = _.template('_.map(<%= collection %>,<%= repeatFunction %>.bind(<%= repeatBinds %>))'); var ifTemplate = _.template('((<%= condition %>)?(<%= body %>):null)'); var classSetTemplate = _.template('React.addons.classSet(<%= classSet %>)'); -var tagTemplate = _.template('<%= name %>.apply(this,_.flatten([<%= props %>].concat([<%= children %>])))'); +var simpleTagTemplate = _.template('<%= name %>(<%= props %><%= children %>)'); +var tagTemplate = _.template('<%= name %>.apply(this,_.flatten([<%= props %><%= children %>]))'); var commentTemplate = _.template(' /* <%= data %> */ '); var templateTemplate = _.template("define([<%= requirePaths %>], function (<%= requireNames %>) {\n'use strict';\n <%= injectedFunctions %>\nreturn function(){ return <%= body %>};\n});"); @@ -33,11 +34,9 @@ _.forEach(reactSupportedAttributes,function (attributeReactName) { function concatChildren(children) { var res = ''; - var first = true; _.forEach(children, function (child) { if (child.indexOf(' /*') !== 0 && child) { - res += (first ? '' : ',') + child; - first = false; + res += ',' + child; } else { res += child; } @@ -165,6 +164,12 @@ function addIfNotThere(array, obj) { } } +function hasNonSimpleChildren(node) { + return _.any(node.children,function (child) { + return child.type === 'tag' && child.attribs[templateProp]; + }); +} + function convertHtmlToReact(node, context) { if (node.type === 'tag') { context = { @@ -193,7 +198,11 @@ function convertHtmlToReact(node, context) { return convertHtmlToReact(child, context); })); - data.body = tagTemplate(data); + if (hasNonSimpleChildren(node)) { + data.body = tagTemplate(data); + } else { + data.body = simpleTagTemplate(data); + } if (node.attribs[templateProp]) { data.repeatFunction = generateInjectedFunc(context,"repeat"+capitalize(data.item),"return "+data.body); @@ -295,4 +304,4 @@ module.exports = { convertTemplateToReact: convertTemplateToReact, convertFile: convertFile, _test: {} -}; \ No newline at end of file +}; diff --git a/test/data/div.rt.js b/test/data/div.rt.js index 7a36e77..9ff92d3 100644 --- a/test/data/div.rt.js +++ b/test/data/div.rt.js @@ -4,6 +4,6 @@ define([ ], function (React, _) { 'use strict'; return function () { - return React.DOM.div.apply(this, _.flatten([{}].concat([]))); + return React.DOM.div({}); }; -}); \ No newline at end of file +}); diff --git a/test/data/repeat.rt.js b/test/data/repeat.rt.js index ec5272e..d848ffb 100644 --- a/test/data/repeat.rt.js +++ b/test/data/repeat.rt.js @@ -8,15 +8,18 @@ define([ return false; } function repeatItems2(items, itemsIndex) { - return React.DOM.div.apply(this, _.flatten([{}].concat([React.DOM.span.apply(this, _.flatten([{ - 'style': { - width: 'auto', - lineHeight: '5px' - }, - 'onClick': onClick1.bind(this, items, itemsIndex) - }].concat(['Mock'])))]))); + return React.DOM.div({}, React.DOM.span({ + 'style': { + width: 'auto', + lineHeight: '5px' + }, + 'onClick': onClick1.bind(this, items, itemsIndex) + }, 'Mock')); } return function () { - return React.DOM.p.apply(this, _.flatten([{}].concat([_.map(this.props.things, repeatItems2.bind(this))]))); + return React.DOM.p.apply(this, _.flatten([ + {}, + _.map(this.props.things, repeatItems2.bind(this)) + ])); }; }); \ No newline at end of file diff --git a/test/data/test.rt.js b/test/data/test.rt.js index 0adc4cb..226cd77 100644 --- a/test/data/test.rt.js +++ b/test/data/test.rt.js @@ -4,33 +4,27 @@ define([ ], function (React, _) { 'use strict'; return function () { - return React.DOM.div.apply(this, _.flatten([{}].concat([ - React.DOM.div.apply(this, _.flatten([{ - 'style': { - position: 'relative', - textAlign: 'center', - top: this.props.config.previewTop, - height: this.props.config.previewHeight - } - }].concat([React.DOM.div.apply(this, _.flatten([{ - 'style': { - margin: 'auto', - height: '100%', - width: this.props.config.previewWidth || '100%' - } - }].concat([React.DOM.iframe.apply(this, _.flatten([{ - 'id': 'preview', - 'src': 'http://localhost/sites/412?ds=true', - 'style': { - width: '100%', - height: '100%', - border: '0' - } - }].concat([])))])))]))), - React.DOM.div.apply(this, _.flatten([{}].concat([ - 'editor', - !this.props.editorState.previewMode ? React.DOM.div.apply(this, _.flatten([{}].concat(['left bar']))) : null - ]))) - ]))); + return React.DOM.div({}, React.DOM.div({ + 'style': { + position: 'relative', + textAlign: 'center', + top: this.props.config.previewTop, + height: this.props.config.previewHeight + } + }, React.DOM.div({ + 'style': { + margin: 'auto', + height: '100%', + width: this.props.config.previewWidth || '100%' + } + }, React.DOM.iframe({ + 'id': 'preview', + 'src': 'http://localhost/sites/412?ds=true', + 'style': { + width: '100%', + height: '100%', + border: '0' + } + }))), React.DOM.div({}, 'editor', !this.props.editorState.previewMode ? React.DOM.div({}, 'left bar') : null)); }; -}); \ No newline at end of file +}); diff --git a/test/src/test.js b/test/src/test.js index 3d6772e..7588b36 100644 --- a/test/src/test.js +++ b/test/src/test.js @@ -18,9 +18,9 @@ test('conversion test', function (t) { function check(testFile) { var filename = path.join(dataPath, testFile); var html = fs.readFileSync(filename).toString(); - var expected = fs.readFileSync(filename + '.js').toString().replace(/\r/g,""); + var expected = fs.readFileSync(filename + '.js').toString().replace(/\r/g,"").trim(); // var expected = fs.readFileSync(filename.replace(".html", ".js")).toString(); - var actual = reactTemplates.convertTemplateToReact(html).replace(/\r/g,""); + var actual = reactTemplates.convertTemplateToReact(html).replace(/\r/g,"").trim(); t.equal(actual, expected); if (actual !== expected) { fs.writeFileSync(filename + '.actual.js', actual); @@ -29,7 +29,10 @@ test('conversion test', function (t) { }); function normalizeHtml(html) { - return cheerio.load(html,{normalizeWhitespace:true}).html().replace(/\>\s+\<"); + return cheerio.load(html,{normalizeWhitespace:true}).html() + .replace(/\>\s+/mg,">") + .replace(/\s+\\s+\<"); } test('html tests', function (t) { @@ -88,4 +91,3 @@ test('util.isStale', function (t) { fs.unlinkSync(a); fs.unlinkSync(b); }); -