diff --git a/src/main/java/com/github/sommeri/less4j/core/compiler/expressions/MiscFunctions.java b/src/main/java/com/github/sommeri/less4j/core/compiler/expressions/MiscFunctions.java index dccb5619..5f73761c 100644 --- a/src/main/java/com/github/sommeri/less4j/core/compiler/expressions/MiscFunctions.java +++ b/src/main/java/com/github/sommeri/less4j/core/compiler/expressions/MiscFunctions.java @@ -272,7 +272,7 @@ protected Expression evaluate(List splitParameters, ProblemsHandler if (splitParameters.size() == 1) { CssString filenameArg = (CssString) splitParameters.get(0); filename = filenameArg.getValue(); - + mimetype = guessMimetype(filename); } else { CssString mimetypeArg = (CssString) splitParameters.get(0); @@ -282,24 +282,27 @@ protected Expression evaluate(List splitParameters, ProblemsHandler filename = filenameArg.getValue(); } + String[] filenameParts = filename.split("#", 2); + filename = filenameParts[0]; + String fragments = filenameParts.length > 1 ? filenameParts[1] : ""; + LessSource source = token.getSource(); try { - LessSource dataSource = source.relativeSource(filename); byte[] data = dataSource.getBytes(); // **** less.js comment - flag is not implemented yet **** // IE8 cannot handle a data-uri larger than 32KB. If this is exceeded // and the --ieCompat flag is enabled, return a normal url() instead. - int fileSizeInKB = data.length/1024; - if (fileSizeInKB >=DATA_URI_MAX_KB) { + int fileSizeInKB = data.length / 1024; + if (fileSizeInKB >= DATA_URI_MAX_KB) { problemsHandler.warnIE8UnsafeDataUri(functionCall, filename, fileSizeInKB, DATA_URI_MAX_KB); FunctionExpression result = new FunctionExpression(token, "url", functionCall.getParameter().clone()); result.configureParentToAllChilds(); return result; } - - return toDataUri(token, mimetype, data); + + return toDataUri(token, mimetype, data, fragments); } catch (FileNotFound ex) { problemsHandler.errorFileNotFound(functionCall, filename); @@ -324,18 +327,18 @@ private String guessMimetype(String filename) { return mimetype; } - private Expression toDataUri(HiddenTokenAwareTree token, String mimetype, byte[] data) { + private Expression toDataUri(HiddenTokenAwareTree token, String mimetype, byte[] data, String fragments) { if (mimetype != null && mimetype.toLowerCase().endsWith("base64")) - return toDataUri(token, mimetype, PrintUtils.base64Encode(data)); + return toDataUri(token, mimetype, PrintUtils.base64Encode(data), fragments); else - return toDataUri(token, mimetype, PrintUtils.toUtf8AsUri(new String(data))); + return toDataUri(token, mimetype, PrintUtils.toUtf8AsUri(new String(data)), fragments); } - private Expression toDataUri(HiddenTokenAwareTree token, String mimetype, String data) { + private Expression toDataUri(HiddenTokenAwareTree token, String mimetype, String data, String fragments) { StringBuilder value = new StringBuilder("data:"); - value.append(mimetype).append(",").append(data); + value.append(mimetype).append(",").append(data).append(fragments); - CssString parameter = new CssString(token, value.toString(), "\""); + CssString parameter = new CssString(token, value.toString(), "\""); return new FunctionExpression(token, "url", parameter); } @@ -367,7 +370,7 @@ class SvgGradient extends CatchAllMultiParameterFunction { @Override protected Expression evaluate(List splitParameters, ProblemsHandler problemsHandler, FunctionExpression functionCall, HiddenTokenAwareTree token) { - String direction = toDirection(splitParameters.get(0)), gradientDirectionSvg =""; + String direction = toDirection(splitParameters.get(0)), gradientDirectionSvg = ""; List stops = splitParameters.subList(1, splitParameters.size()); String gradientType = "linear", rectangleDimension = "x=\"0\" y=\"0\" width=\"1\" height=\"1\""; @@ -380,7 +383,7 @@ protected Expression evaluate(List splitParameters, ProblemsHandler gradientDirectionSvg = "x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\""; } else if ("to top right".equals(direction)) { gradientDirectionSvg = "x1=\"0%\" y1=\"100%\" x2=\"100%\" y2=\"0%\""; - } else if (direction!=null && direction.startsWith("ellipse")) { + } else if (direction != null && direction.startsWith("ellipse")) { gradientType = "radial"; gradientDirectionSvg = "cx=\"50%\" cy=\"50%\" r=\"75%\""; rectangleDimension = "x=\"-50\" y=\"-50\" width=\"101\" height=\"101\""; @@ -388,7 +391,7 @@ protected Expression evaluate(List splitParameters, ProblemsHandler problemsHandler.wrongEnumeratedArgument(functionCall, "direction", "to bottom", "to right", "to bottom right", "to top right", "ellipse", "ellipse at center"); return new FaultyExpression(functionCall); } - + StringBuilder returner = new StringBuilder(""); returner.append(""); returner.append("<"); @@ -396,7 +399,7 @@ protected Expression evaluate(List splitParameters, ProblemsHandler returner.append("Gradient id=\"gradient\" gradientUnits=\"userSpaceOnUse\" "); returner.append(gradientDirectionSvg); returner.append(">"); - + Iterator iterator = stops.iterator(); boolean isFirstStop = true; while (iterator.hasNext()) { @@ -405,11 +408,11 @@ protected Expression evaluate(List splitParameters, ProblemsHandler return new FaultyExpression(functionCall); isFirstStop = false; } - + returner.append(""); returner.append(""); - String result = useBase64? PrintUtils.base64Encode(returner.toString().getBytes()) : returner.toString(); + String result = useBase64 ? PrintUtils.base64Encode(returner.toString().getBytes()) : returner.toString(); return toDataUri(functionCall.getUnderlyingStructure(), result, useBase64); } @@ -419,21 +422,21 @@ private Expression toDataUri(HiddenTokenAwareTree token, String data, boolean us value.append(";base64"); value.append(",").append(data); - CssString parameter = new CssString(token, value.toString(), "\'"); + CssString parameter = new CssString(token, value.toString(), "\'"); return new FunctionExpression(token, "url", parameter); } private boolean addColorStop(StringBuilder returner, Expression colorStop, boolean isFirst, boolean isLast, FunctionExpression errorNode, ProblemsHandler problemsHandler) { - if (colorStop.getType()==ASTCssNodeType.LIST_EXPRESSION) { + if (colorStop.getType() == ASTCssNodeType.LIST_EXPRESSION) { ListExpression list = (ListExpression) colorStop; List expressions = list.getExpressions(); - if (expressions.isEmpty() || expressions.size()>2) { + if (expressions.isEmpty() || expressions.size() > 2) { problemsHandler.errorSvgGradientArgument(errorNode); return false; - } - + } + Expression color = expressions.get(0); - Expression position =expressions.size()>1? expressions.get(1) : null; + Expression position = expressions.size() > 1 ? expressions.get(1) : null; addColorStop(returner, color, position, isFirst, isLast, errorNode, problemsHandler); } else { addColorStop(returner, colorStop, null, isFirst, isLast, errorNode, problemsHandler); @@ -442,17 +445,17 @@ private boolean addColorStop(StringBuilder returner, Expression colorStop, boole } private boolean addColorStop(StringBuilder returner, Expression colorE, Expression position, boolean isFirst, boolean isLast, FunctionExpression errorNode, ProblemsHandler problemsHandler) { - if (colorE.getType()!=ASTCssNodeType.COLOR_EXPRESSION) { + if (colorE.getType() != ASTCssNodeType.COLOR_EXPRESSION) { problemsHandler.errorSvgGradientArgument(errorNode); return false; } - if (!isLast && !isFirst && position==null) { + if (!isLast && !isFirst && position == null) { problemsHandler.errorSvgGradientArgument(errorNode); return false; } - + ColorExpression color = (ColorExpression) colorE; - String positionValue = position!=null ? toCss(position) : isFirst ? "0%" : "100%"; + String positionValue = position != null ? toCss(position) : isFirst ? "0%" : "100%"; returner.append("