Fixes #353 - body-only-if does not work with custom tags (only HTML tags)

This commit is contained in:
Patrick Steele-Idem 2016-08-11 16:07:53 -06:00
parent d6fcfab09e
commit 1d480e82ca
7 changed files with 77 additions and 3 deletions

View File

@ -173,6 +173,15 @@ function getNextNestedTagVarName(tagDef, context) {
return safeVarName(tagDef.name) + (nestedTagVarInfo.next++);
}
function getNextRenderBodyVar(context) {
var key = 'CustomTag_renderBodyVar';
var nextVarInfo = context.data[key] || (context.data[key] = {
next: 0
});
return 'renderBodyConditional'+ (nextVarInfo.next++);
}
class CustomTag extends HtmlElement {
constructor(el, tagDef) {
super(el);
@ -201,6 +210,8 @@ class CustomTag extends HtmlElement {
var isRepeated;
var targetProperty;
var bodyOnlyIf = this.bodyOnlyIf;
if (isNestedTag) {
parentTagName = tagDef.parentTagName;
isRepeated = tagDef.isRepeated === true;
@ -251,10 +262,21 @@ class CustomTag extends HtmlElement {
}
}
var renderBodyFunctionVarIdentifier;
var renderBodyFunctionVar;
// Store the renderBody function with the input, but only if the body does not have
// nested tags
if (renderBodyFunction && !hasNestedTags) {
inputProps.renderBody = renderBodyFunction;
if (bodyOnlyIf) {
// Move the renderBody function into a local variable
renderBodyFunctionVarIdentifier = builder.identifier(getNextRenderBodyVar(context));
renderBodyFunctionVar = builder.var(renderBodyFunctionVarIdentifier, renderBodyFunction);
inputProps.renderBody = renderBodyFunctionVarIdentifier;
} else {
inputProps.renderBody = renderBodyFunction;
}
} else {
bodyOnlyIf = null;
}
inputProps = builder.literal(inputProps);
@ -279,6 +301,8 @@ class CustomTag extends HtmlElement {
var rendererRequirePath;
var requireRendererFunctionCall;
if (rendererPath) {
rendererRequirePath = context.getRequirePath(rendererPath);
requireRendererFunctionCall = builder.require(JSON.stringify(rendererRequirePath));
@ -286,13 +310,15 @@ class CustomTag extends HtmlElement {
requireRendererFunctionCall = builder.literal(null);
}
var finalNode;
if (tagDef.template) {
let templateRequirePath = context.getRequirePath(tagDef.template);
let templateVar = context.importTemplate(templateRequirePath);
let renderMethod = builder.memberExpression(templateVar, builder.identifier('render'));
let renderArgs = [ inputProps, 'out' ];
let renderFunctionCall = builder.functionCall(renderMethod, renderArgs);
return renderFunctionCall;
finalNode = renderFunctionCall;
} else {
var loadTagVar = codegen.addStaticVar('__loadTag', '__helpers.t');
@ -332,7 +358,26 @@ class CustomTag extends HtmlElement {
}
}
let tagFunctionCall = builder.functionCall(tagVar, tagArgs);
return tagFunctionCall;
finalNode = tagFunctionCall;
}
if (bodyOnlyIf && renderBodyFunctionVar) {
var ifStatement = builder.ifStatement(
bodyOnlyIf,
[
builder.functionCall(renderBodyFunctionVarIdentifier, [builder.identifierOut()])
],
builder.elseStatement([
finalNode
]));
return [
renderBodyFunctionVar,
ifStatement
];
} else {
return finalNode;
}
}
}

View File

@ -200,6 +200,18 @@
]
},
"<*>": {
"@body-only-if": {
"type": "statement",
"autocomplete": [
{
"snippet": "body-only-if(${1:condition})",
"descriptionMoreURL": "http://markojs.com/docs/marko/language-guide/#body-only-if"
},
{
"descriptionMoreURL": "http://markojs.com/docs/marko/language-guide/#body-only-if"
}
]
},
"@if": {
"type": "statement",
"autocomplete": [

View File

@ -0,0 +1,6 @@
<div class="hello">
<h1>test-hello</h1>
<div class="body">
<invoke data.renderBody(out) />
</div>
</div>

View File

@ -0,0 +1 @@
This is the body content (a)<div class="hello"><h1>test-hello</h1><div class="body">This is the body content (b)</div></div>

View File

@ -0,0 +1,6 @@
<test-hello body-only-if(0 < 1)>
This is the body content (a)
</test-hello>
<test-hello body-only-if(0 > 1)>
This is the body content (b)
</test-hello>

View File

@ -0,0 +1,3 @@
exports.templateData = {
"url": "/foo"
};

View File

@ -2,6 +2,7 @@
"name",
"age",
"foo-on-*",
"body-only-if",
"if",
"else-if",
"else",