/// <summary> /// Feeds the style with a block about the specific media. /// When no media is specified, "all" will be used /// </summary> /// <param name="media"></param> /// <param name="block"></param> private void FeedStyleBlock(string media, string block) { if (string.IsNullOrEmpty(media)) media = "all"; var bracketIndex = block.IndexOf("{", StringComparison.Ordinal); var blockSource = block.Substring(bracketIndex).Replace("{", string.Empty).Replace("}", string.Empty); if (bracketIndex < 0) return; ///TODO: Only supporting definitions like: /// h1, h2, h3 {... ///Support needed for definitions like: ///* {... ///h1 h2 {... ///h1 > h2 {... ///h1:before {... ///h1:hover {... var classes = block.Substring(0, bracketIndex).Split(','); for (var i = 0; i < classes.Length; i++) { var className = classes[i].Trim(); if (string.IsNullOrEmpty(className)) continue; var newblock = new Block(blockSource); //Create media blocks if necessary if (!MediaBlocks.ContainsKey(media)) MediaBlocks.Add(media, new Dictionary<string, Block>()); if (!MediaBlocks[media].ContainsKey(className)) { //Create block MediaBlocks[media].Add(className, newblock); } else { //Merge newblock and oldblock's properties var oldblock = MediaBlocks[media][className]; foreach (var property in newblock.Properties.Keys) { if (oldblock.Properties.ContainsKey(property)) { oldblock.Properties[property] = newblock.Properties[property]; } else { oldblock.Properties.Add(property, newblock.Properties[property]); } } oldblock.UpdatePropertyValues(); } } }
/// <summary> /// Applies style to all boxes in the tree /// </summary> private void CascadeStyles(Box startBox) { var someBlock = false; foreach (var b in startBox.Boxes) { b.InheritStyle(); if (b.HtmlTag != null) { //Check if tag name matches with a defined class if (MediaBlocks["all"].ContainsKey(b.HtmlTag.TagName)) { MediaBlocks["all"][b.HtmlTag.TagName].AssignTo(b); } //Check if class="" attribute matches with a defined style if (b.HtmlTag.HasAttribute("class") && MediaBlocks["all"].ContainsKey("." + b.HtmlTag.Attributes["class"])) { MediaBlocks["all"]["." + b.HtmlTag.Attributes["class"]].AssignTo(b); } b.HtmlTag.TranslateAttributes(b); //Check for the style="" attribute if (b.HtmlTag.HasAttribute("style")) { var block = new Block(b.HtmlTag.Attributes["style"]); block.AssignTo(b); } //Check for the <style> tag if (b.HtmlTag.TagName.Equals("style", StringComparison.CurrentCultureIgnoreCase) && b.Boxes.Count == 1) { FeedStyleSheet(b.Boxes[0].Text); } //Check for the <link rel=stylesheet> tag if (b.HtmlTag.TagName.Equals("link", StringComparison.CurrentCultureIgnoreCase) && b.GetAttribute("rel", string.Empty) .Equals("stylesheet", StringComparison.CurrentCultureIgnoreCase)) { FeedStyleSheet(Value.GetStyleSheet(b.GetAttribute("href", string.Empty))); } } CascadeStyles(b); } if (someBlock) { foreach (var box in startBox.Boxes) { box.Display = Css.Constants.Block; } } }