/// <summary> /// Creates a rule with the enumeration of tokens. /// </summary> public static CssRule CreateRule(this CssTokenizer tokenizer, CssToken token, CssParser parser) { switch (token.Type) { case CssTokenType.AtKeyword: return tokenizer.CreateAtRule(token, parser); case CssTokenType.CurlyBracketOpen: tokenizer.RaiseErrorOccurred(CssParseError.InvalidBlockStart, token.Position); tokenizer.SkipUnknownRule(); return null; case CssTokenType.String: case CssTokenType.Url: case CssTokenType.CurlyBracketClose: case CssTokenType.RoundBracketClose: case CssTokenType.SquareBracketClose: tokenizer.RaiseErrorOccurred(CssParseError.InvalidToken, token.Position); tokenizer.SkipUnknownRule(); return null; default: return new CssStyleState(tokenizer, parser).Create(token); } }
public string SortStyleSheet(string css) { ICssParser parser = new CssParser(); StyleSheet stylesheet = parser.Parse(css.Trim(), true); CssFormatter formatter = new CssFormatter(); formatter.Options.RemoveLastSemicolon = false; StringBuilder sb = new StringBuilder(stylesheet.Text); var visitor = new CssItemCollector<RuleBlock>(true); stylesheet.Accept(visitor); foreach (RuleBlock rule in visitor.Items.Where(r => r.IsValid).Reverse()) { if (rule.Declarations.Count <= 1) continue; int start = rule.OpenCurlyBrace.AfterEnd; int length = rule.Length - 2; string text = formatter.Format(rule.Text).Trim().Trim('}', '{'); string[] declarations = text.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries); var sorted = SortDeclarations(declarations); sb.Remove(start, length); sb.Insert(start, string.Join("", sorted)); } return sb.ToString(); }
private async static Task ParseDocument() { string fileName = GetSolutionFilePath(); if (!string.IsNullOrEmpty(fileName) && File.Exists(fileName)) { CssParser parser = new CssParser(); StyleSheet stylesheet = parser.Parse(await FileHelpers.ReadAllTextRetry(fileName), false); if (stylesheet.IsValid) { var visitor = new CssItemCollector<AtDirective>(); stylesheet.Accept(visitor); AtDirective at = visitor.Items.SingleOrDefault(a => a.Keyword.Text == _rootDirective); if (at != null) { var visitorPalette = new CssItemCollector<AtDirective>(true); at.Accept(visitorPalette); _directives = visitorPalette.Items.Where(a => a.Keyword.Text != at.Keyword.Text).ToList(); } } InitializeWatcher(fileName); } else { _hasFile = false; } }
public void AddStylesheet_ContainsUnsupportedMediaQuery_ShouldStrip() { var stylesheet = "@media print { div { width: 90%; } }"; var parser = new CssParser(); parser.AddStyleSheet(stylesheet); Assert.AreEqual(0, parser.Styles.Count); }
public void AddStylesheet_ContainsAtCharsetRule_ShouldStripRuleAndParseStylesheet() { var stylesheet = "@charset utf-8; div { width: 100% }"; var parser = new CssParser(); parser.AddStyleSheet(stylesheet); Assert.IsTrue(parser.Styles.ContainsKey("div")); }
/// <summary> /// Parses an @-rule with the given name, if there is any. /// </summary> public static CssRule CreateAtRule(this CssTokenizer tokenizer, CssToken token, CssParser parser) { Creator creator; if (creators.TryGetValue(token.Data, out creator)) return creator(tokenizer, parser).Create(token); return new CssUnknownState(tokenizer, parser).Create(token); }
public void StartSearch(INavigateToCallback callback, string searchValue) { if (searchValue.Length > 0 && (searchValue[0] == '.' || searchValue[0] == '#')) { CssParser parser = new CssParser(); var state = new Tuple<CssParser, string, INavigateToCallback>(parser, searchValue, callback); System.Threading.ThreadPool.QueueUserWorkItem(DoWork, state); } }
public void AddStylesheet_ContainsAtPageSection_ShouldStripRuleAndParseStylesheet() { var stylesheet = "@page :first { margin: 2in 3in; } div { width: 100% }"; var parser = new CssParser(); parser.AddStyleSheet(stylesheet); Assert.AreEqual(1, parser.Styles.Count); Assert.IsTrue(parser.Styles.ContainsKey("div")); }
public void AddStylesheet_ContainsImportStatement_ShouldStripOutImportStatement() { var stylesheet = "@import url(http://google.com/stylesheet); div { width : 600px; }"; var parser = new CssParser(); parser.AddStyleSheet(stylesheet); Assert.AreEqual(1, parser.Styles.Count); Assert.IsTrue(parser.Styles.ContainsKey("div")); Assert.AreEqual("600px", parser.Styles["div"].Attributes["width"].Value); }
public static StyleSheet Parse(TextReader reader, CssContext context = null) { var sheet = new StyleSheet(context ?? new CssContext()); var rules = new List<CssRule>(); IList<Browser> browsers = null; using (var parser = new CssParser(reader)) { foreach (var node in parser.ReadNodes()) { if (node.Kind == NodeKind.Mixin) { var mixin = (MixinNode)node; sheet.Context.Mixins.Add(mixin.Name, mixin); } else if (node.Kind == NodeKind.Directive) { var directive = (CssDirective)node; if (directive.Name == "support") { var parts = directive.Value.Split(Seperators.Space); // SpaceArray... BrowserType browserType; if (Enum.TryParse(parts[0].Trim(), true, out browserType)) { if (browsers == null) { browsers = new List<Browser>(); } var browserVersion = float.Parse(parts[parts.Length - 1].Trim(' ', '+')); browsers.Add(new Browser(browserType, browserVersion)); } } } else { sheet.AddChild(node); } } if (browsers != null) { sheet.Context.SetCompatibility(browsers.ToArray()); } } return sheet; }
private static IEnumerable<ParseItem> GetItems(string filePath, string searchValue) { var cssParser = new CssParser(); StyleSheet ss = cssParser.Parse(File.ReadAllText(filePath), true); return new CssItemAggregator<ParseItem> { (ClassSelector c) => c.Text.Contains(searchValue) ? c : null, (IdSelector c) => c.Text.Contains(searchValue) ? c : null }.Crawl(ss).Where(s => s != null); }
public static CssValue Parse(string text) { using (var reader = new SourceReader(new StringReader(text))) { var tokenizer = new CssTokenizer(reader, LexicalMode.Value); var parser = new CssParser(tokenizer); return parser.ReadValueList(); } }
public void AddStylesheet_ContainsSupportedMediaQuery_ShouldParseQueryRules() { var stylesheet = "@media only screen { div { width: 600px; } }"; var parser = new CssParser(); parser.AddStyleSheet(stylesheet); Assert.AreEqual(1, parser.Styles.Count); Assert.IsTrue(parser.Styles.ContainsKey("div")); Assert.AreEqual("600px", parser.Styles["div"].Attributes["width"].Value); }
public string Parse(string zenSyntax, ZenType type) { switch (type) { case ZenType.CSS: CssParser cssParser = new CssParser(); return cssParser.Parse(zenSyntax.Trim()); case ZenType.HTML: HtmlParser htmlParser = new HtmlParser(); return htmlParser.Parse(zenSyntax.Trim()); } return null; }
public void AddStylesheet_ContainsUnsupportedMediaQueryAndNormalRules_ShouldStripMediaQueryAndParseRules() { var stylesheet = "div { width: 600px; } @media only screen and (max-width:620px) { div { width: 100% } } p { font-family: serif; }"; var parser = new CssParser(); parser.AddStyleSheet(stylesheet); Assert.AreEqual(2, parser.Styles.Count); Assert.IsTrue(parser.Styles.ContainsKey("div")); Assert.AreEqual("600px", parser.Styles["div"].Attributes["width"].Value); Assert.IsTrue(parser.Styles.ContainsKey("p")); Assert.AreEqual("serif", parser.Styles["p"].Attributes["font-family"].Value); }
/// <summary> /// Merges a css rule. /// </summary> /// <returns>The rule.</returns> /// <param name="curStyle">Target TextStyleParameters</param> /// <param name="css">Css value</param> /// <param name="clone">If set to <c>true</c> clone the style</param> public static TextStyleParameters MergeRule(TextStyleParameters curStyle, string css, bool clone) { var parser = new CssParser (); var rules = parser.ParseAll (css); if (rules.Count () != 1) { throw new NotSupportedException ("Only a single css class may be merged at a time"); } var mergedStyle = clone ? curStyle.Clone () : curStyle; var rule = rules.FirstOrDefault (); if (rule != null) { ParseCSSRule (ref mergedStyle, rule); } return mergedStyle; }
public string[] SortDeclarations(IEnumerable<string> declarations) { Dictionary<string, string> inlineCommentStorage = new Dictionary<string, string>(); List<string> filteredDeclarations = new List<string>(); // How could you do this with clever linq stuff? foreach (string attribute in declarations) { string trimmedAttribute = attribute.Trim(); Match inlineCommentRegexMatch = Regex.Match(trimmedAttribute, "/\\*.*\\*/"); if (inlineCommentRegexMatch.Success && inlineCommentRegexMatch.Index > 0) { string comment = inlineCommentRegexMatch.Value.Trim(); string value = trimmedAttribute.Remove(inlineCommentRegexMatch.Index).Trim(); inlineCommentStorage.Add(value, comment); filteredDeclarations.Add(value); } else { filteredDeclarations.Add(attribute.Trim()); } } string rule = "div {" + string.Join(Environment.NewLine, filteredDeclarations) + "}"; CssParser parser = new CssParser(); StyleSheet sheet = parser.Parse(rule, true); var comments = sheet.RuleSets[0].Block.Children.Where(c => c is CComment).Select(c => Environment.NewLine + c.Text); var decls = sheet.RuleSets[0].Block.Declarations.Select(d => d.Text); var sorted = decls.OrderBy(d => d, new DeclarationComparer()); List<string> list = new List<string>(Stringify(sorted)); list.AddRange(comments.OrderBy(c => c)); var query = from c in list join o in inlineCommentStorage on c equals o.Key into gj from sublist in gj.DefaultIfEmpty() select c + (sublist.Key == null ? string.Empty : ' ' + sublist.Value); return query.ToArray(); }
/// <summary> /// Parses the specified CSS /// </summary> /// <param name="css">Css.</param> public static Dictionary<string, TextStyleParameters> Parse(string css) { var parser = new CssParser (); var rules = parser.ParseAll (css); var textStyles = new Dictionary<string, TextStyleParameters> (); foreach (var rule in rules) { foreach (var selector in rule.Selectors) { // If it doesnt exist, create it if (!textStyles.ContainsKey (selector)) textStyles [selector] = new TextStyleParameters (selector); var curStyle = textStyles [selector]; ParseCSSRule (ref curStyle, rule); } } return textStyles; }
internal CssViewportRule(CssParser parser) : base(CssRuleType.Viewport, RuleNames.ViewPort, parser) { }
public void CssSheetInvalidStatementRulesetUnexpectedAtKeyword() { var sheet = CssParser.ParseStyleSheet(@"p @here {color: red}"); Assert.AreEqual(0, sheet.Rules.Length); }
internal CssSupportsRule(CssParser parser) : base(CssRuleType.Supports, parser) { _condition = empty; }
public void CssSheetInvalidStatementRulesetUnexpectedRightBrace() { var sheet = CssParser.ParseStyleSheet(@"}} {{ - }}"); Assert.AreEqual(0, sheet.Rules.Length); }
internal CssDocumentRule(CssParser parser) : base(CssRuleType.Document, parser) { }
internal CssFontFaceRule(CssParser parser) : base(CssRuleType.FontFace, RuleNames.FontFace, parser) { }
internal CssImportRule(CssParser parser) : base(CssRuleType.Import, parser) { AppendChild(new MediaList(parser)); }
internal MediaList(CssParser parser) { _parser = parser; }
internal CssDocumentRule(CssParser parser) : base(CssRuleType.Document, parser) { _conditions = new List <CssDocumentFunction>(); }
/// <summary> /// Write the given html tag with all its attributes and styles. /// </summary> /// <param name="cssParser">used to parse CSS data</param> /// <param name="sb">the string builder to write html into</param> /// <param name="box">the css box with the html tag to write</param> /// <param name="styleGen">Controls the way styles are generated when html is generated</param> private static void WriteHtmlTag(CssParser cssParser, StringBuilder sb, CssBox box, HtmlGenerationStyle styleGen) { sb.AppendFormat("<{0}", box.HtmlTag.Name); // collect all element style properties including from stylesheet var tagStyles = new Dictionary <string, string>(); var tagCssBlock = box.HtmlContainer.CssData.GetCssBlock(box.HtmlTag.Name); if (tagCssBlock != null) { // TODO:a handle selectors foreach (var cssBlock in tagCssBlock) { foreach (var prop in cssBlock.Properties) { tagStyles[prop.Key] = prop.Value; } } } if (box.HtmlTag.HasAttributes()) { sb.Append(" "); foreach (var att in box.HtmlTag.Attributes) { // handle image tags by inserting the image using base64 data if (styleGen == HtmlGenerationStyle.Inline && att.Key == HtmlConstants.Style) { // if inline style add the styles to the collection var block = cssParser.ParseCssBlock(box.HtmlTag.Name, box.HtmlTag.TryGetAttribute("style")); foreach (var prop in block.Properties) { tagStyles[prop.Key] = prop.Value; } } else if (styleGen == HtmlGenerationStyle.Inline && att.Key == HtmlConstants.Class) { // if inline style convert the style class to actual properties and add to collection var cssBlocks = box.HtmlContainer.CssData.GetCssBlock("." + att.Value); if (cssBlocks != null) { // TODO:a handle selectors foreach (var cssBlock in cssBlocks) { foreach (var prop in cssBlock.Properties) { tagStyles[prop.Key] = prop.Value; } } } } else { sb.AppendFormat("{0}=\"{1}\" ", att.Key, att.Value); } } sb.Remove(sb.Length - 1, 1); } // if inline style insert the style tag with all collected style properties if (styleGen == HtmlGenerationStyle.Inline && tagStyles.Count > 0) { var cleanTagStyles = StripDefaultStyles(box, tagStyles); if (cleanTagStyles.Count > 0) { sb.Append(" style=\""); foreach (var style in cleanTagStyles) { sb.AppendFormat("{0}: {1}; ", style.Key, style.Value); } sb.Remove(sb.Length - 1, 1); sb.Append("\""); } } sb.AppendFormat("{0}>", box.HtmlTag.IsSingle ? "/" : ""); }
public void Setup() { CssParser.defaultCssNamespace = "XamlCSS.Tests.Dom, XamlCSS.Tests, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"; defaultStyleSheet = CssParser.Parse(@"@namespace ui ""XamlCSS.Tests.Dom, XamlCSS.Tests, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"";"); }
public void TestTokenize() { var tokens = CssParser.Tokenize(test1).ToList(); Assert.Contains(new CssToken(CssTokenType.Identifier, "red"), tokens); }
internal CssDeclarationRule(CssRuleType type, String name, CssParser parser) : base(type, parser) { _name = name; }
internal CssGroupingRule(CssRuleType type, CssParser parser) : base(type, parser) { _rules = new CssRuleList(this); }
internal CssMediaRule(CssParser parser) : base(CssRuleType.Media, parser) { AppendChild(new MediaList(parser)); }
static void CreateCssSelectorTest(String url, List <String> methods) { Console.Write("Loading " + url + " ... "); var client = new HttpClient(); var result = client.GetAsync(url).Result; var source = result.Content.ReadAsStreamAsync().Result; IDocument html = null; try { html = DocumentBuilder.Html(source); } catch { Console.WriteLine("error!!!"); return; } var title = Sanatize(html.GetElementsByTagName("title")[0].TextContent); var content = html.GetElementsByTagName("content")[0].InnerHtml.Trim().Replace("\"", "\"\""); var css = html.GetElementsByTagName("css")[0].TextContent; var sheet = CssParser.ParseStyleSheet(css); var selectors = new StringBuilder(); var i = 1; if (methods.Contains(title)) { var ltr = 'A'; while (methods.Contains(title + ltr.ToString())) { ltr = (Char)((int)ltr + 1); } title += ltr.ToString(); } foreach (var rule in sheet.Rules) { if (rule is ICssStyleRule) { selectors.Append(@" var selectorINDEX = doc.QuerySelectorAll(""SELECTOR""); Assert.AreEqual(0, selectorINDEX.Length);" .Replace("SELECTOR", ((ICssStyleRule)rule).SelectorText) .Replace("INDEX", i.ToString())); i++; } } File.AppendAllText("test.cs", @" /// <summary> /// Test taken from URL /// </summary> public void TITLE() { var source = @""HTML""; var doc = DocumentBuilder.Html(source); SELECTORS } " .Replace("URL", url) .Replace("TITLE", title) .Replace("HTML", content) .Replace("SELECTORS", selectors.ToString()) ); Console.WriteLine("success."); methods.Add(title); }
public CssUnknownRule(String name, CssParser parser) : base(CssRuleType.Unknown, parser) { _name = name; }
internal CssRule(CssRuleType type, CssParser parser) { _type = type; _parser = parser; }
private IEnumerable <CssSourceMapNode> ProcessGeneratedMaps(string cssfileContents) { ParseItem item = null; Selector selector = null; StyleSheet styleSheet = null; SimpleSelector simple = null; int start; var parser = new CssParser(); var result = new List <CssSourceMapNode>(); styleSheet = parser.Parse(cssfileContents, false); foreach (var node in MapNodes) { start = cssfileContents.NthIndexOfCharInString('\n', node.GeneratedLine); start += node.GeneratedColumn; item = styleSheet.ItemAfterPosition(start); if (item == null) { continue; } selector = item.FindType <Selector>(); if (selector == null) { continue; } var depth = node.OriginalSelector.TreeDepth / 2; if (depth < selector.SimpleSelectors.Count) { simple = selector.SimpleSelectors.First(); if (simple == null) { simple = item.Parent != null?item.Parent.FindType <SimpleSelector>() : null; } if (simple == null) { continue; } var selectorText = new StringBuilder(); for (int i = 0; i < node.OriginalSelector.SimpleSelectors.Count; i++) { if (simple == null) { break; } selectorText.Append(simple.Text).Append(" "); simple = simple.NextSibling as SimpleSelector; } StyleSheet sheet = parser.Parse(selectorText.ToString(), false); if (sheet == null || !sheet.RuleSets.Any() || !sheet.RuleSets.First().Selectors.Any()) { continue; } selector = sheet.RuleSets.First().Selectors.First() as Selector; if (selector == null) { continue; } } node.GeneratedSelector = selector; result.Add(node); } return(result); }
public CssCharsetState(CssTokenizer tokenizer, CssParser parser) : base(tokenizer, parser) { }
public void CssSheetInvalidStatementRulesetUnexpectedRightParenthesis() { var sheet = CssParser.ParseStyleSheet(@") ( {} ) p {color: red }"); Assert.AreEqual(0, sheet.Rules.Length); }
/// <summary> /// Constructs a new CSS condition rule. /// </summary> internal CssConditionRule(CssRuleType type, CssParser parser) : base(type, parser) { }
public void CssSheetInvalidStatementAtRuleUnexpectedAtKeyword() { var sheet = CssParser.ParseStyleSheet(@"@foo @bar;"); Assert.AreEqual(0, sheet.Rules.Length); }
public static void StyleFromSource(CSSStyleSheet sheet, String source) { var parser = new CssParser(sheet, source); parser.Parse(); }
internal CssKeyframeRule(CssParser parser) : base(CssRuleType.Keyframe, parser) { AppendChild(new CssStyleDeclaration(this)); }
// A very ugly hack for a very ugly bug: https://github.com/hcatlin/libsass/issues/324 // Remove this and its caller in previous method, when it is fixed in original repo // and https://github.com/andrew/node-sass/ is released with the fix. // Overwriting all positions belonging to original/source file. private IEnumerable<CssSourceMapNode> CorrectionsForScss(string cssFileContents) { // Sort collection for generated file. var sortedForGenerated = MapNodes.OrderBy(x => x.GeneratedLine) .ThenBy(x => x.GeneratedColumn) .ToList(); ParseItem item = null; Selector selector = null; SimpleSelector simple = null; StyleSheet styleSheet = null, cssStyleSheet = null; int start = 0, indexInCollection, targetDepth; string fileContents = null, simpleText = ""; var result = new List<CssSourceMapNode>(); var contentCollection = new Dictionary<string, string>(); // So we don't have to read file for each map item. var parser = new CssParser(); cssStyleSheet = parser.Parse(cssFileContents, false); foreach (var node in MapNodes) { // Cache source file contents. if (!contentCollection.ContainsKey(node.SourceFilePath)) { if (!File.Exists(node.SourceFilePath)) // Lets say someone deleted the reference file. continue; fileContents = File.ReadAllText(node.SourceFilePath); contentCollection.Add(node.SourceFilePath, fileContents); styleSheet = _parser.Parse(fileContents, false); } start = cssFileContents.NthIndexOfCharInString('\n', node.GeneratedLine); start += node.GeneratedColumn; item = cssStyleSheet.ItemAfterPosition(start); if (item == null) continue; selector = item.FindType<Selector>(); simple = item.FindType<SimpleSelector>(); if (selector == null || simple == null) continue; simpleText = simple.Text; indexInCollection = sortedForGenerated.FindIndex(e => e.Equals(node));//sortedForGenerated.IndexOf(node); targetDepth = 0; for (int i = indexInCollection; i >= 0 && node.GeneratedLine == sortedForGenerated[i].GeneratedLine; targetDepth++, --i) ; start = fileContents.NthIndexOfCharInString('\n', node.OriginalLine); start += node.OriginalColumn; item = styleSheet.ItemAfterPosition(start); while (item.TreeDepth > targetDepth) { item = item.Parent; } // selector = item.FindType<RuleSet>().Selectors.First(); RuleSet rule; ScssRuleBlock scssRuleBlock = item as ScssRuleBlock; if (scssRuleBlock == null) rule = item as RuleSet; else rule = scssRuleBlock.RuleSets.First(); // Because even on the same TreeDepth, there may be mulitple ruleblocks // and the selector names may include & or other symbols which are diff // fromt he generated counterpart, here is the guess work item = rule.Children.FirstOrDefault(r => r is Selector && r.Text.Trim() == simpleText) as Selector; selector = item == null ? null : item as Selector; if (selector == null) { // One more try; dive deep and sniff then skip. var items = rule.Children.Where(r => r is RuleBlock) .SelectMany(r => (r as RuleBlock).Children .Where(s => s is RuleSet) .Select(s => (s as RuleSet).Selectors.FirstOrDefault(sel => sel.Text.Trim() == simpleText))); selector = items.Any() ? items.First() : null; if (selector == null) continue; } node.OriginalLine = fileContents.Substring(0, selector.Start).Count(s => s == '\n'); node.OriginalColumn = fileContents.GetLineColumn(selector.Start, node.OriginalLine); result.Add(node); } return result; }
internal CssSupportsRule(CssParser parser) : base(CssRuleType.Supports, parser) { }
/// <summary> /// Write the given html tag with all its attributes and styles. /// </summary> /// <param name="sb">the string builder to write html into</param> /// <param name="box">the css box with the html tag to write</param> /// <param name="indent">the indent to use for nice formating</param> /// <param name="styleGen">Controls the way styles are generated when html is generated</param> private static void WriteHtmlTag(StringBuilder sb, CssBox box, int indent, HtmlGenerationStyle styleGen) { sb.Append(new string(' ', indent * 4)); sb.AppendFormat("<{0}", box.HtmlTag.Name); // collect all element style properties incliding from stylesheet var tagStyles = new Dictionary <string, string>(); IEnumerable <CssBlock> tagCssBlock = box.HtmlContainer.CssData.GetCssBlock(box.HtmlTag.Name); if (tagCssBlock != null) { // atodo: handle selectors foreach (CssBlock cssBlock in tagCssBlock) { foreach (var prop in cssBlock.Properties) { tagStyles[prop.Key] = prop.Value; } } } if (box.HtmlTag.HasAttributes()) { sb.Append(" "); foreach (var att in box.HtmlTag.Attributes) { // handle image tags by inserting the image using base64 data if (box.HtmlTag.Name == "img" && att.Key == "src" && (att.Value.StartsWith("property") || att.Value.StartsWith("method"))) { Image img = ((CssBoxImage)box).Image; if (img != null) { using (var buffer = new MemoryStream()) { img.Save(buffer, ImageFormat.Png); string base64 = Convert.ToBase64String(buffer.ToArray()); sb.AppendFormat("{0}=\"data:image/png;base64, {1}\" ", att.Key, base64); } } } else if (styleGen == HtmlGenerationStyle.Inline && att.Key == HtmlConstants.Style) { // if inline style add the styles to the collection CssBlock block = CssParser.ParseCssBlock(box.HtmlTag.Name, box.HtmlTag.TryGetAttribute("style")); foreach (var prop in block.Properties) { tagStyles[prop.Key] = prop.Value; } } else if (styleGen == HtmlGenerationStyle.Inline && att.Key == HtmlConstants.Class) { // if inline style convert the style class to actual properties and add to collection IEnumerable <CssBlock> cssBlocks = box.HtmlContainer.CssData.GetCssBlock("." + att.Value); if (cssBlocks != null) { // atodo: handle selectors foreach (CssBlock cssBlock in cssBlocks) { foreach (var prop in cssBlock.Properties) { tagStyles[prop.Key] = prop.Value; } } } } else { sb.AppendFormat("{0}=\"{1}\" ", att.Key, att.Value); } } sb.Remove(sb.Length - 1, 1); } // if inline style insert the style tag with all collected style properties if (styleGen == HtmlGenerationStyle.Inline && tagStyles.Count > 0) { sb.Append(" style=\""); foreach (var style in tagStyles) { sb.AppendFormat("{0}: {1}; ", style.Key, style.Value); } sb.Remove(sb.Length - 1, 1); sb.Append("\""); } sb.AppendFormat("{0}>", box.HtmlTag.IsSingle ? "/" : ""); sb.AppendLine(); }
public CssBuilder(CssTokenizer tokenizer, CssParser parser) { _tokenizer = tokenizer; _parser = parser; }
static ICssStyleSheet ParseStyleSheet(String source) { var parser = new CssParser(); return(parser.ParseStylesheet(source)); }
public CssKeyframesState(CssTokenizer tokenizer, CssParser parser) : base(tokenizer, parser) { }
public static ICssStyleSheet ToCssStylesheet(this String sourceCode, IConfiguration configuration = null) { var parser = new CssParser(configuration); return(parser.ParseStylesheet(sourceCode)); }
public CssMediaState(CssTokenizer tokenizer, CssParser parser) : base(tokenizer, parser) { }
public static ICssStyleSheet ToCssStylesheet(this Stream content, IConfiguration configuration = null) { var parser = new CssParser(configuration); return(parser.ParseStylesheet(content)); }
private IEnumerable<CssSourceMapNode> ProcessGeneratedMaps(string fileContents) { ParseItem item = null; Selector selector = null; StyleSheet styleSheet = null; SimpleSelector simple = null; int start; var parser = new CssParser(); var result = new List<CssSourceMapNode>(); styleSheet = parser.Parse(fileContents, false); foreach (var node in MapNodes) { start = fileContents.NthIndexOfCharInString('\n', node.GeneratedLine); start += node.GeneratedColumn; item = styleSheet.ItemAfterPosition(start); if (item == null) continue; selector = item.FindType<Selector>(); if (selector == null) continue; var depth = node.OriginalSelector.TreeDepth / 2; if (depth < selector.SimpleSelectors.Count) { simple = selector.SimpleSelectors.First(); if (simple == null) simple = item.Parent != null ? item.Parent.FindType<SimpleSelector>() : null; if (simple == null) continue; var selectorText = new StringBuilder(); for (int i = 0; i < node.OriginalSelector.SimpleSelectors.Count; i++) { selectorText.Append(simple.Text).Append(" "); if (simple.NextSibling == null) continue; simple = simple.NextSibling as SimpleSelector; } selector = parser.Parse(selectorText.ToString(), false).RuleSets.First().Selectors.First() as Selector; if (selector == null) continue; } node.GeneratedSelector = selector; result.Add(node); } return result; }
// A very ugly hack for a very ugly bug: https://github.com/hcatlin/libsass/issues/324 // Remove this and its caller in previous method, when it is fixed in original repo // and https://github.com/andrew/node-sass/ is released with the fix. // Overwriting all positions belonging to original/source file. private async Task <IEnumerable <CssSourceMapNode> > CorrectionsForScss(string cssFileContents) { // Sort collection for generated file. var sortedForGenerated = MapNodes.OrderBy(x => x.GeneratedLine) .ThenBy(x => x.GeneratedColumn) .ToList(); ParseItem item = null; Selector selector = null; SimpleSelector simple = null; StyleSheet styleSheet = null, cssStyleSheet = null; int start = 0, indexInCollection, targetDepth; string fileContents = null, simpleText = ""; var result = new List <CssSourceMapNode>(); var contentCollection = new HashSet <string>(); // So we don't have to read file for each map item. var parser = new CssParser(); cssStyleSheet = parser.Parse(cssFileContents, false); foreach (var node in MapNodes) { // Cache source file contents. if (!contentCollection.Contains(node.SourceFilePath)) { if (!File.Exists(node.SourceFilePath)) // Lets say someone deleted the reference file. { continue; } fileContents = await FileHelpers.ReadAllTextRetry(node.SourceFilePath); contentCollection.Add(node.SourceFilePath); styleSheet = _parser.Parse(fileContents, false); } start = cssFileContents.NthIndexOfCharInString('\n', node.GeneratedLine); start += node.GeneratedColumn; item = cssStyleSheet.ItemAfterPosition(start); if (item == null) { continue; } selector = item.FindType <Selector>(); simple = item.FindType <SimpleSelector>(); if (selector == null || simple == null) { continue; } simpleText = simple.Text; indexInCollection = sortedForGenerated.FindIndex(e => e.Equals(node));//sortedForGenerated.IndexOf(node); targetDepth = 0; for (int i = indexInCollection; i >= 0 && node.GeneratedLine == sortedForGenerated[i].GeneratedLine; targetDepth++, --i) { ; } start = fileContents.NthIndexOfCharInString('\n', node.OriginalLine); start += node.OriginalColumn; item = styleSheet.ItemAfterPosition(start); if (item == null) { continue; } while (item.TreeDepth > targetDepth) { item = item.Parent; } // selector = item.FindType<RuleSet>().Selectors.First(); RuleSet rule; ScssRuleBlock scssRuleBlock = item as ScssRuleBlock; rule = scssRuleBlock == null ? item as RuleSet : scssRuleBlock.RuleSets.FirstOrDefault(); if (rule == null) { continue; } // Because even on the same TreeDepth, there may be mulitple ruleblocks // and the selector names may include & or other symbols which are diff // fromt he generated counterpart, here is the guess work item = rule.Children.FirstOrDefault(r => r is Selector && r.Text.Trim() == simpleText) as Selector; selector = item == null ? null : item as Selector; if (selector == null) { // One more try: look for the selector in neighboring rule blocks then skip. selector = rule.Children.Where(r => r is RuleBlock) .SelectMany(r => (r as RuleBlock).Children .Where(s => s is RuleSet) .Select(s => (s as RuleSet).Selectors.FirstOrDefault(sel => sel.Text.Trim() == simpleText))) .FirstOrDefault(); if (selector == null) { continue; } } node.OriginalLine = fileContents.Substring(0, selector.Start).Count(s => s == '\n'); node.OriginalColumn = fileContents.GetLineColumn(selector.Start, node.OriginalLine); result.Add(node); } return(result); }
static public StyleSheet MakeStyleSheet(string text) { CssParser parser = new CssParser(); return(parser.Parse(text, insertComments: true)); }
/// <summary> /// Inserts a new keyframe rule into the current CSSKeyframesRule. /// </summary> /// <param name="rule">A string containing a keyframe in the same format as an entry of a @keyframes at-rule.</param> public void Add(String rule) { var value = CssParser.ParseKeyframeRule(rule); _rules.Insert(value, _rules.Length, _ownerSheet, this); }
/// <summary> /// Constructs a new CSS condition rule. /// </summary> internal CssConditionRule (CssRuleType type, CssParser parser) : base(type, parser) { }
public void TestParseCss() { var styleSheet = CssParser.Parse(css); Assert.AreEqual(1, styleSheet.Rules.Count); }