private void emitSingleFragment()

in src/main/java/org/apache/sling/scripting/sightly/impl/html/dom/MarkupHandler.java [206:283]


    private void emitSingleFragment(String name, Interpolation interpolation, char quoteChar, PluginInvoke invoke) {
        Expression valueExpression =
                expressionWrapper.transform(interpolation, null, ExpressionContext.ATTRIBUTE); // raw expression
        String attrValue = symbolGenerator.next("attrValue"); // holds the raw attribute value
        String attrContent = symbolGenerator.next("attrContent"); // holds the escaped attribute value
        String isTrueVar = symbolGenerator.next("isTrueAttr"); // holds the comparison (attrValue == true)
        String shouldDisplayAttr = symbolGenerator.next("shouldDisplayAttr");
        MarkupContext markupContext = getAttributeMarkupContext(name);
        boolean alreadyEscaped = false;
        if (valueExpression.getRoot() instanceof RuntimeCall) {
            RuntimeCall rc = (RuntimeCall) valueExpression.getRoot();
            if (RuntimeCall.XSS.equals(rc.getFunctionName())) {
                alreadyEscaped = true;
            }
        }
        ExpressionNode node = valueExpression.getRoot();
        stream.write(new VariableBinding.Start(attrValue, node)); // attrContent = <expr>
        if (!alreadyEscaped) {
            Expression contentExpression = valueExpression.withNode(new Identifier(attrValue));
            stream.write(new VariableBinding.Start(
                    attrContent,
                    adjustContext(compilerContext, contentExpression, markupContext)
                            .getRoot()));
            stream.write(new VariableBinding.Start(
                    shouldDisplayAttr,
                    new BinaryOperation(
                            BinaryOperator.AND,
                            new BinaryOperation(
                                    BinaryOperator.AND,
                                    new BinaryOperation(
                                            BinaryOperator.NEQ, NullLiteral.INSTANCE, new Identifier(attrContent)),
                                    new BinaryOperation(
                                            BinaryOperator.NEQ, StringConstant.EMPTY, new Identifier(attrContent))),
                            new BinaryOperation(
                                    BinaryOperator.AND,
                                    new BinaryOperation(
                                            BinaryOperator.NEQ, StringConstant.EMPTY, new Identifier(attrValue)),
                                    new BinaryOperation(
                                            BinaryOperator.NEQ, BooleanConstant.FALSE, new Identifier(attrValue))))));

        } else {
            stream.write(new VariableBinding.Start(
                    shouldDisplayAttr,
                    new BinaryOperation(
                            BinaryOperator.AND,
                            new BinaryOperation(BinaryOperator.NEQ, NullLiteral.INSTANCE, new Identifier(attrValue)),
                            new BinaryOperation(
                                    BinaryOperator.AND,
                                    new BinaryOperation(
                                            BinaryOperator.NEQ, StringConstant.EMPTY, new Identifier(attrValue)),
                                    new BinaryOperation(
                                            BinaryOperator.NEQ, BooleanConstant.FALSE, new Identifier(attrValue))))));
        }
        stream.write(new Conditional.Start(shouldDisplayAttr, true)); // if (attrContent)

        emitAttributeStart(name); // write("attrName");
        invoke.beforeAttributeValue(stream, name, node);
        stream.write(new VariableBinding.Start(
                isTrueVar, // isTrueAttr = (attrValue == true)
                new BinaryOperation(BinaryOperator.EQ, BooleanConstant.TRUE, new Identifier(attrValue))));
        stream.write(new Conditional.Start(isTrueVar, false)); // if (!isTrueAttr)
        emitAttributeValueStart(quoteChar); // write("='");
        if (!alreadyEscaped) {
            stream.write(new OutputVariable(attrContent)); // write(attrContent)
        } else {
            stream.write(new OutputVariable(attrValue)); // write(attrValue)
        }
        emitAttributeEnd(quoteChar); // write("'");
        stream.write(Conditional.END); // end if isTrueAttr
        stream.write(VariableBinding.END); // end scope for isTrueAttr
        invoke.afterAttributeValue(stream, name);
        stream.write(Conditional.END); // end if attrContent
        stream.write(VariableBinding.END); // end scope for attrContent
        if (!alreadyEscaped) {
            stream.write(VariableBinding.END);
        }
        stream.write(VariableBinding.END); // end scope for attrValue
    }