Ejemplo n.º 1
0
        public static string HtmlList(IEnumerable items, HtmlDumpOptions options)
        {
            if (options == null)
            {
                options = new HtmlDumpOptions();
            }

            if (items is IDictionary <string, object> single)
            {
                items = new[] { single }
            }
            ;

            var depth      = options.Depth;
            var childDepth = options.ChildDepth;

            options.Depth += 1;

            try
            {
                var parentClass = options.ClassName;
                var childClass  = options.ChildClass;
                var className   = ((depth < childDepth ? parentClass : childClass ?? parentClass)
                                   ?? options.Defaults.GetDefaultTableClassName());

                var headerStyle = options.HeaderStyle;
                var headerTag   = options.HeaderTag ?? "th";

                var           sbHeader = StringBuilderCache.Allocate();
                var           sbRows   = StringBuilderCacheAlt.Allocate();
                List <string> keys     = null;

                foreach (var item in items)
                {
                    if (item is IDictionary <string, object> d)
                    {
                        if (keys == null)
                        {
                            keys = options.Headers?.ToList() ?? EnumerableExtensions.AllKeysWithDefaultValues(items);
                            sbHeader.Append("<tr>");
                            foreach (var key in keys)
                            {
                                sbHeader.Append('<').Append(headerTag).Append('>');
                                sbHeader.Append(ViewUtils.StyleText(key, headerStyle)?.HtmlEncode());
                                sbHeader.Append("</").Append(headerTag).Append('>');
                            }
                            sbHeader.Append("</tr>");
                        }

                        sbRows.Append("<tr>");
                        foreach (var key in keys)
                        {
                            var value = d[key];
                            if (ReferenceEquals(value, items))
                            {
                                break; // Prevent cyclical deps like 'it' binding
                            }
                            sbRows.Append("<td>");

                            if (!isComplexType(value))
                            {
                                sbRows.Append(GetScalarHtml(value, options.Defaults));
                            }
                            else
                            {
                                var htmlValue = HtmlDump(value, options);
                                sbRows.Append(htmlValue.AsString());
                            }

                            sbRows.Append("</td>");
                        }
                        sbRows.Append("</tr>");
                    }
                }

                var isEmpty = sbRows.Length == 0;
                if (isEmpty && options.CaptionIfEmpty == null)
                {
                    return(string.Empty);
                }

                var htmlHeaders = StringBuilderCache.ReturnAndFree(sbHeader);
                var htmlRows    = StringBuilderCacheAlt.ReturnAndFree(sbRows);

                var sb = StringBuilderCache.Allocate();
                sb.Append("<table");

                if (options.Id != null)
                {
                    sb.Append(" id=\"").Append(options.Id).Append("\"");
                }
                if (!string.IsNullOrEmpty(className))
                {
                    sb.Append(" class=\"").Append(className).Append("\"");
                }

                sb.Append(">");

                var caption = options.Caption;
                if (isEmpty)
                {
                    caption = options.CaptionIfEmpty;
                }

                if (caption != null && !options.HasCaption)
                {
                    sb.Append("<caption>").Append(caption.HtmlEncode()).Append("</caption>");
                    options.HasCaption = true;
                }

                if (htmlHeaders.Length > 0)
                {
                    sb.Append("<thead>").Append(htmlHeaders).Append("</thead>");
                }
                if (htmlRows.Length > 0)
                {
                    sb.Append("<tbody>").Append(htmlRows).Append("</tbody>");
                }

                sb.Append("</table>");

                var html = StringBuilderCache.ReturnAndFree(sb);
                return(html);
            }
            finally
            {
                options.Depth = depth;
            }
        }