internal static Value Combine(Value cur, Value next) { if (cur == null) return next; var ret = new List<Value>(); var left = cur as CompoundValue; if (left != null) { ret.AddRange(left.Values); } else { ret.Add(cur); } ret.Add(next); return new CompoundValue(ret); }
public Import(Value import, MediaQuery forMedia, int start, int stop, string file) { ToImport = import; MediaQuery = forMedia; Start = start; Stop = stop; FilePath = file; }
internal LocalValue(Value val) { Value = val; }
internal HSLColorValue(Value hue, Value saturation, Value lightness) { Hue = hue; Saturation = saturation; Lightness = lightness; }
internal FormatValue(Value val) { Value = val; }
internal UrlValue(Value path) { UrlPath = path; }
internal RGBColorValue(Value r, Value g, Value b) { Red = r; Green = g; Blue = b; }
internal RatioValue(Value lhs, Value rhs) { LeftHand = lhs; RightHand = rhs; }
internal StepsValue(Value numSteps, Value dir) { NumberOfSteps = numSteps; Direction = dir; }
internal AttributeValue(Value attr, Value type, Value fallback) { Attribute = attr; Type = type; Fallback = fallback; }
private static Value CacheBreakValue(Value val) { var compound = val as CompoundValue; if (compound != null) { return new CompoundValue(compound.Values.Select(v => CacheBreakValue(v)).ToArray()); } var comma = val as CommaDelimittedValue; if (comma != null) { return new CommaDelimittedValue(comma.Values.Select(v => CacheBreakValue(v)).ToList()); } var url = val as UrlValue; if (url != null) { return new UrlValue(AddCacheBreaker(url.UrlPath)); } return val; }
private static Value AddCacheBreaker(Value val) { var asStr = val as StringValue; if (asStr != null) { var breaker = GenerateCacheBreaker(asStr.Value); if (asStr.Value.Contains('?')) { breaker = "&_=" + breaker; } else { breaker = "?_=" + breaker; } return new StringValue(asStr.Value + breaker); } var asQuoted = val as QuotedStringValue; if (asQuoted != null) { var breaker = GenerateCacheBreaker(asQuoted.Value); if (asQuoted.Value.Contains('?')) { breaker = "&_=" + breaker; } else { breaker = "?_=" + breaker; } return new QuotedStringValue(asQuoted.Value + breaker); } throw new InvalidOperationException("Expected string or quoted string value, found [" + val + "]"); }
internal VariableProperty(string name, Value value, int start, int stop, string file) { Name = name; Value = value; Start = start; Stop = stop; FilePath = file; }
public EqualFeatureMedia(string feature, Value equals, IPosition forPosition) : base(forPosition) { Feature = feature; EqualsValue = equals; }
public MoreVariable(string varName, Value value, int start, int stop, string filePath) { Name = varName; Value = value; Start = start; Stop = stop; FilePath = filePath; }
public MaxFeatureMedia(string feature, Value max, IPosition forPosition) : base(forPosition) { Feature = feature; Max = max; }
internal CounterValue(Value counter, Value style) { Counter = counter; Style = style; }
internal RGBAColorValue(Value red, Value green, Value blue, Value alpha) { Red = red; Green = green; Blue = blue; Alpha = alpha; }
internal CubicBezierValue(Value x1, Value y1, Value x2, Value y2) { X1 = x1; Y1 = y1; X2 = x2; Y2 = y2; }
// Sanity check on types, clips to proper range, and converts to (smaller, and consistent) [0,255] format internal static Value WriteSanityCheck(Value color, string name) { if(!(color is NumberValue) && !(color is NumberWithUnitValue)) { throw new InvalidOperationException(name + " must be a number or a percentage, found ["+color+"]"); } if(color is NumberWithUnitValue && ((NumberWithUnitValue)color).Unit != Unit.Percent) { throw new InvalidOperationException(name + " must be a number or a percentage, found ["+color+"]"); } decimal val; if (color is NumberValue) { val = ((NumberValue)color).Value; } else { val = 255m * ((NumberWithUnitValue)color).Value; } if (val > 255) val = 255; if (val < 0) val = 0; return new NumberValue(decimal.Round(val)); }
private static MathValue ParseMathValue(char op, Value lhs, ParserStream stream, IPosition forPosition) { stream.Advance(); // skip operator if (lhs == null) { Current.RecordError(ErrorType.Parser, forPosition, "Expected value, found '" + op + "'"); throw new StoppedParsingException(); } Operator @operator; switch (op) { case '+': @operator = Operator.Plus; break; case '-': @operator = Operator.Minus; break; case '*': @operator = Operator.Mult; break; case '/': @operator = Operator.Div; break; case '%': @operator = Operator.Mod; break; default: throw new InvalidOperationException("Unexpected operator [" + op + "]"); } var rhs = ParseImpl(stream, forPosition, allowSelectorIncludes: false); return new MathValue(lhs, @operator, rhs); }
private static Value UnrollMath(Value value) { var compound = value as CompoundValue; if (compound != null) { var ret = new List<Value>(); foreach (var v in compound.Values) { ret.Add(UnrollMath(v)); } return new CompoundValue(ret); } var comma = value as CommaDelimittedValue; if (comma != null) { var ret = new List<Value>(); foreach (var v in comma.Values) { ret.Add(UnrollMath(v)); } return new CommaDelimittedValue(ret); } var exists = value as LeftExistsValue; if (exists != null) { return new LeftExistsValue(UnrollMath(exists.IfExists)); } var group = value as GroupedValue; if (group != null) return group.Value; var math = value as MathValue; if (math == null) return value; return UnrollMathImpl(math); }
private static Value MinifyValue(Value value) { var comma = value as CommaDelimittedValue; if (comma != null) { var minified = comma.Values.Select(s => MinifyValue(s)).ToList(); return new CommaDelimittedValue(minified); } var compound = value as CompoundValue; if (compound != null) { var minified = compound.Values.Select(s => MinifyValue(s)).ToList(); return new CompoundValue(minified); } if (value is ColorValue) { return MinifyColor((ColorValue)value); } if (value is NumberWithUnitValue) { return MinifyNumberWithUnit((NumberWithUnitValue)value); } if (value is NumberValue) { return MinifyNumberValue((NumberValue)value); } if (value is LinearGradientValue) { return MinifyLinearGradient((LinearGradientValue)value); } if (value is RadialGradientValue) { return MinifyRadialGradient((RadialGradientValue)value); } return value; }
public GroupedValue(Value value) { Value = value; }
private static string ValueToString(Value value) { using (var mem = new StringWriter()) { value.Write(mem); return mem.ToString(); } }
internal LeftExistsValue(Value ifExists) { IfExists = ifExists; }
private static bool IsValidTypeFor(string featureName, Value value) { var validTypes = FeatureValueTypes[featureName.ToLowerInvariant()]; if (!validTypes.Contains(value.GetType())) return false; switch (featureName.ToLowerInvariant()) { case "monochrome": case "color": case "color-index": // Must be a non-negative integer var numValue = ((NumberValue)value).Value; return Math.Sign(numValue) != -1 && Math.Truncate(numValue) == numValue; case "grid": return ((NumberValue)value).Value.In(0, 1); case "orientation": return ((StringValue)value).Value.ToLowerInvariant().In("landscape", "portrait"); case "resolution": return ((NumberWithUnitValue)value).Unit.In(Unit.DPI, Unit.DPCM); case "scan": return ((StringValue)value).Value.ToLowerInvariant().In("progressive", "scan"); } return true; }
private static bool ConvertColorPart(Value val, IPosition position, out decimal part) { part = 0; if (val is NumberWithUnitValue) { var unit = (NumberWithUnitValue)val; if (unit.Unit != Unit.Percent) { Current.RecordError(ErrorType.Compiler, position, "Color parts must be raw numbers or percents, found [" + val + "]"); return false; } var v = unit.Value; if(v > 100) { v = 100; Current.RecordWarning(ErrorType.Compiler, position, "Clipped color-part percent from [" + unit.Value + "] to 100"); } if(v < 0) { v = 0; Current.RecordWarning(ErrorType.Compiler, position, "Clipped color-part percent from [" + unit.Value + "] to 0"); } part = decimal.Round(255m * (v / 100m), 0, MidpointRounding.AwayFromZero); return true; } var noUnit = (NumberValue)val; var x = noUnit.Value; if (x > 255) { x = 255; Current.RecordWarning(ErrorType.Compiler, position, "Clipped color-part from [" + noUnit.Value + "] to 255"); } if (x < 0) { x = 0; Current.RecordWarning(ErrorType.Compiler, position, "Clipped color-part from [" + noUnit.Value + "] to 0"); } if (x <= 1) { x *= 255m; } part = x; return true; }
private static void VerifyColorStop(Value value) { var asCompound = value as CompoundValue; if (asCompound != null) { if (asCompound.Values.Count() != 2) { Current.RecordError(ErrorType.Compiler, value, "color-stops should be composed of two values, one color and one length or percentage"); return; } var first = asCompound.Values.ElementAt(0) as ColorValue; var second = asCompound.Values.ElementAt(1) as NumberWithUnitValue; if (first == null) { Current.RecordError(ErrorType.Compiler, value, "a color-stop's first value should be a color"); return; } if (second == null) { Current.RecordError(ErrorType.Compiler, value, "a color-stop's second value should be a percentage or length"); return; } if (second.Unit == Unit.Percent) { if (second.Value < 0 || second.Value > 100) { Current.RecordError(ErrorType.Compiler, value, "a color-stop's second value, if a percentage, should be between 0% and 100%"); return; } } else { if (!second.Unit.In(Unit.EM, Unit.EX, Unit.CH, Unit.REM, Unit.VH, Unit.VW, Unit.VM, Unit.PX, Unit.MM, Unit.CM, Unit.IN, Unit.PT, Unit.PC)) { Current.RecordError(ErrorType.Compiler, value, "a color-stop's second value, if not a percentage, should be a length"); return; } } return; } if (!(value is ColorValue)) { Current.RecordError(ErrorType.Compiler, value, "a color-stop should be a color if it is composed of only one value"); } }
public MixinParameter(string name, Value defaultValue) { Name = name; DefaultValue = defaultValue; }
internal MathValue(Value lhs, Operator op, Value rhs) { LeftHand = lhs; Operator = op; RightHand = rhs; }
private static void BindParameter(Scope scope, Dictionary<string, MixinBlock> mixinReferences, Dictionary<string, Value> boundVariables, MixinParameter @param, Value value) { if (value is IncludeSelectorValue) { var toMap = (IncludeSelectorValue)value; mixinReferences[@param.Name] = CreateAnonMixin(toMap); return; } if (!(value is FuncValue)) { boundVariables[@param.Name] = value.Bind(scope); return; } var funcVal = value as FuncValue; var asMixin = scope.LookupMixin(funcVal.Name); if (asMixin == null) { var val = scope.LookupVariable(funcVal.Name, -1, -1, null); if (val is IncludeSelectorValue) { var toMap = (IncludeSelectorValue)val; mixinReferences[@param.Name] = CreateAnonMixin(toMap); return; } boundVariables[@param.Name] = funcVal.Bind(scope); } else { mixinReferences[@param.Name] = asMixin; } }
public MinFeatureMedia(string feature, Value min, IPosition forPosition) : base(forPosition) { Feature = feature; Min = min; }