Permalink
Browse files

Adding steps() value for #19

  • Loading branch information...
1 parent 8cfa97a commit 408863c1ea6332e5949fbbd30ce44883ca081d7b @kevin-montrose committed Jul 2, 2012
@@ -454,6 +454,52 @@ private static void VerifyCycle(IEnumerable<Value> values)
}
}
+ private static void VerifySteps(IEnumerable<Value> values)
+ {
+ foreach (var value in values)
+ {
+ var comma = value as CommaDelimittedValue;
+ if (comma != null)
+ {
+ VerifySteps(comma.Values);
+ continue;
+ }
+
+ var compound = value as CompoundValue;
+ if (compound != null)
+ {
+ VerifySteps(compound.Values);
+ continue;
+ }
+
+ var steps = value as StepsValue;
+ if (steps != null)
+ {
+ var numSteps = steps.NumberOfSteps as NumberValue;
+ var dir = steps.Direction as StringValue;
+
+ if (numSteps == null || numSteps is NumberWithUnitValue)
+ {
+ Current.RecordError(ErrorType.Compiler, value, "steps() expects an untyped integer for its first parameter");
+ }
+ else
+ {
+ var v = numSteps.Value;
+
+ if (decimal.Round(v, 0) != v || v <= 0)
+ {
+ Current.RecordError(ErrorType.Compiler, value, "steps() expects an integer value > 0 as its first parameter");
+ }
+ }
+
+ if (dir == null || !(dir.Value.ToLowerInvariant().In("end", "start")))
+ {
+ Current.RecordError(ErrorType.Compiler, value, "steps() expects one of end or start as its second parameter");
+ }
+ }
+ }
+ }
+
public static List<Block> Task(List<Block> blocks)
{
var media = blocks.OfType<MediaBlock>().Select(t => t.MediaQuery);
@@ -473,6 +519,7 @@ public static List<Block> Task(List<Block> blocks)
var values = allProps.OfType<NameValueProperty>().Select(s => s.Value).ToList();
VerifyCycle(values);
+ VerifySteps(values);
return blocks;
}
@@ -2104,6 +2104,65 @@ internal override void Write(TextWriter output)
}
}
+ class StepsValue : Value
+ {
+ public Value NumberOfSteps { get; private set; }
+ public Value Direction { get; private set; }
+
+ public override bool NeedsEvaluate
+ {
+ get
+ {
+ return NumberOfSteps.NeedsEvaluate || Direction.NeedsEvaluate;
+ }
+ }
+
+ public StepsValue(Value numSteps, Value dir)
+ {
+ NumberOfSteps = numSteps;
+ Direction = dir;
+ }
+
+ public override Value Bind(Scope scope)
+ {
+ return new StepsValue(NumberOfSteps.Bind(scope), Direction.Bind(scope));
+ }
+
+ internal override Value Evaluate()
+ {
+ return new StepsValue(NumberOfSteps.Evaluate(), Direction.Evaluate());
+ }
+
+ internal override List<string> ReferredToVariables()
+ {
+ return NumberOfSteps.ReferredToVariables().Union(Direction.ReferredToVariables()).ToList();
+ }
+
+ internal override void Write(TextWriter output)
+ {
+ output.Write("steps(");
+ NumberOfSteps.Write(output);
+ output.Write(',');
+ Direction.Write(output);
+ output.Write(')');
+ }
+
+ public override bool Equals(object obj)
+ {
+ var other = obj as StepsValue;
+ if (other == null) return false;
+
+ return
+ NumberOfSteps.Equals(other.NumberOfSteps) &&
+ Direction.Equals(other.Direction);
+ }
+
+ public override int GetHashCode()
+ {
+ return NumberOfSteps.GetHashCode() ^ (-1 * Direction.GetHashCode());
+ }
+ }
+
class UrlValue : Value
{
public Value UrlPath { get; private set; }
@@ -279,6 +279,19 @@ private static Value ParseString(ParserStream stream, IPosition forPosition)
return new CycleValue(param);
}
+
+ if (toDate.Equals("steps", StringComparison.InvariantCultureIgnoreCase))
+ {
+ var val = ParseGroup(stream, forPosition).Value;
+ var param = val as CommaDelimittedValue;
+ if (param == null || param.Values.Count() != 2)
+ {
+ Current.RecordError(ErrorType.Parser, forPosition, "steps() expects 2 parameters");
+ throw new StoppedParsingException();
+ }
+
+ return new StepsValue(param.Values.ElementAt(0), param.Values.ElementAt(1));
+ }
}
if (buffer.Length == 6 && (stream.HasMore() && stream.Peek() == '('))
View
@@ -2877,5 +2877,18 @@ public void TerminalFontLikeValue()
Assert.IsFalse(Current.HasErrors(), string.Join("\r\n", Current.GetErrors(ErrorType.Compiler).Union(Current.GetErrors(ErrorType.Parser)).Select(s => s.Message)));
Assert.AreEqual("a{font:foo / bar}b{border-radius:x / a}", written);
}
+
+ [TestMethod]
+ public void Steps()
+ {
+ var written =
+ TryCompile(
+ @"a{
+ transition-timing-function: steps(2, end);
+ }"
+ );
+ Assert.IsFalse(Current.HasErrors(), string.Join("\r\n", Current.GetErrors(ErrorType.Compiler).Union(Current.GetErrors(ErrorType.Parser)).Select(s => s.Message)));
+ Assert.AreEqual("a{transition-timing-function:steps(2,end)}", written);
+ }
}
}
View
@@ -1162,5 +1162,24 @@ public void InvalidCycle()
Assert.AreEqual("cycle() values cannot contain attr() values", aErrors[0].Message);
Assert.AreEqual("cycle() values cannot contain calc() values", aErrors[1].Message);
}
+
+ [TestMethod]
+ public void InvalidSteps()
+ {
+ var a =
+ @"a {
+ b: steps(1, foo);
+ c: steps(foo, end);
+ d: steps(0, start);
+ }";
+ TryCompile(a);
+ Assert.IsTrue(Current.HasErrors());
+ var aErrors = Current.GetErrors(ErrorType.Compiler);
+
+ Assert.AreEqual(3, aErrors.Count);
+ Assert.AreEqual("steps() expects one of end or start as its second parameter", aErrors[0].Message);
+ Assert.AreEqual("steps() expects an untyped integer for its first parameter", aErrors[1].Message);
+ Assert.AreEqual("steps() expects an integer value > 0 as its first parameter", aErrors[2].Message);
+ }
}
}
View
@@ -583,5 +583,18 @@ public void Counters()
Assert.AreEqual(null, aCounters.Style);
Assert.AreEqual("world", bCounters.Style.ToString());
}
+
+ [TestMethod]
+ public void Steps()
+ {
+ var a = Value.Parse("steps(2, end)");
+
+ Assert.AreEqual(typeof(StepsValue), a.GetType());
+
+ var aSteps = (StepsValue)a;
+
+ Assert.AreEqual("2", aSteps.NumberOfSteps.ToString());
+ Assert.AreEqual("end", aSteps.Direction.ToString());
+ }
}
}

0 comments on commit 408863c

Please sign in to comment.