/// <summary> /// Applies style to all boxes in the tree.<br/> /// If the html tag has style defined for each apply that style to the css box of the tag.<br/> /// If the html tag has "class" attribute and the class name has style defined apply that style on the tag css box.<br/> /// If the html tag has "style" attribute parse it and apply the parsed style on the tag css box.<br/> /// If the html tag is "style" tag parse it content and add to the css data for all future tags parsing.<br/> /// If the html tag is "link" that point to style data parse it content and add to the css data for all future tags parsing.<br/> /// </summary> /// <param name="box"></param> /// <param name="htmlContainer">the html container to use for reference resolve</param> /// <param name="cssData"> </param> /// <param name="cssDataChanged">check if the css data has been modified by the handled html not to change the base css data</param> private static void CascadeStyles(CssBox box, HtmlContainer htmlContainer, ref CssData cssData, ref bool cssDataChanged) { box.InheritStyle(); if (box.HtmlTag != null) { // try assign style using the html element tag AssignCssBlocks(box, cssData, box.HtmlTag.Name); // try assign style using the "class" attribute of the html element if (box.HtmlTag.HasAttribute("class")) { AssignClassCssBlocks(box, cssData); } // try assign style using the "id" attribute of the html element if (box.HtmlTag.HasAttribute("id")) { var id = box.HtmlTag.TryGetAttribute("id"); AssignCssBlocks(box, cssData, "#" + id); } TranslateAttributes(box.HtmlTag, box); // Check for the style="" attribute if (box.HtmlTag.HasAttribute("style")) { var block = CssParser.ParseCssBlock(box.HtmlTag.Name, box.HtmlTag.TryGetAttribute("style")); AssignCssBlock(box, block); } // Check for the <style> tag if (box.HtmlTag.Name.Equals("style", StringComparison.CurrentCultureIgnoreCase) && box.Boxes.Count == 1) { CloneCssData(ref cssData, ref cssDataChanged); CssParser.ParseStyleSheet(cssData, box.Boxes[0].Text.CutSubstring()); } // Check for the <link rel=stylesheet> tag if (box.HtmlTag.Name.Equals("link", StringComparison.CurrentCultureIgnoreCase) && box.GetAttribute("rel", string.Empty).Equals("stylesheet", StringComparison.CurrentCultureIgnoreCase)) { CloneCssData(ref cssData, ref cssDataChanged); string stylesheet; CssData stylesheetData; StylesheetLoadHandler.LoadStylesheet(htmlContainer, box.GetAttribute("href", string.Empty), box.HtmlTag.Attributes, out stylesheet, out stylesheetData); if (stylesheet != null) { CssParser.ParseStyleSheet(cssData, stylesheet); } else if (stylesheetData != null) { cssData.Combine(stylesheetData); } } } // cascade text decoration only to boxes that actually have text so it will be handled correctly. if (box.TextDecoration != String.Empty && box.Text == null) { foreach (var childBox in box.Boxes) { childBox.TextDecoration = box.TextDecoration; } box.TextDecoration = string.Empty; } foreach (var childBox in box.Boxes) { CascadeStyles(childBox, htmlContainer, ref cssData, ref cssDataChanged); } }
/// <summary> /// /// </summary> /// <param name="tag"></param> /// <param name="box"></param> private static void TranslateAttributes(HtmlTag tag, CssBox box) { if (tag.HasAttributes()) { foreach (string att in tag.Attributes.Keys) { string value = tag.Attributes[att]; switch (att) { case HtmlConstants.Align: if (value == HtmlConstants.Left || value == HtmlConstants.Center || value == HtmlConstants.Right || value == HtmlConstants.Justify) { box.TextAlign = value.ToLower(); } else { box.VerticalAlign = value.ToLower(); } break; case HtmlConstants.Background: box.BackgroundImage = value.ToLower(); break; case HtmlConstants.Bgcolor: box.BackgroundColor = value.ToLower(); break; case HtmlConstants.Border: if (!string.IsNullOrEmpty(value) && value != "0") { box.BorderLeftStyle = box.BorderTopStyle = box.BorderRightStyle = box.BorderBottomStyle = CssConstants.Solid; } box.BorderLeftWidth = box.BorderTopWidth = box.BorderRightWidth = box.BorderBottomWidth = TranslateLength(value); if (tag.Name == HtmlConstants.Table) { if (value != "0") { ApplyTableBorder(box, "1px"); } } else { box.BorderTopStyle = box.BorderLeftStyle = box.BorderRightStyle = box.BorderBottomStyle = CssConstants.Solid; } break; case HtmlConstants.Bordercolor: box.BorderLeftColor = box.BorderTopColor = box.BorderRightColor = box.BorderBottomColor = value.ToLower(); break; case HtmlConstants.Cellspacing: box.BorderSpacing = TranslateLength(value); break; case HtmlConstants.Cellpadding: ApplyTablePadding(box, value); break; case HtmlConstants.Color: box.Color = value.ToLower(); break; case HtmlConstants.Dir: box.Direction = value.ToLower(); break; case HtmlConstants.Face: box.FontFamily = CssParser.ParseFontFamily(value); break; case HtmlConstants.Height: box.Height = TranslateLength(value); break; case HtmlConstants.Hspace: box.MarginRight = box.MarginLeft = TranslateLength(value); break; case HtmlConstants.Nowrap: box.WhiteSpace = CssConstants.NoWrap; break; case HtmlConstants.Size: if (tag.Name.Equals(HtmlConstants.Hr, StringComparison.OrdinalIgnoreCase)) { box.Height = TranslateLength(value); } else if (tag.Name.Equals(HtmlConstants.Font, StringComparison.OrdinalIgnoreCase)) { box.FontSize = value; } break; case HtmlConstants.Valign: box.VerticalAlign = value.ToLower(); break; case HtmlConstants.Vspace: box.MarginTop = box.MarginBottom = TranslateLength(value); break; case HtmlConstants.Width: box.Width = TranslateLength(value); break; } } } }