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);
        }
示例#2
0
        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);
        }
示例#3
0
        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);
        }
示例#4
0
        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;
        }
示例#8
0
        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;
                }
            }
        }
示例#11
0
        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);
        }
示例#13
0
        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;
                        }
                    }
                }
            }
        }
示例#19
0
        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);
        }
示例#20
0
        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;
        }
示例#22
0
        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;
        }
示例#26
0
        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;
                        }
                    }
                }
            }
        }
示例#28
0
        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);
            }
        }
示例#30
0
        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));
            }
        }
示例#31
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);
        }
示例#32
0
        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);
        }
示例#34
0
        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);
        }
示例#35
0
        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>());
        }
示例#36
0
        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));
                    }
                }
            }
        }
示例#37
0
        /// <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();
                }
            }
        }
示例#42
0
        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);
        }