public string SortScss(string scss) { ICssParser parser = CssParserLocator.FindComponent(ContentTypeManager.GetContentType(ScssContentTypeDefinition.ScssContentType)).CreateParser(); StyleSheet stylesheet = parser.Parse(scss.Trim(), true); return(PreprocessorSorting(stylesheet)); }
private void Initialize(string targetFileContents, string mapFileContents, string directory, IContentType contentType) { _contentType = contentType; _parser = CssParserLocator.FindComponent(_contentType).CreateParser(); _directory = directory; PopulateMap(targetFileContents, mapFileContents); // Begin two-steps initialization. }
public void TestMixinExpansion() { var lessFactory = CssParserLocator.FindComponent(ContentTypeManager.GetContentType(LessContentTypeDefinition.LessContentType)); var lessCode = @"a { .myMixin(@p) { b, code { } } }"; var lessDoc = lessFactory.CreateParser().Parse(lessCode, false); var lessBlocks = new CssItemAggregator <RuleSet>(true) { (RuleSet rs) => rs }.Crawl(lessDoc).ToList(); // Remove all but the deepest blocks while (0 < lessBlocks.RemoveAll(c => lessBlocks.Any(c.IsParentOf))) { ; } var literalExpansions = lessBlocks.SelectMany(rs => LessDocument.GetSelectorNames(rs, LessMixinAction.Literal)).ToList(); literalExpansions.Should().Equal(new[] { "a .myMixin(@p) b", "a .myMixin(@p) code" }); var skipExpansions = lessBlocks.SelectMany(rs => LessDocument.GetSelectorNames(rs, LessMixinAction.Skip)).ToList(); skipExpansions.Should().BeEmpty(); var nestedExpansions = lessBlocks.SelectMany(rs => LessDocument.GetSelectorNames(rs, LessMixinAction.NestedOnly)).ToList(); nestedExpansions.Should().Equal(new[] { "«mixin .myMixin» b", "«mixin .myMixin» code" }); }
public void TestMixinExpansion() { var scssFactory = CssParserLocator.FindComponent(ContentTypeManager.GetContentType(ScssContentTypeDefinition.ScssContentType)); var scssCode = @"a { @mixin myMixin($p) { b, code { width: $p+10+px; } } @include myMixin(1) } "; var scssDoc = scssFactory.CreateParser().Parse(scssCode, false); var scssBlocks = new CssItemAggregator <RuleSet>(true) { (RuleSet rs) => rs }.Crawl(scssDoc).ToList(); // Remove all but the deepest blocks while (0 < scssBlocks.RemoveAll(c => scssBlocks.Any(c.IsParentOf))) { ; } var literalExpansions = scssBlocks.SelectMany(rs => ScssDocument.GetSelectorNames(rs, ScssMixinAction.Literal)).ToList(); literalExpansions.Should().Equal(new[] { "a b", "a code" }); var skipExpansions = scssBlocks.SelectMany(rs => ScssDocument.GetSelectorNames(rs, ScssMixinAction.Skip)).ToList(); skipExpansions.Should().BeEmpty(); }
private string FindFile(IEnumerable <string> extensions, out int position) { ICssParser parser = CssParserLocator.FindComponent(Mef.GetContentType(LessContentTypeDefinition.LessContentType)).CreateParser(); string root = ProjectHelpers.GetProjectFolder(TextView.TextBuffer.GetFileName()); position = -1; string result = null; foreach (string ext in extensions) { foreach (string file in Directory.GetFiles(root, "*" + ext, SearchOption.AllDirectories)) { if (file.EndsWith(".min" + ext, StringComparison.OrdinalIgnoreCase)) { continue; } string text = File.ReadAllText(file); int index = text.IndexOf("." + _className, StringComparison.Ordinal); if (index > -1) { var css = parser.Parse(text, true); var visitor = new CssItemCollector <ClassSelector>(false); css.Accept(visitor); var selectors = visitor.Items.Where(c => c.ClassName.Text == _className); var high = selectors.FirstOrDefault(c => c.FindType <AtDirective>() == null && (c.Parent.NextSibling == null || c.Parent.NextSibling.Text == ",")); if (high != null) { position = high.Start; return(file); } var medium = selectors.FirstOrDefault(c => c.Parent.NextSibling == null || c.Parent.NextSibling.Text == ","); if (medium != null) { position = medium.Start; result = file; continue; } var low = selectors.FirstOrDefault(); if (low != null) { position = low.Start; result = file; continue; } } } } return(result); }
private string FindRuleSetInFile(IEnumerable <string> extensions, string id, out RuleSet rule) { string root = ProjectHelpers.GetProjectFolder(peekableItem._textbuffer.GetFileName()); string result = null; bool isLow = false, isMedium = false; rule = null; foreach (string ext in extensions) { ICssParser parser = CssParserLocator.FindComponent(Mef.GetContentType(ext.Trim('.'))).CreateParser(); foreach (string file in Directory.EnumerateFiles(root, "*" + ext, SearchOption.AllDirectories)) { if (file.EndsWith(".min" + ext, StringComparison.OrdinalIgnoreCase) || file.Contains("node_modules") || file.Contains("bower_components")) { continue; } string text = FileHelpers.ReadAllTextRetry(file).ConfigureAwait(false).GetAwaiter().GetResult(); int index = text.IndexOf("#" + id, StringComparison.Ordinal); if (index == -1) { continue; } var css = parser.Parse(text, true); var visitor = new CssItemCollector <IdSelector>(false); css.Accept(visitor); var selectors = visitor.Items.Where(c => c.HashName.Text == "#" + id); var high = selectors.FirstOrDefault(c => c.FindType <AtDirective>() == null && (c.Parent.NextSibling == null || c.Parent.NextSibling.Text == ",")); if (high != null) { rule = high.FindType <RuleSet>(); return(file); } var medium = selectors.FirstOrDefault(c => c.Parent.NextSibling == null || c.Parent.NextSibling.Text == ","); if (medium != null && !isMedium) { rule = medium.FindType <RuleSet>(); result = file; isMedium = true; continue; } var low = selectors.FirstOrDefault(); if (low != null && !isMedium && !isLow) { rule = low.FindType <RuleSet>(); result = file; isLow = true; continue; } } } return(result); }
protected override ICssParser CreateParser() { return(CssParserLocator.FindComponent(Mef.GetContentType(ScssContentTypeDefinition.ScssContentType)).CreateParser()); }
public CssDependencyGraph(string extension, IFileExtensionRegistryService fileExtensionRegistry) : base(fileExtensionRegistry.GetContentTypeForExtension(extension.TrimStart('.')), fileExtensionRegistry) { Extension = extension; parserFactory = CssParserLocator.FindComponent(ContentType); }
public async Task SelectorExpansionTest() { #region LESS sources var testSources = new[] { @" @media all { a { @media all { @media all { b { color: goldenrod; em { color: goldenrod; } } } } } } ", @" // Taken from http://blog.slaks.net/2013-09-29/less-css-secrets-of-the-ampersand/ a { color: blue; &:hover { color: green; } } form a { color: purple; body.QuietMode & { color: black; } } .quoted-source { background: #fcc; blockquote& { background: #fdc; } } .btn.btn-primary.btn-lg[disabled] { & + & + & { margin-left: 10px; } } p, blockquote, ul, li { border-top: 1px solid gray; & + & { border-top: 0; } } ", @" // Taken from https://github.com/less/less.js/blob/master/test/less/selectors.less h1, h2, h3 { a, p { &:hover { color: red; } } } #all { color: blue; } #the { color: blue; } #same { color: blue; } ul, li, div, q, blockquote, textarea { margin: 0; } td { margin: 0; padding: 0; } td, input { line-height: 1em; } a { color: red; &:hover { color: blue; } div & { color: green; } p & span { color: yellow; } } .foo { .bar, .baz { & .qux { display: block; } .qux & { display: inline; } .qux& { display: inline-block; } .qux & .biz { display: none; } } } .b { &.c { .a& { color: red; } } } .b { .c & { &.a { color: red; } } } .p { .foo &.bar { color: red; } } .p { .foo&.bar { color: red; } } .foo { .foo + & { background: amber; } & + & { background: amber; } } .foo, .bar { & + & { background: amber; } } .foo, .bar { a, b { & > & { background: amber; } } } .other ::fnord { color: red } .other::fnord { color: red } .other { ::bnord {color: red } &::bnord {color: red } } ", @"// Taken from https://github.com/less/less.js/blob/master/test/less/rulesets.less #first > .one { > #second .two > #deux { width: 50%; #third { &:focus { color: black; #fifth { > #sixth { .seventh #eighth { + #ninth { color: purple; } } } } } height: 100%; } #fourth, #five, #six { color: #110000; .seven, .eight > #nine { border: 1px solid black; } #ten { color: red; } } } font-size: 2em; } " }; #endregion var lessFactory = CssParserLocator.FindComponent(ContentTypeManager.GetContentType(LessContentTypeDefinition.LessContentType)); foreach (var lessCode in testSources) { var cssCode = await new LessCompiler().CompileSourceAsync(lessCode, ".less"); var lessDoc = lessFactory.CreateParser().Parse(lessCode, false); var cssDoc = new CssParser().Parse(cssCode, false); var cssSelectors = new CssItemAggregator <string>(false) { (Selector s) => CssExtensions.SelectorText(s) }.Crawl(cssDoc); var lessSelectors = new CssItemAggregator <RuleSet>(true) { (RuleSet rs) => rs }.Crawl(lessDoc) .Where(rs => rs.Block.Declarations.Any()) // Skip selectors that don't have any rules; these won't end up in the CSS .SelectMany(rs => LessDocument.GetSelectorNames(rs, LessMixinAction.Literal)) .ToList(); lessSelectors.Should().Equal(cssSelectors); } }
private string FindFile(IEnumerable <string> extensions, out int position) { string root = ProjectHelpers.GetProjectFolder(TextView.TextBuffer.GetFileName()); position = -1; bool isLow = false, isMedium = false; string result = null; foreach (string ext in extensions) { ICssParser parser = CssParserLocator.FindComponent(ProjectHelpers.GetContentType(ext.Trim('.'))).CreateParser(); foreach (string file in Directory.EnumerateFiles(root, "*" + ext, SearchOption.AllDirectories)) { if (file.EndsWith(".min" + ext, StringComparison.OrdinalIgnoreCase) || file.Contains("node_modules") || file.Contains("bower_components")) { continue; } string text = File.ReadAllText(file); int index = text.IndexOf("." + _className, StringComparison.Ordinal); if (index == -1) { continue; } Microsoft.WebTools.Languages.Css.TreeItems.StyleSheet css = parser.Parse(text, true); var visitor = new CssItemCollector <ClassSelector>(false); css.Accept(visitor); IEnumerable <ClassSelector> selectors = visitor.Items.Where(c => c.ClassName.Text == _className); ClassSelector high = selectors.FirstOrDefault(c => c.FindType <AtDirective>() == null && (c.Parent.NextSibling == null || c.Parent.NextSibling.Text == ",")); if (high != null) { position = high.Start; return(file); } ClassSelector medium = selectors.FirstOrDefault(c => c.Parent.NextSibling == null || c.Parent.NextSibling.Text == ","); if (medium != null && !isMedium) { position = medium.Start; result = file; isMedium = true; continue; } ClassSelector low = selectors.FirstOrDefault(); if (low != null && !isMedium && !isLow) { position = low.Start; result = file; isLow = true; continue; } } } return(result); }