Merge branch 'scope-variable-references' of https://github.com/anchann/react-templates into anchann-scope-variable-references

This commit is contained in:
ido 2015-07-30 13:40:39 +03:00
commit 3415de3661
5 changed files with 44 additions and 8 deletions

1
.gitignore vendored
View File

@ -22,3 +22,4 @@ npm-debug.log
### Test Output ###
test/data/*.rt.actual.js
test/data/*.code.js

View File

@ -297,11 +297,17 @@ function convertHtmlToReact(node, context) {
var data = {name: convertTagNameToConstructor(node.name, context)};
if (node.attribs[scopeAttr]) {
data.scopeMapping = {};
//data.scopeMapping = {};
data.scopeName = '';
// these are variables that were already in scope, unrelated to the ones declared in rt-scope
data.outerScopeMapping = {};
_.each(context.boundParams, function (boundParam) {
data.scopeMapping[boundParam] = boundParam;
data.outerScopeMapping[boundParam] = boundParam;
});
// these are variables declared in the rt-scope attribute
data.innerScopeMapping = {};
_.each(node.attribs[scopeAttr].split(';'), function (scopePart) {
if (scopePart.trim().length === 0) {
return;
@ -313,10 +319,15 @@ function convertHtmlToReact(node, context) {
}
var scopeName = scopeSubParts[1].trim();
validateJS(scopeName, node, context);
// this adds both parameters to the list of parameters passed further down
// the scope chain, as well as variables that are locally bound before any
// function call, as with the ones we generate for rt-scope.
stringUtils.addIfMissing(context.boundParams, scopeName);
data.scopeName += stringUtils.capitalize(scopeName);
data.scopeMapping[scopeName] = scopeSubParts[0].trim();
validateJS(data.scopeMapping[scopeName], node, context);
data.innerScopeMapping[scopeName] = scopeSubParts[0].trim();
validateJS(data.innerScopeMapping[scopeName], node, context);
});
}
@ -372,8 +383,13 @@ function convertHtmlToReact(node, context) {
data.body = ifTemplate(data);
}
if (node.attribs[scopeAttr]) {
var generatedFuncName = generateInjectedFunc(context, 'scope' + data.scopeName, 'return ' + data.body, _.keys(data.scopeMapping));
data.body = generatedFuncName + '.apply(this, [' + _.values(data.scopeMapping).join(',') + '])';
var scopeVarDeclarations = _.reduce(data.innerScopeMapping, function(acc, rightHandSide, leftHandSide) {
var declaration = "var " + leftHandSide + " = " + rightHandSide + ";"
return acc + declaration;
}, "");
var functionBody = scopeVarDeclarations + 'return ' + data.body;
var generatedFuncName = generateInjectedFunc(context, 'scope' + data.scopeName, functionBody, _.keys(data.outerScopeMapping));
data.body = generatedFuncName + '.apply(this, [' + _.values(data.outerScopeMapping).join(',') + '])';
}
return data.body;
} else if (node.type === 'comment') {

View File

@ -0,0 +1,11 @@
<div>
<div rt-repeat="foo in [1]">
<!-- can't seem to have an object literal here; will deal with this separately -->
<div rt-scope="[{first: 'Jack', last: 'Sparrow', skills: ['talking', 'fighting', 'commandeering']}][0] as pirate; pirate.first as first">
<h1>{first} {pirate.last}</h1>
<div rt-scope="pirate.skills as skills">
<span rt-repeat="skill in skills">{skill}</span>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1 @@
<div><div><div><h1>Jack Sparrow</h1><div><span>talking</span><span>fighting</span><span>commandeering</span></div></div></div></div>

View File

@ -119,12 +119,15 @@ test('conversion test', function (t) {
* @param {string} actual
* @param {string} expected
* @param {string} filename
* @return {boolean} whether actual is equal to expected
*/
function compareAndWrite(t, actual, expected, filename) {
t.equal(actual, expected);
if (actual !== expected) {
fs.writeFileSync(filename + '.actual.js', actual);
return false;
}
return true;
}
test('convert div with all module types', function (t) {
@ -175,7 +178,7 @@ function normalizeHtml(html) {
}
test('html tests', function (t) {
var files = ['scope.rt', 'scope-trailing-semicolon.rt', 'lambda.rt', 'eval.rt', 'props.rt', 'custom-element.rt', 'style.rt', 'concat.rt', 'js-in-attr.rt', 'props-class.rt', 'rt-class.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'];
t.plan(files.length);
files.forEach(check);
@ -202,9 +205,13 @@ test('html tests', function (t) {
var actual = React.renderToStaticMarkup(comp());
actual = normalizeHtml(actual);
expected = normalizeHtml(expected);
compareAndWrite(t, actual, expected, filename);
var equal = compareAndWrite(t, actual, expected, filename);
if (!equal) {
fs.writeFileSync(filename + '.code.js', code);
}
} catch (e) {
console.log(testFile, e);
fs.writeFileSync(filename + '.code.js', code);
}
}
});