Transition?ParseValue(CSSValueList values) { CSSPrimitiveValue <Time> delay = null; CSSPrimitiveValue <Time> duration = null; CSSTimingValue function = null; String property = null; for (var i = 0; i < values.Length; i++) { if (function == null && (function = values[i].ToTimingFunction()) != null) { continue; } if (property == null && values[i] is CSSIdentifierValue) { property = ((CSSIdentifierValue)values[i]).Value; continue; } if (values[i] is CSSPrimitiveValue <Time> ) { var time = (CSSPrimitiveValue <Time>)values[i]; if (duration == null) { duration = time; continue; } else if (delay == null) { delay = time; continue; } } return(null); } return(new Transition { Delay = delay != null ? delay.Value : Time.Zero, Duration = duration != null ? duration.Value : Time.Zero, Timing = function ?? CSSTimingValue.Ease, Property = property ?? "all" }); }
Animation?ParseValue(CSSValueList values) { CSSPrimitiveValue <Time> delay = null; CSSPrimitiveValue <Time> duration = null; CSSPrimitiveValue <Number> iterationCount = null; CSSTimingValue function = null; AnimationFillMode? fillMode = null; AnimationDirection? direction = null; String name = null; for (var i = 0; i < values.Length; i++) { if (function == null && (function = values[i].ToTimingFunction()) != null) { continue; } if (values[i] is CSSIdentifierValue) { if (name == null) { name = ((CSSIdentifierValue)values[i]).Value; continue; } if (!fillMode.HasValue && (fillMode = values[i].ToFillMode()).HasValue) { continue; } if (!direction.HasValue && (direction = values[i].ToDirection()).HasValue) { continue; } } if (values[i] is CSSPrimitiveValue <Time> ) { var time = (CSSPrimitiveValue <Time>)values[i]; if (duration == null) { duration = time; continue; } else if (delay == null) { delay = time; continue; } } if (iterationCount == null && values[i] is CSSPrimitiveValue <Number> ) { iterationCount = (CSSPrimitiveValue <Number>)values[i]; continue; } return(null); } return(new Animation { Delay = delay != null ? delay.Value : Time.Zero, Duration = duration != null ? duration.Value : Time.Zero, Timing = function ?? CSSTimingValue.Ease, Name = name ?? "none", IterationCount = iterationCount != null ? iterationCount.Value.Value : 1f, FillMode = fillMode.HasValue ? fillMode.Value : AnimationFillMode.None, Direction = direction.HasValue ? direction.Value : AnimationDirection.Normal }); }
/// <summary> /// Creates a single value from the given source. /// </summary> /// <param name="source">The token iterator.</param> /// <returns>The value or NULL.</returns> CSSValue CreateValue(IEnumerator <CssToken> source) { CSSValue value = null; switch (source.Current.Type) { case CssTokenType.String: // 'i am a string' value = new CSSPrimitiveValue(UnitType.String, ((CssStringToken)source.Current).Data); break; case CssTokenType.Url: // url('this is a valid URL') value = new CSSPrimitiveValue(UnitType.Uri, ((CssStringToken)source.Current).Data); break; case CssTokenType.Ident: // ident value = new CSSPrimitiveValue(UnitType.Ident, ((CssKeywordToken)source.Current).Data); break; case CssTokenType.Percentage: // 5% value = new CSSPrimitiveValue(UnitType.Percentage, ((CssUnitToken)source.Current).Data); break; case CssTokenType.Dimension: // 3px value = new CSSPrimitiveValue(((CssUnitToken)source.Current).Unit, ((CssUnitToken)source.Current).Data); break; case CssTokenType.Number: // 173 value = new CSSPrimitiveValue(UnitType.Number, ((CssNumberToken)source.Current).Data); break; case CssTokenType.Hash: // #string HtmlColor color; if (HtmlColor.TryFromHex(((CssKeywordToken)source.Current).Data, out color)) { value = new CSSPrimitiveValue(color); } break; case CssTokenType.Delim: // e.g. #0F3, #012345, ... if (((CssDelimToken)source.Current).Data == '#') { String hash = String.Empty; while (source.MoveNext()) { var stop = false; switch (source.Current.Type) { case CssTokenType.Number: case CssTokenType.Dimension: case CssTokenType.Ident: var rest = source.Current.ToValue(); if (hash.Length + rest.Length <= 6) { hash += rest; } else { stop = true; } break; default: stop = true; break; } if (stop || hash.Length == 6) { break; } } if (HtmlColor.TryFromHex(hash, out color)) { value = new CSSPrimitiveValue(color); } } break; case CssTokenType.Function: // rgba(255, 255, 20, 0.5) value = CreateFunction(source); break; } return(value); }
/// <summary> /// Determines if the given value represents a valid state of this property. /// </summary> /// <param name="value">The state that should be used.</param> /// <returns>True if the state is valid, otherwise false.</returns> protected override Boolean IsValid(CSSValue value) { if (value != CSSValue.Inherit) { var values = value as CSSValueList ?? new CSSValueList(value); var image = new CSSValueList(); var position = new CSSValueList(); var size = new CSSValueList(); var repeat = new CSSValueList(); var attachment = new CSSValueList(); var origin = new CSSValueList(); var clip = new CSSValueList(); var color = new CSSPrimitiveValue<Color>(Color.Transparent); var list = values.ToList(); for (int i = 0; i < list.Count; i++) { var entry = list[i]; var hasImage = false; var hasPosition = false; var hasRepeat = false; var hasAttachment = false; var hasBox = false; var hasColor = i + 1 != list.Count; for (int j = 0; j < entry.Length; j++) { if (!hasPosition && (entry[j].IsOneOf("top", "left", "center", "bottom", "right") || entry[j].AsCalc() != null)) { hasPosition = true; position.Add(entry[j]); while (j + 1 < entry.Length && (entry[j + 1].IsOneOf("top", "left", "center", "bottom", "right") || entry[j + 1].AsCalc() != null)) position.Add(entry[++j]); if (j + 1 < entry.Length && entry[j + 1] == CSSValue.Delimiter) { j += 2; if (j < entry.Length && (entry[j].IsOneOf("auto", "contain", "cover") || entry[j].AsCalc() != null)) { size.Add(entry[j]); if (j + 1 < entry.Length && (entry[j + 1].Is("auto") || entry[j + 1].AsCalc() != null)) size.Add(entry[++j]); } else return false; } else size.Add(new CSSIdentifierValue("auto")); continue; } if (!hasImage && entry[j].AsImage() != null) { hasImage = true; image.Add(entry[j]); } else if (!hasRepeat && entry[j].IsOneOf("repeat-x", "repeat-y", "repeat", "space", "round", "no-repeat")) { hasRepeat = true; repeat.Add(entry[j]); if (j + 1 < entry.Length && entry[j + 1].IsOneOf("repeat", "space", "round", "no-repeat")) repeat.Add(entry[++j]); } else if (!hasAttachment && entry[j].IsOneOf("local", "fixed", "scroll")) { hasAttachment = true; attachment.Add(entry[j]); } else if (!hasBox && entry[j].ToBoxModel().HasValue) { hasBox = true; origin.Add(entry[j]); if (j + 1 < entry.Length && entry[j + 1].ToBoxModel().HasValue) clip.Add(entry[++j]); else clip.Add(new CSSIdentifierValue("border-box")); } else { if (hasColor) return false; hasColor = true; color = entry[j].AsColor(); if (color == null) return false; } } if (!hasImage) image.Add(new CSSIdentifierValue("none")); if (!hasPosition) { position.Add(new CSSIdentifierValue("center")); size.Add(new CSSIdentifierValue("auto")); } if (!hasRepeat) repeat.Add(new CSSIdentifierValue("repeat")); if (!hasAttachment) attachment.Add(new CSSIdentifierValue("scroll")); if (!hasBox) { origin.Add(new CSSIdentifierValue("border-box")); clip.Add(new CSSIdentifierValue("border-box")); } if (i + 1 < list.Count) { image.Add(CSSValue.Separator); position.Add(CSSValue.Separator); size.Add(CSSValue.Separator); repeat.Add(CSSValue.Separator); attachment.Add(CSSValue.Separator); origin.Add(CSSValue.Separator); clip.Add(CSSValue.Separator); } } _image.Value = image; _position.Value = position; _repeat.Value = repeat; _attachment.Value = attachment; _origin.Value = origin; _size.Value = size; _clip.Value = clip; _color.Value = color; } return true; }
protected override Boolean IsValid(CSSValue value) { if (value != CSSValue.Inherit) { var values = value as CSSValueList ?? new CSSValueList(value); var image = new CSSValueList(); var position = new CSSValueList(); var size = new CSSValueList(); var repeat = new CSSValueList(); var attachment = new CSSValueList(); var origin = new CSSValueList(); var clip = new CSSValueList(); var color = new CSSPrimitiveValue <Color>(AngleSharp.DOM.Color.Transparent); var list = values.ToList(); for (int i = 0; i < list.Count; i++) { var entry = list[i]; var hasImage = false; var hasPosition = false; var hasRepeat = false; var hasAttachment = false; var hasBox = false; var hasColor = i + 1 != list.Count; for (int j = 0; j < entry.Length; j++) { if (!hasPosition && (entry[j].IsOneOf("top", "left", "center", "bottom", "right") || entry[j].AsCalc() != null)) { hasPosition = true; position.Add(entry[j]); while (j + 1 < entry.Length && (entry[j + 1].IsOneOf("top", "left", "center", "bottom", "right") || entry[j + 1].AsCalc() != null)) { position.Add(entry[++j]); } if (j + 1 < entry.Length && entry[j + 1] == CSSValue.Delimiter) { j += 2; if (j < entry.Length && (entry[j].IsOneOf("auto", "contain", "cover") || entry[j].AsCalc() != null)) { size.Add(entry[j]); if (j + 1 < entry.Length && (entry[j + 1].Is("auto") || entry[j + 1].AsCalc() != null)) { size.Add(entry[++j]); } } else { return(false); } } else { size.Add(new CSSIdentifierValue("auto")); } continue; } if (!hasImage && entry[j].AsImage() != null) { hasImage = true; image.Add(entry[j]); } else if (!hasRepeat && entry[j].IsOneOf("repeat-x", "repeat-y", "repeat", "space", "round", "no-repeat")) { hasRepeat = true; repeat.Add(entry[j]); if (j + 1 < entry.Length && entry[j + 1].IsOneOf("repeat", "space", "round", "no-repeat")) { repeat.Add(entry[++j]); } } else if (!hasAttachment && entry[j].IsOneOf("local", "fixed", "scroll")) { hasAttachment = true; attachment.Add(entry[j]); } else if (!hasBox && entry[j].ToBoxModel().HasValue) { hasBox = true; origin.Add(entry[j]); if (j + 1 < entry.Length && entry[j + 1].ToBoxModel().HasValue) { clip.Add(entry[++j]); } else { clip.Add(new CSSIdentifierValue("border-box")); } } else { if (hasColor) { return(false); } hasColor = true; color = entry[j].AsColor(); if (color == null) { return(false); } } } if (!hasImage) { image.Add(new CSSIdentifierValue("none")); } if (!hasPosition) { position.Add(new CSSIdentifierValue("center")); size.Add(new CSSIdentifierValue("auto")); } if (!hasRepeat) { repeat.Add(new CSSIdentifierValue("repeat")); } if (!hasAttachment) { attachment.Add(new CSSIdentifierValue("scroll")); } if (!hasBox) { origin.Add(new CSSIdentifierValue("border-box")); clip.Add(new CSSIdentifierValue("border-box")); } if (i + 1 < list.Count) { image.Add(CSSValue.Separator); position.Add(CSSValue.Separator); size.Add(CSSValue.Separator); repeat.Add(CSSValue.Separator); attachment.Add(CSSValue.Separator); origin.Add(CSSValue.Separator); clip.Add(CSSValue.Separator); } } _image.Value = image; _position.Value = position; _repeat.Value = repeat; _attachment.Value = attachment; _origin.Value = origin; _size.Value = size; _clip.Value = clip; _color.Value = color; } return(true); }