Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1552)

Unified Diff: src/com/google/caja/plugin/JsWriter.java

Issue 61041: Cajole to HTML (Closed) Base URL: http://google-caja.googlecode.com/svn/trunk/
Patch Set: Cajole to HTML Created 14 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/com/google/caja/plugin/JsWriter.java
===================================================================
--- src/com/google/caja/plugin/JsWriter.java (revision 3513)
+++ src/com/google/caja/plugin/JsWriter.java (working copy)
@@ -1,188 +0,0 @@
-// Copyright (C) 2007 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.caja.plugin;
-
-import com.google.caja.lexer.CharProducer;
-import com.google.caja.lexer.FilePosition;
-import com.google.caja.lexer.JsLexer;
-import com.google.caja.lexer.JsTokenQueue;
-import com.google.caja.lexer.ParseException;
-import com.google.caja.lexer.escaping.Escaping;
-import com.google.caja.parser.js.Block;
-import com.google.caja.parser.js.Expression;
-import com.google.caja.parser.js.ExpressionStmt;
-import com.google.caja.parser.js.Operation;
-import com.google.caja.parser.js.Operator;
-import com.google.caja.parser.js.Parser;
-import com.google.caja.parser.js.Reference;
-import com.google.caja.parser.js.Statement;
-import com.google.caja.parser.js.StringLiteral;
-import com.google.caja.reporting.MessageQueue;
-
-import java.util.List;
-
-/**
- * Functions for composing javascript template functions.
- */
-final class JsWriter {
-
- /**
- * Appends a statement like tgt.push(toAppend) to the given block, but
- * makes sure to flatten with any like operation that would immediately
- * precede it.
- *
- * @param toAppend an expression that should evaluate to a string
- * @param tgtMembers the parts of a dotted name of a function to call, such as
- * <code>{ "out___", "push" }</code> to append to an Array {@code "out___"}.
- * @param b a block to append the a statement whose side effect is to
- * append the result of evaluating toAppend to the list described by tgt.
- */
- static void append(Expression toAppend, List<String> tgtMembers, Block b) {
- Operation fnCall = null;
- // Look for an existing call to push
- List<? extends Statement> children = b.children();
- if (!children.isEmpty()) {
- Statement last = children.get(children.size() - 1);
- if (last instanceof ExpressionStmt) {
- Expression e = ((ExpressionStmt) last).getExpression();
- if (e instanceof Operation
- && Operator.FUNCTION_CALL == ((Operation) e).getOperator()) {
- Expression fn = ((Operation) e).children().get(0);
- if (matchesChain(fn, tgtMembers)) {
- fnCall = (Operation) e;
- }
- }
- }
- }
- // Make one
- if (null == fnCall) {
- Expression target = makeTargetReference(tgtMembers);
- fnCall = Operation.create(
- target.getFilePosition(), Operator.FUNCTION_CALL, target);
- b.appendChild(new ExpressionStmt(fnCall.getFilePosition(), fnCall));
- }
- if (toAppend instanceof StringLiteral) {
- // If toAppend and last child are both string literals, combine them
- List<? extends Expression> fnCallOperands = fnCall.children();
- if (fnCallOperands.size() > 1) {
- Expression last = fnCallOperands.get(fnCallOperands.size() - 1);
- if (last instanceof StringLiteral) {
- StringLiteral concatenation = StringLiteral.valueOf(
- FilePosition.span(
- last.getFilePosition(), toAppend.getFilePosition()),
- ((StringLiteral) last).getUnquotedValue()
- + ((StringLiteral) toAppend).getUnquotedValue()
- );
- fnCall.replaceChild(concatenation, last);
- return;
- }
- }
- }
- fnCall.insertBefore(toAppend, null);
- }
-
- static void appendString(
- FilePosition pos, String string, List<String> tgtChain, Block b) {
- JsWriter.append(StringLiteral.valueOf(pos, string), tgtChain, b);
- }
-
- static void appendText(
- FilePosition pos, String text, Esc escaping, List<String> tgtChain,
- Block b) {
- if ("".equals(text)) { return; }
- JsWriter.append(
- StringLiteral.valueOf(
- pos, escaping != JsWriter.Esc.NONE ? htmlEscape(text) : text),
- tgtChain, b);
- }
-
- static String htmlEscape(String text) {
- StringBuilder out = new StringBuilder();
- Escaping.escapeXml(text, false, out);
- return out.toString();
- }
-
- static Expression asExpression(
- CharProducer cp, FilePosition pos, MessageQueue mq) {
- // Parse as a javascript expression.
- JsLexer lexer = new JsLexer(cp);
- JsTokenQueue tq = new JsTokenQueue(lexer, pos.source());
- tq.setInputRange(pos);
- Parser p = new Parser(tq, mq);
- Expression e;
- try {
- e = p.parseExpression(true);
- p.getTokenQueue().expectEmpty();
- } catch (ParseException ex) {
- ex.toMessageQueue(mq);
- e = null;
- }
-
- if (null == e) {
- Operation voidOp = Operation.undefined(pos);
- return voidOp;
- }
-
- // Wrap in an ExpressionStmt so the expression is guaranteed to have a
- // proper parent
- ExpressionStmt stmt = new ExpressionStmt(e.getFilePosition(), e);
-
- // Expression will be sanitized in a later pass
-
- e = stmt.getExpression(); // Refetch e in case it was rewritten
- // Make e not a child of stmt
- stmt.replaceChild(Operation.undefined(e.getFilePosition()), e);
- return e;
- }
-
- static Expression makeTargetReference(List<String> tgtMembers) {
- Expression target = TreeConstruction.ref(tgtMembers.get(0));
- for (int i = 1; i < tgtMembers.size(); ++i) {
- target = Operation.createInfix(Operator.MEMBER_ACCESS,
- target, TreeConstruction.ref(tgtMembers.get(i)));
- }
- return target;
- }
-
- private static boolean matchesChain(Expression e, List<String> refChain) {
- return matchesChain(e, refChain, refChain.size() - 1);
- }
-
- private static boolean matchesChain(
- Expression e, List<String> refChain, int i) {
- if (0 == i) {
- if (!(e instanceof Reference)) { return false; }
- String ident = ((Reference) e).getIdentifierName();
- return ident.equals(refChain.get(0));
- }
- if (!(e instanceof Operation)) { return false; }
- Operation op = (Operation) e;
- if (Operator.MEMBER_ACCESS != op.getOperator()) { return false; }
- List<? extends Expression> children = op.children();
- Expression lhs = children.get(0);
- Expression rhs = children.get(1);
- if (!(rhs instanceof Reference)) { return false; }
- String ident = ((Reference) rhs).getIdentifierName();
- if (!ident.equals(refChain.get(i))) { return false; }
- return matchesChain(lhs, refChain, i - 1);
- }
-
- static enum Esc {
- HTML,
- HTML_ATTRIB,
- NONE,
- ;
- }
-}

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b