Search in sources :

Example 1 with HtmlAttributeValueNode

use of com.google.template.soy.soytree.HtmlAttributeValueNode in project closure-templates by google.

the class GenIncrementalDomCodeVisitor method maybeGetKeyNodeValue.

/**
 * Gets the 'key' for an element to use in Incremental DOM to be used in the {@code
 * incrementalDom.elementOpen} or {@code incrementalDom.elementVoid} calls.
 *
 * <pre>
 * &lt;div key="test" /div&gt;
 * </pre>
 *
 * generates
 *
 * <pre>
 * incrementalDom.elementVoid('div', 'test')
 * </pre>
 *
 * @param parentNode The SoyNode representing the parent.
 * @return A string containing the JavaScript expression to retrieve the key, or null if the
 *     parent has no attribute child.
 */
@Nullable
private CodeChunk.WithValue maybeGetKeyNodeValue(HtmlOpenTagNode parentNode) {
    // TODO(lukes): it seems like we should be able to support conditional keys
    HtmlAttributeNode keyAttr = parentNode.getDirectAttributeNamed(KEY_ATTRIBUTE_NAME);
    if (keyAttr != null) {
        List<CodeChunk.WithValue> chunks = ImmutableList.of();
        if (keyAttr.hasValue()) {
            // TODO(lukes): add a dedicated method for this to HtmlAttributeNode?  if there is a value
            // it should _always_ be an HtmlAttributeValueNode
            HtmlAttributeValueNode value = (HtmlAttributeValueNode) keyAttr.getChild(1);
            // TODO(lukes): this limitation is arbitrary.  fix it.
            checkState(isComputableAsJsExprsVisitor.execOnChildren(value), "Attribute values that cannot be evalutated to simple expressions is not yet" + " supported  for Incremental DOM code generation");
            chunks = genJsExprsVisitor.execOnChildren(value);
        }
        // to be string (RawTextNode or PrintNode)
        return CodeChunkUtils.concatChunksForceString(chunks);
    }
    return null;
}
Also used : HtmlAttributeNode(com.google.template.soy.soytree.HtmlAttributeNode) HtmlAttributeValueNode(com.google.template.soy.soytree.HtmlAttributeValueNode) Nullable(javax.annotation.Nullable)

Example 2 with HtmlAttributeValueNode

use of com.google.template.soy.soytree.HtmlAttributeValueNode in project closure-templates by google.

the class ContentSecurityPolicyNonceInjectionPass method createCspInjection.

/**
 * Generates an AST fragment that looks like: {if $ij.csp_nonce}nonce="{$ij.csp_nonce}"{/if}
 *
 * @param insertionLocation The location where it is being inserted
 * @param nodeIdGen The id generator to use
 */
private static IfNode createCspInjection(SourceLocation insertionLocation, IdGenerator nodeIdGen) {
    IfNode ifNode = new IfNode(nodeIdGen.genId(), insertionLocation);
    IfCondNode ifCondNode = new IfCondNode(nodeIdGen.genId(), insertionLocation, "if", referenceCspNonce(insertionLocation));
    ifNode.addChild(ifCondNode);
    HtmlAttributeNode nonceAttribute = new HtmlAttributeNode(nodeIdGen.genId(), insertionLocation, insertionLocation.getBeginPoint());
    ifCondNode.addChild(nonceAttribute);
    nonceAttribute.addChild(new RawTextNode(nodeIdGen.genId(), "nonce", insertionLocation));
    HtmlAttributeValueNode attributeValue = new HtmlAttributeValueNode(nodeIdGen.genId(), insertionLocation, HtmlAttributeValueNode.Quotes.DOUBLE);
    nonceAttribute.addChild(attributeValue);
    // NOTE: we do not need to insert any print directives here, unlike the old implementation since
    // we are running before the autoescaper, so the escaper should insert whatever print directives
    // are appropriate.
    PrintNode printNode = new PrintNode(nodeIdGen.genId(), insertionLocation, // Implicit.  {$ij.csp_nonce} not {print $ij.csp_nonce}
    true, /* isImplicit= */
    referenceCspNonce(insertionLocation), /* attributes= */
    ImmutableList.of(), ErrorReporter.exploding());
    attributeValue.addChild(printNode);
    return ifNode;
}
Also used : IfCondNode(com.google.template.soy.soytree.IfCondNode) HtmlAttributeNode(com.google.template.soy.soytree.HtmlAttributeNode) IfNode(com.google.template.soy.soytree.IfNode) PrintNode(com.google.template.soy.soytree.PrintNode) RawTextNode(com.google.template.soy.soytree.RawTextNode) HtmlAttributeValueNode(com.google.template.soy.soytree.HtmlAttributeValueNode)

Example 3 with HtmlAttributeValueNode

use of com.google.template.soy.soytree.HtmlAttributeValueNode in project closure-templates by google.

the class HtmlRewritePassTest method testAttributes.

@Test
public void testAttributes() {
    TemplateNode node = runPass("<div class=\"foo\"></div>");
    assertThatSourceString(node).isEqualTo("<div class=\"foo\"></div>");
    String structure = "" + "HTML_OPEN_TAG_NODE\n" + "  RAW_TEXT_NODE\n" + "  HTML_ATTRIBUTE_NODE\n" + "    RAW_TEXT_NODE\n" + "    HTML_ATTRIBUTE_VALUE_NODE\n" + "      RAW_TEXT_NODE\n" + "HTML_CLOSE_TAG_NODE\n" + "  RAW_TEXT_NODE\n" + "";
    assertThatASTString(node).isEqualTo(structure);
    // test alternate quotation marks
    node = runPass("<div class='foo'></div>");
    assertThatSourceString(node).isEqualTo("<div class='foo'></div>");
    assertThatASTString(node).isEqualTo(structure);
    node = runPass("<div class=foo></div>");
    assertThatSourceString(node).isEqualTo("<div class=foo></div>");
    assertThatASTString(node).isEqualTo(structure);
    // This is a tricky case, according to the spec the '/' belongs to the attribute, not the tag
    node = runPass("<input class=foo/>");
    assertThatSourceString(node).isEqualTo("<input class=foo/>");
    HtmlOpenTagNode openTag = (HtmlOpenTagNode) node.getChild(0);
    assertThat(openTag.isSelfClosing()).isFalse();
    HtmlAttributeValueNode attributeValue = (HtmlAttributeValueNode) ((HtmlAttributeNode) openTag.getChild(1)).getChild(1);
    assertThat(attributeValue.getQuotes()).isEqualTo(HtmlAttributeValueNode.Quotes.NONE);
    assertThat(((RawTextNode) attributeValue.getChild(0)).getRawText()).isEqualTo("foo/");
}
Also used : TemplateNode(com.google.template.soy.soytree.TemplateNode) RawTextNode(com.google.template.soy.soytree.RawTextNode) HtmlOpenTagNode(com.google.template.soy.soytree.HtmlOpenTagNode) HtmlAttributeValueNode(com.google.template.soy.soytree.HtmlAttributeValueNode) Test(org.junit.Test)

Example 4 with HtmlAttributeValueNode

use of com.google.template.soy.soytree.HtmlAttributeValueNode in project closure-templates by google.

the class VeLogInstrumentationVisitor method visitHtmlAttributeNode.

/**
 * For HtmlAttributeNode that has a logging function as its value, replace the logging function
 * with its place holder, and append a new data attribute that contains all the desired
 * information that are used later by the runtime library.
 */
@Override
protected void visitHtmlAttributeNode(HtmlAttributeNode node) {
    // Skip attributes that do not have a value.
    if (!node.hasValue()) {
        return;
    }
    SourceLocation insertionLocation = node.getSourceLocation();
    for (FunctionNode function : SoyTreeUtils.getAllNodesOfType(node, FunctionNode.class)) {
        if (!(function.getSoyFunction() instanceof LoggingFunction)) {
            continue;
        }
        FunctionNode funcNode = new FunctionNode(VeLogJsSrcLoggingFunction.INSTANCE, insertionLocation);
        funcNode.addChild(new StringNode(function.getFunctionName(), QuoteStyle.SINGLE, insertionLocation));
        funcNode.addChild(new ListLiteralNode(function.getChildren(), insertionLocation));
        StandaloneNode attributeName = node.getChild(0);
        if (attributeName instanceof RawTextNode) {
            // If attribute name is a plain text, directly pass it as a function argument.
            funcNode.addChild(new StringNode(((RawTextNode) attributeName).getRawText(), QuoteStyle.SINGLE, insertionLocation));
        } else {
            // Otherwise wrap the print node or call node into a let block, and use the let variable
            // as a function argument.
            String varName = "soy_logging_function_attribute_" + counter;
            LetContentNode letNode = LetContentNode.forVariable(nodeIdGen.genId(), attributeName.getSourceLocation(), varName, null);
            // Adds a let var which references to the original attribute name, and move the name to
            // the let block.
            node.replaceChild(attributeName, new PrintNode(nodeIdGen.genId(), insertionLocation, /* isImplicit= */
            true, /* expr= */
            new VarRefNode(varName, insertionLocation, false, letNode.getVar()), /* attributes= */
            ImmutableList.of(), ErrorReporter.exploding()));
            letNode.addChild(attributeName);
            node.getParent().addChild(node.getParent().getChildIndex(node), letNode);
            funcNode.addChild(new VarRefNode(varName, insertionLocation, false, letNode.getVar()));
        }
        funcNode.addChild(new IntegerNode(counter++, insertionLocation));
        PrintNode loggingFunctionAttribute = new PrintNode(nodeIdGen.genId(), insertionLocation, /* isImplicit= */
        true, /* expr= */
        funcNode, /* attributes= */
        ImmutableList.of(), ErrorReporter.exploding());
        // Append the logging function attribute to its parent
        int appendIndex = node.getParent().getChildIndex(node) + 1;
        node.getParent().addChild(appendIndex, loggingFunctionAttribute);
        // Replace the original attribute value to the placeholder.
        HtmlAttributeValueNode placeHolder = new HtmlAttributeValueNode(nodeIdGen.genId(), insertionLocation, Quotes.DOUBLE);
        placeHolder.addChild(new RawTextNode(nodeIdGen.genId(), ((LoggingFunction) function.getSoyFunction()).getPlaceholder(), insertionLocation));
        node.replaceChild(node.getChild(1), placeHolder);
        // logging function in a html attribute value.
        break;
    }
    visitChildren(node);
}
Also used : SourceLocation(com.google.template.soy.base.SourceLocation) ListLiteralNode(com.google.template.soy.exprtree.ListLiteralNode) IntegerNode(com.google.template.soy.exprtree.IntegerNode) FunctionNode(com.google.template.soy.exprtree.FunctionNode) StandaloneNode(com.google.template.soy.soytree.SoyNode.StandaloneNode) VarRefNode(com.google.template.soy.exprtree.VarRefNode) StringNode(com.google.template.soy.exprtree.StringNode) LoggingFunction(com.google.template.soy.logging.LoggingFunction) PrintNode(com.google.template.soy.soytree.PrintNode) RawTextNode(com.google.template.soy.soytree.RawTextNode) LetContentNode(com.google.template.soy.soytree.LetContentNode) HtmlAttributeValueNode(com.google.template.soy.soytree.HtmlAttributeValueNode)

Example 5 with HtmlAttributeValueNode

use of com.google.template.soy.soytree.HtmlAttributeValueNode in project closure-templates by google.

the class GenIncrementalDomCodeVisitor method getAttributeValues.

private List<CodeChunk.WithValue> getAttributeValues(HtmlAttributeNode node) {
    if (!node.hasValue()) {
        // the runtime knows to create an attribute.
        return ImmutableList.of(LITERAL_EMPTY_STRING);
    }
    HtmlAttributeValueNode value = (HtmlAttributeValueNode) node.getChild(1);
    if (!isComputableAsJsExprsVisitor.execOnChildren(value)) {
        String outputVar = "html_attribute_" + node.getId();
        getJsCodeBuilder().pushOutputVar(outputVar).setOutputVarInited();
        SanitizedContentKind prev = getJsCodeBuilder().getContentKind();
        getJsCodeBuilder().setContentKind(SanitizedContentKind.TEXT);
        CodeChunk appends = visitChildrenReturningCodeChunk(value);
        getJsCodeBuilder().popOutputVar();
        getJsCodeBuilder().setContentKind(prev);
        return ImmutableList.of(CodeChunk.id(outputVar).withInitialStatements(ImmutableList.<CodeChunk>of(VariableDeclaration.builder(outputVar).setRhs(CodeChunk.LITERAL_EMPTY_STRING).build(), appends)));
    }
    return genJsExprsVisitor.execOnChildren(value);
}
Also used : CodeChunk(com.google.template.soy.jssrc.dsl.CodeChunk) SanitizedContentKind(com.google.template.soy.base.internal.SanitizedContentKind) HtmlAttributeValueNode(com.google.template.soy.soytree.HtmlAttributeValueNode)

Aggregations

HtmlAttributeValueNode (com.google.template.soy.soytree.HtmlAttributeValueNode)5 RawTextNode (com.google.template.soy.soytree.RawTextNode)3 HtmlAttributeNode (com.google.template.soy.soytree.HtmlAttributeNode)2 PrintNode (com.google.template.soy.soytree.PrintNode)2 SourceLocation (com.google.template.soy.base.SourceLocation)1 SanitizedContentKind (com.google.template.soy.base.internal.SanitizedContentKind)1 FunctionNode (com.google.template.soy.exprtree.FunctionNode)1 IntegerNode (com.google.template.soy.exprtree.IntegerNode)1 ListLiteralNode (com.google.template.soy.exprtree.ListLiteralNode)1 StringNode (com.google.template.soy.exprtree.StringNode)1 VarRefNode (com.google.template.soy.exprtree.VarRefNode)1 CodeChunk (com.google.template.soy.jssrc.dsl.CodeChunk)1 LoggingFunction (com.google.template.soy.logging.LoggingFunction)1 HtmlOpenTagNode (com.google.template.soy.soytree.HtmlOpenTagNode)1 IfCondNode (com.google.template.soy.soytree.IfCondNode)1 IfNode (com.google.template.soy.soytree.IfNode)1 LetContentNode (com.google.template.soy.soytree.LetContentNode)1 StandaloneNode (com.google.template.soy.soytree.SoyNode.StandaloneNode)1 TemplateNode (com.google.template.soy.soytree.TemplateNode)1 Nullable (javax.annotation.Nullable)1