├── art
├── mediatype.png
├── font-preview.png
├── image-preview.png
└── color-adornments.png
├── src
├── Resources
│ ├── Icon.png
│ ├── Browsers
│ │ ├── c.png
│ │ ├── e.png
│ │ ├── ff.png
│ │ ├── ie.png
│ │ ├── o.png
│ │ └── s.png
│ └── nopreview.png
├── CssToolsPackage.cs
├── Properties
│ └── AssemblyInfo.cs
├── QuickInfo
│ ├── Font
│ │ ├── FontQuickInfoSourceProvider.cs
│ │ ├── FontQuickInfoControllerProvider.cs
│ │ ├── FontQuickInfoController.cs
│ │ └── FontQuickInfo.cs
│ ├── Image
│ │ ├── ImageQuickInfoSourceProvider.cs
│ │ ├── ImageQuickInfoControllerProvider.cs
│ │ ├── ImageQuickInfoController.cs
│ │ └── ImageQuickInfo.cs
│ ├── Selector
│ │ ├── SelectorQuickInfoSourceProvider.cs
│ │ ├── SelectorQuickInfoControllerProvider.cs
│ │ ├── SelectorQuickInfoController.cs
│ │ ├── SelectorQuickInfo.cs
│ │ └── SelectorSpecificity.cs
│ └── ValueOrder
│ │ ├── ValueOrderSignatureHelpSourceProvider.cs
│ │ ├── RemoveCssSignatureHelpSource.cs
│ │ ├── ValueOrderSignatureHelpSource.cs
│ │ └── ValueOrderSignature.cs
├── BrowserLink
│ └── BrowserInfo
│ │ ├── BrowserInfo.js
│ │ └── BrowserInfo.cs
├── Adornments
│ ├── ColorTaggerProvider.cs
│ ├── ColorTag.cs
│ ├── ColorAdornmentTaggerProvider.cs
│ ├── ColorAdornment.cs
│ ├── ColorAdornmentTagger.cs
│ └── ColorTagger.cs
├── source.extension.cs
├── Helpers
│ ├── CssItemCollector.cs
│ ├── OptionHelpers.cs
│ ├── CssItemAggregator.cs
│ ├── CssTreeWatcher.cs
│ └── VendorHelpers.cs
├── Completion
│ ├── Filter
│ │ ├── HideUncommonCompletionListFilter.cs
│ │ ├── HideInheritInitialCompletionListFilter.cs
│ │ ├── ObsoleteCompletionListFilter.cs
│ │ └── WebkitScrollbarCompletionListFilter.cs
│ ├── ContextProviders
│ │ ├── MediaQueryContextProvider.cs
│ │ ├── LessPseudoContextProvider.cs
│ │ └── MediaFeatureContextProvider.cs
│ ├── CompletionProviders
│ │ ├── RegionCompletionProvider.cs
│ │ ├── BrowserLinkCompletionProvider.cs
│ │ ├── ColorCompletionProvider.cs
│ │ ├── MediaTypeCompletionProvider.cs
│ │ ├── FontCompletionProvider.cs
│ │ ├── MediaCompletionProvider.cs
│ │ └── MediaValueCompletionProvider.cs
│ ├── RegionCompletionListEntry.cs
│ ├── CompletionListEntry.cs
│ ├── FontFamilyCompletionListEntry.cs
│ └── BrowserCompletionListEntry.cs
├── ExtensionMethods
│ ├── ColorModelExtensions.cs
│ ├── Extensions.cs
│ ├── AtDirectiveExtensions.cs
│ ├── DeclarationExtensions.cs
│ └── CssExtensions.cs
├── source.extension.vsixmanifest
├── Commands
│ ├── RetriggerCommandTarget.cs
│ ├── CssCreationListener.cs
│ └── ArrowsCommandTarget.cs
├── Classify
│ ├── Base64TaggerProvider.cs
│ ├── ImportantClassifier.cs
│ ├── ValueTaggerProvider.cs
│ ├── VendorClassifier.cs
│ └── CssHighlightWordTagger.cs
├── packages.config
└── DragDrop
│ └── FontDrop.cs
├── lib
├── Microsoft.WebTools.Languages.Css.dll
├── Microsoft.WebTools.Languages.Shared.dll
├── Microsoft.WebTools.Languages.Css.Editor.dll
├── Microsoft.WebTools.Languages.Extensions.dll
└── Microsoft.WebTools.Languages.Shared.Editor.dll
├── .gitignore
├── .github
├── ISSUE_TEMPLATE.md
└── CONTRIBUTING.md
├── .gitattributes
├── LICENSE
├── appveyor.yml
├── CHANGELOG.md
├── CssTools2019.sln
└── README.md
/art/mediatype.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/CssTools2019/master/art/mediatype.png
--------------------------------------------------------------------------------
/art/font-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/CssTools2019/master/art/font-preview.png
--------------------------------------------------------------------------------
/art/image-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/CssTools2019/master/art/image-preview.png
--------------------------------------------------------------------------------
/art/color-adornments.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/CssTools2019/master/art/color-adornments.png
--------------------------------------------------------------------------------
/src/Resources/Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/CssTools2019/master/src/Resources/Icon.png
--------------------------------------------------------------------------------
/src/Resources/Browsers/c.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/CssTools2019/master/src/Resources/Browsers/c.png
--------------------------------------------------------------------------------
/src/Resources/Browsers/e.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/CssTools2019/master/src/Resources/Browsers/e.png
--------------------------------------------------------------------------------
/src/Resources/Browsers/ff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/CssTools2019/master/src/Resources/Browsers/ff.png
--------------------------------------------------------------------------------
/src/Resources/Browsers/ie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/CssTools2019/master/src/Resources/Browsers/ie.png
--------------------------------------------------------------------------------
/src/Resources/Browsers/o.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/CssTools2019/master/src/Resources/Browsers/o.png
--------------------------------------------------------------------------------
/src/Resources/Browsers/s.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/CssTools2019/master/src/Resources/Browsers/s.png
--------------------------------------------------------------------------------
/src/Resources/nopreview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/CssTools2019/master/src/Resources/nopreview.png
--------------------------------------------------------------------------------
/lib/Microsoft.WebTools.Languages.Css.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/CssTools2019/master/lib/Microsoft.WebTools.Languages.Css.dll
--------------------------------------------------------------------------------
/lib/Microsoft.WebTools.Languages.Shared.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/CssTools2019/master/lib/Microsoft.WebTools.Languages.Shared.dll
--------------------------------------------------------------------------------
/lib/Microsoft.WebTools.Languages.Css.Editor.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/CssTools2019/master/lib/Microsoft.WebTools.Languages.Css.Editor.dll
--------------------------------------------------------------------------------
/lib/Microsoft.WebTools.Languages.Extensions.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/CssTools2019/master/lib/Microsoft.WebTools.Languages.Extensions.dll
--------------------------------------------------------------------------------
/lib/Microsoft.WebTools.Languages.Shared.Editor.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madskristensen/CssTools2019/master/lib/Microsoft.WebTools.Languages.Shared.Editor.dll
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | packages
2 |
3 | # User files
4 | *.suo
5 | *.user
6 | *.sln.docstates
7 | .vs/
8 |
9 | # Build results
10 | [Dd]ebug/
11 | [Rr]elease/
12 | x64/
13 | [Bb]in/
14 | [Oo]bj/
15 |
16 | # MSTest test Results
17 | [Tt]est[Rr]esult*/
18 | [Bb]uild[Ll]og.*
19 |
20 | # NCrunch
21 | *.ncrunchsolution
22 | *.ncrunchproject
23 | _NCrunch_WebCompiler
--------------------------------------------------------------------------------
/src/CssToolsPackage.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.Shell;
2 | using System;
3 | using System.Runtime.InteropServices;
4 |
5 | namespace CssTools
6 | {
7 | [PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
8 | [InstalledProductRegistration(Vsix.Name, Vsix.Description, Vsix.Version)]
9 | [Guid("fd12c213-77b8-4e48-b372-17b83b533789")]
10 | public sealed class CssToolsPackage : AsyncPackage
11 | {
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ### Installed product versions
2 | - Visual Studio: [example 2015 Professional]
3 | - This extension: [example 1.1.21]
4 |
5 | ### Description
6 | Replace this text with a short description
7 |
8 | ### Steps to recreate
9 | 1. Replace this
10 | 2. text with
11 | 3. the steps
12 | 4. to recreate
13 |
14 | ### Current behavior
15 | Explain what it's doing and why it's wrong
16 |
17 | ### Expected behavior
18 | Explain what it should be doing after it's fixed.
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2016 Mads Kristensen
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
--------------------------------------------------------------------------------
/src/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using CssTools;
2 | using System.Reflection;
3 | using System.Runtime.InteropServices;
4 |
5 | [assembly: AssemblyTitle(Vsix.Name)]
6 | [assembly: AssemblyDescription(Vsix.Description)]
7 | [assembly: AssemblyConfiguration("")]
8 | [assembly: AssemblyCompany(Vsix.Author)]
9 | [assembly: AssemblyProduct(Vsix.Name)]
10 | [assembly: AssemblyCopyright(Vsix.Author)]
11 | [assembly: AssemblyTrademark("")]
12 | [assembly: AssemblyCulture("")]
13 |
14 | [assembly: ComVisible(false)]
15 |
16 | [assembly: AssemblyVersion(Vsix.Version)]
17 | [assembly: AssemblyFileVersion(Vsix.Version)]
18 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | image: Visual Studio 2019 Preview
2 |
3 | install:
4 | - ps: (new-object Net.WebClient).DownloadString("https://raw.github.com/madskristensen/ExtensionScripts/master/AppVeyor/vsix.ps1") | iex
5 |
6 | before_build:
7 | - ps: Vsix-IncrementVsixVersion | Vsix-UpdateBuildVersion
8 | - ps: Vsix-TokenReplacement src\source.extension.cs 'Version = "([0-9\\.]+)"' 'Version = "{version}"'
9 |
10 | build_script:
11 | - nuget restore -Verbosity quiet
12 | - msbuild /p:configuration=Release /p:DeployExtension=false /p:ZipPackageCompressionLevel=normal /v:m
13 |
14 | after_test:
15 | - ps: Vsix-PushArtifacts | Vsix-PublishToGallery
16 |
--------------------------------------------------------------------------------
/src/QuickInfo/Font/FontQuickInfoSourceProvider.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.Composition;
2 | using Microsoft.VisualStudio.Language.Intellisense;
3 | using Microsoft.VisualStudio.Text;
4 | using Microsoft.VisualStudio.Utilities;
5 |
6 | namespace CssTools
7 | {
8 | [Export(typeof(IQuickInfoSourceProvider))]
9 | [Name("Font QuickInfo Source")]
10 | [Order(Before = "Default Quick Info Presenter")]
11 | [ContentType("CSS")]
12 | internal class FontQuickInfoSourceProvider : IQuickInfoSourceProvider
13 | {
14 | public IQuickInfoSource TryCreateQuickInfoSource(ITextBuffer textBuffer)
15 | {
16 | return new FontQuickInfo(textBuffer);
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/BrowserLink/BrowserInfo/BrowserInfo.js:
--------------------------------------------------------------------------------
1 | (function (browserLink, $) {
2 | ///
3 | ///
4 |
5 | function SendInfo() {
6 |
7 | var width = window.innerWidth || document.body.clientWidth;
8 | var height = window.innerHeight || document.body.clientHeight;
9 |
10 | browserLink.invoke("CollectInfo", width, height);
11 | }
12 |
13 | window.addEventListener('resize', function (event) {
14 | SendInfo();
15 | });
16 |
17 | return {
18 |
19 | onConnected: function () { // Optional. Is called when a connection is established
20 | SendInfo();
21 | }
22 | };
23 | });
--------------------------------------------------------------------------------
/src/QuickInfo/Image/ImageQuickInfoSourceProvider.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.Composition;
2 | using Microsoft.VisualStudio.Language.Intellisense;
3 | using Microsoft.VisualStudio.Text;
4 | using Microsoft.VisualStudio.Utilities;
5 |
6 | namespace CssTools
7 | {
8 | [Export(typeof(IQuickInfoSourceProvider))]
9 | [Name("Image QuickInfo Source")]
10 | [Order(Before = "Default Quick Info Presenter")]
11 | [ContentType("CSS")]
12 | internal class ImageQuickInfoSourceProvider : IQuickInfoSourceProvider
13 | {
14 | public IQuickInfoSource TryCreateQuickInfoSource(ITextBuffer textBuffer)
15 | {
16 | return new ImageQuickInfo(textBuffer);
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/QuickInfo/Selector/SelectorQuickInfoSourceProvider.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.Composition;
2 | using Microsoft.VisualStudio.Language.Intellisense;
3 | using Microsoft.VisualStudio.Text;
4 | using Microsoft.VisualStudio.Utilities;
5 |
6 | namespace CssTools
7 | {
8 | [Export(typeof(IQuickInfoSourceProvider))]
9 | [Name("Selector QuickInfo Source")]
10 | [Order(Before = "Default Quick Info Presenter")]
11 | [ContentType("CSS")]
12 | internal class SelectorQuickInfoSourceProvider : IQuickInfoSourceProvider
13 | {
14 | public IQuickInfoSource TryCreateQuickInfoSource(ITextBuffer textBuffer)
15 | {
16 | return new SelectorQuickInfo(textBuffer);
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/Adornments/ColorTaggerProvider.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.Text;
2 | using Microsoft.VisualStudio.Text.Tagging;
3 | using Microsoft.VisualStudio.Utilities;
4 | using System;
5 | using System.ComponentModel.Composition;
6 |
7 | namespace CssTools
8 | {
9 | [Export(typeof(ITaggerProvider))]
10 | [ContentType("css")]
11 | [TagType(typeof(ColorTag))]
12 | internal sealed class ColorTaggerProvider : ITaggerProvider
13 | {
14 | public ITagger CreateTagger(ITextBuffer buffer) where T : ITag
15 | {
16 | if (buffer == null)
17 | throw new ArgumentNullException("buffer");
18 |
19 | return buffer.Properties.GetOrCreateSingletonProperty(() => new ColorTagger(buffer)) as ITagger;
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/source.extension.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------------------------
2 | //
3 | // This file was generated by VSIX Synchronizer
4 | //
5 | // ------------------------------------------------------------------------------
6 | namespace CssTools
7 | {
8 | internal sealed partial class Vsix
9 | {
10 | public const string Id = "1c63270f-485d-4810-99b8-e9d9de82610c";
11 | public const string Name = "CSS Tools 2019";
12 | public const string Description = @"Provides additional features to the CSS editor in Visual Studio.";
13 | public const string Language = "en-US";
14 | public const string Version = "1.1";
15 | public const string Author = "Mads Kristensen";
16 | public const string Tags = "css, less, sass, scss, stylesheet";
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Road map
2 |
3 | - [ ] Light bulbs
4 |
5 | Features that have a checkmark are complete and available for
6 | download in the
7 | [CI build](http://vsixgallery.com/extension/0020efc9-e999-4e6f-a2b6-604127f480bc/).
8 |
9 | # Change log
10 |
11 | These are the changes to each version that has been released
12 | on the official Visual Studio extension gallery.
13 |
14 | ## 1.0
15 |
16 | - [x] Initial release
17 | - [x] Color adornments
18 | - [x] Font preview
19 | - [x] Image preview
20 | - [x] Selector specificity tooltip
21 | - [x] Property value signature help
22 | - [x] Selector highlighter
23 | - [x] Various classifiers
24 | - [x] Drag 'n drop font files
25 | - [x] Media query Intellisense powered by Browser Link
26 | - [x] Font import Intellisense
27 | - [x] Intellisense filters for unsupported properties
28 | - [x] Vendor property synchronization
29 | - [x] Darken/lighten hex colors
--------------------------------------------------------------------------------
/src/QuickInfo/Font/FontQuickInfoControllerProvider.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.ComponentModel.Composition;
3 | using Microsoft.VisualStudio.Language.Intellisense;
4 | using Microsoft.VisualStudio.Text;
5 | using Microsoft.VisualStudio.Text.Editor;
6 | using Microsoft.VisualStudio.Utilities;
7 |
8 | namespace CssTools
9 | {
10 | [Export(typeof(IIntellisenseControllerProvider))]
11 | [Name("Font QuickInfo Controller")]
12 | [ContentType("css")]
13 | public class FontQuickInfoControllerProvider : IIntellisenseControllerProvider
14 | {
15 | [Import]
16 | public IQuickInfoBroker QuickInfoBroker { get; set; }
17 |
18 | public IIntellisenseController TryCreateIntellisenseController(ITextView textView, IList subjectBuffers)
19 | {
20 | return new FontQuickInfoController(textView, subjectBuffers, this);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/QuickInfo/Image/ImageQuickInfoControllerProvider.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.ComponentModel.Composition;
3 | using Microsoft.VisualStudio.Language.Intellisense;
4 | using Microsoft.VisualStudio.Text;
5 | using Microsoft.VisualStudio.Text.Editor;
6 | using Microsoft.VisualStudio.Utilities;
7 |
8 | namespace CssTools
9 | {
10 | [Export(typeof(IIntellisenseControllerProvider))]
11 | [Name("Image QuickInfo Controller")]
12 | [ContentType("CSS")]
13 | public class ImageQuickInfoControllerProvider : IIntellisenseControllerProvider
14 | {
15 | [Import]
16 | public IQuickInfoBroker QuickInfoBroker { get; set; }
17 |
18 | public IIntellisenseController TryCreateIntellisenseController(ITextView textView, IList subjectBuffers)
19 | {
20 | return new ImageQuickInfoController(textView, subjectBuffers, this);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/QuickInfo/Selector/SelectorQuickInfoControllerProvider.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.ComponentModel.Composition;
3 | using Microsoft.VisualStudio.Language.Intellisense;
4 | using Microsoft.VisualStudio.Text;
5 | using Microsoft.VisualStudio.Text.Editor;
6 | using Microsoft.VisualStudio.Utilities;
7 |
8 | namespace CssTools
9 | {
10 | [Export(typeof(IIntellisenseControllerProvider))]
11 | [Name("Selector QuickInfo Controller")]
12 | [ContentType("CSS")]
13 | public class SelectorQuickInfoControllerProvider : IIntellisenseControllerProvider
14 | {
15 | [Import]
16 | public IQuickInfoBroker QuickInfoBroker { get; set; }
17 |
18 | public IIntellisenseController TryCreateIntellisenseController(ITextView textView, IList subjectBuffers)
19 | {
20 | return new SelectorQuickInfoController(textView, subjectBuffers, this);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/Helpers/CssItemCollector.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Microsoft.WebTools.Languages.Css.Parser;
3 |
4 | namespace CssTools
5 | {
6 | ///
7 | /// Creates a list of CSS ParseItems of a certain type
8 | /// (when passed in as the visitor to any item's Accept() function)
9 | ///
10 | internal class CssItemCollector : ICssSimpleTreeVisitor where T : ParseItem
11 | {
12 | public IList Items { get; private set; }
13 | private bool _includeChildren;
14 |
15 | public CssItemCollector() : this(false) { }
16 |
17 | public CssItemCollector(bool includeChildren)
18 | {
19 | _includeChildren = includeChildren;
20 | Items = new List();
21 | }
22 |
23 | public VisitItemResult Visit(ParseItem parseItem)
24 | {
25 | var item = parseItem as T;
26 |
27 | if (item != null)
28 | {
29 | Items.Add(item);
30 | return (_includeChildren) ? VisitItemResult.Continue : VisitItemResult.SkipChildren;
31 | }
32 |
33 | return VisitItemResult.Continue;
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/Completion/Filter/HideUncommonCompletionListFilter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Collections.Specialized;
3 | using System.ComponentModel.Composition;
4 | using Microsoft.VisualStudio.Utilities;
5 | using Microsoft.WebTools.Languages.Css.Editor.Completion;
6 | using Microsoft.WebTools.Languages.Shared.Editor.Completion;
7 |
8 | namespace CssTools
9 | {
10 | [Export(typeof(ICssCompletionListFilter))]
11 | [Name("HideUncommonCompletionListFilter")]
12 | internal class HideUncommonCompletionListFilter : ICssCompletionListFilter
13 | {
14 | private static readonly StringCollection _cache = new StringCollection()
15 | {
16 | "widows", // Rarely used and get's in the way of "width"
17 | };
18 |
19 | public void FilterCompletionList(IList completions, CssCompletionContext context)
20 | {
21 | if (context.ContextType != CssCompletionContextType.PropertyName)
22 | return;
23 |
24 | foreach (CssCompletionEntry entry in completions)
25 | {
26 | if (_cache.Contains(entry.DisplayText))
27 | {
28 | entry.FilterType = CompletionEntryFilterTypes.NeverVisible;
29 | }
30 | }
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/src/Completion/ContextProviders/MediaQueryContextProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.Composition;
4 | using Microsoft.VisualStudio.Utilities;
5 | using Microsoft.WebTools.Languages.Css.Editor.Completion;
6 | using Microsoft.WebTools.Languages.Css.Parser;
7 | using Microsoft.WebTools.Languages.Css.TreeItems.AtDirectives;
8 |
9 | namespace CssTools
10 | {
11 | [Export(typeof(ICssCompletionContextProvider))]
12 | [Name("MediaQueryCompletionContextProvider")]
13 | internal class MediaQueryCompletionContextProvider : ICssCompletionContextProvider
14 | {
15 | public IEnumerable ItemTypes
16 | {
17 | get
18 | {
19 | return new Type[] { typeof(MediaQuery), };
20 | }
21 | }
22 |
23 | public CssCompletionContext GetCompletionContext(ParseItem item, int position)
24 | {
25 | var token = item.StyleSheet.ItemBeforePosition(position);
26 |
27 | // Don't handle expressions. MediaFeatureContextProvider.cs does that
28 | if (token.FindType() != null)
29 | return null;
30 |
31 | return new CssCompletionContext((CssCompletionContextType)612, token.Start, token.Length, null);
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/CssTools2019.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.25921.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CssTools", "src\CssTools.csproj", "{F9226ED2-B38A-4A5B-89C6-F0A30A253E05}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D1FDE0E6-30E3-474E-A176-5C5A56FBDDDF}"
9 | ProjectSection(SolutionItems) = preProject
10 | appveyor.yml = appveyor.yml
11 | CHANGELOG.md = CHANGELOG.md
12 | README.md = README.md
13 | EndProjectSection
14 | EndProject
15 | Global
16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
17 | Debug|Any CPU = Debug|Any CPU
18 | Release|Any CPU = Release|Any CPU
19 | EndGlobalSection
20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
21 | {F9226ED2-B38A-4A5B-89C6-F0A30A253E05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22 | {F9226ED2-B38A-4A5B-89C6-F0A30A253E05}.Debug|Any CPU.Build.0 = Debug|Any CPU
23 | {F9226ED2-B38A-4A5B-89C6-F0A30A253E05}.Release|Any CPU.ActiveCfg = Release|Any CPU
24 | {F9226ED2-B38A-4A5B-89C6-F0A30A253E05}.Release|Any CPU.Build.0 = Release|Any CPU
25 | EndGlobalSection
26 | GlobalSection(SolutionProperties) = preSolution
27 | HideSolutionNode = FALSE
28 | EndGlobalSection
29 | EndGlobal
30 |
--------------------------------------------------------------------------------
/src/QuickInfo/ValueOrder/ValueOrderSignatureHelpSourceProvider.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel.Composition;
2 | using Microsoft.VisualStudio.Language.Intellisense;
3 | using Microsoft.VisualStudio.Text;
4 | using Microsoft.VisualStudio.Utilities;
5 | using Microsoft.WebTools.Languages.Shared.ContentTypes;
6 |
7 | namespace CssTools
8 | {
9 | [Export(typeof(ISignatureHelpSourceProvider))]
10 | [Name("Value Order Signature Help Source")]
11 | [Order(Before = "CSS Signature Help Source")]
12 | [ContentType(CssContentTypeDefinition.CssContentType)]
13 | internal class ValueOrderSignatureHelpSourceProvider : ISignatureHelpSourceProvider
14 | {
15 | public ISignatureHelpSource TryCreateSignatureHelpSource(ITextBuffer textBuffer)
16 | {
17 | return new ValueOrderSignatureHelpSource(textBuffer);
18 | }
19 | }
20 |
21 | [Export(typeof(ISignatureHelpSourceProvider))]
22 | [Name("Value Order Signature Help Source2")]
23 | [Order(After = "Default")]
24 | [ContentType(CssContentTypeDefinition.CssContentType)]
25 | internal class RemoveCssSignatureHelpSourceProvider : ISignatureHelpSourceProvider
26 | {
27 | public ISignatureHelpSource TryCreateSignatureHelpSource(ITextBuffer textBuffer)
28 | {
29 | return new RemoveCssSignatureHelpSource(textBuffer);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/Completion/ContextProviders/LessPseudoContextProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.Composition;
4 | using Microsoft.VisualStudio.Utilities;
5 | using Microsoft.WebTools.Languages.Css.Editor.Completion;
6 | using Microsoft.WebTools.Languages.Css.Parser;
7 | using Microsoft.WebTools.Languages.Css.TreeItems;
8 | using Microsoft.WebTools.Languages.Css.TreeItems.Selectors;
9 | using Microsoft.WebTools.Languages.Extensions.Less.Parser;
10 |
11 | namespace CssTools
12 | {
13 | [Export(typeof(ICssCompletionContextProvider))]
14 | [Name("LessPseudoContextProvider")]
15 | [Order(Before = "Default Pseudo")]
16 | internal class LessPseudoContextProvider : ICssCompletionContextProvider
17 | {
18 | public IEnumerable ItemTypes
19 | {
20 | get
21 | {
22 | return new Type[]
23 | {
24 | typeof(PseudoClassFunctionSelector),
25 | typeof(PseudoClassSelector),
26 | typeof(PseudoElementFunctionSelector),
27 | typeof(PseudoElementSelector)
28 | };
29 | }
30 | }
31 |
32 | public CssCompletionContext GetCompletionContext(ParseItem item, int position)
33 | {
34 | RuleSet rule = item.FindType();
35 |
36 | if (rule != null && rule.Parent is LessRuleBlock)
37 | {
38 | return new CssCompletionContext(CssCompletionContextType.Invalid, item.Start, item.Length, item);
39 | }
40 |
41 | return null;
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/src/Adornments/ColorTag.cs:
--------------------------------------------------------------------------------
1 | //***************************************************************************
2 | //
3 | // Copyright (c) Microsoft Corporation. All rights reserved.
4 | // This code is licensed under the Visual Studio SDK license terms.
5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
9 | //
10 | //***************************************************************************
11 |
12 | using Microsoft.VisualStudio.Text.Tagging;
13 | using System.Windows.Media;
14 |
15 | namespace CssTools
16 | {
17 | ///
18 | /// Data tag indicating that the tagged text represents a color.
19 | ///
20 | ///
21 | /// Note that this tag has nothing directly to do with adornments or other UI.
22 | /// This sample's adornments will be produced based on the data provided in these tags.
23 | /// This separation provides the potential for other extensions to consume color tags
24 | /// and provide alternative UI or other derived functionality over this data.
25 | ///
26 | internal class ColorTag : ITag
27 | {
28 | internal readonly Color Color;
29 |
30 | internal ColorTag(Color color)
31 | {
32 | this.Color = color;
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Completion/Filter/HideInheritInitialCompletionListFilter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.ComponentModel.Composition;
3 | using Microsoft.VisualStudio.Utilities;
4 | using Microsoft.WebTools.Languages.Css.Editor.Completion;
5 | using Microsoft.WebTools.Languages.Css.TreeItems;
6 | using Microsoft.WebTools.Languages.Shared.Editor.Completion;
7 |
8 | namespace CssTools
9 | {
10 | [Export(typeof(ICssCompletionListFilter))]
11 | [Name("Inherit/Initial Filter")]
12 | internal class HideInheritInitialCompletionListFilter : ICssCompletionListFilter
13 | {
14 | public void FilterCompletionList(IList completions, CssCompletionContext context)
15 | {
16 | if (context.ContextType != CssCompletionContextType.PropertyValue)
17 | return;
18 |
19 | // Only show inherit/initial/unset on the "all" property
20 | Declaration dec = context.ContextItem.FindType();
21 |
22 | if (dec != null && dec.PropertyNameText == "all")
23 | return;
24 |
25 | foreach (CssCompletionEntry entry in completions)
26 | {
27 | if (entry.DisplayText == "initial" || entry.DisplayText == "inherit" || entry.DisplayText == "unset")
28 | {
29 | entry.FilterType = CompletionEntryFilterTypes.NeverVisible;
30 | }
31 | }
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/src/ExtensionMethods/ColorModelExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Windows.Media;
2 | using Microsoft.WebTools.Languages.Shared.Editor.ColorPicker;
3 |
4 | namespace CssTools
5 | {
6 | internal static class ColorModelExtensions
7 | {
8 | private const float _factor = 0.025F;
9 |
10 | public static ColorModel Brighten(this ColorModel color)
11 | {
12 | if ((color.HslLightness + _factor) < 1)
13 | {
14 | color.HslLightness += _factor;
15 | }
16 |
17 | return color;
18 | }
19 |
20 | public static ColorModel Darken(this ColorModel color)
21 | {
22 | if ((color.HslLightness - _factor) > 0)
23 | {
24 | color.HslLightness -= _factor;
25 | }
26 |
27 | return color;
28 | }
29 |
30 | public static ColorModel Invert(this ColorModel color)
31 | {
32 | ColorModel model = new ColorModel()
33 | {
34 | Red = ~(byte)color.Red,
35 | Green = ~(byte)color.Green,
36 | Blue = ~(byte)color.Blue
37 | };
38 |
39 | return model;
40 |
41 | }
42 |
43 | public static SolidColorBrush ToBrush(this ColorModel color)
44 | {
45 | Color c = Color.FromRgb(
46 | (byte)color.Red,
47 | (byte)color.Green,
48 | (byte)color.Blue
49 | );
50 |
51 | SolidColorBrush brush = new SolidColorBrush(c);
52 | brush.Freeze();
53 | return brush;
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/Completion/CompletionProviders/RegionCompletionProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.Composition;
4 | using System.Windows.Threading;
5 | using Microsoft.VisualStudio.Text;
6 | using Microsoft.VisualStudio.Text.Editor;
7 | using Microsoft.VisualStudio.Utilities;
8 | using Microsoft.WebTools.Languages.Css.Editor.Completion;
9 |
10 | namespace CssTools
11 | {
12 | [Export(typeof(ICssCompletionProvider))]
13 | [Name("RegionCompletionProvider")]
14 | internal class RegionCompletionProvider : ICssCompletionListProvider, ICssCompletionCommitListener
15 | {
16 | private RegionCompletionListEntry _entry = new RegionCompletionListEntry();
17 |
18 | public CssCompletionContextType ContextType
19 | {
20 | get { return CssCompletionContextType.ItemNameSelector; }
21 | }
22 |
23 | public IEnumerable GetListEntries(CssCompletionContext context)
24 | {
25 | var line = context.Snapshot.GetLineFromPosition(context.ContextItem.Start);
26 | string text = line.GetText().Trim();
27 |
28 | if (text.Length == context.ContextItem.Length)
29 | {
30 | yield return _entry;
31 | }
32 | }
33 |
34 | public void OnCommitted(ICssCompletionListEntry entry, ITrackingSpan contextSpan, SnapshotPoint caret, ITextView textView)
35 | {
36 | if (entry.DisplayText == "Add region...")
37 | {
38 | Dispatcher.CurrentDispatcher.BeginInvoke(
39 | new Action(() => System.Windows.Forms.SendKeys.Send("{TAB}")), DispatcherPriority.Normal);
40 | }
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/src/source.extension.vsixmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CSS Tools 2019
6 | Provides additional features to the CSS editor in Visual Studio.
7 | https://github.com/madskristensen/CssTools
8 | Resources\LICENSE
9 | https://github.com/madskristensen/CssTools/blob/master/CHANGELOG.md
10 | Resources\Icon.png
11 | Resources\Icon.png
12 | css, less, sass, scss, stylesheet
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/Completion/ContextProviders/MediaFeatureContextProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.Composition;
4 | using Microsoft.VisualStudio.Utilities;
5 | using Microsoft.WebTools.Languages.Css.Editor.Completion;
6 | using Microsoft.WebTools.Languages.Css.Parser;
7 | using Microsoft.WebTools.Languages.Css.TreeItems.AtDirectives;
8 |
9 | namespace CssTools
10 | {
11 | [Export(typeof(ICssCompletionContextProvider))]
12 | [Name("MediaFeatureCompletionContextProvider")]
13 | internal class MediaFeatureCompletionContextProvider : ICssCompletionContextProvider
14 | {
15 | public IEnumerable ItemTypes
16 | {
17 | get
18 | {
19 | return new Type[] { typeof(MediaExpression), };
20 | }
21 | }
22 |
23 | public CssCompletionContext GetCompletionContext(ParseItem item, int position)
24 | {
25 | MediaExpression expr = (MediaExpression)item;
26 |
27 | if (expr.MediaFeature != null &&
28 | (position >= expr.Values.TextStart && position <= expr.Values.TextAfterEnd) ||
29 | (expr.Colon != null && position >= expr.Colon.AfterEnd))
30 | {
31 | return new CssCompletionContext((CssCompletionContextType)611, expr.Values.TextStart, expr.Values.TextLength, null);
32 | }
33 |
34 | if (expr.OpenFunctionBrace == null || position < expr.OpenFunctionBrace.Start)
35 | return null;
36 |
37 | int length = expr.MediaFeature != null ? expr.MediaFeature.Length : 1;
38 |
39 | return new CssCompletionContext((CssCompletionContextType)610, expr.OpenFunctionBrace.AfterEnd, length, null);
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Completion/Filter/ObsoleteCompletionListFilter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.ComponentModel.Composition;
3 | using Microsoft.VisualStudio.Utilities;
4 | using Microsoft.WebTools.Languages.Css.Editor.Completion;
5 | using Microsoft.WebTools.Languages.Css.Editor.Schemas;
6 | using Microsoft.WebTools.Languages.Shared.Editor.Completion;
7 |
8 | namespace CssTools
9 | {
10 | [Export(typeof(ICssCompletionListFilter))]
11 | [Name("ObsoleteCompletionListFilter")]
12 | internal class ObsoleteCompletionListFilter : ICssCompletionListFilter
13 | {
14 | public void FilterCompletionList(IList completions, CssCompletionContext context)
15 | {
16 | ICssSchemaInstance rootSchema = CssSchemaManager.SchemaManager.GetSchemaRoot(null);
17 | ICssSchemaInstance schema = CssSchemaManager.SchemaManager.GetSchemaForItem(rootSchema, context.ContextItem);
18 |
19 | foreach (CssCompletionEntry entry in completions)
20 | {
21 | ICssCompletionListEntry prop = GetSchemaEntry(schema, context, entry);
22 |
23 | if (prop != null && !string.IsNullOrEmpty(prop.GetAttribute("obsolete")))
24 | entry.FilterType = CompletionEntryFilterTypes.NeverVisible;
25 | }
26 | }
27 |
28 | private static ICssCompletionListEntry GetSchemaEntry(ICssSchemaInstance schema, CssCompletionContext context, CssCompletionEntry entry)
29 | {
30 | switch (context.ContextType)
31 | {
32 | case CssCompletionContextType.AtDirectiveName:
33 | return schema.GetAtDirective(entry.DisplayText);
34 |
35 | case CssCompletionContextType.PropertyName:
36 | return schema.GetProperty(entry.DisplayText);
37 |
38 | case CssCompletionContextType.PseudoClassOrElement:
39 | return schema.GetPseudo(entry.DisplayText);
40 | }
41 |
42 | return null;
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/src/Completion/Filter/WebkitScrollbarCompletionListFilter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Collections.Specialized;
3 | using System.ComponentModel.Composition;
4 | using Microsoft.VisualStudio.Utilities;
5 | using Microsoft.WebTools.Languages.Css.Editor.Completion;
6 | using Microsoft.WebTools.Languages.Css.Parser;
7 | using Microsoft.WebTools.Languages.Shared.Editor.Completion;
8 |
9 | namespace CssTools
10 | {
11 | [Export(typeof(ICssCompletionListFilter))]
12 | [Name("WebkitScrollbarCompletionListFilter")]
13 | internal class WebkitScrollbarCompletionListFilter : ICssCompletionListFilter
14 | {
15 | private static readonly StringCollection _cache = new StringCollection()
16 | {
17 | ":horizontal",
18 | ":vertical",
19 | ":decrement",
20 | ":increment",
21 | ":start",
22 | ":end",
23 | ":double-button",
24 | ":single-button",
25 | ":no-button",
26 | ":corner-present",
27 | ":window-inactive",
28 | };
29 |
30 | public void FilterCompletionList(IList completions, CssCompletionContext context)
31 | {
32 | if (context.ContextType != CssCompletionContextType.PseudoClassOrElement)
33 | return;
34 |
35 | ParseItem prev = context.ContextItem.PreviousSibling;
36 | bool hasScrollbar = false;
37 |
38 | if (prev != null)
39 | {
40 | hasScrollbar = prev.Text.Contains(":-webkit-resizer") || prev.Text.Contains(":-webkit-scrollbar");
41 | }
42 |
43 | foreach (CssCompletionEntry entry in completions)
44 | {
45 | if (hasScrollbar)
46 | {
47 | entry.FilterType = _cache.Contains(entry.DisplayText) ? entry.FilterType : CompletionEntryFilterTypes.NeverVisible;
48 | }
49 | else
50 | {
51 | entry.FilterType = !_cache.Contains(entry.DisplayText) ? entry.FilterType : CompletionEntryFilterTypes.NeverVisible;
52 | }
53 | }
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/src/Completion/CompletionProviders/BrowserLinkCompletionProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.Composition;
4 | using System.Linq;
5 | using Microsoft.VisualStudio.Utilities;
6 | using Microsoft.WebTools.Languages.Css.Editor.Completion;
7 | using Microsoft.WebTools.Languages.Css.TreeItems;
8 |
9 | namespace CssTools
10 | {
11 | [Export(typeof(ICssCompletionProvider))]
12 | [Name("BrowserLinkCompletionProvider")]
13 | internal class BrowserLinkCompletionProvider : ICssCompletionListProvider
14 | {
15 | public CssCompletionContextType ContextType
16 | {
17 | get { return CssCompletionContextType.PropertyValue; }
18 | }
19 |
20 | public IEnumerable GetListEntries(CssCompletionContext context)
21 | {
22 | Declaration dec = context.ContextItem.FindType();
23 |
24 | if (dec == null || dec.PropertyName == null)
25 | yield break;
26 |
27 | if (dec.PropertyName.Text.EndsWith("width", StringComparison.OrdinalIgnoreCase))
28 | {
29 | foreach (var browser in BrowserInfo.BrowserCapDictionary.Values.OrderByDescending(b => b.Width))
30 | {
31 | string value = browser.Width + "px";
32 | yield return new BrowserCompletionListEntry(value, browser.Name);
33 | }
34 | }
35 | else if (dec.PropertyName.Text.EndsWith("height", StringComparison.OrdinalIgnoreCase))
36 | {
37 | foreach (var browser in BrowserInfo.BrowserCapDictionary.Values.OrderByDescending(b => b.Height))
38 | {
39 | string value = browser.Height + "px";
40 | yield return new BrowserCompletionListEntry(value, browser.Name);
41 | }
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/Adornments/ColorAdornmentTaggerProvider.cs:
--------------------------------------------------------------------------------
1 | //***************************************************************************
2 | //
3 | // Copyright (c) Microsoft Corporation. All rights reserved.
4 | // This code is licensed under the Visual Studio SDK license terms.
5 | // THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
6 | // ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
7 | // IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
8 | // PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
9 | //
10 | //***************************************************************************
11 |
12 | using Microsoft.VisualStudio.Text;
13 | using Microsoft.VisualStudio.Text.Editor;
14 | using Microsoft.VisualStudio.Text.Tagging;
15 | using Microsoft.VisualStudio.Utilities;
16 | using System;
17 | using System.ComponentModel.Composition;
18 |
19 | namespace CssTools
20 | {
21 | [Export(typeof(IViewTaggerProvider))]
22 | [ContentType("css")]
23 | [TagType(typeof(IntraTextAdornmentTag))]
24 | [TextViewRole(PredefinedTextViewRoles.Document)]
25 | internal sealed class ColorAdornmentTaggerProvider : IViewTaggerProvider
26 | {
27 | #pragma warning disable 649 // "field never assigned to" -- field is set by MEF.
28 | [Import]
29 | internal IBufferTagAggregatorFactoryService BufferTagAggregatorFactoryService;
30 | #pragma warning restore 649
31 |
32 | public ITagger CreateTagger(ITextView textView, ITextBuffer buffer) where T : ITag
33 | {
34 | if (textView == null)
35 | throw new ArgumentNullException("textView");
36 |
37 | if (buffer == null)
38 | throw new ArgumentNullException("buffer");
39 |
40 | if (textView.Roles.Contains("DIFF"))
41 | return null;
42 |
43 | return ColorAdornmentTagger.GetTagger(
44 | textView, buffer,
45 | new Lazy>(
46 | () => BufferTagAggregatorFactoryService.CreateTagAggregator(buffer)))
47 | as ITagger;
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CSS Tools
2 |
3 | [](https://ci.appveyor.com/project/madskristensen/csstools2019)
4 |
5 | Download this extension from the [VS Marketplace](https://marketplace.visualstudio.com/vsgallery/a2b0e9a8-85c6-4495-8578-dc1da0a8791c)
6 | or get the [CI build](http://vsixgallery.com/extension/1c63270f-485d-4810-99b8-e9d9de82610c/).
7 |
8 | ---------------------------------------
9 |
10 | Provides additional features to the CSS editor in Visual Studio.
11 |
12 | See the [change log](CHANGELOG.md) for changes and road map.
13 |
14 | ## Features
15 |
16 | - Color adornments
17 | - Image and font preview
18 | - Selector specificity tooltip
19 | - Drag 'n drop of font files
20 | - Darken/lighten hex colors
21 | - Vendor property synchronization
22 | - Media query Intellisense powered by Browser Link
23 |
24 | ### Color adornments
25 | All color types are supported, including the new CSS 3 formats.
26 |
27 | 
28 |
29 | ### Image and font preview
30 | 
31 |
32 | 
33 |
34 | ### Darken/lighten hex colors
35 | Place the caret on a hex color value and hit **Ctrl+Shift+Up/Down** to
36 | darken or lighten the color value.
37 |
38 | The same can be done with any number value such as `1.2px` to increase
39 | or decrease the value.
40 |
41 | ### Vendor property synchronization
42 | [](http://www.youtube.com/watch?v=9NFKU7CCewE)
43 |
44 | ### Media query Intellisense
45 | 
46 |
47 | ## Contribute
48 | Check out the [contribution guidelines](.github/CONTRIBUTING.md)
49 | if you want to contribute to this project.
50 |
51 | For cloning and building this project yourself, make sure
52 | to install the
53 | [Extensibility Tools 2015](https://visualstudiogallery.msdn.microsoft.com/ab39a092-1343-46e2-b0f1-6a3f91155aa6)
54 | extension for Visual Studio which enables some features
55 | used by this project.
56 |
57 | ## License
58 | [Apache 2.0](LICENSE)
--------------------------------------------------------------------------------
/src/ExtensionMethods/Extensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.Text;
2 | using System;
3 | using System.Linq;
4 | using System.Windows.Media.Imaging;
5 |
6 | namespace CssTools
7 | {
8 | static class Extensions
9 | {
10 | ///Runs a callback when an iamge is fully downloaded, or immediately if the image has already been downloaded.
11 | public static void OnDownloaded(this BitmapSource image, Action callback)
12 | {
13 | if (image.IsDownloading)
14 | image.DownloadCompleted += (s, e) => callback();
15 | else
16 | callback();
17 | }
18 |
19 | ///Replaces a TextBuffer's entire content with the specified text.
20 | public static void SetText(this ITextBuffer buffer, string text)
21 | {
22 | buffer.Replace(new Span(0, buffer.CurrentSnapshot.Length), text);
23 | }
24 |
25 | ///Test the numericality of sequence.
26 | public static bool IsNumeric(this string input)
27 | {
28 | return input.All(digit => char.IsDigit(digit) || digit.Equals('.'));
29 | }
30 |
31 | ///Find the cloumn position in the last line.
32 | public static int GetLineColumn(this string text, int targetIndex, int lineNumber)
33 | {
34 | var result = targetIndex - text.NthIndexOfCharInString('\n', lineNumber);
35 |
36 | return Math.Max(0, result);
37 | }
38 |
39 | //Find the nth occurance of needle in haystack..
40 | public static int NthIndexOfCharInString(this string strHaystack, char charNeedle, int intOccurrenceToFind)
41 | {
42 | if (intOccurrenceToFind < 1) return 0;
43 |
44 | int intReturn = -1;
45 | int count = 0;
46 | int n = 0;
47 |
48 | while (count < intOccurrenceToFind && (n = strHaystack.IndexOf(charNeedle, n)) != -1)
49 | {
50 | n++;
51 | count++;
52 | }
53 |
54 | if (count == intOccurrenceToFind) intReturn = n;
55 |
56 | return intReturn;
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/QuickInfo/ValueOrder/RemoveCssSignatureHelpSource.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Microsoft.VisualStudio.Language.Intellisense;
4 | using Microsoft.VisualStudio.Text;
5 | using Microsoft.WebTools.Languages.Css.Editor.Document;
6 | using Microsoft.WebTools.Languages.Css.Parser;
7 | using Microsoft.WebTools.Languages.Css.TreeItems;
8 |
9 | namespace CssTools
10 | {
11 | internal class RemoveCssSignatureHelpSource : ISignatureHelpSource
12 | {
13 | private ITextBuffer _buffer;
14 |
15 | public RemoveCssSignatureHelpSource(ITextBuffer buffer)
16 | {
17 | _buffer = buffer;
18 | }
19 |
20 | public void AugmentSignatureHelpSession(ISignatureHelpSession session, IList signatures)
21 | {
22 | SnapshotPoint? point = session.GetTriggerPoint(_buffer.CurrentSnapshot);
23 | if (!point.HasValue)
24 | return;
25 |
26 | CssEditorDocument document = CssEditorDocument.FromTextBuffer(_buffer);
27 | ParseItem item = document.StyleSheet.ItemBeforePosition(point.Value.Position);
28 |
29 | if (item == null)
30 | return;
31 |
32 | Declaration dec = item.FindType();
33 | if (dec == null || dec.PropertyName == null || dec.Colon == null)
34 | return;
35 |
36 | foreach (ISignature signature in signatures)
37 | {
38 | if (signature is ValueOrderSignature)
39 | {
40 | signatures.RemoveAt(signatures.Count - 1);
41 | break;
42 | }
43 | }
44 | }
45 |
46 | public ISignature GetBestMatch(ISignatureHelpSession session)
47 | {
48 | return (session.Signatures != null && session.Signatures.Count > 0)
49 | ? session.Signatures[0]
50 | : null;
51 | }
52 |
53 | private bool m_isDisposed;
54 | public void Dispose()
55 | {
56 | if (!m_isDisposed)
57 | {
58 | GC.SuppressFinalize(this);
59 | m_isDisposed = true;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/Commands/RetriggerCommandTarget.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.Windows.Threading;
4 | using Microsoft.VisualStudio;
5 | using Microsoft.VisualStudio.OLE.Interop;
6 | using Microsoft.VisualStudio.Text.Editor;
7 | using Microsoft.VisualStudio.TextManager.Interop;
8 | using Microsoft.WebTools.Languages.Css.Editor.Completion;
9 |
10 | namespace CssTools
11 | {
12 | internal class RetriggerTarget : IOleCommandTarget
13 | {
14 | private ITextView _textView;
15 | private IOleCommandTarget _nextCommandTarget;
16 |
17 | public RetriggerTarget(IVsTextView adapter, ITextView textView)
18 | {
19 | _textView = textView;
20 | ErrorHandler.ThrowOnFailure(adapter.AddCommandFilter(this, out _nextCommandTarget));
21 | }
22 |
23 | public int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
24 | {
25 | if (pguidCmdGroup == VSConstants.VSStd2K && nCmdID == (uint)VSConstants.VSStd2KCmdID.TYPECHAR)
26 | {
27 | char typedChar = (char)(ushort)Marshal.GetObjectForNativeVariant(pvaIn);
28 |
29 | switch (typedChar)
30 | {
31 | case '!':
32 | case '=':
33 | //case '/':
34 | case '[':
35 | Retrigger();
36 | break;
37 | }
38 | }
39 |
40 | return _nextCommandTarget.Exec(ref pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
41 | }
42 |
43 | private void Retrigger()
44 | {
45 | Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
46 | {
47 | var controller = CssCompletionController.FromView(_textView);
48 |
49 | if (controller != null)
50 | controller.OnShowMemberList(true);
51 |
52 | }), DispatcherPriority.Normal, null);
53 | }
54 |
55 | public int QueryStatus(ref Guid pguidCmdGroup, uint cCmds, OLECMD[] prgCmds, IntPtr pCmdText)
56 | {
57 | return _nextCommandTarget.QueryStatus(ref pguidCmdGroup, cCmds, prgCmds, pCmdText);
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/src/Completion/CompletionProviders/ColorCompletionProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.Composition;
4 | using System.Drawing;
5 | using System.Reflection;
6 | using Microsoft.VisualStudio.Language.Intellisense;
7 | using Microsoft.VisualStudio.Utilities;
8 | using Microsoft.WebTools.Languages.Css.Editor.Classify;
9 | using Microsoft.WebTools.Languages.Css.Editor.Completion;
10 | using Microsoft.WebTools.Languages.Shared.Editor.Completion.Presenter;
11 |
12 | namespace CssTools
13 | {
14 | [Export(typeof(ICssCompletionProvider))]
15 | [Name("ColorCompletionProvider")]
16 | [Order(Before = "Default PropertyValue")]
17 | internal class ColorCompletionProvider : ICssCompletionListProvider, ICssCompletionPresenterProvider
18 | {
19 | public CssCompletionContextType ContextType
20 | {
21 | get { return CssCompletionContextType.PropertyValue; }
22 | }
23 |
24 | public IEnumerable GetListEntries(CssCompletionContext context)
25 | {
26 | yield break;
27 | }
28 |
29 | public CompletionPresenterInfo TryCreateCompletionPresenter(ICompletionSession session, CssCompletionContext context)
30 | {
31 | string text = context.Snapshot.GetText(context.SpanStart, context.SpanLength);
32 | if (Color.FromName(text).IsKnownColor)
33 | {
34 | return CreatePresenter(session, context);
35 | }
36 |
37 | return new CompletionPresenterInfo(null, true);
38 | }
39 |
40 | private static CompletionPresenterInfo CreatePresenter(ICompletionSession session, CssCompletionContext context)
41 | {
42 | object[] parameters = new object[] { session, context };
43 | BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
44 | Type type = typeof(CssClassifier).Assembly.GetType("Microsoft.WebTools.Languages.Css.Editor.Completion.ColorPicker.ColorPickerPresenter");
45 | object colorPicker = Activator.CreateInstance(type, flags, null, parameters, null);
46 |
47 | return new CompletionPresenterInfo((IIntellisensePresenter)colorPicker, false);
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/src/QuickInfo/Font/FontQuickInfoController.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Microsoft.VisualStudio.Language.Intellisense;
3 | using Microsoft.VisualStudio.Text;
4 | using Microsoft.VisualStudio.Text.Editor;
5 |
6 | namespace CssTools
7 | {
8 | internal class FontQuickInfoController : IIntellisenseController
9 | {
10 | private ITextView m_textView;
11 | private IList m_subjectBuffers;
12 | private FontQuickInfoControllerProvider m_provider;
13 |
14 | internal FontQuickInfoController(ITextView textView, IList subjectBuffers, FontQuickInfoControllerProvider provider)
15 | {
16 | m_textView = textView;
17 | m_subjectBuffers = subjectBuffers;
18 | m_provider = provider;
19 |
20 | m_textView.MouseHover += this.OnTextViewMouseHover;
21 | }
22 |
23 | private void OnTextViewMouseHover(object sender, MouseHoverEventArgs e)
24 | {
25 | //find the mouse position by mapping down to the subject buffer
26 | SnapshotPoint? point = m_textView.BufferGraph.MapDownToFirstMatch
27 | (new SnapshotPoint(m_textView.TextSnapshot, e.Position),
28 | PointTrackingMode.Positive,
29 | snapshot => m_subjectBuffers.Contains(snapshot.TextBuffer),
30 | PositionAffinity.Predecessor);
31 |
32 | if (point != null)
33 | {
34 | ITrackingPoint triggerPoint = point.Value.Snapshot.CreateTrackingPoint(point.Value.Position,
35 | PointTrackingMode.Positive);
36 |
37 | if (!m_provider.QuickInfoBroker.IsQuickInfoActive(m_textView))
38 | {
39 | m_provider.QuickInfoBroker.TriggerQuickInfo(m_textView, triggerPoint, true);
40 | }
41 | }
42 | }
43 |
44 | public void Detach(ITextView textView)
45 | {
46 | if (m_textView == textView)
47 | {
48 | m_textView.MouseHover -= this.OnTextViewMouseHover;
49 | m_textView = null;
50 | }
51 | }
52 |
53 | public void ConnectSubjectBuffer(ITextBuffer subjectBuffer)
54 | {
55 | }
56 |
57 | public void DisconnectSubjectBuffer(ITextBuffer subjectBuffer)
58 | {
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/QuickInfo/Image/ImageQuickInfoController.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Microsoft.VisualStudio.Language.Intellisense;
3 | using Microsoft.VisualStudio.Text;
4 | using Microsoft.VisualStudio.Text.Editor;
5 |
6 | namespace CssTools
7 | {
8 | internal class ImageQuickInfoController : IIntellisenseController
9 | {
10 | private ITextView m_textView;
11 | private IList m_subjectBuffers;
12 | private ImageQuickInfoControllerProvider m_provider;
13 |
14 | internal ImageQuickInfoController(ITextView textView, IList subjectBuffers, ImageQuickInfoControllerProvider provider)
15 | {
16 | m_textView = textView;
17 | m_subjectBuffers = subjectBuffers;
18 | m_provider = provider;
19 |
20 | m_textView.MouseHover += this.OnTextViewMouseHover;
21 | }
22 |
23 | private void OnTextViewMouseHover(object sender, MouseHoverEventArgs e)
24 | {
25 | //find the mouse position by mapping down to the subject buffer
26 | SnapshotPoint? point = m_textView.BufferGraph.MapDownToFirstMatch
27 | (new SnapshotPoint(m_textView.TextSnapshot, e.Position),
28 | PointTrackingMode.Positive,
29 | snapshot => m_subjectBuffers.Contains(snapshot.TextBuffer),
30 | PositionAffinity.Predecessor);
31 |
32 | if (point != null)
33 | {
34 | ITrackingPoint triggerPoint = point.Value.Snapshot.CreateTrackingPoint(point.Value.Position,
35 | PointTrackingMode.Positive);
36 |
37 | if (!m_provider.QuickInfoBroker.IsQuickInfoActive(m_textView))
38 | {
39 | m_provider.QuickInfoBroker.TriggerQuickInfo(m_textView, triggerPoint, true);
40 | }
41 | }
42 | }
43 |
44 | public void Detach(ITextView textView)
45 | {
46 | if (m_textView == textView)
47 | {
48 | m_textView.MouseHover -= this.OnTextViewMouseHover;
49 | m_textView = null;
50 | }
51 | }
52 |
53 |
54 | public void ConnectSubjectBuffer(ITextBuffer subjectBuffer)
55 | {
56 | }
57 |
58 | public void DisconnectSubjectBuffer(ITextBuffer subjectBuffer)
59 | {
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/BrowserLink/BrowserInfo/BrowserInfo.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.Web.BrowserLink;
2 | using System.Collections.Generic;
3 | using System.ComponentModel.Composition;
4 | using System.IO;
5 |
6 | namespace CssTools
7 | {
8 | [Export(typeof(IBrowserLinkExtensionFactory))]
9 | public class BrowserInfoFactory : IBrowserLinkExtensionFactory
10 | {
11 | public BrowserLinkExtension CreateExtensionInstance(BrowserLinkConnection connection)
12 | {
13 | return new BrowserInfo();
14 | }
15 |
16 | public string GetScript()
17 | {
18 | using (Stream stream = GetType().Assembly.GetManifestResourceStream("CssTools.BrowserLink.BrowserInfo.BrowserInfo.js"))
19 | using (StreamReader reader = new StreamReader(stream))
20 | {
21 | return reader.ReadToEnd();
22 | }
23 | }
24 | }
25 |
26 | public class BrowserInfo : BrowserLinkExtension
27 | {
28 | private static Dictionary _browserCapDictionary = new Dictionary();
29 | private BrowserLinkConnection _current;
30 |
31 | public static Dictionary BrowserCapDictionary { get { return _browserCapDictionary; } }
32 |
33 | public override void OnConnected(BrowserLinkConnection connection)
34 | {
35 | _current = connection;
36 |
37 | base.OnConnected(connection);
38 | }
39 |
40 | public override void OnDisconnecting(BrowserLinkConnection connection)
41 | {
42 | if (_browserCapDictionary.ContainsKey(connection.ConnectionId))
43 | _browserCapDictionary.Remove(connection.ConnectionId);
44 |
45 | base.OnDisconnecting(connection);
46 | }
47 |
48 | [BrowserLinkCallback] // This method can be called from JavaScript
49 | public void CollectInfo(int width, int height)
50 | {
51 | var browserCap = new BrowserCap
52 | {
53 | Name = _current.AppName,
54 | Width = width,
55 | Height = height,
56 | };
57 |
58 | _browserCapDictionary[_current.ConnectionId] = browserCap;
59 | }
60 | }
61 |
62 | public class BrowserCap
63 | {
64 | public string Name { get; set; }
65 | public int Width { get; set; }
66 | public int Height { get; set; }
67 | }
68 | }
--------------------------------------------------------------------------------
/src/Completion/CompletionProviders/MediaTypeCompletionProvider.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.ComponentModel.Composition;
3 | using Microsoft.VisualStudio.Language.Intellisense;
4 | using Microsoft.VisualStudio.Utilities;
5 | using Microsoft.WebTools.Languages.Css.Editor.Completion;
6 | using Microsoft.WebTools.Languages.Css.Parser;
7 | using Microsoft.WebTools.Languages.Css.TreeItems.AtDirectives;
8 |
9 | namespace CssTools
10 | {
11 | [Export(typeof(ICssCompletionProvider))]
12 | [Name("MediaTypeCompletionProvider")]
13 | internal class MediaTypeCompletionProvider : ICssCompletionListProvider
14 | {
15 | public CssCompletionContextType ContextType
16 | {
17 | get { return (CssCompletionContextType)612; }
18 | }
19 |
20 | public IEnumerable GetListEntries(CssCompletionContext context)
21 | {
22 | MediaQuery query = (MediaQuery)context.ContextItem;
23 | ParseItem item = query.StyleSheet.ItemAfterPosition(context.SpanStart);
24 |
25 | if (query.MediaType != null && query.MediaType.AfterEnd < item.Start)
26 | {
27 | yield return new CompletionListEntry("and", 0, StandardGlyphGroup.GlyphGroupOperator);
28 | yield break;
29 | }
30 |
31 | if (item != query.Operation || query.MediaType == null)
32 | {
33 | yield return new CompletionListEntry("all");
34 | yield return new CompletionListEntry("aural");
35 | yield return new CompletionListEntry("braille");
36 | yield return new CompletionListEntry("embossed");
37 | yield return new CompletionListEntry("handheld");
38 | yield return new CompletionListEntry("print");
39 | yield return new CompletionListEntry("projection");
40 | yield return new CompletionListEntry("screen");
41 | yield return new CompletionListEntry("tty");
42 | yield return new CompletionListEntry("tv");
43 | }
44 |
45 | if (item != query.MediaType || query.Operation == null)
46 | {
47 | yield return new CompletionListEntry("not", 1, StandardGlyphGroup.GlyphGroupOperator);
48 | yield return new CompletionListEntry("only", 1, StandardGlyphGroup.GlyphGroupOperator);
49 | }
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/Adornments/ColorAdornment.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows;
3 | using System.Windows.Controls;
4 | using System.Windows.Media;
5 | using Microsoft.VisualStudio.Text.Editor;
6 | using Microsoft.WebTools.Languages.Css.Editor.Completion;
7 |
8 | namespace CssTools
9 | {
10 | internal sealed class ColorAdornment : Border
11 | {
12 | private static SolidColorBrush _borderColor = OptionHelpers.BackgroundColor.Invert().ToBrush();
13 |
14 | internal ColorAdornment(ColorTag colorTag, ITextView view)
15 | {
16 | this.Padding = new Thickness(0);
17 | this.BorderThickness = new Thickness(1);
18 | this.Margin = new Thickness(0, 0, 2, 3);
19 | this.Width = OptionHelpers.FontSize;
20 | this.Height = this.Width;
21 | this.Cursor = System.Windows.Input.Cursors.Arrow;
22 | this.MouseUp += delegate { ColorAdornmentMouseUp(view); };
23 |
24 | Update(colorTag);
25 | }
26 |
27 | private static void ColorAdornmentMouseUp(ITextView view)
28 | {
29 | try
30 | {
31 | CssCompletionController.FromView(view).OnShowMemberList(filterList: true);
32 | }
33 | catch
34 | { }
35 | }
36 |
37 | internal void Update(ColorTag colorTag)
38 | {
39 | this.Background = new SolidColorBrush(colorTag.Color);
40 |
41 | if (!HasContrastToBackground(colorTag.Color))
42 | {
43 | this.BorderThickness = new Thickness(1);
44 | this.BorderBrush = _borderColor;
45 | }
46 | else
47 | {
48 | this.BorderThickness = new Thickness(0);
49 | this.BorderBrush = this.Background;
50 | }
51 | }
52 |
53 | private static bool HasContrastToBackground(Color color)
54 | {
55 | // The color is very transparent (alpha channel)
56 | if (color.A < 13)
57 | {
58 | return false;
59 | }
60 |
61 | var b = OptionHelpers.BackgroundColor;
62 | double bBrightness = b.Red * 299 + b.Green * 587 + b.Blue * 114;
63 | double cBrightness = color.R * 299 + color.G * 587 + color.B * 114;
64 | double distance = Math.Abs(cBrightness - bBrightness) / 1000;
65 |
66 | return distance > 20;
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/ExtensionMethods/AtDirectiveExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using Microsoft.WebTools.Languages.Css.Editor.Completion;
5 | using Microsoft.WebTools.Languages.Css.Editor.Schemas;
6 | using Microsoft.WebTools.Languages.Css.TreeItems.AtDirectives;
7 |
8 | namespace CssTools
9 | {
10 | internal static class AtDirectiveExtensions
11 | {
12 | public static bool IsVendorSpecific(this AtDirective directive)
13 | {
14 | return directive.Keyword.Text[0] == '-';
15 | }
16 |
17 |
18 | public static bool TryGetStandardPropertyName(this AtDirective directive, out string standardName, ICssSchemaInstance schema)
19 | {
20 | standardName = null;
21 |
22 | string propText = directive.Keyword.Text;
23 | string prefix = VendorHelpers.GetPrefixes(schema).SingleOrDefault(p => propText.StartsWith(p, StringComparison.Ordinal));
24 | if (prefix != null)
25 | {
26 | standardName = propText.Substring(prefix.Length);
27 | return true;
28 | }
29 |
30 | return false;
31 | }
32 |
33 | public static IEnumerable GetMissingVendorSpecifics(this AtDirective directive, ICssSchemaInstance schema)
34 | {
35 | IEnumerable possible = GetPossibleVendorSpecifics(directive, schema);
36 |
37 | var visitorRules = new CssItemCollector();
38 | directive.Parent.Accept(visitorRules);
39 |
40 | foreach (string item in possible)
41 | {
42 | if (!visitorRules.Items.Any(d => d.Keyword != null && "@" + d.Keyword.Text == item))
43 | yield return item;
44 | }
45 | }
46 |
47 | public static IEnumerable GetPossibleVendorSpecifics(this AtDirective directive, ICssSchemaInstance schema)
48 | {
49 | string text = directive.Keyword.Text;
50 |
51 | foreach (string prefix in VendorHelpers.GetPrefixes(schema).Where(p => p != "-o-")) // Remove -o- since the parser doesn't recognize -o-keyframes
52 | {
53 | ICssCompletionListEntry entry = schema.GetAtDirective("@" + prefix + text);
54 | if (entry != null && string.IsNullOrEmpty(entry.GetAttribute("obsolete")))
55 | yield return entry.DisplayText;
56 | }
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/QuickInfo/Selector/SelectorQuickInfoController.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Microsoft.VisualStudio.Language.Intellisense;
3 | using Microsoft.VisualStudio.Text;
4 | using Microsoft.VisualStudio.Text.Editor;
5 |
6 | namespace CssTools
7 | {
8 | internal class SelectorQuickInfoController : IIntellisenseController
9 | {
10 | private ITextView m_textView;
11 | private IList m_subjectBuffers;
12 | private SelectorQuickInfoControllerProvider m_provider;
13 |
14 | internal SelectorQuickInfoController(ITextView textView, IList subjectBuffers, SelectorQuickInfoControllerProvider provider)
15 | {
16 | m_textView = textView;
17 | m_subjectBuffers = subjectBuffers;
18 | m_provider = provider;
19 |
20 | m_textView.MouseHover += this.OnTextViewMouseHover;
21 | }
22 |
23 | private void OnTextViewMouseHover(object sender, MouseHoverEventArgs e)
24 | {
25 | //find the mouse position by mapping down to the subject buffer
26 | SnapshotPoint? point = m_textView.BufferGraph
27 | .MapDownToFirstMatch(
28 | new SnapshotPoint(m_textView.TextSnapshot, e.Position),
29 | PointTrackingMode.Positive,
30 | snapshot => m_subjectBuffers.Contains(snapshot.TextBuffer),
31 | PositionAffinity.Predecessor);
32 |
33 | if (point == null)
34 | return;
35 |
36 | ITrackingPoint triggerPoint = point.Value.Snapshot.CreateTrackingPoint(point.Value.Position,
37 | PointTrackingMode.Positive);
38 |
39 | if (m_provider.QuickInfoBroker.IsQuickInfoActive(m_textView))
40 | return;
41 |
42 | m_provider.QuickInfoBroker.TriggerQuickInfo(m_textView, triggerPoint, true);
43 | }
44 |
45 | public void Detach(ITextView textView)
46 | {
47 | if (m_textView != textView)
48 | return;
49 |
50 | m_textView.MouseHover -= this.OnTextViewMouseHover;
51 | m_textView = null;
52 | }
53 |
54 | public void ConnectSubjectBuffer(ITextBuffer subjectBuffer) { }
55 |
56 | public void DisconnectSubjectBuffer(ITextBuffer subjectBuffer) { }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/ExtensionMethods/DeclarationExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using Microsoft.WebTools.Languages.Css.Editor.Completion;
5 | using Microsoft.WebTools.Languages.Css.Editor.Schemas;
6 | using Microsoft.WebTools.Languages.Css.TreeItems;
7 |
8 | namespace CssTools
9 | {
10 | internal static class DeclarationExtensions
11 | {
12 | public static bool IsVendorSpecific(this Declaration declaration)
13 | {
14 | return declaration.PropertyName.Text.StartsWith("-", StringComparison.Ordinal);
15 | }
16 |
17 | public static bool TryGetStandardPropertyName(this Declaration declaration, out string standardName, ICssSchemaInstance schema)
18 | {
19 | standardName = null;
20 |
21 | if (declaration.IsVendorSpecific())
22 | {
23 | string propText = declaration.PropertyName.Text;
24 | string prefix = VendorHelpers.GetPrefixes(schema).SingleOrDefault(p => propText.StartsWith(p, StringComparison.Ordinal));
25 | if (prefix != null)
26 | {
27 | standardName = propText.Substring(prefix.Length);
28 | return true;
29 | }
30 | }
31 |
32 | return false;
33 | }
34 |
35 | public static IEnumerable GetMissingVendorSpecifics(this Declaration declaration, ICssSchemaInstance schema)
36 | {
37 | RuleBlock rule = declaration.FindType();
38 | IEnumerable possible = GetPossibleVendorSpecifics(declaration, schema);
39 |
40 | foreach (string item in possible)
41 | {
42 | if (!rule.GetDeclarations().Any(d => d.PropertyName != null && d.PropertyName.Text == item))
43 | yield return item;
44 | }
45 | }
46 |
47 | public static IEnumerable GetPossibleVendorSpecifics(this Declaration declaration, ICssSchemaInstance schema)
48 | {
49 | string text = declaration.PropertyName.Text;
50 |
51 | foreach (string prefix in VendorHelpers.GetPrefixes(schema))
52 | {
53 | ICssCompletionListEntry entry = schema.GetProperty(prefix + text);
54 | if (entry != null && string.IsNullOrEmpty(entry.GetAttribute("obsolete")))
55 | yield return entry.DisplayText;
56 | }
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/Completion/RegionCompletionListEntry.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.VisualStudio.Text;
3 | using Microsoft.WebTools.Languages.Css.Editor.Completion;
4 | using Microsoft.WebTools.Languages.Css.Editor.Schemas.Browsers;
5 | using Microsoft.WebTools.Languages.Shared.Editor.Completion;
6 |
7 | namespace CssTools
8 | {
9 | internal class RegionCompletionListEntry : ICssCompletionListEntry
10 | {
11 | public string Description
12 | {
13 | get { return string.Empty; }
14 | }
15 |
16 | public string DisplayText
17 | {
18 | get { return "Add region..."; }
19 | }
20 |
21 | public string GetSyntax(Version version)
22 | {
23 | return string.Empty;
24 | }
25 |
26 | public string GetAttribute(string name)
27 | {
28 | return string.Empty;
29 | }
30 |
31 | public string GetInsertionText(CssTextSource textSource, ITrackingSpan typingSpan)
32 | {
33 | return "region";//"/*#region MyRegion */\n\n\n\n/*#endregion*/";
34 | }
35 |
36 | public string GetVersionedAttribute(string name, Version version)
37 | {
38 | return GetAttribute(name);
39 | }
40 |
41 | public bool AllowQuotedString
42 | {
43 | get { return false; }
44 | }
45 |
46 | public bool IsBuilder
47 | {
48 | get { return true; }
49 | }
50 |
51 | public int SortingPriority { get { return 0; } }
52 |
53 |
54 | public bool IsSupported(BrowserVersion browser)
55 | {
56 | return true;
57 | }
58 |
59 | public bool IsSupported(Version cssVersion)
60 | {
61 | return true;
62 | }
63 |
64 |
65 | public ITrackingSpan ApplicableTo
66 | {
67 | get { return null; }
68 | }
69 |
70 | public CompletionEntryFilterTypes FilterType
71 | {
72 | get { return CompletionEntryFilterTypes.AlwaysVisible; }
73 | }
74 |
75 | public System.Windows.Media.ImageSource Icon
76 | {
77 | get { return null; }
78 | }
79 |
80 | public bool IsCommitChar(char typedCharacter)
81 | {
82 | return false;
83 | }
84 |
85 | public bool IsMuteCharacter(char typedCharacter)
86 | {
87 | return false;
88 | }
89 |
90 | public bool RetriggerIntellisense
91 | {
92 | get { return false; }
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/ExtensionMethods/CssExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Microsoft.WebTools.Languages.Css.Editor.Schemas;
4 | using Microsoft.WebTools.Languages.Css.Parser;
5 | using Microsoft.WebTools.Languages.Css.TreeItems;
6 | using Microsoft.WebTools.Languages.Css.TreeItems.Functions;
7 | using Microsoft.WebTools.Languages.Css.TreeItems.Selectors;
8 |
9 | namespace CssTools
10 | {
11 | public static class CssExtensions
12 | {
13 | ///Gets the selector portion of the text of a Selector object, excluding any trailing comma.
14 | public static string SelectorText(this Selector selector)
15 | {
16 | if (selector.Comma == null) return selector.Text;
17 | return selector.Text.Substring(0, selector.Comma.Start - selector.Start).Trim();
18 | }
19 |
20 | public static bool IsPseudoElement(this ParseItem item)
21 | {
22 | if (item.Text.StartsWith("::", StringComparison.Ordinal))
23 | return true;
24 |
25 | var schema = CssSchemaManager.SchemaManager.GetSchemaRoot(null);
26 | return schema.GetPseudo(":" + item.Text) != null;
27 | }
28 |
29 | public static bool IsDataUri(this UrlItem item)
30 | {
31 | if (item.UrlString == null || string.IsNullOrEmpty(item.UrlString.Text))
32 | return false;
33 |
34 | return item.UrlString.Text.Contains(";base64,");
35 | }
36 |
37 | ///
38 | /// Use this to make things work on 15.4 and 15.5+
39 | ///
40 | public static IEnumerable GetDeclarations(this RuleBlock rule)
41 | {
42 | var declaration = rule.GetType().GetProperty("Declarations")?.GetValue(rule);
43 | if (declaration == null)
44 | return System.Linq.Enumerable.Empty();
45 | else
46 | return declaration as IEnumerable;
47 | }
48 |
49 | //[SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "Flags", Justification = "Match enum name")]
50 | //public static CssErrorFlags ToCssErrorFlags(this WarningLocation location)
51 | //{
52 | // switch (location)
53 | // {
54 | // case WarningLocation.Warnings:
55 | // return CssErrorFlags.UnderlinePurple | CssErrorFlags.TaskListWarning;
56 |
57 | // default:
58 | // return CssErrorFlags.UnderlinePurple | CssErrorFlags.TaskListMessage;
59 | // }
60 | //}
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/QuickInfo/Selector/SelectorQuickInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Microsoft.VisualStudio.Language.Intellisense;
4 | using Microsoft.VisualStudio.Text;
5 | using Microsoft.WebTools.Languages.Css.Editor.Document;
6 | using Microsoft.WebTools.Languages.Css.Parser;
7 | using Microsoft.WebTools.Languages.Css.TreeItems.Selectors;
8 | using Microsoft.WebTools.Languages.Extensions.Less.Parser.Mixin;
9 | using Microsoft.WebTools.Languages.Extensions.Scss.Parser.MixinDirective;
10 |
11 | namespace CssTools
12 | {
13 | internal class SelectorQuickInfo : IQuickInfoSource
14 | {
15 | private ITextBuffer _buffer;
16 |
17 | public SelectorQuickInfo(ITextBuffer subjectBuffer)
18 | {
19 | _buffer = subjectBuffer;
20 | }
21 |
22 | public void AugmentQuickInfoSession(IQuickInfoSession session, IList