Skip to content
This repository has been archived by the owner on Feb 23, 2022. It is now read-only.

Commit

Permalink
Implement a string concatenation gss function: concat(...)
Browse files Browse the repository at this point in the history
This allows to dynamically construct urls, e.g.

@def HOST static.example.com
.img {
  background-image: url(concat('//', HOST, '/image.png');
}
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=105082418
  • Loading branch information
iflan committed Oct 14, 2015
1 parent deb5ee5 commit 030a38a
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 2 deletions.
46 changes: 44 additions & 2 deletions src/com/google/common/css/compiler/gssfunctions/GssFunctions.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.google.common.css.compiler.ast.CssHexColorNode;
import com.google.common.css.compiler.ast.CssLiteralNode;
import com.google.common.css.compiler.ast.CssNumericNode;
import com.google.common.css.compiler.ast.CssStringNode;
import com.google.common.css.compiler.ast.CssValueNode;
import com.google.common.css.compiler.ast.ErrorManager;
import com.google.common.css.compiler.ast.GssError;
Expand Down Expand Up @@ -84,6 +85,9 @@ public static Map<String, GssFunction> getFunctionMap() {
// Logic functions.
.put("selectFrom", new SelectFrom())

// String functions.
.put("concat", new Concat())

.build();
}

Expand Down Expand Up @@ -463,8 +467,8 @@ public Color addValuesToHsbComponents(Color baseColor,
*/
public static class MakeMutedColor implements GssFunction {

private float LOSS_OF_SATURATION_FOR_MUTED_TONE = 0.2f;
private String ARGUMENT_COUNT_ERROR_MESSAGE = "makeMutedColor " +
private final float LOSS_OF_SATURATION_FOR_MUTED_TONE = 0.2f;
private final String ARGUMENT_COUNT_ERROR_MESSAGE = "makeMutedColor " +
"expected arguments: backgroundColorStr, foregroundColorStr and an " +
"optional loss of saturation value (0 <= loss <= 1).";

Expand Down Expand Up @@ -573,6 +577,44 @@ public String getCallResultString(List<String> args) throws
}
}

/**
* Implementation of the concat(…) GssFunction. It concatenates a variable number of strings.
* e.g. concat('a', 'b') yields 'ab'. Mainly useful for use with constants.
*/
public static class Concat implements GssFunction {

@Override
public Integer getNumExpectedArguments() {
return null; // Variable list of arguments
}

@Override
public List<CssValueNode> getCallResultNodes(List<CssValueNode> args, ErrorManager errorManager)
throws GssFunctionException {
StringBuilder result = new StringBuilder();
for (CssValueNode arg : args) {
result.append(arg.getValue());
}
return ImmutableList.of((CssValueNode) new CssStringNode(
CssStringNode.Type.SINGLE_QUOTED_STRING, result.toString()));
}

@Override
public String getCallResultString(List<String> args) throws GssFunctionException {
StringBuilder result = new StringBuilder();
for (String arg : args) {
if (arg.length() > 1 && ((arg.startsWith("'") && arg.endsWith("'"))
|| (arg.startsWith("\"") && arg.endsWith("\"")))) {
result.append(CssStringNode.unescape(arg.substring(1, arg.length() - 1)));
} else {
result.append(arg);
}
}
return new CssStringNode(CssStringNode.Type.SINGLE_QUOTED_STRING, result.toString())
.toString();
}
}


/**
* Abstract class implementing the shared logic for the arithmetic functions.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,14 @@ public void testScalars() throws GssParserException {
+ "); }",
"A { width: 60px; }");
}

public void testConcat() throws GssParserException {
test("A { background-image:url(concat('http://', www, '.google.com', \"/example.gif\")); }",
"A { background-image:url('http://www.google.com/example.gif'); }");
test("A { x:concat(a); }", "A { x:'a'; }");
test("A { x:concat(\"'\", \"\\\"\", 'bar','\"', '\\''); }",
"A { x:'\\'\"bar\"\\'' }");
test("A { x:concat('\\\\\\\\'); }",
"A { x:'\\\\\\\\'; }");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -216,4 +216,17 @@ private void testFunctionCallFail(GssFunction funct, ImmutableList<String> args)
// Expected to fail.
}
}

public void testConcat() throws Exception {
GssFunctions.Concat funct = new GssFunctions.Concat();
assertEquals("'ab'", funct.getCallResultString(ImmutableList.of("a", "b")));
assertEquals("'a'", funct.getCallResultString(ImmutableList.of("a")));
assertEquals("'a'", funct.getCallResultString(ImmutableList.of("'a'")));
assertEquals("'a'", funct.getCallResultString(ImmutableList.of("\"a\"")));
assertEquals("'abc'", funct.getCallResultString(ImmutableList.of("a", "b", "c")));
assertEquals("''", funct.getCallResultString(ImmutableList.<String>of()));
assertEquals("'ab'", funct.getCallResultString(ImmutableList.of("'a'", "'b'")));
assertEquals("'\"'", funct.getCallResultString(ImmutableList.of("'\"'")));
assertEquals("'\\''", funct.getCallResultString(ImmutableList.of("'")));
}
}

0 comments on commit 030a38a

Please sign in to comment.