Example #1
0
        public ItemCheckResult CheckItem(ParseItem item, ICssCheckerContext context)
        {
            if (!WESettings.GetBoolean(WESettings.Keys.ValidateVendorSpecifics))
            {
                return(ItemCheckResult.Continue);
            }

            AtDirective dir = item as AtDirective;

            if (!dir.IsValid || !dir.IsVendorSpecific() || context == null)
            {
                return(ItemCheckResult.Continue);
            }


            ICssSchemaInstance rootSchema = CssSchemaManager.SchemaManager.GetSchemaRoot(null);
            ICssSchemaInstance schema     = CssSchemaManager.SchemaManager.GetSchemaForItem(rootSchema, dir);

            if (schema.GetAtDirective("@" + dir.Keyword.Text) == null)
            {
                string message = string.Format(Resources.ValidationVendorDirective, dir.Keyword.Text);
                context.AddError(new SimpleErrorTag(dir.Keyword, message, CssErrorFlags.TaskListWarning | CssErrorFlags.UnderlineRed));
                return(ItemCheckResult.CancelCurrentItem);
            }

            return(ItemCheckResult.Continue);
        }
Example #2
0
        private static void ParseDocument()
        {
            string fileName = GetSolutionFilePath();

            if (!string.IsNullOrEmpty(fileName) && File.Exists(fileName))
            {
                CssParser  parser     = new CssParser();
                StyleSheet stylesheet = parser.Parse(File.ReadAllText(fileName), false);

                if (stylesheet.IsValid)
                {
                    var visitor = new CssItemCollector <AtDirective>();
                    stylesheet.Accept(visitor);

                    AtDirective at = visitor.Items.SingleOrDefault(a => a.Keyword.Text == _rootDirective);
                    if (at != null)
                    {
                        var visitorPalette = new CssItemCollector <AtDirective>(true);
                        at.Accept(visitorPalette);
                        _directives = visitorPalette.Items.Where(a => a.Keyword.Text != at.Keyword.Text).ToList();
                    }
                }

                InitializeWatcher(fileName);
            }
            else
            {
                _hasFile = false;
            }
        }
Example #3
0
        public ItemCheckResult CheckItem(ParseItem item, ICssCheckerContext context)
        {
            AtDirective directive = (AtDirective)item;

            if (context == null || !directive.IsValid || !directive.IsVendorSpecific())
            {
                return(ItemCheckResult.Continue);
            }

            ICssCompletionListEntry entry = VendorHelpers.GetMatchingStandardEntry(directive, context);

            if (entry != null)
            {
                var visitor = new CssItemCollector <AtDirective>();
                directive.Parent.Accept(visitor);
                if (!visitor.Items.Any(a => "@" + a.Keyword.Text == entry.DisplayText))
                {
                    string message = string.Format(CultureInfo.InvariantCulture, Resources.BestPracticeAddMissingStandardDirective, entry.DisplayText);
                    context.AddError(new SimpleErrorTag(directive.Keyword, message));
                    return(ItemCheckResult.CancelCurrentItem);
                }
            }

            return(ItemCheckResult.Continue);
        }
Example #4
0
        public ItemCheckResult CheckItem(ParseItem item, ICssCheckerContext context)
        {
            if (!WESettings.Instance.Css.ValidateVendorSpecifics)
            {
                return(ItemCheckResult.Continue);
            }

            AtDirective directive = (AtDirective)item;

            if (!directive.IsValid || directive.IsVendorSpecific() || context == null)
            {
                return(ItemCheckResult.Continue);
            }

            ICssSchemaInstance schema = CssEditorChecker.GetSchemaForItem(context, item);
            var missingEntries        = directive.GetMissingVendorSpecifics(schema);

            if (missingEntries.Any())
            {
                string    error = string.Format(CultureInfo.InvariantCulture, Resources.BestPracticeAddMissingVendorSpecificDirective, directive.Keyword.Text, string.Join(", ", missingEntries));
                ICssError tag   = new SimpleErrorTag(directive.Keyword, error);
                context.AddError(tag);
                return(ItemCheckResult.CancelCurrentItem);
            }

            return(ItemCheckResult.Continue);
        }
        public virtual ParseItem CreateNextChild(ParseItem previousChild, ItemFactory itemFactory, ITextProvider text, TokenStream tokens)
        {
            if (IsNestedBlock)
            {
                if (tokens.CurrentToken.IsScopeBlocker())
                {
                    return(null);
                }

                // Only nested stylesheets (like in @media) should look for braces

                if (previousChild is TokenItem && ((TokenItem)previousChild).TokenType == CssTokenType.CloseCurlyBrace)
                {
                    // No more children after the close curly brace
                    return(null);
                }

                if (previousChild == null && tokens.CurrentToken.TokenType != CssTokenType.OpenCurlyBrace)
                {
                    // First child must be a curly brace
                    return(null);
                }

                if (tokens.CurrentToken.TokenType == CssTokenType.OpenCurlyBrace)
                {
                    return((previousChild == null) ? new TokenItem(tokens.AdvanceToken(), CssClassifierContextType.CurlyBrace) : null);
                }

                if (tokens.CurrentToken.TokenType == CssTokenType.CloseCurlyBrace)
                {
                    return(new TokenItem(tokens.AdvanceToken(), CssClassifierContextType.CurlyBrace));
                }
            }

            ParseItem newChild = null;

            switch (tokens.CurrentToken.TokenType)
            {
            case CssTokenType.EndOfFile:
                break;

            case CssTokenType.ScopeBlocker:
                newChild = UnknownItem.ParseUnknown(this, itemFactory, text, tokens);
                break;

            case CssTokenType.At:
                newChild = AtDirective.ParseDirective(this, itemFactory, text, tokens);
                break;

            default:
                newChild = ParseDefaultChild(itemFactory, text, tokens);
                break;
            }

            return(newChild);
        }
Example #6
0
        public MissingStandardDirectiveSmartTagAction(ITrackingSpan span, AtDirective directive, string standardName)
        {
            _span         = span;
            _directive    = directive;
            _standardName = standardName;

            if (Icon == null)
            {
                Icon = BitmapFrame.Create(new Uri("pack://application:,,,/WebEssentials2015;component/Resources/Images/warning.png", UriKind.RelativeOrAbsolute));
            }
        }
        public MissingStandardDirectiveSmartTagAction(ITrackingSpan span, AtDirective directive, string standardName)
        {
            _span = span;
            _directive = directive;
            _standardName = standardName;

            if (Icon == null)
            {
                Icon = BitmapFrame.Create(new Uri("pack://application:,,,/WebEssentials2013;component/Resources/Images/warning.png", UriKind.RelativeOrAbsolute));
            }
        }
Example #8
0
 protected override void VisitAtDirective(AtDirective item)
 {
     if (TryFindKeyframesIdentifier(item, out var identifier))
     {
         KeyframesIdentifiers.Add(identifier);
     }
     else
     {
         VisitDefault(item);
     }
 }
        public VendorDirectiveSmartTagAction(ITrackingSpan span, AtDirective directive, IEnumerable<string> prefixes)
        {
            _span = span;
            _directive = directive;
            _prefixes = prefixes;

            if (Icon == null)
            {
                Icon = BitmapFrame.Create(new Uri("pack://application:,,,/WebEssentials2013;component/Resources/Images/warning.png", UriKind.RelativeOrAbsolute));
            }
        }
        public static ICssCompletionListEntry GetMatchingStandardEntry(AtDirective directive, ICssSchemaInstance rootSchema)
        {
            string standardName;
            if (directive.TryGetStandardPropertyName(out standardName, rootSchema))
            {
                ICssSchemaInstance schema = CssSchemaManager.SchemaManager.GetSchemaForItem(rootSchema, directive);
                return schema.GetAtDirective("@" + standardName);
            }

            return null;
        }
        public static ICssCompletionListEntry GetMatchingStandardEntry(AtDirective directive, ICssCheckerContext context)
        {
            string standardName;
            if (directive.TryGetStandardPropertyName(out standardName, CssEditorChecker.GetSchemaForItem(context, directive)))
            {
                ICssSchemaInstance schema = CssEditorChecker.GetSchemaForItem(context, directive);
                return schema.GetAtDirective("@" + standardName);
            }

            return null;
        }
Example #12
0
        public static IEnumerable<string> GetPossibleVendorSpecifics(this AtDirective directive, ICssSchemaInstance schema)
        {
            string text = directive.Keyword.Text;

            foreach (string prefix in VendorHelpers.GetPrefixes(schema).Where(p => p != "-o-")) // Remove -o- since the parser doesn't recognize -o-keyframes
            {
                ICssCompletionListEntry entry = schema.GetAtDirective("@" + prefix + text);
                if (entry != null && string.IsNullOrEmpty(entry.GetAttribute("obsolete")))
                    yield return entry.DisplayText;
            }
        }
Example #13
0
        public VendorDirectiveSmartTagAction(ITrackingSpan span, AtDirective directive, IEnumerable <string> prefixes)
        {
            _span      = span;
            _directive = directive;
            _prefixes  = prefixes;

            if (Icon == null)
            {
                Icon = BitmapFrame.Create(new Uri("pack://application:,,,/WebEssentials2015;component/Resources/Images/warning.png", UriKind.RelativeOrAbsolute));
            }
        }
        protected override string GetLabel(ParseItem item)
        {
            AtDirective dir = item as AtDirective;

            if (dir != null)
            {
                return("@" + dir.Keyword.Text);
            }

            return(item.Text);
        }
Example #15
0
        private static bool SchemaLookup(ParseItem item, ITextBuffer buffer)
        {
            if (item is ClassSelector || item is IdSelector || item is ItemName || item.Parent is RuleBlock || item.Parent is StyleSheet)
            {
                return(false);
            }

            ICssSchemaInstance schema = CssSchemaManager.SchemaManager.GetSchemaRootForBuffer(buffer);

            Declaration dec = item.FindType <Declaration>();

            if (dec != null && dec.PropertyName != null)
            {
                return(OpenReferenceUrl(schema.GetProperty, dec.PropertyName.Text, "http://realworldvalidator.com/css/properties/"));
            }

            PseudoClassFunctionSelector pseudoClassFunction = item.FindType <PseudoClassFunctionSelector>();

            if (pseudoClassFunction != null)
            {
                return(OpenReferenceUrl(schema.GetPseudo, pseudoClassFunction.Colon.Text + pseudoClassFunction.Function.FunctionName.Text + ")", "http://realworldvalidator.com/css/pseudoclasses/"));
            }

            PseudoElementFunctionSelector pseudoElementFunction = item.FindType <PseudoElementFunctionSelector>();

            if (pseudoElementFunction != null)
            {
                return(OpenReferenceUrl(schema.GetPseudo, pseudoElementFunction.DoubleColon.Text + pseudoElementFunction.Function.FunctionName.Text + ")", "http://realworldvalidator.com/css/pseudoelements/"));
            }

            PseudoElementSelector pseudoElement = item.FindType <PseudoElementSelector>();

            if (pseudoElement != null && pseudoElement.PseudoElement != null)
            {
                return(OpenReferenceUrl(schema.GetPseudo, pseudoElement.DoubleColon.Text + pseudoElement.PseudoElement.Text, "http://realworldvalidator.com/css/pseudoelements/"));
            }

            PseudoClassSelector pseudoClass = item.FindType <PseudoClassSelector>();

            if (pseudoClass != null && pseudoClass.PseudoClass != null)
            {
                return(OpenReferenceUrl(schema.GetPseudo, pseudoClass.Colon.Text + pseudoClass.PseudoClass.Text, "http://realworldvalidator.com/css/pseudoclasses/"));
            }

            AtDirective directive = item.FindType <AtDirective>();

            if (directive != null)
            {
                return(OpenReferenceUrl(schema.GetAtDirective, directive.At.Text + directive.Keyword.Text, "http://realworldvalidator.com/css/atdirectives/"));
            }

            return(false);
        }
Example #16
0
        public static ICssCompletionListEntry GetMatchingStandardEntry(AtDirective directive, ICssSchemaInstance rootSchema)
        {
            string standardName;

            if (directive.TryGetStandardPropertyName(out standardName, rootSchema))
            {
                ICssSchemaInstance schema = CssSchemaManager.SchemaManager.GetSchemaForItem(rootSchema, directive);
                return(schema.GetAtDirective("@" + standardName));
            }

            return(null);
        }
Example #17
0
        public static ICssCompletionListEntry GetMatchingStandardEntry(AtDirective directive, ICssCheckerContext context)
        {
            string standardName;

            if (directive.TryGetStandardPropertyName(out standardName, CssEditorChecker.GetSchemaForItem(context, directive)))
            {
                ICssSchemaInstance schema = CssEditorChecker.GetSchemaForItem(context, directive);
                return(schema.GetAtDirective("@" + standardName));
            }

            return(null);
        }
Example #18
0
        public static IEnumerable<string> GetMissingVendorSpecifics(this AtDirective directive, ICssSchemaInstance schema)
        {
            IEnumerable<string> possible = GetPossibleVendorSpecifics(directive, schema);

            var visitorRules = new CssItemCollector<AtDirective>();
            directive.Parent.Accept(visitorRules);

            foreach (string item in possible)
            {
                if (!visitorRules.Items.Any(d => d.Keyword != null && "@" + d.Keyword.Text == item))
                    yield return item;
            }
        }
Example #19
0
        public static bool TryGetStandardPropertyName(this AtDirective directive, out string standardName, ICssSchemaInstance schema)
        {
            standardName = null;

            string propText = directive.Keyword.Text;
            string prefix = VendorHelpers.GetPrefixes(schema).SingleOrDefault(p => propText.StartsWith(p, StringComparison.Ordinal));
            if (prefix != null)
            {
                standardName = propText.Substring(prefix.Length);
                return true;
            }

            return false;
        }
Example #20
0
 protected override void VisitAtDirective(AtDirective item)
 {
     // Whenever we see "@keyframes something { ... }", we want to insert right after "something"
     if (TryFindKeyframesIdentifier(item, out var identifier))
     {
         Edits.Add(new InsertKeyframesNameScopeEdit {
             Position = identifier.AfterEnd
         });
     }
     else
     {
         VisitDefault(item);
     }
 }
Example #21
0
            protected override void VisitAtDirective(AtDirective item)
            {
                if (item.Children.Count >= 2 &&
                    item.Children[0] is TokenItem firstChild &&
                    firstChild.TokenType == CssTokenType.At &&
                    item.Children[1] is TokenItem secondChild &&
                    string.Equals(secondChild.Text, "import", StringComparison.OrdinalIgnoreCase))
                {
                    var linePosition = _sourceText.Lines.GetLinePosition(item.Start);
                    var sourceSpan   = new SourceSpan(_filePath, item.Start, linePosition.Line, linePosition.Character, item.Length);
                    _diagnostics.Add(RazorDiagnosticFactory.CreateCssRewriting_ImportNotAllowed(sourceSpan));
                }

                base.VisitAtDirective(item);
            }
Example #22
0
        private static void HandleDirective(ParseItem item, ICssCheckerContext context)
        {
            AtDirective dir = (AtDirective)item;

            if (dir == null || dir.Keyword == null)
            {
                return;
            }

            if (dir.IsVendorSpecific())
            {
                string message = string.Format("Validation (W3C): \"@{0}\" is not a valid W3C @-directive", dir.Keyword.Text);
                context.AddError(new SimpleErrorTag(dir.Keyword, message, CssErrorFlags.TaskListWarning | CssErrorFlags.UnderlineRed));
            }
        }
Example #23
0
        protected virtual ParseItem CreateDirective(ItemFactory itemFactory, ITextProvider text, TokenStream tokens)
        {
            ParseItem item = AtDirective.ParseDirective(this, itemFactory, text, tokens);

            if (item is AtDirective directive &&
                directive.Keyword != null &&
                !directive.Keyword.HasParseErrors &&
                !IsExpectedDirective(directive))
            {
                // @directives aren't expected in rules

                directive.Keyword.AddParseError(ParseErrorType.UnexpectedAtDirective, ParseErrorLocation.WholeItem);
            }

            return(item);
        }
Example #24
0
        private static bool TryFindKeyframesIdentifier(AtDirective atDirective, out ParseItem identifier)
        {
            var keyword = atDirective.Keyword;

            if (string.Equals(keyword?.Text, "keyframes", StringComparison.OrdinalIgnoreCase))
            {
                var nextSiblingText = keyword.NextSibling?.Text;
                if (!string.IsNullOrEmpty(nextSiblingText))
                {
                    identifier = keyword.NextSibling;
                    return(true);
                }
            }

            identifier = null;
            return(false);
        }
Example #25
0
 public void FilterErrorList(IList <ICssError> errors, ICssCheckerContext context)
 {
     for (int i = errors.Count - 1; i > -1; i--)
     {
         ICssError error = errors[i];
         if (error.Item.IsValid)
         {
             AtDirective atDir = error.Item.FindType <AtDirective>();
             if (atDir != null && atDir.IsValid && atDir.Keyword.Text == "-ms-keyframes")
             {
                 errors.RemoveAt(i);
                 ICssError tag = new SimpleErrorTag(error.Item, error.Text + _message, CssErrorFlags.TaskListError | CssErrorFlags.UnderlineRed);
                 errors.Insert(i, tag);
             }
         }
     }
 }
        public IEnumerable <ISmartTagAction> GetSmartTagActions(ParseItem item, int position, ITrackingSpan itemTrackingSpan, ITextView view)
        {
            AtDirective directive = (AtDirective)item;

            if (!item.IsValid || !directive.IsVendorSpecific())
            {
                yield break;
            }

            ICssSchemaInstance schema = CssSchemaManager.SchemaManager.GetSchemaRootForBuffer(view.TextBuffer);
            var visitor = new CssItemCollector <AtDirective>();

            directive.Parent.Accept(visitor);

            ICssCompletionListEntry entry = VendorHelpers.GetMatchingStandardEntry(directive, schema);

            if (entry != null && !visitor.Items.Any(d => d.Keyword != null && "@" + d.Keyword.Text == entry.DisplayText))
            {
                yield return(new MissingStandardDirectiveSmartTagAction(itemTrackingSpan, directive, entry.DisplayText));
            }
        }
        public ItemCheckResult CheckItem(ParseItem item, ICssCheckerContext context)
        {
            if (!WESettings.Instance.Css.ValidateVendorSpecifics)
            {
                return(ItemCheckResult.Continue);
            }

            AtDirective dir = item as AtDirective;

            if (!dir.IsValid || !dir.IsVendorSpecific() || context == null)
            {
                return(ItemCheckResult.Continue);
            }


            ICssSchemaInstance rootSchema = CssSchemaManager.SchemaManager.GetSchemaRoot(null);
            ICssSchemaInstance schema     = CssSchemaManager.SchemaManager.GetSchemaForItem(rootSchema, dir);

            ICssCompletionListEntry at = schema.GetAtDirective("@" + dir.Keyword.Text);

            if (at == null)
            {
                string message = string.Format(CultureInfo.CurrentCulture, Resources.ValidationVendorDirective, dir.Keyword.Text);
                context.AddError(new SimpleErrorTag(dir.Keyword, message, CssErrorFlags.TaskListWarning | CssErrorFlags.UnderlineRed));
                return(ItemCheckResult.CancelCurrentItem);
            }
            else
            {
                string obsolete = at.GetAttribute("obsolete");
                if (!string.IsNullOrEmpty(obsolete))
                {
                    string message = string.Format(CultureInfo.CurrentCulture, Resources.BestPracticeRemoveObsolete, "@" + dir.Keyword.Text, obsolete);
                    context.AddError(new SimpleErrorTag(dir.Keyword, message, CssErrorFlags.TaskListMessage));
                    return(ItemCheckResult.CancelCurrentItem);
                }
            }

            return(ItemCheckResult.Continue);
        }
        private static Tuple <ParseItem, ICssCompletionListEntry> GetEntriesAndPoint(ParseItem item, SnapshotPoint point, ICssSchemaInstance schema)
        {
            // Declaration
            Declaration dec = item.FindType <Declaration>();

            if (dec != null && dec.PropertyName != null && dec.PropertyName.ContainsRange(point.Position, 1))
            {
                return(Tuple.Create <ParseItem, ICssCompletionListEntry>(dec.PropertyName, schema.GetProperty(dec.PropertyName.Text)));
            }

            if (dec != null && dec.IsValid && dec.Values.TextStart <= point.Position && dec.Values.TextAfterEnd >= point.Position)
            {
                var entry = schema.GetProperty(dec.PropertyName.Text);

                if (entry != null)
                {
                    var list   = schema.GetPropertyValues(entry.DisplayText);
                    var theOne = dec.StyleSheet.ItemFromRange(point.Position, 0);

                    return(Tuple.Create <ParseItem, ICssCompletionListEntry>(theOne,
                                                                             list.SingleOrDefault(r => r.DisplayText.Equals(theOne.Text, StringComparison.OrdinalIgnoreCase))));
                }
            }

            // Pseudo class
            PseudoClassSelector pseudoClass = item.FindType <PseudoClassSelector>();

            if (pseudoClass != null)
            {
                return(Tuple.Create <ParseItem, ICssCompletionListEntry>(pseudoClass, schema.GetPseudo(pseudoClass.Text)));
            }

            // Pseudo class function
            PseudoClassFunctionSelector pseudoClassFunction = item.FindType <PseudoClassFunctionSelector>();

            if (pseudoClassFunction != null)
            {
                return(Tuple.Create <ParseItem, ICssCompletionListEntry>(pseudoClassFunction, schema.GetPseudo(pseudoClassFunction.Text)));
            }

            // Pseudo element
            PseudoElementSelector pseudoElement = item.FindType <PseudoElementSelector>();

            if (pseudoElement != null)
            {
                return(Tuple.Create <ParseItem, ICssCompletionListEntry>(pseudoElement, schema.GetPseudo(pseudoElement.Text)));
            }

            // Pseudo element function
            PseudoElementFunctionSelector pseudoElementFunction = item.FindType <PseudoElementFunctionSelector>();

            if (pseudoElementFunction != null)
            {
                return(Tuple.Create <ParseItem, ICssCompletionListEntry>(pseudoElementFunction, schema.GetPseudo(pseudoElementFunction.Text)));
            }

            // @-directive
            AtDirective atDirective = item.Parent as AtDirective;

            if (atDirective != null && atDirective.Keyword != null)
            {
                return(Tuple.Create <ParseItem, ICssCompletionListEntry>(atDirective.Keyword, schema.GetAtDirective("@" + atDirective.Keyword.Text)));
            }

            return(null);
        }
Example #29
0
 public static bool IsVendorSpecific(this AtDirective directive)
 {
     return(directive.Keyword.Text[0] == '-');
 }
Example #30
0
 protected virtual void VisitAtDirective(AtDirective item)
 {
     VisitDefault(item);
 }
Example #31
0
 protected virtual bool IsExpectedDirective(AtDirective directive)
 {
     // no directives are expected to be inside of rule blocks
     return(false);
 }
Example #32
0
        public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan)
        {
            applicableToSpan = null;

            if (!EnsureTreeInitialized() || session == null || qiContent == null || qiContent.Count > 0 || !WESettings.GetBoolean(WESettings.Keys.ShowBrowserTooltip))
            {
                return;
            }

            SnapshotPoint?point = session.GetTriggerPoint(_buffer.CurrentSnapshot);

            if (!point.HasValue)
            {
                return;
            }

            ParseItem item = _tree.StyleSheet.ItemBeforePosition(point.Value.Position);

            if (item == null || !item.IsValid)
            {
                return;
            }

            ParseItem theOne = null;
            ICssCompletionListEntry entry  = null;
            ICssSchemaInstance      schema = CssSchemaManager.SchemaManager.GetSchemaForItem(_rootSchema, item);

            // Declaration
            Declaration dec = item.FindType <Declaration>();

            if (dec != null && dec.PropertyName != null && dec.PropertyName.ContainsRange(point.Value.Position, 1))
            {
                entry  = schema.GetProperty(dec.PropertyName.Text);
                theOne = dec.PropertyName;
            }
            else if (dec != null && dec.IsValid && dec.Values.TextStart <= point.Value.Position && dec.Values.TextAfterEnd >= point.Value.Position)
            {
                entry = schema.GetProperty(dec.PropertyName.Text);
                if (entry != null)
                {
                    var list = schema.GetPropertyValues(entry.DisplayText);
                    theOne = dec.StyleSheet.ItemFromRange(point.Value.Position, 0);
                    entry  = list.SingleOrDefault(r => r.DisplayText.Equals(theOne.Text, StringComparison.OrdinalIgnoreCase));
                }
            }

            // Pseudo class
            if (entry == null)
            {
                PseudoClassSelector pseudoClass = item.FindType <PseudoClassSelector>();
                if (pseudoClass != null)
                {
                    entry  = schema.GetPseudo(pseudoClass.Text);
                    theOne = pseudoClass;
                }
            }

            // Pseudo class function
            if (entry == null)
            {
                PseudoClassFunctionSelector pseudoClassFunction = item.FindType <PseudoClassFunctionSelector>();
                if (pseudoClassFunction != null)
                {
                    entry  = schema.GetPseudo(pseudoClassFunction.Text);
                    theOne = pseudoClassFunction;
                }
            }

            // Pseudo element
            if (entry == null)
            {
                PseudoElementSelector pseudoElement = item.FindType <PseudoElementSelector>();
                if (pseudoElement != null)
                {
                    entry  = schema.GetPseudo(pseudoElement.Text);
                    theOne = pseudoElement;
                }
            }

            // Pseudo element function
            if (entry == null)
            {
                PseudoElementFunctionSelector pseudoElementFunction = item.FindType <PseudoElementFunctionSelector>();
                if (pseudoElementFunction != null)
                {
                    entry  = schema.GetPseudo(pseudoElementFunction.Text);
                    theOne = pseudoElementFunction;
                }
            }

            // @-directive
            if (entry == null)
            {
                AtDirective atDirective = item.Parent as AtDirective;
                if (atDirective != null && atDirective.Keyword != null)
                {
                    entry  = schema.GetAtDirective("@" + atDirective.Keyword.Text);
                    theOne = atDirective.Keyword;
                }
            }

            if (entry != null)
            {
                applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(theOne.Start, theOne.Length, SpanTrackingMode.EdgeNegative);

                string syntax = entry.GetSyntax(schema.Version);
                string b      = entry.GetAttribute("browsers");

                if (string.IsNullOrEmpty(b) && theOne.Parent != null && theOne.Parent is Declaration)
                {
                    b = schema.GetProperty(((Declaration)theOne.Parent).PropertyName.Text).GetAttribute("browsers");
                    if (string.IsNullOrEmpty(syntax))
                    {
                        syntax = theOne.Text;
                    }
                }

                if (!string.IsNullOrEmpty(syntax))
                {
                    qiContent.Add("Example: " + syntax);
                }

                Dictionary <string, string> browsers = GetBrowsers(b);
                qiContent.Add(CreateBrowserList(browsers));
            }
        }