Skip to content

Commit

Permalink
feat: Add support for CSS #127
Browse files Browse the repository at this point in the history
  • Loading branch information
Samir Boulema committed Nov 25, 2021
1 parent a3570ab commit ddecec3
Show file tree
Hide file tree
Showing 14 changed files with 251 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
- 'feature/**'

env:
version: '8.7.${{ github.run_number }}'
version: '8.8.${{ github.run_number }}'
repoUrl: ${{ github.server_url }}/${{ github.repository }}

jobs:
Expand Down
16 changes: 16 additions & 0 deletions CodeNav.Languages.CSS/CodeNav.Languages.CSS.projitems
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MSBuildAllProjects Condition="'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' &lt; '16.0'">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
<HasSharedItems>true</HasSharedItems>
<SharedGUID>55d33626-0080-407a-bcda-52dafc2eb45c</SharedGUID>
</PropertyGroup>
<PropertyGroup Label="Configuration">
<Import_RootNamespace>CodeNav.Languages.CSS</Import_RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)Mappers\BaseMapper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Mappers\SyntaxMapper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Models\CodeStyleRuleItem.cs" />
</ItemGroup>
</Project>
13 changes: 13 additions & 0 deletions CodeNav.Languages.CSS/CodeNav.Languages.CSS.shproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>55d33626-0080-407a-bcda-52dafc2eb45c</ProjectGuid>
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
<PropertyGroup />
<Import Project="CodeNav.Languages.CSS.projitems" Label="Shared" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
</Project>
44 changes: 44 additions & 0 deletions CodeNav.Languages.CSS/Mappers/BaseMapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using CodeNav.Helpers;
using CodeNav.Mappers;
using CodeNav.Models;
using ExCSS;
using Microsoft.CodeAnalysis.Text;
using System;
using System.Windows.Media;
using TextSpan = Microsoft.CodeAnalysis.Text.TextSpan;
using Colors = System.Windows.Media.Colors;

namespace CodeNav.Languages.CSS.Mappers
{
public static class BaseMapper
{
public static T MapBase<T>(Rule member, string id, ICodeViewUserControl control) where T : CodeItem
{
var element = Activator.CreateInstance<T>();

var name = string.IsNullOrEmpty(id) ? "anonymous" : id;
var startPos = member.StylesheetText.Range.Start.Position;
var endPos = member.StylesheetText.Range.End.Position;

element.Name = name;
element.FullName = name;
element.Id = name;
element.Tooltip = name;
element.StartLine = member.StylesheetText.Range.Start.Line - 1;
element.StartLinePosition = new LinePosition(member.StylesheetText.Range.Start.Line - 1, 0);
element.EndLine = member.StylesheetText.Range.End.Line - 1;
element.EndLinePosition = new LinePosition(member.StylesheetText.Range.End.Line - 1, 0);
element.Span = new TextSpan(startPos, endPos - startPos);
element.ForegroundColor = Colors.Black;
element.Access = CodeItemAccessEnum.Public;
element.FontSize = SettingsHelper.Font.SizeInPoints;
element.ParameterFontSize = SettingsHelper.Font.SizeInPoints - 1;
element.FontFamily = new FontFamily(SettingsHelper.Font.FontFamily.Name);
element.FontStyle = FontStyleMapper.Map(SettingsHelper.Font.Style);
element.Control = control;
element.FilePath = control.CodeDocumentViewModel.FilePath;

return element;
}
}
}
126 changes: 126 additions & 0 deletions CodeNav.Languages.CSS/Mappers/SyntaxMapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
using CodeNav.Languages.CSS.Models;
using CodeNav.Mappers;
using CodeNav.Models;
using ExCSS;
using Microsoft.CodeAnalysis;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Colors = System.Windows.Media.Colors;

namespace CodeNav.Languages.CSS.Mappers
{
public static class SyntaxMapper
{
public static List<CodeItem> Map(Document document, ICodeViewUserControl control)
=> Map(document.FilePath, control);

public static List<CodeItem> Map(string filePath, ICodeViewUserControl control)
{
if (!File.Exists(filePath))
{
return new List<CodeItem>();
}

var text = File.ReadAllText(filePath);

var ast = new StylesheetParser().Parse(text);

return new List<CodeItem>
{
new CodeNamespaceItem
{
Id = "Namespace" + filePath,
Kind = CodeItemKindEnum.Namespace,
BorderColor = Colors.DarkGray,
Members = MapMembers(ast, control)
}
};
}

private static List<CodeItem> MapMembers(Stylesheet ast, ICodeViewUserControl control)
{
if (ast?.Children?.Any() != true)
{
return new List<CodeItem>();
}

return ast.Children.SelectMany(c => MapMember(c, control)).ToList();
}

private static List<CodeItem> MapMember(IStylesheetNode member, ICodeViewUserControl control)
{
switch (member)
{
case StyleRule styleRule:
return MapStyleRule(styleRule, control);
case Rule rule when rule.Type == RuleType.Page:
return MapPageRule(rule, control);
case Rule rule when rule.Type == RuleType.Namespace:
return MapNamespaceRule(rule, control);
case Rule rule when rule.Type == RuleType.Media:
return MapMediaRule(rule, control);
case Rule rule when rule.Type == RuleType.FontFace:
return MapFontFaceRule(rule, control);
default:
break;
}

return new List<CodeItem>();
}

private static List<CodeItem> MapStyleRule(StyleRule styleRule, ICodeViewUserControl control)
{
var item = BaseMapper.MapBase<CodeStyleRuleItem>(styleRule, styleRule.SelectorText, control);

item.Kind = CodeItemKindEnum.StyleRule;
item.Moniker = IconMapper.MapMoniker(item.Kind, item.Access);

return new List<CodeItem> { item };
}

private static List<CodeItem> MapPageRule(Rule rule, ICodeViewUserControl control)
{
var item = BaseMapper.MapBase<CodeStyleRuleItem>(rule, "page", control);

item.Kind = CodeItemKindEnum.PageRule;
item.Moniker = IconMapper.MapMoniker(item.Kind, item.Access);

return new List<CodeItem> { item };
}

private static List<CodeItem> MapNamespaceRule(Rule rule, ICodeViewUserControl control)
{
var item = BaseMapper.MapBase<CodeStyleRuleItem>(rule, (rule as INamespaceRule).Prefix, control);

item.Kind = CodeItemKindEnum.NamespaceRule;
item.Moniker = IconMapper.MapMoniker(item.Kind, item.Access);

return new List<CodeItem> { item };
}

private static List<CodeItem> MapMediaRule(Rule rule, ICodeViewUserControl control)
{
var item = BaseMapper.MapBase<CodeClassItem>(rule, (rule as IMediaRule).Media.MediaText, control);

item.Kind = CodeItemKindEnum.MediaRule;
item.Moniker = IconMapper.MapMoniker(item.Kind, item.Access);
item.BorderColor = Colors.DarkGray;
item.Members = (rule as IMediaRule).Rules.SelectMany(r => MapMember(r, control)).ToList();

return new List<CodeItem> { item };
}

private static List<CodeItem> MapFontFaceRule(Rule rule, ICodeViewUserControl control)
{
var fontRule = rule as IFontFaceRule;

var item = BaseMapper.MapBase<CodeStyleRuleItem>(rule, $"{fontRule.Family} {fontRule.Weight}" , control);

item.Kind = CodeItemKindEnum.FontFaceRule;
item.Moniker = IconMapper.MapMoniker(item.Kind, item.Access);

return new List<CodeItem> { item };
}
}
}
8 changes: 8 additions & 0 deletions CodeNav.Languages.CSS/Models/CodeStyleRuleItem.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using CodeNav.Models;

namespace CodeNav.Languages.CSS.Models
{
public class CodeStyleRuleItem : CodeItem
{
}
}
3 changes: 3 additions & 0 deletions CodeNav.Shared/CodeNavMarginFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ namespace CodeNav
[ContentType("Basic")]
[ContentType("JavaScript")]
[ContentType("TypeScript")]
[ContentType("CSS")]
[TextViewRole(PredefinedTextViewRoles.Debuggable)] // This is to prevent the margin from loading in the diff view
internal sealed class CodeNavLeftFactory : IWpfTextViewMarginProvider
{
Expand All @@ -31,6 +32,7 @@ public IWpfTextViewMargin CreateMargin(IWpfTextViewHost wpfTextViewHost, IWpfTex
[ContentType("Basic")]
[ContentType("JavaScript")]
[ContentType("TypeScript")]
[ContentType("CSS")]
[TextViewRole(PredefinedTextViewRoles.Debuggable)] // This is to prevent the margin from loading in the diff view
internal sealed class CodeNavRightFactory : IWpfTextViewMarginProvider
{
Expand All @@ -48,6 +50,7 @@ public IWpfTextViewMargin CreateMargin(IWpfTextViewHost wpfTextViewHost, IWpfTex
[ContentType("Basic")]
[ContentType("JavaScript")]
[ContentType("TypeScript")]
[ContentType("CSS")]
[TextViewRole(PredefinedTextViewRoles.Debuggable)]
internal sealed class CodeNavTopFactory : IWpfTextViewMarginProvider
{
Expand Down
15 changes: 15 additions & 0 deletions CodeNav.Shared/Mappers/IconMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,21 @@ public static ImageMoniker MapMoniker(CodeItemKindEnum kind, CodeItemAccessEnum
case CodeItemKindEnum.SwitchSection:
monikerString = "FlowDecision";
break;
case CodeItemKindEnum.StyleRule:
monikerString = "Rule";
break;
case CodeItemKindEnum.PageRule:
monikerString = "PageStyle";
break;
case CodeItemKindEnum.NamespaceRule:
monikerString = "Namespace";
break;
case CodeItemKindEnum.MediaRule:
monikerString = "Media";
break;
case CodeItemKindEnum.FontFaceRule:
monikerString = "Font";
break;
default:
monikerString = $"Property{accessString}";
break;
Expand Down
4 changes: 4 additions & 0 deletions CodeNav.Shared/Mappers/SyntaxMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ public static async Task<List<CodeItem>> MapDocument(ICodeViewUserControl contro
{
return SyntaxMapperJS.Map(filePath, control);
}
else if (fileExtension == ".css")
{
return Languages.CSS.Mappers.SyntaxMapper.Map(filePath, control);
}
else if (fileExtension == ".cs")
{
var tree = CSharpSyntaxTree.ParseText(text);
Expand Down
7 changes: 6 additions & 1 deletion CodeNav.Shared/Models/CodeItemKindEnum.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ public enum CodeItemKindEnum
SwitchSection,
Variable,
LocalFunction,
BaseClass
BaseClass,
StyleRule,
PageRule,
NamespaceRule,
MediaRule,
FontFaceRule
}
}
2 changes: 1 addition & 1 deletion CodeNav.Tests/CodeNav.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
<ItemGroup>
<ProjectReference Include="..\CodeNav.VS2022\CodeNav.VS2022.csproj">
<Project>{5f314b23-2d45-4748-90be-362411f06ef0}</Project>
<Name>CodeNav.VS2019</Name>
<Name>CodeNav.VS2022</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Expand Down
4 changes: 4 additions & 0 deletions CodeNav.VS2022/CodeNav.VS2022.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="ExCSS">
<Version>4.1.1</Version>
</PackageReference>
<PackageReference Include="Microsoft.ApplicationInsights">
<Version>2.19.0</Version>
</PackageReference>
Expand Down Expand Up @@ -178,6 +181,7 @@
</ItemGroup>
<ItemGroup />
<Import Project="..\CodeNav.Shared\CodeNav.Shared.projitems" Label="Shared" />
<Import Project="..\CodeNav.Languages.CSS\CodeNav.Languages.CSS.projitems" Label="Shared" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Expand Down
9 changes: 9 additions & 0 deletions CodeNav.sln
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,14 @@ Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "CodeNav.Shared", "CodeNav.S
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeNav.VS2019", "CodeNav.VS2019\CodeNav.VS2019.csproj", "{B5B2D0BD-CCDF-4E89-AF10-C8C60B087ECE}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Languages", "Languages", "{8DFFB8DD-7AEB-4200-A268-BF13D0DDD6A9}"
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "CodeNav.Languages.CSS", "CodeNav.Languages.CSS\CodeNav.Languages.CSS.shproj", "{55D33626-0080-407A-BCDA-52DAFC2EB45C}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
CodeNav.Languages.CSS\CodeNav.Languages.CSS.projitems*{55d33626-0080-407a-bcda-52dafc2eb45c}*SharedItemsImports = 13
CodeNav.Languages.CSS\CodeNav.Languages.CSS.projitems*{5f314b23-2d45-4748-90be-362411f06ef0}*SharedItemsImports = 4
CodeNav.Shared\CodeNav.Shared.projitems*{5f314b23-2d45-4748-90be-362411f06ef0}*SharedItemsImports = 4
CodeNav.Shared\CodeNav.Shared.projitems*{b5b2d0bd-ccdf-4e89-af10-c8c60b087ece}*SharedItemsImports = 4
CodeNav.Shared\CodeNav.Shared.projitems*{fdb3d737-bcd7-42b1-a560-ca869de9bce3}*SharedItemsImports = 13
Expand Down Expand Up @@ -75,6 +81,9 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{55D33626-0080-407A-BCDA-52DAFC2EB45C} = {8DFFB8DD-7AEB-4200-A268-BF13D0DDD6A9}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F182C2A3-8479-440F-B192-2E5F16581804}
EndGlobalSection
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Visual Studio extension to show the code structure of your current document
- C#
- Visual Basic
- JavaScript
- CSS

## Installing
[Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=SamirBoulema.CodeNav) [![Visual Studio Marketplace](https://img.shields.io/vscode-marketplace/v/SamirBoulema.CodeNav.svg?style=flat)](https://marketplace.visualstudio.com/items?itemName=SamirBoulema.CodeNav)
Expand Down

0 comments on commit ddecec3

Please sign in to comment.