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); }
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; } }
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); }
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); }
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)); } }
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; }
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; } }
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); }
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); }
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); }
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; } }
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; }
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); } }
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); }
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)); } }
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); }
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); }
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); }
public static bool IsVendorSpecific(this AtDirective directive) { return(directive.Keyword.Text[0] == '-'); }
protected virtual void VisitAtDirective(AtDirective item) { VisitDefault(item); }
protected virtual bool IsExpectedDirective(AtDirective directive) { // no directives are expected to be inside of rule blocks return(false); }
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)); } }