/// <summary> /// Consumes a sequence of tokens representing a storyboard target selector. /// </summary> /// <param name="state">The parser state.</param> /// <returns>A new <see cref="UvssSelector"/> object representing the selector that was consumed.</returns> private static UvssSelector ConsumeStoryboardTargetSelector(UvssParserState state) { var selector = default(UvssSelector); if (state.CurrentToken.TokenType == UvssLexerTokenType.OpenParenthesis) { var tokens = GetTokensBetweenParentheses(state); var tokensState = new UvssParserState(state.Source, tokens); selector = ConsumeSelector(tokensState, true); } state.AdvanceBeyondWhiteSpace(); return selector; }
/// <summary> /// Consumes a sequence of tokens representing a storyboard animation. /// </summary> /// <param name="state">The parser state.</param> /// <returns>A new <see cref="UvssStoryboardAnimation"/> object representing the animation that was consumed.</returns> private static UvssStoryboardAnimation ConsumeStoryboardAnimation(UvssParserState state) { state.AdvanceBeyondWhiteSpace(); if (state.IsPastEndOfStream) return null; var animationToken = state.TryConsumeNonWhiteSpace(); MatchTokenOrFail(state, animationToken, UvssLexerTokenType.Identifier, "animation"); var propertyToken = state.TryConsumeNonWhiteSpace(); MatchTokenOrFail(state, propertyToken, UvssLexerTokenType.Identifier); var propertyNameStart = propertyToken.Value.Start; var propertyNameLength = propertyToken.Value.Length; while (true) { if (state.CurrentToken.TokenType != UvssLexerTokenType.Identifier) break; propertyNameLength += state.CurrentToken.Length; state.Consume(); } AdvanceBeyondWhiteSpaceOrFail(state); var navigationExpression = ConsumeOptionalNavigationExpression(state); var keyframes = ConsumeStoryboardKeyframeList(state); return new UvssStoryboardAnimation(state.Source.Substring(propertyNameStart, propertyNameLength), navigationExpression, keyframes); }
/// <summary> /// Consumes a sequence of tokens representing a UVSS property trigger condition. /// </summary> /// <param name="state">The parser state.</param> /// <returns>The trigger condition that was parsed.</returns> private static PropertyTriggerCondition ConsumePropertyTriggerCondition(UvssParserState state) { state.AdvanceBeyondWhiteSpace(); var propertyToken = state.TryConsumeNonWhiteSpace(); MatchTokenOrFail(state, propertyToken, UvssLexerTokenType.StyleName); state.AdvanceBeyondWhiteSpace(); var opToken = state.TryConsumeNonWhiteSpace(); MatchTokenOrFail(state, opToken, UvssLexerTokenType.ComparisonOperator); var opValue = default(TriggerComparisonOp); switch (opToken.Value.Value) { case "=": opValue = TriggerComparisonOp.Equals; break; case "<>": opValue = TriggerComparisonOp.NotEquals; break; case "<": opValue = TriggerComparisonOp.LessThan; break; case "<=": opValue = TriggerComparisonOp.LessThanOrEqualTo; break; case ">": opValue = TriggerComparisonOp.GreaterThan; break; case ">=": opValue = TriggerComparisonOp.GreaterThanOrEqualTo; break; } state.AdvanceBeyondWhiteSpace(); var valueTokens = GetTokensBetweenCurlyBraces(state); var value = String.Join(String.Empty, valueTokens.Select(x => x.Value)).Trim(); return new PropertyTriggerCondition(opValue, propertyToken.Value.Value, value); }
/// <summary> /// Consumes a sequence of tokens representing a storyboard target filter. /// </summary> /// <param name="state">The parser state.</param> /// <returns>A new <see cref="UvssStoryboardTargetFilter"/> object representing the filter that was consumed.</returns> private static UvssStoryboardTargetFilter ConsumeStoryboardTargetFilter(UvssParserState state) { AdvanceBeyondWhiteSpaceOrFail(state); var filter = new UvssStoryboardTargetFilter(); if (state.CurrentToken.TokenType != UvssLexerTokenType.Identifier) { filter.Add("FrameworkElement"); } else { while (state.CurrentToken.TokenType == UvssLexerTokenType.Identifier) { if (state.IsPastEndOfStream) ThrowUnexpectedEOF(state); var type = state.CurrentToken.Value; filter.Add(type); state.Consume(); state.AdvanceBeyondWhiteSpace(); } } return filter; }
/// <summary> /// Consumes a sequence of tokens representing a UVSS selector. /// </summary> /// <param name="state">The parser state.</param> /// <param name="allowEOF">A value indicating whether hitting the end of file is valid.</param> /// <returns>A new <see cref="UvssSelector"/> object representing the selector that was consumed.</returns> private static UvssSelector ConsumeSelector(UvssParserState state, Boolean allowEOF = false) { state.AdvanceBeyondWhiteSpace(); var parts = new List<UvssSelectorPart>(); var pseudoClass = false; while (true) { var part = ConsumeSelectorPart(state, allowEOF, !pseudoClass, parts.Any()); if (part != null) { if (!String.IsNullOrEmpty(part.PseudoClass)) pseudoClass = true; parts.Add(part); } if (state.IsPastEndOfStream) { if (allowEOF) { break; } ThrowUnexpectedEOF(state); } if (state.CurrentToken.TokenType == UvssLexerTokenType.Comma) break; if (state.CurrentToken.TokenType != UvssLexerTokenType.WhiteSpace) break; state.Advance(); } return new UvssSelector(parts); }
/// <summary> /// Consumes a sequence of tokens representing a UVSS style list. /// </summary> /// <param name="state">The parser state.</param> /// <param name="styles">A <see cref="UvssStyleCollection"/> object representing the style list that was consumed.</param> /// <param name="triggers">A <see cref="UvssTriggerCollection"/> object representing the trigger list that was consumed.</param> private static void ConsumeStyleList(UvssParserState state, out UvssStyleCollection styles, out UvssTriggerCollection triggers) { state.AdvanceBeyondWhiteSpace(); var styleListTokens = GetTokensBetweenCurlyBraces(state); var styleListState = new UvssParserState(state.Source, styleListTokens); var tempStyles = new List<UvssStyle>(); var tempTriggers = new List<Trigger>(); while (ConsumeStyleOrTrigger(styleListState, tempStyles, tempTriggers)) { } styles = new UvssStyleCollection(tempStyles); triggers = new UvssTriggerCollection(tempTriggers); }
/// <summary> /// Advances the parser state beyond any current white space. If the end of the stream is reached, /// a syntax exception is thrown. /// </summary> /// <param name="state">The parser state.</param> private static void AdvanceBeyondWhiteSpaceOrFail(UvssParserState state) { state.AdvanceBeyondWhiteSpace(); if (state.IsPastEndOfStream) { ThrowUnexpectedEOF(state); } }
/// <summary> /// Consumes an optional token which represents an easing function. /// </summary> /// <param name="state">The parser state.</param> /// <returns>A string which represents one of the standard easing functions.</returns> private static String ConsumeOptionalEasingFunction(UvssParserState state) { if (state.CurrentToken.TokenType == UvssLexerTokenType.Identifier) { var easing = state.CurrentToken.Value; state.Advance(); state.AdvanceBeyondWhiteSpace(); return easing; } return null; }
/// <summary> /// Consumes a 'play-storyboard' trigger action. /// </summary> /// <param name="state">The parser state.</param> /// <param name="trigger">The trigger to populate with actions.</param> /// <returns><c>true</c> if a trigger action was successfully consumed; otherwise, <c>false</c>.</returns> private static Boolean ConsumePlayStoryboardTriggerAction(UvssParserState state, Trigger trigger) { var selector = default(UvssSelector); state.AdvanceBeyondWhiteSpace(); if (state.CurrentToken.TokenType == UvssLexerTokenType.OpenParenthesis) { var tokens = GetTokensBetweenParentheses(state); var tokensState = new UvssParserState(state.Source, tokens); selector = ConsumeSelector(tokensState, true); } state.AdvanceBeyondWhiteSpace(); var value = GetStringBetweenCurlyBraces(state); var action = new PlayStoryboardTriggerAction(value, selector); trigger.Actions.Add(action); return true; }
/// <summary> /// Gets the source string between a matching pair of curly braces. /// </summary> /// <param name="state">The parser state.</param> /// <returns>The source string between the specified matching pair of tokens.</returns> private static String GetStringBetweenCurlyBraces(UvssParserState state) { state.AdvanceBeyondWhiteSpace(); var valueTokens = GetTokensBetweenCurlyBraces(state); var value = String.Join(String.Empty, valueTokens.Select(x => x.Value)).Trim(); return value; }
/// <summary> /// Consumes a 'set' trigger action. /// </summary> /// <param name="state">The parser state.</param> /// <param name="trigger">The trigger to populate with actions.</param> /// <returns><c>true</c> if a trigger action was successfully consumed; otherwise, <c>false</c>.</returns> private static Boolean ConsumeSetTriggerAction(UvssParserState state, Trigger trigger) { var selector = default(UvssSelector); state.AdvanceBeyondWhiteSpace(); var propertyNameToken = state.TryConsumeNonWhiteSpace(); MatchTokenOrFail(state, propertyNameToken, UvssLexerTokenType.StyleName); state.AdvanceBeyondWhiteSpace(); if (state.CurrentToken.TokenType == UvssLexerTokenType.OpenParenthesis) { var selectorOpenParensToken = state.TryConsumeNonWhiteSpace(); MatchTokenOrFail(state, selectorOpenParensToken, UvssLexerTokenType.OpenParenthesis); selector = ConsumeSelector(state, false); var selectorCloseParensToken = state.TryConsumeNonWhiteSpace(); MatchTokenOrFail(state, selectorCloseParensToken, UvssLexerTokenType.CloseParenthesis); } state.AdvanceBeyondWhiteSpace(); var value = GetStringBetweenCurlyBraces(state); var action = new SetTriggerAction(propertyNameToken.Value.Value, selector, value); trigger.Actions.Add(action); return true; }
/// <summary> /// Consumes a list of trigger actions. /// </summary> /// <param name="state">The parser state.</param> /// <param name="trigger">The trigger to populate with actions.</param> /// <returns><c>true</c> if a trigger action list was successfully consumed; otherwise, <c>false</c>.</returns> private static Boolean ConsumeTriggerActions(UvssParserState state, Trigger trigger) { var openCurlyToken = state.TryConsumeNonWhiteSpace(); MatchTokenOrFail(state, openCurlyToken, UvssLexerTokenType.OpenCurlyBrace); while (true) { state.AdvanceBeyondWhiteSpace(); var nextToken = state.TryConsumeNonWhiteSpace(); if (nextToken.HasValue && nextToken.Value.TokenType == UvssLexerTokenType.CloseCurlyBrace) { return true; } MatchTokenOrFail(state, nextToken, UvssLexerTokenType.Identifier); if (String.Equals(nextToken.Value.Value, "set", StringComparison.InvariantCultureIgnoreCase)) { if (!ConsumeSetTriggerAction(state, trigger)) return false; continue; } if (String.Equals(nextToken.Value.Value, "play-sfx", StringComparison.InvariantCultureIgnoreCase)) { if (!ConsumePlaySfxTriggerAction(state, trigger)) return false; continue; } if (String.Equals(nextToken.Value.Value, "play-storyboard", StringComparison.InvariantCultureIgnoreCase)) { if (!ConsumePlayStoryboardTriggerAction(state, trigger)) return false; continue; } ThrowExpectedValue(state, nextToken.Value, "set|play-sfx|play-storyboard"); } }
/// <summary> /// Consumes a sequence of tokens representing a UVSS event trigger. /// </summary> /// <param name="state">The parser state.</param> /// <param name="triggers">The list containing the triggers being created.</param> /// <returns><c>true</c> if a trigger was successfully consumed; otherwise, <c>false</c>.</returns> private static Boolean ConsumeEventTrigger(UvssParserState state, List<Trigger> triggers) { state.AdvanceBeyondWhiteSpace(); var eventNameToken = state.TryConsumeNonWhiteSpace(); MatchTokenOrFail(state, eventNameToken, UvssLexerTokenType.StyleName); state.AdvanceBeyondWhiteSpace(); var handled = false; var setHandled = false; if (state.CurrentToken.TokenType == UvssLexerTokenType.OpenParenthesis) { state.Consume(); while (true) { if (state.CurrentToken.TokenType == UvssLexerTokenType.CloseParenthesis) { state.Consume(); break; } var argToken = state.TryConsumeNonWhiteSpace(); MatchTokenOrFail(state, argToken, UvssLexerTokenType.Identifier); if (String.Equals(argToken.Value.Value, "handled", StringComparison.InvariantCultureIgnoreCase)) { handled = true; continue; } if (String.Equals(argToken.Value.Value, "set-handled", StringComparison.InvariantCultureIgnoreCase)) { setHandled = true; continue; } return false; } } var trigger = new EventTrigger(eventNameToken.Value.Value, handled, setHandled); if (!ConsumeTriggerActions(state, trigger)) return false; triggers.Add(trigger); return true; }
/// <summary> /// Consumes a sequence of tokens representing an optional navigation expression. /// </summary> /// <param name="state">The parser state.</param> /// <returns>A new <see cref="UvssNavigationExpression"/> object representing the animation that was consumed.</returns> private static UvssNavigationExpression ConsumeOptionalNavigationExpression(UvssParserState state) { if (state.CurrentToken.TokenType == UvssLexerTokenType.Pipe) { var navigationProperty = default(String); var navigationPropertyType = default(String); var navigationPropertyIndex = default(Int32?); state.Consume(); state.AdvanceBeyondWhiteSpace(); var propertyToken = state.TryConsumeNonWhiteSpace(); MatchTokenOrFail(state, propertyToken, UvssLexerTokenType.Identifier); navigationProperty = propertyToken.Value.Value; state.AdvanceBeyondWhiteSpace(); if (state.CurrentToken.TokenType == UvssLexerTokenType.IndexOperator) { var indexToken = state.Consume(); state.AdvanceBeyondWhiteSpace(); var indexValue = indexToken.Value; navigationPropertyIndex = Int32.Parse(indexValue.Substring(1, indexValue.Length - 2)); } if (state.CurrentToken.TokenType == UvssLexerTokenType.AsOperator) { state.Consume(); var propertyTypeToken = state.TryConsumeNonWhiteSpace(); MatchTokenOrFail(state, propertyTypeToken, UvssLexerTokenType.Identifier); navigationPropertyType = propertyTypeToken.Value.Value; } AdvanceBeyondWhiteSpaceOrFail(state); return new UvssNavigationExpression(navigationProperty, navigationPropertyType, navigationPropertyIndex); } return null; }
/// <summary> /// Consumes a sequence of tokens representing a UVSS rule. /// </summary> /// <param name="state">The parser state.</param> /// <returns>A new <see cref="UvssRule"/> object representing the rule that was consumed.</returns> private static UvssRule ConsumeRule(UvssParserState state) { state.AdvanceBeyondWhiteSpace(); if (state.IsPastEndOfStream) return null; var selectors = ConsumeSelectorList(state); var navigation = ConsumeOptionalNavigationExpression(state); var styles = default(UvssStyleCollection); var triggers = default(UvssTriggerCollection); ConsumeStyleList(state, out styles, out triggers); return new UvssRule(selectors, navigation, styles, triggers); }
/// <summary> /// Consumes a sequence of tokens representing a storyboard keyframe. /// </summary> /// <param name="state">The parser state.</param> /// <returns>A new <see cref="UvssStoryboardKeyframe"/> object representing the keyframe that was consumed.</returns> private static UvssStoryboardKeyframe ConsumeStoryboardKeyframe(UvssParserState state) { state.AdvanceBeyondWhiteSpace(); if (state.IsPastEndOfStream) return null; var keyframeToken = state.TryConsumeNonWhiteSpace(); MatchTokenOrFail(state, keyframeToken, UvssLexerTokenType.Identifier, "keyframe"); var timeToken = state.TryConsumeNonWhiteSpace(); MatchTokenOrFail(state, timeToken, UvssLexerTokenType.Number); AdvanceBeyondWhiteSpaceOrFail(state); var easing = ConsumeOptionalEasingFunction(state); var valueTokens = GetTokensBetweenCurlyBraces(state); var value = String.Join(String.Empty, valueTokens.Select(x => x.Value)); var time = Double.Parse(timeToken.Value.Value); return new UvssStoryboardKeyframe(easing, value, time); }
/// <summary> /// Consumes a sequence of tokens representing a storyboard. /// </summary> /// <param name="state">The parser state.</param> /// <returns>A new <see cref="UvssStoryboard"/> object representing the storyboard that was consumed.</returns> private static UvssStoryboard ConsumeStoryboard(UvssParserState state) { state.AdvanceBeyondWhiteSpace(); if (state.IsPastEndOfStream) return null; if (state.CurrentToken.TokenType != UvssLexerTokenType.Identifier) return null; if (!state.CurrentToken.Value.StartsWith("@")) return null; var id = state.Consume(); var loopBehavior = ConsumeOptionalLoopBehavior(state); var targets = ConsumeStoryboardTargetList(state); return new UvssStoryboard(id.Value.Substring(1), loopBehavior, targets); }
/// <summary> /// Consumes a sequence of tokens representing a UVSS selector list. /// </summary> /// <param name="state">The parser state.</param> /// <returns>A new <see cref="UvssSelectorCollection"/> object representing the selector list that was consumed.</returns> private static UvssSelectorCollection ConsumeSelectorList(UvssParserState state) { state.AdvanceBeyondWhiteSpace(); var selectors = new List<UvssSelector>(); while (true) { var selector = ConsumeSelector(state); selectors.Add(selector); AdvanceBeyondWhiteSpaceOrFail(state); if (state.CurrentToken.TokenType != UvssLexerTokenType.Comma) break; state.Advance(); } return new UvssSelectorCollection(selectors); }
/// <summary> /// Consumes a sequence of tokens representing a list of storyboard targets. /// </summary> /// <param name="state">The parser state.</param> /// <returns>A new <see cref="UvssStoryboardTargetCollection"/> object representing the target collection that was consumed.</returns> private static UvssStoryboardTargetCollection ConsumeStoryboardTargetList(UvssParserState state) { state.AdvanceBeyondWhiteSpace(); var target = default(UvssStoryboardTarget); var targets = new UvssStoryboardTargetCollection(); var targetsTokens = GetTokensBetweenCurlyBraces(state); var targetsState = new UvssParserState(state.Source, targetsTokens); while ((target = ConsumeStoryboardTarget(targetsState)) != null) { targets.Add(target); } return targets; }
/// <summary> /// Consumes a sequence of tokens representing a UVSS selector part. /// </summary> /// <param name="state">The parser state.</param> /// <param name="allowEOF">A value indicating whether hitting the end of file is valid.</param> /// <param name="allowPseudoClass">A value indicating whether parts with pseduo classes are valid.</param> /// <param name="allowChild">A value indicating whether this selector part can be an immediate child.</param> /// <returns>A new <see cref="UvssSelectorPart"/> object representing the selector part that was consumed.</returns> private static UvssSelectorPart ConsumeSelectorPart(UvssParserState state, Boolean allowEOF, Boolean allowPseudoClass, Boolean allowChild) { var element = default(String); var id = default(String); var pseudoClass = default(String); var classes = new List<String>(); var valid = false; var qualifier = UvssSelectorPartQualifier.None; var universal = false; var elementIsExact = false; while (true) { if (state.IsPastEndOfStream) { if (allowEOF && (qualifier == UvssSelectorPartQualifier.None || valid)) { break; } ThrowUnexpectedEOF(state); } var token = state.CurrentToken; if (token.TokenType == UvssLexerTokenType.WhiteSpace || token.TokenType == UvssLexerTokenType.Comma || token.TokenType == UvssLexerTokenType.OpenCurlyBrace || token.TokenType == UvssLexerTokenType.Pipe) { if (qualifier != UvssSelectorPartQualifier.None && !valid) { ThrowUnexpectedToken(state, token); } break; } if (token.TokenType == UvssLexerTokenType.ChildSelector || token.TokenType == UvssLexerTokenType.LogicalChildSelector || token.TokenType == UvssLexerTokenType.TemplatedChildSelector) { if (!allowChild) ThrowUnexpectedToken(state, token); switch (token.TokenType) { case UvssLexerTokenType.ChildSelector: qualifier = UvssSelectorPartQualifier.VisualChild; break; case UvssLexerTokenType.LogicalChildSelector: qualifier = UvssSelectorPartQualifier.LogicalChild; break; case UvssLexerTokenType.TemplatedChildSelector: qualifier = UvssSelectorPartQualifier.TemplatedChild; break; } state.Advance(); state.AdvanceBeyondWhiteSpace(); continue; } if (token.TokenType == UvssLexerTokenType.Identifier || token.TokenType == UvssLexerTokenType.UniversalSelector) { if (!String.IsNullOrEmpty(pseudoClass)) ThrowUnexpectedToken(state, token); state.Advance(); if (token.TokenType == UvssLexerTokenType.UniversalSelector) { valid = true; universal = true; continue; } else { var typename = default(String); var specific = false; if (IsSelectorForElement(token.Value, out typename, out specific)) { if (element != null || universal) ThrowUnexpectedValue(state, token); valid = true; element = typename; elementIsExact = specific; continue; } } if (IsSelectorForID(token.Value)) { if (id != null) ThrowUnexpectedValue(state, token); valid = true; id = token.Value; continue; } valid = true; classes.Add(token.Value); continue; } if (token.TokenType == UvssLexerTokenType.Colon) { if (!valid) ThrowUnexpectedToken(state, token); state.Advance(); var identifier = state.TryConsume(); if (identifier == null) ThrowUnexpectedEOF(state); if (identifier.Value.TokenType != UvssLexerTokenType.Identifier) ThrowExpectedToken(state, identifier.Value, UvssLexerTokenType.Identifier); pseudoClass = identifier.Value.Value; break; } if (valid) break; ThrowUnexpectedToken(state, token); } return valid ? new UvssSelectorPart(qualifier, element, elementIsExact, id, pseudoClass, classes) : null; }
/// <summary> /// Consumes a sequence of tokens representing a storyboard target. /// </summary> /// <param name="state">The parser state.</param> /// <returns>A new <see cref="UvssStoryboardTarget"/> object representing the target that was consumed.</returns> private static UvssStoryboardTarget ConsumeStoryboardTarget(UvssParserState state) { state.AdvanceBeyondWhiteSpace(); if (state.IsPastEndOfStream) return null; var targetToken = state.TryConsumeNonWhiteSpace(); MatchTokenOrFail(state, targetToken, UvssLexerTokenType.Identifier, "target"); var filter = ConsumeStoryboardTargetFilter(state); var selector = ConsumeStoryboardTargetSelector(state); var animations = ConsumeStoryboardAnimationList(state); return new UvssStoryboardTarget(selector, filter, animations); }
/// <summary> /// Consumes a sequence of tokens representing a UVSS style or UVSS trigger. /// </summary> /// <param name="state">The parser state.</param> /// <param name="styles">The list containing the styles being created.</param> /// <param name="triggers">The list containing the triggers being created.</param> /// <returns><c>true</c> if a style or trigger was successfully consumed; otherwise, <c>false</c>.</returns> private static Boolean ConsumeStyleOrTrigger(UvssParserState state, List<UvssStyle> styles, List<Trigger> triggers) { state.AdvanceBeyondWhiteSpace(); if (state.IsPastEndOfStream) return false; var qualifierImportant = false; var nameToken = state.TryConsumeNonWhiteSpace(); if (nameToken.HasValue && nameToken.Value.TokenType == UvssLexerTokenType.TriggerKeyword) { return ConsumeTrigger(state, triggers); } MatchTokenOrFail(state, nameToken, UvssLexerTokenType.StyleName); AdvanceBeyondWhiteSpaceOrFail(state); UvssStyleArgumentsCollection arguments; if (state.CurrentToken.TokenType == UvssLexerTokenType.OpenParenthesis) { arguments = ConsumeStyleArguments(state); ValidateStyleArguments(state, nameToken.Value.Value, arguments); } else { arguments = new UvssStyleArgumentsCollection(null); } var colonToken = state.TryConsumeNonWhiteSpace(); MatchTokenOrFail(state, colonToken, UvssLexerTokenType.Colon); var valueTokens = new List<UvssLexerToken>(); while (!state.IsPastEndOfStream) { var token = state.Consume(); if (token.TokenType == UvssLexerTokenType.Semicolon) { break; } if (token.TokenType == UvssLexerTokenType.StyleQualifier) { if (String.Equals("!important", token.Value, StringComparison.OrdinalIgnoreCase)) { qualifierImportant = true; } continue; } valueTokens.Add(token); } var container = default(String); var name = nameToken.Value.Value; var value = String.Join(String.Empty, valueTokens.Select(x => x.Value)).Trim(); if (name.Contains('.')) { var nameParts = name.Split('.'); container = nameParts[0]; name = nameParts[1]; } var style = new UvssStyle(arguments, container, name, value, qualifierImportant); styles.Add(style); return true; }
/// <summary> /// Consumes a sequence of tokens representing a UVSS property trigger condition list. /// </summary> /// <param name="state">The parser state.</param> /// <returns>A collection containing the trigger condition list that was parsed.</returns> private static IEnumerable<PropertyTriggerCondition> ConsumePropertyTriggerConditionList(UvssParserState state) { var conditions = new List<PropertyTriggerCondition>(); while (true) { var condition = ConsumePropertyTriggerCondition(state); conditions.Add(condition); state.AdvanceBeyondWhiteSpace(); if (state.IsPastEndOfStream || state.CurrentToken.TokenType != UvssLexerTokenType.Comma) break; state.Consume(); } return conditions; }