/// <summary> /// Init. /// </summary> public HtmlContainerInt(RAdapter adapter) { ArgChecker.AssertArgNotNull(adapter, "global"); _adapter = adapter; _cssParser = new CssParser(adapter); }
/// <summary> /// Init. /// </summary> public DomParser(CssParser cssParser) { ArgChecker.AssertArgNotNull(cssParser, "cssParser"); _cssParser = cssParser; }
/// <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 ? "/" : ""); }
/// <summary> /// Write the given html DOM sub-tree into the given string builder.<br/> /// If <paramref name="selectedBoxes"/> are given write html only from those tags. /// </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 html sub-tree to write</param> /// <param name="styleGen">Controls the way styles are generated when html is generated</param> /// <param name="selectedBoxes">Control if to generate only selected boxes, if given only boxes found in hash will be generated</param> /// <param name="selectionRoot">the box the is the root of selected boxes (the first box to contain multiple selected boxes)</param> private static void WriteHtml(CssParser cssParser, StringBuilder sb, CssBox box, HtmlGenerationStyle styleGen, Dictionary<CssBox, bool> selectedBoxes, CssBox selectionRoot) { if (box.HtmlTag == null || selectedBoxes == null || selectedBoxes.ContainsKey(box)) { if (box.HtmlTag != null) { if (box.HtmlTag.Name != "link" || !box.HtmlTag.Attributes.ContainsKey("href") || (!box.HtmlTag.Attributes["href"].StartsWith("property") && !box.HtmlTag.Attributes["href"].StartsWith("method"))) { WriteHtmlTag(cssParser, sb, box, styleGen); if (box == selectionRoot) sb.Append("<!--StartFragment-->"); } if (styleGen == HtmlGenerationStyle.InHeader && box.HtmlTag.Name == "html" && box.HtmlContainer.CssData != null) { sb.AppendLine("<head>"); WriteStylesheet(sb, box.HtmlContainer.CssData); sb.AppendLine("</head>"); } } if (box.Words.Count > 0) { foreach (var word in box.Words) { if (selectedBoxes == null || word.Selected) { var wordText = GetSelectedWord(word, selectedBoxes != null); sb.Append(HtmlUtils.EncodeHtml(wordText)); } } } foreach (var childBox in box.Boxes) { WriteHtml(cssParser, sb, childBox, styleGen, selectedBoxes, selectionRoot); } if (box.HtmlTag != null && !box.HtmlTag.IsSingle) { if (box == selectionRoot) sb.Append("<!--EndFragment-->"); sb.AppendFormat("</{0}>", box.HtmlTag.Name); } } }
/// <summary> /// Parse the given stylesheet to <see cref="CssData"/> object.<br/> /// If <paramref name="combineWithDefault"/> is true the parsed css blocks are added to the /// default css data (as defined by W3), merged if class name already exists. If false only the data in the given stylesheet is returned. /// </summary> /// <seealso cref="http://www.w3.org/TR/CSS21/sample.html"/> /// <param name="adapter">Platform adapter</param> /// <param name="stylesheet">the stylesheet source to parse</param> /// <param name="combineWithDefault">true - combine the parsed css data with default css data, false - return only the parsed css data</param> /// <returns>the parsed css data</returns> public static CssData Parse(RAdapter adapter, string stylesheet, bool combineWithDefault = true) { CssParser parser = new CssParser(adapter); return parser.ParseStyleSheet(stylesheet, combineWithDefault); }