示例#1
0
        /// <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;
        }
示例#2
0
        /// <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);
        }
示例#3
0
        /// <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);
        }
示例#4
0
        /// <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;
        }
示例#5
0
        /// <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);
        }
示例#6
0
        /// <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);
        }
示例#7
0
        /// <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);
            }
        }
示例#8
0
        /// <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;
        }
示例#9
0
        /// <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;
        }
示例#10
0
        /// <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;
        }
示例#11
0
        /// <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;
        }
示例#12
0
        /// <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");
            }
        }
示例#13
0
        /// <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;
        }
示例#14
0
        /// <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;
        }
示例#15
0
        /// <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);
        }
示例#16
0
        /// <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);
        }
示例#17
0
        /// <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);
        }
示例#18
0
        /// <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);
        }
示例#19
0
        /// <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;
        }
示例#20
0
        /// <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;
        }
示例#21
0
        /// <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);
        }
示例#22
0
        /// <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;
        }
示例#23
0
        /// <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;
        }