// Generate statement to ensure data is defined, if necessary.
if ((new ShouldEnsureDataIsDefinedVisitor()).exec(node)) {
jsCodeBuilder.appendLine("opt_data = opt_data || {};");
}
JsExpr resultJsExpr;
if (!isCodeStyleStringbuilder && isComputableAsJsExprsVisitor.exec(node)) {
// Case 1: The code style is 'concat' and the whole template body can be represented as JS
// expressions. We specially handle this case because we don't want to generate the variable
// 'output' at all. We simply concatenate the JS expressions and return the result.
List<JsExpr> templateBodyJsExprs = genJsExprsVisitor.exec(node);
resultJsExpr = JsExprUtils.concatJsExprs(templateBodyJsExprs);
} else {
// Case 2: Normal case.
jsCodeBuilder.pushOutputVar("output");
if (isCodeStyleStringbuilder) {
jsCodeBuilder.appendLine("var output = opt_sb || new soy.StringBuilder();");
jsCodeBuilder.setOutputVarInited();
}
visitChildren(node);
if (isCodeStyleStringbuilder) {
resultJsExpr = new JsExpr("opt_sb ? '' : output.toString()", Integer.MAX_VALUE);
} else {
resultJsExpr = new JsExpr("output", Integer.MAX_VALUE);
}
jsCodeBuilder.popOutputVar();
}
if (node.getContentKind() != null) {
if (isCodeStyleStringbuilder) {
// TODO: In string builder mode, the only way to support strict is if callers know
// whether their callees are strict and wrap at the call site. This is challenging
// because most projects compile Javascript one file at a time. Since concat mode
// is faster in most browsers nowadays, this may not be a priority.
throw SoySyntaxExceptionUtils.createWithNode(
"Soy's StringBuilder-based code generation mode does not currently support " +
"autoescape=\"strict\".",
node);
}
// Templates with autoescape="strict" return the SanitizedContent wrapper for its kind:
// - Call sites are wrapped in an escaper. Returning SanitizedContent prevents re-escaping.
// - The topmost call into Soy returns a SanitizedContent. This will make it easy to take
// the result of one template and feed it to another, and also to confidently assign sanitized
// HTML content to innerHTML.
resultJsExpr = JsExprUtils.maybeWrapAsSanitizedContent(
node.getContentKind(), resultJsExpr);
}
jsCodeBuilder.appendLine("return ", resultJsExpr.getText(), ";");
localVarTranslations.pop();
}