Пример #1
0
        public string SortScss(string scss)
        {
            ICssParser parser     = CssParserLocator.FindComponent(ContentTypeManager.GetContentType(ScssContentTypeDefinition.ScssContentType)).CreateParser();
            StyleSheet stylesheet = parser.Parse(scss.Trim(), true);

            return(PreprocessorSorting(stylesheet));
        }
Пример #2
0
 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.
 }
Пример #3
0
        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" });
        }
Пример #4
0
        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();
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }
Пример #7
0
 protected override ICssParser CreateParser()
 {
     return(CssParserLocator.FindComponent(Mef.GetContentType(ScssContentTypeDefinition.ScssContentType)).CreateParser());
 }
Пример #8
0
 public CssDependencyGraph(string extension, IFileExtensionRegistryService fileExtensionRegistry)
     : base(fileExtensionRegistry.GetContentTypeForExtension(extension.TrimStart('.')), fileExtensionRegistry)
 {
     Extension     = extension;
     parserFactory = CssParserLocator.FindComponent(ContentType);
 }
Пример #9
0
        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);
            }
        }
Пример #10
0
        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);
        }