Skip to content

Commit

Permalink
Various bug fixes, some cleaning up and some additional unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
lukeapage authored and jamesfoster-excelpoint committed May 28, 2011
1 parent 072ac33 commit 9ae43b9
Show file tree
Hide file tree
Showing 12 changed files with 152 additions and 69 deletions.
10 changes: 7 additions & 3 deletions src/dotless.Core/Parser/Functions/StringFunctions.cs
Expand Up @@ -42,9 +42,13 @@ protected override Node Evaluate(Env env)

MatchEvaluator replacement = m =>
{
if (m.Value == "%s")
return stringValue(args[i++]);
return args[i++].ToCSS(env);
var value = (m.Value == "%s") ?
stringValue(args[i++]) :
args[i++].ToCSS(env);
return char.IsUpper(m.Value[1]) ?
System.Web.HttpUtility.UrlEncode(value) :
value;
};

str = Regex.Replace(str, "%[sda]", replacement, RegexOptions.IgnoreCase);
Expand Down
Expand Up @@ -72,7 +72,7 @@ public Variable Variable(string name, int index)
return new Variable(name) { Index = index };
}

public Url Url(TextNode value, IEnumerable<string> paths, int index)
public Url Url(Node value, IEnumerable<string> paths, int index)
{
return new Url(value, paths) { Index = index };
}
Expand Down
2 changes: 1 addition & 1 deletion src/dotless.Core/Parser/Infrastructure/INodeProvider.cs
Expand Up @@ -22,7 +22,7 @@ public interface INodeProvider
Number Number(string value, string unit, int index);
Shorthand Shorthand(Node first, Node second, int index);
Variable Variable(string name, int index);
Url Url(TextNode value, IEnumerable<string> paths, int index);
Url Url(Node value, IEnumerable<string> paths, int index);
Script Script(string script, int index);

//mixins
Expand Down
37 changes: 31 additions & 6 deletions src/dotless.Core/Parser/Parsers.cs
Expand Up @@ -213,7 +213,21 @@ public Url Url(Parser parser)
if (parser.Tokenizer.CurrentChar != 'u' || !parser.Tokenizer.Match(@"url\("))
return null;

var value = Quoted(parser) || parser.Tokenizer.MatchAny(@"[^\)""']*") || new TextNode("");
Node value = Quoted(parser);

if (!value) {
var memory = parser.Tokenizer.Location;
value = Expression(parser);

if (value && !parser.Tokenizer.Peek(')')) {
value = null;
parser.Tokenizer.Location = memory;
}
}

if (!value) {
value = parser.Tokenizer.MatchAny(@"[^\)""']*") || new TextNode("");
}

if (!parser.Tokenizer.Match(')'))
throw new ParsingException("missing closing ) for url()", parser.Tokenizer.Location.Index);
Expand Down Expand Up @@ -931,14 +945,25 @@ public Node Addition(Parser parser)
// such as a Color, or a Variable
//
public Node Operand(Parser parser)
{
{
CharMatchResult negate = null;

if (parser.Tokenizer.CurrentChar == '-' && parser.Tokenizer.Peek(@"-[@\(]"))
{
negate = parser.Tokenizer.Match('-');
}

var operand = Sub(parser) ??
Dimension(parser) ??
Color(parser) ??
(Node) Variable(parser);

if (operand != null)
return operand;
(Node) Variable(parser);

if (operand != null)
{
return negate ?
NodeProvider.Operation("*", NodeProvider.Number("-1", "", negate.Index), operand, negate.Index) :
operand;
}

if (parser.Tokenizer.CurrentChar == 'u' && parser.Tokenizer.Peek(@"url\("))
return null;
Expand Down
7 changes: 0 additions & 7 deletions src/dotless.Core/Parser/Tokenizer.cs
Expand Up @@ -75,7 +75,6 @@ public void SetupInput(string input)
{
i += match.Length;
_chunks.Add(new Chunk(match.Value, ChunkType.Comment));
//Chunk.Append(match.Value, _chunks);
continue;
} else
{
Expand All @@ -91,7 +90,6 @@ public void SetupInput(string input)
{
i += match.Length;
_chunks.Add(new Chunk(match.Value, ChunkType.QuotedString));
//Chunk.Append(match.Value, _chunks);
continue;
} else
{
Expand Down Expand Up @@ -143,11 +141,6 @@ public string GetComment()
if (this.CurrentChar != '/')
return null;

//Once CSS Hacks are supported, implement this exception
//if (comment.Value.EndsWith(@"\*/")) {
// throw new ParsingException("The IE6 comment hack is not supported", parser.Tokenizer.Location.Index);
//}

var comment = this.Match(this._commentRegEx);
return comment.Value;
}
Expand Down
44 changes: 31 additions & 13 deletions src/dotless.Core/Parser/Tree/Url.cs
Expand Up @@ -5,27 +5,45 @@
using System.Text.RegularExpressions;
using Infrastructure;
using Infrastructure.Nodes;
using Utils;
using Utils;
using Exceptions;

public class Url : Node
{
public TextNode Value { get; set; }
public Node Value { get; set; }

public Url(TextNode value, IEnumerable<string> paths)
public Url(Node value, IEnumerable<string> paths)
{
if (!Regex.IsMatch(value.Value, @"^(http:\/)?\/") && paths.Any())
{
value.Value = paths.Concat(new[] {value.Value}).AggregatePaths();
if (value is TextNode)
{
var textValue = value as TextNode;
if (!Regex.IsMatch(textValue.Value, @"^(http:\/)?\/") && paths.Any())
{
textValue.Value = paths.Concat(new[] { textValue.Value }).AggregatePaths();
}
}

Value = value;
}

public string GetUrl()
{
return Value.Value;
}

}

public Url(Node value)
{
Value = value;
}

public string GetUrl()
{
if (Value is TextNode)
return (Value as TextNode).Value;

throw new ParserException("Imports do not allow expressions");
}

public override Node Evaluate(Env env)
{
return new Url(Value.Evaluate(env));
}

public override string ToCSS(Env env)
{
return "url(" + Value.ToCSS(env) + ")";
Expand Down
7 changes: 7 additions & 0 deletions src/dotless.Test/Specs/ColorsFixture.cs
Expand Up @@ -29,6 +29,13 @@ public void Gray()
{
AssertExpression("#c8c8c8", "rgb(200, 200, 200)");
AssertExpression("gray", "hsl(50, 0, 50)");
AssertExpression("gray", "hsl(50, 0%, 50%)");
}

[Test]
public void Green()
{
AssertExpression("lime", "hsl(120, 100%, 50%)");
}
}
}
71 changes: 50 additions & 21 deletions src/dotless.Test/Specs/CssFixture.cs
Expand Up @@ -308,27 +308,56 @@ public void CheckUrlWithDataNotQuoted()
background: #eeeeee url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAABlBMVEX///////9VfPVsAAAACklEQVQImWNgAAAAAgAB9HFkpgAAAABJRU5ErkJggg%3D%3D) repeat-y 13em 0;
}";
AssertLessUnchanged(input);
}

[Test]
[Ignore("Bug in dotless")]
public void HttpUrl()
{
// In MatchAny where we consider if we hit a comment token, instead of changing
// it to text we should re-parse the comment?
// or does the tokenizer need to be aware of url() as a special case? (see next bug)
AssertExpressionUnchanged(@"image: url(http://), ""}"", url(""http://}"")");
}

[Test]
[Ignore("Bug in dotless")]
public void HttpUrlClosingBraceOnSameLine()
{
var input = @".trickyurl { image: url(http://); }";
var expected = @".trickyurl {
}

[Test]
[Ignore("Bug in dotless")]
public void HttpUrl()
{
AssertExpressionUnchanged(@"url(http://), ""}"", url(""http://}"")");
}

[Test]
[Ignore("Bug in dotless")]
public void HttpUrlClosingBraceOnSameLine()
{
var input = @"
.trickyurl {
image: url(http://); }";

var expected = @"
.trickyurl {
image: url(http://);
}";
AssertLess(input, expected);
}
}";
AssertLess(input, expected);
}

[Test]
public void HttpUrl3()
{
var input = @"
.trickyurl {
image: url(http://);
}";
var expected = @"
.trickyurl {
image: url(http://);
}";
AssertLess(input, expected);
}

[Test]
public void HttpUrl4()
{
var input = @"
.trickyurl {
image: url(""""), url(http://);
}";
var expected = @"
.trickyurl {
image: url(""""), url(http://);
}";
AssertLess(input, expected);
}
}
}
5 changes: 2 additions & 3 deletions src/dotless.Test/Specs/Functions/FormatStringFixture.cs
Expand Up @@ -123,17 +123,16 @@ public void ShortFormatFunctionAcceptingString()
}

[Test]
[Ignore("Supported by less.js, not by dotless")]
public void ShortFormatFunctionUrlEncode()
{
var input = @"
#built-in {
format-url-encode: %('red is %A', #ff0000);
format-url-encode: %('red is %A', #ff1000);
}
";
var expected = @"
#built-in {
format-url-encode: ""red is %23ff0000"";
format-url-encode: 'red is %23ff1000';
}";

AssertLess(input, expected);
Expand Down
17 changes: 4 additions & 13 deletions src/dotless.Test/Specs/OperationsFixture.cs
Expand Up @@ -39,28 +39,19 @@ public void Negative()
}

[Test]
public void NegationsWorking()
{
var variables = new Dictionary<string, string>();
variables["z"] = "4px";

AssertExpression("- 4px", "-@z", variables); //ideally should not have space between - and 4
}

[Test]
[Ignore("Supported by less.js, not by dotless")]
public void NegationsBugs()
public void Negations()
{
var variables = new Dictionary<string, string>();
variables["z"] = "4px";

AssertExpression("-4px", "-@z", variables);
AssertExpression("0px", "-@z + @z", variables);
AssertExpression("0px", "@z + -@z", variables);
AssertExpression("8px", "@z - -@z", variables);
AssertExpression("0px", "-@z - -@z", variables);

AssertExpression("- 4px", "-(@z)", variables);
AssertExpression("0px", "-(2 + 2) * -@z", variables);
AssertExpression("-4px", "-(@z)", variables);
AssertExpression("16px", "-(2 + 2) * -@z", variables);
}

[Test]
Expand Down
18 changes: 18 additions & 0 deletions src/dotless.Test/Specs/StringsFixture.cs
Expand Up @@ -149,6 +149,24 @@ public void StringInterpolationMultipleCalls()
AssertLess(input, expected);
}

[Test]
public void StringInterpolationInUrl()
{
var input = @"
#interpolation {
@var: '/dev';
url: url(""http://lesscss.org@{var}/image.jpg"");
}
";
var expected = @"
#interpolation {
url: url(""http://lesscss.org/dev/image.jpg"");
}";

AssertLess(input, expected);
}


[Test]
public void BracesInQuotes()
{
Expand Down
1 change: 0 additions & 1 deletion src/dotless.Test/Specs/VariablesFixture.cs
Expand Up @@ -350,7 +350,6 @@ public void VariableValuesMulti()
}

[Test]
[Ignore("Supported by less.js but not dotless")]
public void VariableValuesUrl()
{
var input = @"
Expand Down

0 comments on commit 9ae43b9

Please sign in to comment.