/// <summary> /// Throws an exception if the value is invalid according to the currently set options /// </summary> /// <param name="Value"></param> /// <returns></returns> public void CheckAndThrow(ICssProperty Owner, CssValue Value) { if (Owner is null) { throw new ArgumentNullException(nameof(Owner)); } if (Value is null) { throw new ArgumentNullException(nameof(Value)); } Contract.EndContractBlock(); if (!Is_Valid_Value_Type(Value.Type)) { throw new CssException($"The property({Name}) cannot be set to an {Enum.GetName(typeof(ECssValueTypes), Value.Type)}!"); } switch (Value.Type) { case ECssValueTypes.KEYWORD: { // check this value against our keyword whitelist if (KeywordWhitelist != null && KeywordWhitelist.Count > 0) { if (!KeywordWhitelist.Contains(Value.AsString())) { throw new CssException($"Property({Name}) does not accept '{Value.AsString()}' as a value!"); } } } break; } }
/// <summary> /// Throws an exception if the value is invalid according to the currently set options /// </summary> /// <param name="Value"></param> /// <returns></returns> public void CheckAndThrow(ICssProperty Owner, CssValue Value) { if (Owner is null) { throw new ArgumentNullException(nameof(Owner)); } if (Value is null) { throw new ArgumentNullException(nameof(Value)); } Contract.EndContractBlock(); if (!Is_Valid_Value_Type(Value.Type)) { throw new CssException($"The property({Enum.GetName(typeof(EMediaFeatureName), Name.Value)}) cannot be set to an {Enum.GetName(typeof(ECssValueTypes), Value.Type)}!"); } switch (Value.Type) { case ECssValueTypes.KEYWORD: { // check this value against our keyword whitelist if (KeywordWhitelist is object && KeywordWhitelist.Count > 0) { //if (!Array.Exists(keywordWhitelist, x => x.Equals(Value.AsString(), StringComparison.InvariantCultureIgnoreCase))) if (!KeywordWhitelist.Contains(Value.AsString())) { throw new CssException($"Property({Enum.GetName(typeof(EMediaFeatureName), Name.Value)}) does not accept '{Value.AsString()}' as a value!"); } } } break; } }
static bool Compare(Document document, CssValue ValueA, CssValue ValueB, EMediaOperator Op) { /* An Excerpt: * "If a media feature references a concept which does not exist on the device where the UA is running (for example, speech UAs do not have a concept of “width”), the media feature must always evaluate to false." */ double A, B; /* First resolve these values to numbers we can compare */ if (ValueA.Type == ECssValueTypes.KEYWORD) { if (!Lookup.TryEnum(ValueA.AsString(), out EMediaFeatureName _)) {/* If we cant find this keyword then we treat it as if it were an unsupported feature */ return(false); } A = (double)Resolve_Media_Name_Value(document, ValueA.AsEnum <EMediaFeatureName>()); } else { A = ValueA.AsDecimal(); } if (ValueB.Type == ECssValueTypes.KEYWORD) { if (!Lookup.TryEnum(ValueB.AsString(), out EMediaFeatureName _)) {/* If we cant find this keyword then we treat it as if it were an unsupported feature */ return(false); } B = (double)Resolve_Media_Name_Value(document, ValueB.AsEnum <EMediaFeatureName>()); } else { B = ValueB.AsDecimal(); } /* Compare them and return the result */ switch (Op) { case EMediaOperator.EqualTo: { return(A == B); } case EMediaOperator.LessThan: { return(A < B); } case EMediaOperator.GreaterThan: { return(A > B); } case EMediaOperator.LessThanEq: { return(A < B || (A == B)); } case EMediaOperator.GreaterThanEq: { return(A > B || (A == B)); } } return(false); }
private bool Try_Match(Document document) { switch (Context) { case EMediaFeatureContext.Boolean: { /* * ...the media feature is evaluated in a boolean context. * If the feature would be true for any value other than the number 0, a <dimension> with the value 0, or the keyword none, the media feature evaluates to true. * Otherwise, it evaluates to false. */ CssValue value = Values[0]; if (!Lookup.TryEnum(value.AsString(), out EMediaFeatureName nameLookup)) { /* This feature is not supported (or maybe valid) so we need to treat it as if it simply doesnt match */ IsValid = false; return(false); } // CssValue valueA = Values[0]; CssValue valueB = Values[1]; switch (valueB.Type) { case ECssValueTypes.KEYWORD: { return(Compare_Keyword(document, nameLookup, valueB.AsString())); } case ECssValueTypes.INTEGER: case ECssValueTypes.NUMBER: { double A = (double)Resolve_Media_Name_Value(document, nameLookup); double B = valueB.AsDecimal(); return(!(A == B)); } case ECssValueTypes.DIMENSION: case ECssValueTypes.RESOLUTION: { double A = (double)Resolve_Media_Name_Value(document, nameLookup); double B = valueB.Resolve(document.cssUnitResolver); return(!(A == B)); } } } break; case EMediaFeatureContext.Range: { /* Compare all value/operator pairs */ for (int i = 1; i < Operators.Length; i++) { CssValue A = Values[i - 1]; CssValue B = Values[i]; var op = Operators[i - 1]; if (!Compare(document, A, B, op)) { return(false); } } return(true); } } return(false); }