private bool Move(Direction direction) { if (!EnsureInitialized()) { return(false); } int position = _textView.Caret.Position.BufferPosition.Position; ParseItem item = _tree.StyleSheet.ItemBeforePosition(position); if (item == null) { return(false); } NumericalValue unit = item.FindType <NumericalValue>(); if (unit != null) { return(HandleUnits(direction, unit)); } HexColorValue hex = item.FindType <HexColorValue>(); if (hex != null) { return(HandleHex(direction, hex)); } return(false); }
private bool Move(Direction direction) { if (!EnsureInitialized()) { return(false); } int position = _textView.Caret.Position.BufferPosition.Position; ParseItem item = _tree.StyleSheet.ItemBeforePosition(position); Declaration dec = item.FindType <Declaration>(); if (dec != null) { return(HandleDeclaration(direction, dec)); } Selector selector = item.FindType <Selector>(); if (selector != null) { return(HandleSelector(direction, selector)); } return(false); }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (session == null || qiContent == null) { return; } // Map the trigger point down to our buffer. SnapshotPoint?point = session.GetTriggerPoint(_buffer.CurrentSnapshot); if (!point.HasValue) { return; } var tree = CssEditorDocument.FromTextBuffer(_buffer); ParseItem item = tree.StyleSheet.ItemBeforePosition(point.Value.Position); if (item == null || !item.IsValid) { return; } Selector sel = item.FindType <Selector>(); if (sel == null) { return; } // Mixins don't have specificity if (sel.SimpleSelectors.Count == 1) { var subSelectors = sel.SimpleSelectors[0].SubSelectors; if (subSelectors.Count == 1 && subSelectors[0] is LessMixinDeclaration && subSelectors[0] is ScssMixinDeclaration) { return; } } applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(item.Start, item.Length, SpanTrackingMode.EdgeNegative); if (_buffer.ContentType.DisplayName.Equals("css", StringComparison.OrdinalIgnoreCase)) { qiContent.Add(GenerateContent(sel)); return; } HandlePreprocessor(session, point.Value, item.FindType <Selector>(), qiContent); }
private void UpdateAtCaretPosition(CaretPosition caretPosition) { SnapshotPoint?point = caretPosition.Point.GetPoint(_buffer, caretPosition.Affinity); if (!point.HasValue) { return; } var doc = CssEditorDocument.FromTextBuffer(_buffer); ParseItem item = doc.StyleSheet.ItemBeforePosition(point.Value.Position); if (item == null) { return; } ParseItem validItem; validItem = item.FindType <ItemName>() ?? item.FindType <ClassSelector>() ?? item.FindType <IdSelector>() ?? item.FindType <LessVariableName>() ?? (ParseItem)item.FindType <LessMixinName>(); if (validItem == null) { return; // There is no separate token type for a property name, // so I need to ensure that we are in the name portion. //var decl = item.FindType<Declaration>(); //if (decl != null && item.Parent != decl.PropertyName) // validItem = decl.PropertyName; //TODO: What was this for? } // If the new caret position is still within the current word (and on the same snapshot), we don't need to check it if (_currentWord.HasValue && _currentWord.Value.Snapshot == _view.TextSnapshot && point.Value >= _currentWord.Value.Start && point.Value <= _currentWord.Value.End) { return; } _requestedPoint = point.Value; Task.Run(new Action(() => UpdateWordAdornments(validItem))); }
public ItemCheckResult CheckItem(ParseItem item, ICssCheckerContext context) { if (!WESettings.Instance.Css.ValidateZeroUnit) return ItemCheckResult.Continue; NumericalValue number = (NumericalValue)item; UnitValue unit = number as UnitValue; if (unit == null || context == null || item.FindType<Declaration>() == null) return ItemCheckResult.Continue; // The 2nd and 3rd arguments to hsl() require units even when zero var function = unit.Parent.Parent as FunctionColor; if (function != null && function.FunctionName.Text.StartsWith("hsl", StringComparison.OrdinalIgnoreCase)) { var arg = unit.Parent as FunctionArgument; if (arg != function.Arguments[0]) return ItemCheckResult.Continue; } if (number.Number.Text == "0" && unit.UnitType != UnitType.Unknown && unit.UnitType != UnitType.Time) { string message = string.Format(System.Globalization.CultureInfo.CurrentCulture, Resources.BestPracticeZeroUnit, unit.UnitToken.Text); context.AddError(new SimpleErrorTag(number, message)); } return ItemCheckResult.Continue; }
private void UpdateVendorValues(ParseItem item) { Declaration dec = item.FindType <Declaration>(); if (dec != null && Cache.Contains(dec) && !dec.IsVendorSpecific()) { // Find all vendor specifics that isn't the standard property. var matches = Cache.Where(d => d.IsValid && d != dec && d.Parent == dec.Parent && GetStandardName(d) == dec.PropertyName.Text && d.PropertyName.Text != dec.PropertyName.Text); // Undo sometimes messes with the positions, so we have to make this check before proceeding. if (!matches.Any() || dec.Text.Length < dec.Colon.AfterEnd - dec.Start || dec.Colon.AfterEnd < dec.Start) { return; } string text = dec.Text.Substring(dec.Colon.AfterEnd - dec.Start, dec.AfterEnd - dec.Colon.AfterEnd); using (ITextEdit edit = _buffer.CreateEdit()) { foreach (Declaration match in matches.Reverse()) { SnapshotSpan span = new SnapshotSpan(_buffer.CurrentSnapshot, match.Colon.AfterEnd, match.AfterEnd - match.Colon.AfterEnd); if (span.GetText() != text) { edit.Replace(span, text); } } edit.Apply(); } } }
public ItemCheckResult CheckItem(ParseItem item, ICssCheckerContext context) { if (item.Text.TrimStart(':').StartsWith("-")) return ItemCheckResult.Continue; ParseItem next = item.NextSibling; //ParseItem prev = item.PreviousSibling; SimpleSelector sel = item.FindType<SimpleSelector>(); //if (item.Text == ":hover" && prev != null && _invalids.Contains(prev.Text)) //{ // string error = string.Format(Resources.ValidationHoverOrder, prev.Text); // context.AddError(new SimpleErrorTag(item, error, CssErrorFlags.TaskListError | CssErrorFlags.UnderlineRed)); //} if (next != null) { if (next.Text.StartsWith(":") && item.IsPseudoElement() && !next.IsPseudoElement()) { string error = string.Format(Resources.ValidationPseudoOrder, item.Text, next.Text); context.AddError(new SimpleErrorTag(item, error, CssErrorFlags.TaskListError | CssErrorFlags.UnderlineRed)); } else if (!next.Text.StartsWith(":") && item.AfterEnd == next.Start) { string error = string.Format(Resources.BestPracticePseudosAfterOtherSelectors, next.Text); context.AddError(new SimpleErrorTag(next, error)); } } return ItemCheckResult.Continue; }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList<object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (!EnsureTreeInitialized() || session == null || qiContent == null) return; // Map the trigger point down to our buffer. SnapshotPoint? point = session.GetTriggerPoint(_buffer.CurrentSnapshot); if (!point.HasValue) return; ParseItem item = _tree.StyleSheet.ItemBeforePosition(point.Value.Position); if (item == null || !item.IsValid) return; Selector sel = item.FindType<Selector>(); if (sel == null) return; applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(item.Start, item.Length, SpanTrackingMode.EdgeNegative); string content = GenerateContent(sel); qiContent.Add(content); }
public CssCompletionContext GetCompletionContext(ParseItem item, int position) { if (item.FindType<AttributeSelector>() != null) return null; return new CssCompletionContext((CssCompletionContextType)601, item.Start, item.Length, null); }
public void AugmentSignatureHelpSession(ISignatureHelpSession session, IList <ISignature> signatures) { SnapshotPoint?point = session.GetTriggerPoint(_buffer.CurrentSnapshot); if (!point.HasValue) { return; } CssEditorDocument document = CssEditorDocument.FromTextBuffer(_buffer); ParseItem item = document.StyleSheet.ItemBeforePosition(point.Value.Position); if (item == null) { return; } Declaration dec = item.FindType <Declaration>(); if (dec == null || dec.PropertyName == null || dec.Colon == null) { return; } foreach (ISignature signature in signatures) { if (signature is ValueOrderSignature) { signatures.RemoveAt(signatures.Count - 1); break; } } }
public ItemCheckResult CheckItem(ParseItem item, ICssCheckerContext context) { if (!WESettings.Instance.Css.ValidateZeroUnit) { return(ItemCheckResult.Continue); } NumericalValue number = (NumericalValue)item; UnitValue unit = number as UnitValue; if (unit == null || context == null || item.FindType <Declaration>() == null) { return(ItemCheckResult.Continue); } // The 2nd and 3rd arguments to hsl() require units even when zero var function = unit.Parent.Parent as FunctionColor; if (function != null && function.FunctionName.Text.StartsWith("hsl", StringComparison.OrdinalIgnoreCase)) { var arg = unit.Parent as FunctionArgument; if (arg != function.Arguments[0]) { return(ItemCheckResult.Continue); } } if (number.Number.Text == "0" && unit.UnitType != UnitType.Unknown && unit.UnitType != UnitType.Time) { string message = string.Format(System.Globalization.CultureInfo.CurrentCulture, Resources.BestPracticeZeroUnit, unit.UnitToken.Text); context.AddError(new SimpleErrorTag(number, message)); } return(ItemCheckResult.Continue); }
public ItemCheckResult CheckItem(ParseItem item, ICssCheckerContext context) { if (item.Text.TrimStart(':').StartsWith("-")) { return(ItemCheckResult.Continue); } ParseItem next = item.NextSibling; //ParseItem prev = item.PreviousSibling; SimpleSelector sel = item.FindType <SimpleSelector>(); //if (item.Text == ":hover" && prev != null && _invalids.Contains(prev.Text)) //{ // string error = string.Format(Resources.ValidationHoverOrder, prev.Text); // context.AddError(new SimpleErrorTag(item, error, CssErrorFlags.TaskListError | CssErrorFlags.UnderlineRed)); //} if (next != null) { if (next.Text.StartsWith(":") && item.IsPseudoElement() && !next.IsPseudoElement()) { string error = string.Format(Resources.ValidationPseudoOrder, item.Text, next.Text); context.AddError(new SimpleErrorTag(item, error, CssErrorFlags.TaskListError | CssErrorFlags.UnderlineRed)); } else if (!next.Text.StartsWith(":") && item.AfterEnd == next.Start) { string error = string.Format(Resources.BestPracticePseudosAfterOtherSelectors, next.Text); context.AddError(new SimpleErrorTag(next, error)); } } return(ItemCheckResult.Continue); }
private void UpdateAtCaretPosition(CaretPosition caretPosition) { if (!WESettings.GetBoolean(WESettings.Keys.EnableCssSelectorHighligting)) { return; } SnapshotPoint?point = caretPosition.Point.GetPoint(_buffer, caretPosition.Affinity); if (!point.HasValue || !EnsureInitialized()) { return; } ParseItem item = _tree.StyleSheet.ItemBeforePosition(point.Value.Position); if (item == null) { return; } ParseItem validItem = item.FindType <ItemName>(); if (validItem == null) { validItem = item.FindType <ClassSelector>(); } if (validItem == null) { validItem = item.FindType <IdSelector>(); } // If the new caret position is still within the current word (and on the same snapshot), we don't need to check it if (_currentWord.HasValue && _currentWord.Value.Snapshot == _view.TextSnapshot && point.Value >= _currentWord.Value.Start && point.Value <= _currentWord.Value.End) { return; } _requestedPoint = point.Value; Task.Run(new Action(() => UpdateWordAdornments(validItem))); //UpdateWordAdornments(validItem); }
public IEnumerable<ISmartTagAction> GetSmartTagActions(ParseItem item, int position, ITrackingSpan itemTrackingSpan, ITextView view) { RuleSet rule = item.FindType<RuleSet>(); if (rule == null || !rule.Block.IsValid || UsageRegistry.IsRuleUsed(rule)) yield break; yield return new RemoveCssRuleSmartTagAction(itemTrackingSpan, rule); }
public IEnumerable<ISmartTagAction> GetSmartTagActions(ParseItem item, int position, ITrackingSpan itemTrackingSpan, ITextView view) { RuleSet rule = item.FindType<RuleSet>(); if (rule == null || !rule.IsValid || !rule.Block.IsValid) yield break; yield return new SortSmartTagAction(rule, itemTrackingSpan, view); }
public IEnumerable<ISmartTagAction> GetSmartTagActions(ParseItem item, int position, ITrackingSpan itemTrackingSpan, ITextView view) { LessRuleBlock rule = item.FindType<LessRuleBlock>(); if (!item.IsValid || rule == null) yield break; yield return new LessExtractVariableSmartTagAction(itemTrackingSpan, item, "@"); }
public CssCompletionContext GetCompletionContext(ParseItem item, int position) { if (item.FindType <AttributeSelector>() != null) { return(null); } return(new CssCompletionContext((CssCompletionContextType)601, item.Start, item.Length, null)); }
public IEnumerable <ISmartTagAction> GetSmartTagActions(ParseItem item, int position, ITrackingSpan itemTrackingSpan, ITextView view) { UrlItem url = (UrlItem)item; if (!url.IsValid || url.UrlString == null || !url.UrlString.Text.Contains(";base64,")) { yield break; } CComment comment = url.NextSibling as CComment; if (comment != null && comment.CommentText != null) { string path = comment.CommentText.Text.Trim(); yield return(new UpdateEmbedSmartTagAction(itemTrackingSpan, url, path)); } else { RuleBlock rule = item.FindType <RuleBlock>(); Declaration dec = item.FindType <Declaration>(); if (rule == null || dec == null || dec.PropertyName == null) { yield break; } foreach (Declaration sibling in rule.Declarations.Where(d => d.PropertyName != null && d != dec)) { if (sibling.PropertyName.Text == "*" + dec.PropertyName.Text || sibling.PropertyName.Text == "_" + dec.PropertyName.Text) { var visitor = new CssItemCollector <UrlItem>(); sibling.Accept(visitor); UrlItem siblingUrl = visitor.Items.FirstOrDefault(); if (siblingUrl != null && siblingUrl.UrlString != null) { yield return(new UpdateEmbedSmartTagAction(itemTrackingSpan, url, siblingUrl.UrlString.Text)); break; } } } } }
private bool Jump() { if (!EnsureInitialized()) { return(false); } int position = _textView.Caret.Position.BufferPosition.Position; ParseItem item = _tree.StyleSheet.ItemBeforePosition(position); if (item != null) { RuleBlock rule = item.FindType <RuleBlock>(); Declaration dec = item.FindType <Declaration>(); if (rule != null && dec != null) { CommitStatementCompletion(); var line = _textView.TextSnapshot.GetLineFromPosition(position); string text = line.Extent.GetText().TrimEnd(); if (!string.IsNullOrWhiteSpace(text) && !text.EndsWith(";")) { using (ITextEdit edit = _textView.TextBuffer.CreateEdit()) { edit.Replace(line.Extent, text + ";"); edit.Apply(); } } EditorExtensionsPackage.ExecuteCommand("Edit.FormatSelection"); SnapshotPoint point = new SnapshotPoint(_textView.TextBuffer.CurrentSnapshot, rule.AfterEnd); _textView.Caret.MoveTo(point); _textView.ViewScroller.EnsureSpanVisible(new SnapshotSpan(point, 0)); return(true); } } return(false); }
public CssCompletionContext GetCompletionContext(ParseItem item, int position) { RuleSet rule = item.FindType <RuleSet>(); if (rule != null && rule.Parent is LessRuleBlock) { return(new CssCompletionContext(CssCompletionContextType.Invalid, item.Start, item.Length, item)); } return(null); }
public CssCompletionContext GetCompletionContext(ParseItem item, int position) { RuleSet rule = item.FindType<RuleSet>(); if (rule != null && rule.Parent is LessRuleBlock) { return new CssCompletionContext(CssCompletionContextType.Invalid, item.Start, item.Length, item); } return null; }
public IEnumerable <ISmartTagAction> GetSmartTagActions(ParseItem item, int position, ITrackingSpan itemTrackingSpan, ITextView view) { ScssRuleBlock rule = item.FindType <ScssRuleBlock>(); if (!item.IsValid || rule == null) { yield break; } yield return(new LessExtractVariableSmartTagAction(itemTrackingSpan, item, "$")); }
public IEnumerable <ISmartTagAction> GetSmartTagActions(ParseItem item, int position, ITrackingSpan itemTrackingSpan, ITextView view) { RuleSet rule = item.FindType <RuleSet>(); if (rule == null || rule.Block == null || !rule.Block.IsValid || UsageRegistry.IsRuleUsed(rule)) { yield break; } yield return(new RemoveCssRuleSmartTagAction(itemTrackingSpan, rule)); }
public IEnumerable <ISmartTagAction> GetSmartTagActions(ParseItem item, int position, ITrackingSpan itemTrackingSpan, ITextView view) { RuleSet rule = item.FindType <RuleSet>(); if (rule == null || !rule.IsValid || !rule.Block.IsValid) { yield break; } yield return(new SortSmartTagAction(rule, itemTrackingSpan, view)); }
private bool SchemaLookup(ParseItem item) { 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(TextView.TextBuffer); 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; }
private async Task <IEnumerable <CssSourceMapNode> > ProcessSourceMaps() { ParseItem item = null; Selector selector = null; StyleSheet styleSheet = null; int start; var fileContents = ""; var result = new List <CssSourceMapNode>(); var contentCollection = new HashSet <string>(); foreach (var node in MapNodes) { // Cache source file contents. if (!contentCollection.Contains(node.SourceFilePath)) { if (!File.Exists(node.SourceFilePath)) // Lets say someone deleted the reference file. { continue; } fileContents = await FileHelpers.ReadAllTextRetry(node.SourceFilePath); contentCollection.Add(node.SourceFilePath); styleSheet = _parser.Parse(fileContents, false); } start = fileContents.NthIndexOfCharInString('\n', node.OriginalLine); start += node.OriginalColumn; item = styleSheet.ItemAfterPosition(start); if (item == null) { continue; } selector = item.FindType <Selector>(); if (selector == null) { continue; } node.OriginalSelector = selector; result.Add(node); } return(result); }
public IEnumerable<ISmartTagAction> GetSmartTagActions(ParseItem item, int position, ITrackingSpan itemTrackingSpan, ITextView view) { UrlItem url = (UrlItem)item; if (!url.IsValid || url.UrlString == null || !url.UrlString.Text.Contains(";base64,")) yield break; CComment comment = url.NextSibling as CComment; if (comment != null && comment.CommentText != null) { string path = comment.CommentText.Text.Trim(); yield return new UpdateEmbedSmartTagAction(itemTrackingSpan, path); } else { RuleBlock rule = item.FindType<RuleBlock>(); Declaration dec = item.FindType<Declaration>(); if (rule == null || dec == null || dec.PropertyName == null) yield break; foreach (Declaration sibling in rule.Declarations.Where(d => d.PropertyName != null && d != dec)) { if (sibling.PropertyName.Text == "*" + dec.PropertyName.Text || sibling.PropertyName.Text == "_" + dec.PropertyName.Text) { var visitor = new CssItemCollector<UrlItem>(); sibling.Accept(visitor); UrlItem siblingUrl = visitor.Items.FirstOrDefault(); if (siblingUrl != null && siblingUrl.UrlString != null) { yield return new UpdateEmbedSmartTagAction(itemTrackingSpan, siblingUrl.UrlString.Text); break; } } } } }
private bool Move(Direction direction) { if (WebEditor.Host == null) { return(false); } var point = _textView.BufferGraph.MapDownToInsertionPoint(_textView.Caret.Position.BufferPosition, PointTrackingMode.Positive, ts => ts.ContentType.IsOfType(CssContentTypeDefinition.CssContentType)); if (point == null) { return(false); } var tree = CssEditorDocument.FromTextBuffer(point.Value.Snapshot.TextBuffer); ParseItem item = tree.StyleSheet.ItemBeforePosition(point.Value.Position); if (item == null) { return(false); } NumericalValue unit = item.FindType <NumericalValue>(); if (unit != null) { return(HandleUnits(direction, unit, point.Value.Snapshot)); } HexColorValue hex = item.FindType <HexColorValue>(); if (hex != null) { return(HandleHex(direction, hex, point.Value.Snapshot)); } return(false); }
public void AugmentSignatureHelpSession(ISignatureHelpSession session, IList <ISignature> signatures) { SnapshotPoint?point = session.GetTriggerPoint(_buffer.CurrentSnapshot); if (!point.HasValue) { return; } CssEditorDocument document = CssEditorDocument.FromTextBuffer(_buffer); ParseItem item = document.StyleSheet.ItemBeforePosition(point.Value.Position); if (item == null) { return; } Declaration dec = item.FindType <Declaration>(); if (dec == null || dec.PropertyName == null || dec.Colon == null) { return; } int length = dec.Length - (dec.Colon.Start - dec.Start); var span = _buffer.CurrentSnapshot.CreateTrackingSpan(dec.Colon.Start, length, SpanTrackingMode.EdgeNegative); ValueOrderFactory.AddSignatures method = ValueOrderFactory.GetMethod(dec); if (method != null) { signatures.Clear(); method(session, signatures, dec, span); Dispatcher.CurrentDispatcher.BeginInvoke( new Action(() => { if (session == null || session.Properties == null) { return; } session.Properties.AddProperty("dec", dec); session.Match(); }), DispatcherPriority.Normal, null); } }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (session == null || qiContent == null) { return; } // Map the trigger point down to our buffer. SnapshotPoint?point = session.GetTriggerPoint(_buffer.CurrentSnapshot); if (!point.HasValue) { return; } var tree = CssEditorDocument.FromTextBuffer(_buffer); ParseItem item = tree.StyleSheet.ItemBeforePosition(point.Value.Position); if (item == null || !item.IsValid) { return; } Declaration dec = item.FindType <Declaration>(); if (dec == null || !dec.IsValid || !_allowed.Contains(dec.PropertyName.Text.ToUpperInvariant())) { return; } string fontName = item.Text.Trim('\'', '"'); if (fonts.Families.SingleOrDefault(f => f.Name.Equals(fontName, StringComparison.OrdinalIgnoreCase)) != null) { FontFamily font = new FontFamily(fontName); applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(item.Start, item.Length, SpanTrackingMode.EdgeNegative); qiContent.Add(CreateFontPreview(font, 10)); qiContent.Add(CreateFontPreview(font, 11)); qiContent.Add(CreateFontPreview(font, 12)); qiContent.Add(CreateFontPreview(font, 14)); qiContent.Add(CreateFontPreview(font, 25)); qiContent.Add(CreateFontPreview(font, 40)); } }
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); }
private void UpdateAtCaretPosition(CaretPosition caretPosition) { if (!WESettings.GetBoolean(WESettings.Keys.EnableCssSelectorHighligting)) { return; } SnapshotPoint?point = caretPosition.Point.GetPoint(_buffer, caretPosition.Affinity); if (!point.HasValue || !EnsureInitialized()) { return; } ParseItem item = _tree.StyleSheet.ItemBeforePosition(point.Value.Position); if (item == null) { return; } ParseItem validItem; validItem = item.FindType <ItemName>() ?? item.FindType <ClassSelector>() ?? item.FindType <IdSelector>() ?? item.FindType <LessVariableName>() ?? (ParseItem)item.FindType <LessMixinName>(); if (validItem == null) { // There is no separate token type for a property name, // so I need to ensure that we are in the name portion. var decl = item.FindType <Declaration>(); if (decl != null && item.Parent != decl.PropertyName) { validItem = decl.PropertyName; } } // If the new caret position is still within the current word (and on the same snapshot), we don't need to check it if (_currentWord.HasValue && _currentWord.Value.Snapshot == _view.TextSnapshot && point.Value >= _currentWord.Value.Start && point.Value <= _currentWord.Value.End) { return; } _requestedPoint = point.Value; Task.Run(new Action(() => UpdateWordAdornments(validItem))); //UpdateWordAdornments(validItem); }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (session == null || qiContent == null) { return; } // Map the trigger point down to our buffer. SnapshotPoint?point = session.GetTriggerPoint(_buffer.CurrentSnapshot); if (!point.HasValue) { return; } var tree = CssEditorDocument.FromTextBuffer(_buffer); ParseItem item = tree.StyleSheet.ItemBeforePosition(point.Value.Position); if (item == null || !item.IsValid) { return; } Selector sel = item.FindType <Selector>(); if (sel == null) { return; } // Mixins don't have specificity if (sel.SimpleSelectors.Count == 1 && sel.SimpleSelectors[0].SubSelectors.Count == 1 && sel.SimpleSelectors[0].SubSelectors[0] is LessMixinDeclaration) { return; } applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(item.Start, item.Length, SpanTrackingMode.EdgeNegative); string content = GenerateContent(sel); qiContent.Add(content); }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (!EnsureTreeInitialized() || session == null || qiContent == null) { 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; } UrlItem urlItem = item.FindType <UrlItem>(); if (urlItem == null || urlItem.UrlString == null || !urlItem.UrlString.IsValid) { return; } string url = GetFullUrl(urlItem.UrlString.Text.Trim('\'', '"'), _buffer); if (string.IsNullOrEmpty(url)) { return; } applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(point.Value.Position, 1, SpanTrackingMode.EdgeNegative); AddImageContent(qiContent, url); }
public IEnumerable <ColorModel> GetColors(ITextView textView, SnapshotSpan contextSpan) { if (_directives == null && _hasFile) { ParseDocument(); } if (_directives != null && textView != null) { CssEditorDocument document = CssEditorDocument.FromTextBuffer(textView.TextBuffer); ParseItem item = document.Tree.StyleSheet.ItemAfterPosition(contextSpan.Start); Declaration dec = item.FindType <Declaration>(); if (dec != null) { return(GetApplicableColors(dec.PropertyName.Text)); } } return(new List <ColorModel>()); }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (!EnsureTreeInitialized() || session == null || qiContent == null) { 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; } UrlItem urlItem = item.FindType <UrlItem>(); if (urlItem != null && urlItem.UrlString != null && urlItem.UrlString.IsValid) { string url = GetFileName(urlItem.UrlString.Text.Trim('\'', '"')); if (!string.IsNullOrEmpty(url)) { applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(point.Value.Position, 1, SpanTrackingMode.EdgeNegative); var image = CreateImage(url); if (image != null && image.Source != null) { qiContent.Add(image); qiContent.Add(Math.Round(image.Source.Width) + "x" + Math.Round(image.Source.Height)); } } } }
/// <summary> /// This code was copied from CompletionEngine.cs in the CSS code. If this class gets /// copied into the CSS code, reuse that other function (CompletionEngine.GetCompletionContextLeafItem) /// </summary> private static ParseItem GetContextItem(StyleSheet styleSheet, int position) { // Look on both sides of the cursor for a context item. ParseItem prevItem = styleSheet.ItemBeforePosition(position) ?? styleSheet; ParseItem nextItem = styleSheet.ItemAfterPosition(position); if (position > prevItem.AfterEnd) { // Not touching the previous item, check its parents for (; prevItem != null; prevItem = prevItem.Parent) { if (prevItem.IsUnclosed || prevItem.AfterEnd >= position) { break; } } } // Only use the next item if the cursor is touching it, and it's not a comment if (nextItem != null && (position < nextItem.Start || nextItem.FindType <Comment>() != null)) { nextItem = null; } // When two things touch the cursor inside of a selector, always prefer the previous item. // If this logic gets larger, consider a better design to choose between two items. if (nextItem != null && prevItem != null && prevItem.AfterEnd == position && prevItem.FindType <SimpleSelector>() != null) { nextItem = null; } return(nextItem ?? prevItem); }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (session == null || qiContent == null || qiContent.Count > 0 || !WESettings.Instance.Css.ShowBrowserTooltip) { return; } SnapshotPoint?point = session.GetTriggerPoint(_buffer.CurrentSnapshot); if (!point.HasValue) { return; } var tree = CssEditorDocument.FromTextBuffer(_buffer); ParseItem item = tree.StyleSheet.ItemBeforePosition(point.Value.Position); if (item == null || !item.IsValid) { return; } ICssSchemaInstance schema = CssSchemaManager.SchemaManager.GetSchemaForItem(_rootSchema, item); Tuple <ParseItem, ICssCompletionListEntry> tuple = GetEntriesAndPoint(item, point.Value, schema); if (tuple == null) { return; } ParseItem tipItem = tuple.Item1; ICssCompletionListEntry entry = tuple.Item2; if (tipItem == null || entry == null) { return; } var ruleSet = item.FindType <RuleSet>(); //If the selector's full name would require computation (it's nested), compute it and add it to the output if (ruleSet != null && ruleSet.Parent.FindType <RuleSet>() != null) { qiContent.Add(LessDocument.GetLessSelectorName(ruleSet)); } applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tipItem.Start, tipItem.Length, SpanTrackingMode.EdgeNegative); string syntax = entry.GetSyntax(schema.Version); string b = entry.GetAttribute("browsers"); if (string.IsNullOrEmpty(b) && tipItem.Parent != null && tipItem.Parent is Declaration) { b = schema.GetProperty(((Declaration)tipItem.Parent).PropertyName.Text).GetAttribute("browsers"); if (string.IsNullOrEmpty(syntax)) { syntax = tipItem.Text; } } if (!string.IsNullOrEmpty(syntax)) { //var example = CreateExample(syntax); qiContent.Add("Example: " + syntax); } Dictionary <string, string> browsers = GetBrowsers(b); qiContent.Add(CreateBrowserList(browsers)); }
private void UpdateEmbeddedImageValues(ParseItem item) { if (!WESettings.Instance.Css.SyncBase64ImageValues) return; Declaration dec = item.FindType<Declaration>(); if (dec != null && Cache.Contains(dec)) { var url = (UrlItem)dec.Values.First(); if (!url.IsValid || url.UrlString == null || url.UrlString.Text.Contains(";base64,")) return; var matches = Cache.Where(d => d.IsValid && d != dec && d.Parent == dec.Parent && (d.Values[0].NextSibling as CComment) != null); // Undo sometimes messes with the positions, so we have to make this check before proceeding. if (!matches.Any() || dec.Text.Length < dec.Colon.AfterEnd - dec.Start || dec.Colon.AfterEnd < dec.Start) return; string urlText = url.UrlString.Text.Trim('\'', '"'); string filePath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(_buffer.GetFileName()), urlText)); string b64UrlText = FileHelpers.ConvertToBase64(filePath); string b64Url = url.Text.Replace(urlText, b64UrlText); IEnumerable<Tuple<SnapshotSpan, string>> changes = matches.Reverse().SelectMany(match => { ParseItem value = match.Values[0]; CComment comment = value.NextSibling as CComment; SnapshotSpan span = new SnapshotSpan(_buffer.CurrentSnapshot, comment.CommentText.Start, comment.CommentText.Length); url = (UrlItem)value; SnapshotSpan b64Span = new SnapshotSpan(_buffer.CurrentSnapshot, url.Start, url.Length); return new[] { new Tuple<SnapshotSpan, string>(span, urlText), new Tuple<SnapshotSpan, string>(b64Span, b64Url) }; }); Dispatcher.CurrentDispatcher.InvokeAsync(() => { using (ITextEdit edit = _buffer.CreateEdit()) { foreach (Tuple<SnapshotSpan, string> change in changes) { SnapshotSpan currentSpan = change.Item1.TranslateTo(_buffer.CurrentSnapshot, SpanTrackingMode.EdgeExclusive); edit.Replace(currentSpan, change.Item2); } edit.Apply(); } }); } }
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; }
private void UpdateVendorValues(ParseItem item) { if (!WESettings.GetBoolean(WESettings.Keys.SyncVendorValues)) return; Declaration dec = item.FindType<Declaration>(); if (dec != null && Cache.Contains(dec) && !dec.IsVendorSpecific()) { // Find all vendor specifics that isn't the standard property. var matches = Cache.Where(d => d.IsValid && d != dec && d.Parent == dec.Parent && GetStandardName(d) == dec.PropertyName.Text && d.PropertyName.Text != dec.PropertyName.Text); // Undo sometimes messes with the positions, so we have to make this check before proceeding. if (!matches.Any() || dec.Text.Length < dec.Colon.AfterEnd - dec.Start || dec.Colon.AfterEnd < dec.Start) return; string text = dec.Text.Substring(dec.Colon.AfterEnd - dec.Start, dec.AfterEnd - dec.Colon.AfterEnd); using (ITextEdit edit = _buffer.CreateEdit()) { foreach (Declaration match in matches.Reverse()) { SnapshotSpan span = new SnapshotSpan(_buffer.CurrentSnapshot, match.Colon.AfterEnd, match.AfterEnd - match.Colon.AfterEnd); if (span.GetText() != text) edit.Replace(span, text); } edit.Apply(); } } }
private IEnumerable <CssSourceMapNode> ProcessGeneratedMaps(string cssfileContents) { ParseItem item = null; Selector selector = null; StyleSheet styleSheet = null; SimpleSelector simple = null; int start; var parser = new CssParser(); var result = new List <CssSourceMapNode>(); styleSheet = parser.Parse(cssfileContents, false); foreach (var node in MapNodes) { start = cssfileContents.NthIndexOfCharInString('\n', node.GeneratedLine); start += node.GeneratedColumn; item = styleSheet.ItemAfterPosition(start); if (item == null) { continue; } selector = item.FindType <Selector>(); if (selector == null) { continue; } var depth = node.OriginalSelector.TreeDepth / 2; if (depth < selector.SimpleSelectors.Count) { simple = selector.SimpleSelectors.First(); if (simple == null) { simple = item.Parent != null?item.Parent.FindType <SimpleSelector>() : null; } if (simple == null) { continue; } var selectorText = new StringBuilder(); for (int i = 0; i < node.OriginalSelector.SimpleSelectors.Count; i++) { if (simple == null) { break; } selectorText.Append(simple.Text).Append(" "); simple = simple.NextSibling as SimpleSelector; } StyleSheet sheet = parser.Parse(selectorText.ToString(), false); if (sheet == null || !sheet.RuleSets.Any() || !sheet.RuleSets.First().Selectors.Any()) { continue; } selector = sheet.RuleSets.First().Selectors.First() as Selector; if (selector == null) { continue; } } node.GeneratedSelector = selector; result.Add(node); } return(result); }