| 
									
										
										
										
											2020-01-18 09:38:21 +01:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2023-05-21 07:02:41 +02:00
										 |  |  |  * Copyright (c) 2018-2023, Andreas Kling <kling@serenityos.org> | 
					
						
							| 
									
										
										
										
											2021-02-21 13:45:26 +02:00
										 |  |  |  * Copyright (c) 2021, the SerenityOS developers. | 
					
						
							| 
									
										
										
										
											2020-01-18 09:38:21 +01:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-04-22 01:24:48 -07:00
										 |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							| 
									
										
										
										
											2020-01-18 09:38:21 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-14 18:47:21 +02:00
										 |  |  | #include <AK/QuickSort.h>
 | 
					
						
							| 
									
										
										
										
											2020-05-23 21:05:26 +02:00
										 |  |  | #include <AK/StringBuilder.h>
 | 
					
						
							| 
									
										
										
										
											2019-10-03 15:20:13 +02:00
										 |  |  | #include <AK/Utf8View.h>
 | 
					
						
							| 
									
										
										
										
											2022-03-28 20:30:26 +01:00
										 |  |  | #include <LibWeb/CSS/CSSFontFaceRule.h>
 | 
					
						
							| 
									
										
										
										
											2021-02-21 18:36:34 +02:00
										 |  |  | #include <LibWeb/CSS/CSSImportRule.h>
 | 
					
						
							| 
									
										
										
										
											2021-09-29 12:48:04 +01:00
										 |  |  | #include <LibWeb/CSS/CSSMediaRule.h>
 | 
					
						
							| 
									
										
										
										
											2021-02-21 13:45:26 +02:00
										 |  |  | #include <LibWeb/CSS/CSSRule.h>
 | 
					
						
							| 
									
										
										
										
											2021-03-07 15:00:02 +01:00
										 |  |  | #include <LibWeb/CSS/CSSStyleRule.h>
 | 
					
						
							| 
									
										
										
										
											2021-03-07 16:14:04 +01:00
										 |  |  | #include <LibWeb/CSS/CSSStyleSheet.h>
 | 
					
						
							| 
									
										
										
										
											2021-10-08 17:48:14 +01:00
										 |  |  | #include <LibWeb/CSS/CSSSupportsRule.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-07 10:32:51 +01:00
										 |  |  | #include <LibWeb/CSS/PropertyID.h>
 | 
					
						
							| 
									
										
										
										
											2023-08-11 21:26:04 +01:00
										 |  |  | #include <LibWeb/CSS/PseudoClass.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-07 10:32:51 +01:00
										 |  |  | #include <LibWeb/DOM/Comment.h>
 | 
					
						
							|  |  |  | #include <LibWeb/DOM/Document.h>
 | 
					
						
							|  |  |  | #include <LibWeb/DOM/Element.h>
 | 
					
						
							| 
									
										
										
										
											2021-02-10 18:25:05 +01:00
										 |  |  | #include <LibWeb/DOM/ShadowRoot.h>
 | 
					
						
							| 
									
										
										
										
											2020-03-07 10:32:51 +01:00
										 |  |  | #include <LibWeb/DOM/Text.h>
 | 
					
						
							|  |  |  | #include <LibWeb/Dump.h>
 | 
					
						
							| 
									
										
										
										
											2023-08-14 20:19:41 +02:00
										 |  |  | #include <LibWeb/HTML/DocumentState.h>
 | 
					
						
							| 
									
										
										
										
											2023-05-21 07:02:41 +02:00
										 |  |  | #include <LibWeb/HTML/HTMLImageElement.h>
 | 
					
						
							| 
									
										
										
										
											2020-08-19 22:30:33 +01:00
										 |  |  | #include <LibWeb/HTML/HTMLTemplateElement.h>
 | 
					
						
							| 
									
										
										
										
											2023-05-21 07:02:41 +02:00
										 |  |  | #include <LibWeb/HTML/ImageRequest.h>
 | 
					
						
							| 
									
										
										
										
											2023-08-14 20:19:41 +02:00
										 |  |  | #include <LibWeb/HTML/TraversableNavigable.h>
 | 
					
						
							| 
									
										
										
										
											2021-10-06 20:02:41 +02:00
										 |  |  | #include <LibWeb/Layout/BlockContainer.h>
 | 
					
						
							| 
									
										
										
										
											2023-05-03 10:32:23 +02:00
										 |  |  | #include <LibWeb/Layout/FormattingContext.h>
 | 
					
						
							| 
									
										
										
										
											2022-08-05 00:16:35 +02:00
										 |  |  | #include <LibWeb/Layout/FrameBox.h>
 | 
					
						
							| 
									
										
										
										
											2020-11-22 15:53:01 +01:00
										 |  |  | #include <LibWeb/Layout/Node.h>
 | 
					
						
							| 
									
										
										
										
											2021-09-17 23:03:36 +02:00
										 |  |  | #include <LibWeb/Layout/SVGBox.h>
 | 
					
						
							| 
									
										
										
										
											2020-11-22 15:53:01 +01:00
										 |  |  | #include <LibWeb/Layout/TextNode.h>
 | 
					
						
							| 
									
										
										
										
											2023-05-21 07:02:41 +02:00
										 |  |  | #include <LibWeb/Layout/Viewport.h>
 | 
					
						
							| 
									
										
										
										
											2022-03-10 23:13:37 +01:00
										 |  |  | #include <LibWeb/Painting/PaintableBox.h>
 | 
					
						
							| 
									
										
										
										
											2023-03-18 20:22:58 +01:00
										 |  |  | #include <LibWeb/Painting/TextPaintable.h>
 | 
					
						
							| 
									
										
										
										
											2023-05-21 07:02:41 +02:00
										 |  |  | #include <LibWeb/SVG/SVGDecodedImageData.h>
 | 
					
						
							| 
									
										
										
										
											2019-06-15 18:55:47 +02:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-07 10:27:02 +01:00
										 |  |  | namespace Web { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-29 12:48:04 +01:00
										 |  |  | static void indent(StringBuilder& builder, int levels) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for (int i = 0; i < levels; i++) | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |         builder.append("  "sv); | 
					
						
							| 
									
										
										
										
											2021-09-29 12:48:04 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-14 20:19:41 +02:00
										 |  |  | static ErrorOr<void> dump_session_history_entry(StringBuilder& builder, HTML::SessionHistoryEntry const& session_history_entry, int indent_levels) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     indent(builder, indent_levels); | 
					
						
							|  |  |  |     auto const& document = session_history_entry.document_state->document(); | 
					
						
							|  |  |  |     TRY(builder.try_appendff("step=({}) url=({}) is-active=({})\n", session_history_entry.step.get<int>(), session_history_entry.url, document && document->is_active())); | 
					
						
							|  |  |  |     for (auto const& nested_history : session_history_entry.document_state->nested_histories()) { | 
					
						
							|  |  |  |         for (auto const& nested_she : nested_history.entries) { | 
					
						
							|  |  |  |             TRY(dump_session_history_entry(builder, *nested_she, indent_levels + 1)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return {}; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void dump_tree(HTML::TraversableNavigable& traversable) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     StringBuilder builder; | 
					
						
							|  |  |  |     for (auto const& she : traversable.session_history_entries()) { | 
					
						
							|  |  |  |         dump_session_history_entry(builder, *she, 0).release_value_but_fixme_should_propagate_errors(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     dbgln("{}", builder.string_view()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-12 14:13:29 +01:00
										 |  |  | void dump_tree(DOM::Node const& node) | 
					
						
							| 
									
										
										
										
											2021-02-17 15:59:13 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     StringBuilder builder; | 
					
						
							|  |  |  |     dump_tree(builder, node); | 
					
						
							|  |  |  |     dbgln("{}", builder.string_view()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-12 14:13:29 +01:00
										 |  |  | void dump_tree(StringBuilder& builder, DOM::Node const& node) | 
					
						
							| 
									
										
										
										
											2019-06-15 18:55:47 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     static int indent = 0; | 
					
						
							|  |  |  |     for (int i = 0; i < indent; ++i) | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |         builder.append("  "sv); | 
					
						
							| 
									
										
										
										
											2021-02-10 17:13:08 +01:00
										 |  |  |     if (is<DOM::Element>(node)) { | 
					
						
							| 
									
										
										
										
											2021-06-24 19:53:42 +02:00
										 |  |  |         builder.appendff("<{}", verify_cast<DOM::Element>(node).local_name()); | 
					
						
							|  |  |  |         verify_cast<DOM::Element>(node).for_each_attribute([&](auto& name, auto& value) { | 
					
						
							| 
									
										
										
										
											2021-02-17 15:59:13 +01:00
										 |  |  |             builder.appendff(" {}={}", name, value); | 
					
						
							| 
									
										
										
										
											2019-06-15 21:08:36 +02:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |         builder.append(">\n"sv); | 
					
						
							| 
									
										
										
										
											2020-07-26 19:37:56 +02:00
										 |  |  |     } else if (is<DOM::Text>(node)) { | 
					
						
							| 
									
										
										
										
											2021-06-24 19:53:42 +02:00
										 |  |  |         builder.appendff("\"{}\"\n", verify_cast<DOM::Text>(node).data()); | 
					
						
							| 
									
										
										
										
											2021-02-10 17:13:08 +01:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2021-02-17 15:59:13 +01:00
										 |  |  |         builder.appendff("{}\n", node.node_name()); | 
					
						
							| 
									
										
										
										
											2019-06-15 18:55:47 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     ++indent; | 
					
						
							| 
									
										
										
										
											2023-03-08 15:09:16 +01:00
										 |  |  |     if (is<DOM::Element>(node)) { | 
					
						
							|  |  |  |         if (auto* shadow_root = static_cast<DOM::Element const&>(node).shadow_root_internal()) { | 
					
						
							|  |  |  |             dump_tree(builder, *shadow_root); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-02-10 18:25:05 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-05-21 07:02:41 +02:00
										 |  |  |     if (is<HTML::HTMLImageElement>(node)) { | 
					
						
							|  |  |  |         if (auto image_data = static_cast<HTML::HTMLImageElement const&>(node).current_request().image_data()) { | 
					
						
							|  |  |  |             if (is<SVG::SVGDecodedImageData>(*image_data)) { | 
					
						
							|  |  |  |                 ++indent; | 
					
						
							|  |  |  |                 for (int i = 0; i < indent; ++i) | 
					
						
							|  |  |  |                     builder.append("  "sv); | 
					
						
							|  |  |  |                 builder.append("(SVG-as-image isolated context)\n"sv); | 
					
						
							|  |  |  |                 auto& svg_data = verify_cast<SVG::SVGDecodedImageData>(*image_data); | 
					
						
							|  |  |  |                 dump_tree(builder, svg_data.svg_document()); | 
					
						
							|  |  |  |                 --indent; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-07-26 19:37:56 +02:00
										 |  |  |     if (is<DOM::ParentNode>(node)) { | 
					
						
							| 
									
										
										
										
											2020-08-19 22:30:33 +01:00
										 |  |  |         if (!is<HTML::HTMLTemplateElement>(node)) { | 
					
						
							| 
									
										
										
										
											2021-09-12 12:58:17 +02:00
										 |  |  |             static_cast<DOM::ParentNode const&>(node).for_each_child([&](auto& child) { | 
					
						
							|  |  |  |                 dump_tree(builder, child); | 
					
						
							| 
									
										
										
										
											2020-08-19 22:30:33 +01:00
										 |  |  |             }); | 
					
						
							|  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2021-06-24 19:53:42 +02:00
										 |  |  |             auto& template_element = verify_cast<HTML::HTMLTemplateElement>(node); | 
					
						
							| 
									
										
										
										
											2021-09-12 12:58:17 +02:00
										 |  |  |             dump_tree(builder, template_element.content()); | 
					
						
							| 
									
										
										
										
											2020-08-19 22:30:33 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-06-15 18:55:47 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     --indent; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-06-15 22:49:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-12 14:13:29 +01:00
										 |  |  | void dump_tree(Layout::Node const& layout_node, bool show_box_model, bool show_specified_style) | 
					
						
							| 
									
										
										
										
											2020-12-08 22:11:02 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     StringBuilder builder; | 
					
						
							|  |  |  |     dump_tree(builder, layout_node, show_box_model, show_specified_style, true); | 
					
						
							| 
									
										
										
										
											2021-02-17 15:59:13 +01:00
										 |  |  |     dbgln("{}", builder.string_view()); | 
					
						
							| 
									
										
										
										
											2020-12-08 22:11:02 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-12 14:13:29 +01:00
										 |  |  | void dump_tree(StringBuilder& builder, Layout::Node const& layout_node, bool show_box_model, bool show_specified_style, bool interactive) | 
					
						
							| 
									
										
										
										
											2019-06-15 22:49:44 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-02-25 14:49:47 +01:00
										 |  |  |     static size_t indent = 0; | 
					
						
							|  |  |  |     for (size_t i = 0; i < indent; ++i) | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |         builder.append("  "sv); | 
					
						
							| 
									
										
										
										
											2019-06-16 11:28:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-08 12:42:48 +13:00
										 |  |  |     FlyString tag_name; | 
					
						
							| 
									
										
										
										
											2019-06-16 11:28:47 +02:00
										 |  |  |     if (layout_node.is_anonymous()) | 
					
						
							| 
									
										
										
										
											2023-10-08 12:42:48 +13:00
										 |  |  |         tag_name = "(anonymous)"_fly_string; | 
					
						
							| 
									
										
										
										
											2020-11-22 14:46:36 +01:00
										 |  |  |     else if (is<DOM::Element>(layout_node.dom_node())) | 
					
						
							| 
									
										
										
										
											2023-10-08 12:42:48 +13:00
										 |  |  |         tag_name = verify_cast<DOM::Element>(*layout_node.dom_node()).local_name(); | 
					
						
							| 
									
										
										
										
											2019-06-16 11:28:47 +02:00
										 |  |  |     else | 
					
						
							| 
									
										
										
										
											2023-10-08 12:42:48 +13:00
										 |  |  |         tag_name = layout_node.dom_node()->node_name(); | 
					
						
							| 
									
										
										
										
											2019-06-16 11:28:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-20 23:17:14 +13:00
										 |  |  |     String identifier; | 
					
						
							| 
									
										
										
										
											2020-11-22 14:46:36 +01:00
										 |  |  |     if (layout_node.dom_node() && is<DOM::Element>(*layout_node.dom_node())) { | 
					
						
							| 
									
										
										
										
											2021-06-24 19:53:42 +02:00
										 |  |  |         auto& element = verify_cast<DOM::Element>(*layout_node.dom_node()); | 
					
						
							| 
									
										
										
										
											2020-06-12 13:23:07 +02:00
										 |  |  |         StringBuilder builder; | 
					
						
							| 
									
										
										
										
											2023-09-03 14:58:18 +12:00
										 |  |  |         auto id = element.deprecated_attribute(HTML::AttributeNames::id); | 
					
						
							| 
									
										
										
										
											2020-05-23 21:05:26 +02:00
										 |  |  |         if (!id.is_empty()) { | 
					
						
							|  |  |  |             builder.append('#'); | 
					
						
							|  |  |  |             builder.append(id); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-06-12 13:23:07 +02:00
										 |  |  |         for (auto& class_name : element.class_names()) { | 
					
						
							|  |  |  |             builder.append('.'); | 
					
						
							|  |  |  |             builder.append(class_name); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-11-20 23:17:14 +13:00
										 |  |  |         identifier = MUST(builder.to_string()); | 
					
						
							| 
									
										
										
										
											2020-05-23 21:05:26 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |     StringView nonbox_color_on = ""sv; | 
					
						
							|  |  |  |     StringView box_color_on = ""sv; | 
					
						
							|  |  |  |     StringView svg_box_color_on = ""sv; | 
					
						
							|  |  |  |     StringView positioned_color_on = ""sv; | 
					
						
							|  |  |  |     StringView floating_color_on = ""sv; | 
					
						
							| 
									
										
										
										
											2023-01-16 13:51:49 +01:00
										 |  |  |     StringView inline_color_on = ""sv; | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |     StringView line_box_color_on = ""sv; | 
					
						
							|  |  |  |     StringView fragment_color_on = ""sv; | 
					
						
							|  |  |  |     StringView flex_color_on = ""sv; | 
					
						
							| 
									
										
										
										
											2023-05-29 17:40:58 +03:00
										 |  |  |     StringView table_color_on = ""sv; | 
					
						
							| 
									
										
										
										
											2023-05-03 10:32:23 +02:00
										 |  |  |     StringView formatting_context_color_on = ""sv; | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |     StringView color_off = ""sv; | 
					
						
							| 
									
										
										
										
											2020-12-08 22:11:02 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (interactive) { | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |         nonbox_color_on = "\033[33m"sv; | 
					
						
							|  |  |  |         box_color_on = "\033[34m"sv; | 
					
						
							|  |  |  |         svg_box_color_on = "\033[31m"sv; | 
					
						
							|  |  |  |         positioned_color_on = "\033[31;1m"sv; | 
					
						
							|  |  |  |         floating_color_on = "\033[32;1m"sv; | 
					
						
							| 
									
										
										
										
											2023-01-16 13:51:49 +01:00
										 |  |  |         inline_color_on = "\033[36;1m"sv; | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |         line_box_color_on = "\033[34;1m"sv; | 
					
						
							|  |  |  |         fragment_color_on = "\033[35;1m"sv; | 
					
						
							|  |  |  |         flex_color_on = "\033[34;1m"sv; | 
					
						
							| 
									
										
										
										
											2023-05-29 17:40:58 +03:00
										 |  |  |         table_color_on = "\033[91;1m"sv; | 
					
						
							| 
									
										
										
										
											2023-05-03 10:32:23 +02:00
										 |  |  |         formatting_context_color_on = "\033[37;1m"sv; | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |         color_off = "\033[0m"sv; | 
					
						
							| 
									
										
										
										
											2020-12-08 22:11:02 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-01 18:55:47 +01:00
										 |  |  |     if (!is<Layout::Box>(layout_node)) { | 
					
						
							| 
									
										
										
										
											2021-02-23 09:57:02 +03:30
										 |  |  |         builder.appendff("{}{}{} <{}{}{}{}>", | 
					
						
							| 
									
										
										
										
											2020-12-08 22:11:02 +01:00
										 |  |  |             nonbox_color_on, | 
					
						
							| 
									
										
										
										
											2022-10-20 16:06:26 +02:00
										 |  |  |             layout_node.class_name(), | 
					
						
							| 
									
										
										
										
											2020-12-08 22:11:02 +01:00
										 |  |  |             color_off, | 
					
						
							|  |  |  |             tag_name, | 
					
						
							|  |  |  |             nonbox_color_on, | 
					
						
							|  |  |  |             identifier, | 
					
						
							|  |  |  |             color_off); | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |         builder.append("\n"sv); | 
					
						
							| 
									
										
										
										
											2019-10-15 16:48:38 +02:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2021-06-24 19:53:42 +02:00
										 |  |  |         auto& box = verify_cast<Layout::Box>(layout_node); | 
					
						
							| 
									
										
										
										
											2021-09-17 23:03:36 +02:00
										 |  |  |         StringView color_on = is<Layout::SVGBox>(box) ? svg_box_color_on : box_color_on; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-08 22:11:02 +01:00
										 |  |  |         builder.appendff("{}{}{} <{}{}{}{}> ", | 
					
						
							| 
									
										
										
										
											2021-09-17 23:03:36 +02:00
										 |  |  |             color_on, | 
					
						
							| 
									
										
										
										
											2022-10-20 16:06:26 +02:00
										 |  |  |             box.class_name(), | 
					
						
							| 
									
										
										
										
											2020-12-08 22:11:02 +01:00
										 |  |  |             color_off, | 
					
						
							| 
									
										
										
										
											2021-09-17 23:03:36 +02:00
										 |  |  |             color_on, | 
					
						
							| 
									
										
										
										
											2020-12-08 22:11:02 +01:00
										 |  |  |             tag_name, | 
					
						
							|  |  |  |             color_off, | 
					
						
							| 
									
										
										
										
											2023-11-20 23:17:14 +13:00
										 |  |  |             identifier); | 
					
						
							| 
									
										
										
										
											2020-12-08 22:11:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-20 16:00:42 +01:00
										 |  |  |         if (auto const* paintable_box = box.paintable_box()) { | 
					
						
							| 
									
										
										
										
											2022-03-18 22:12:03 +01:00
										 |  |  |             builder.appendff("at ({},{}) content-size {}x{}", | 
					
						
							| 
									
										
										
										
											2023-04-20 16:00:42 +01:00
										 |  |  |                 paintable_box->absolute_x(), | 
					
						
							|  |  |  |                 paintable_box->absolute_y(), | 
					
						
							|  |  |  |                 paintable_box->content_width(), | 
					
						
							|  |  |  |                 paintable_box->content_height()); | 
					
						
							| 
									
										
										
										
											2023-05-29 08:53:39 +02:00
										 |  |  |         } else { | 
					
						
							|  |  |  |             builder.appendff("(not painted)"); | 
					
						
							| 
									
										
										
										
											2022-03-18 22:12:03 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-12-07 19:36:13 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (box.is_positioned()) | 
					
						
							| 
									
										
										
										
											2020-12-08 22:11:02 +01:00
										 |  |  |             builder.appendff(" {}positioned{}", positioned_color_on, color_off); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:36:13 +01:00
										 |  |  |         if (box.is_floating()) | 
					
						
							| 
									
										
										
										
											2020-12-08 22:11:02 +01:00
										 |  |  |             builder.appendff(" {}floating{}", floating_color_on, color_off); | 
					
						
							|  |  |  |         if (box.is_inline_block()) | 
					
						
							| 
									
										
										
										
											2023-01-16 13:51:49 +01:00
										 |  |  |             builder.appendff(" {}inline-block{}", inline_color_on, color_off); | 
					
						
							|  |  |  |         if (box.is_inline_table()) | 
					
						
							|  |  |  |             builder.appendff(" {}inline-table{}", inline_color_on, color_off); | 
					
						
							| 
									
										
										
										
											2022-10-06 16:02:53 +02:00
										 |  |  |         if (box.display().is_flex_inside()) { | 
					
						
							| 
									
										
										
										
											2021-10-21 00:29:31 +02:00
										 |  |  |             StringView direction; | 
					
						
							|  |  |  |             switch (box.computed_values().flex_direction()) { | 
					
						
							|  |  |  |             case CSS::FlexDirection::Column: | 
					
						
							|  |  |  |                 direction = "column"sv; | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             case CSS::FlexDirection::ColumnReverse: | 
					
						
							|  |  |  |                 direction = "column-reverse"sv; | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             case CSS::FlexDirection::Row: | 
					
						
							|  |  |  |                 direction = "row"sv; | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             case CSS::FlexDirection::RowReverse: | 
					
						
							|  |  |  |                 direction = "row-reverse"sv; | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             builder.appendff(" {}flex-container({}){}", flex_color_on, direction, color_off); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-05-29 22:36:15 +02:00
										 |  |  |         if (box.is_flex_item()) | 
					
						
							|  |  |  |             builder.appendff(" {}flex-item{}", flex_color_on, color_off); | 
					
						
							| 
									
										
										
										
											2023-05-29 17:40:58 +03:00
										 |  |  |         if (box.display().is_table_inside()) | 
					
						
							|  |  |  |             builder.appendff(" {}table-box{}", table_color_on, color_off); | 
					
						
							|  |  |  |         if (box.display().is_table_row_group()) | 
					
						
							|  |  |  |             builder.appendff(" {}table-row-group{}", table_color_on, color_off); | 
					
						
							| 
									
										
										
										
											2023-06-04 14:20:19 +00:00
										 |  |  |         if (box.display().is_table_column_group()) | 
					
						
							|  |  |  |             builder.appendff(" {}table-column-group{}", table_color_on, color_off); | 
					
						
							| 
									
										
										
										
											2023-05-29 17:40:58 +03:00
										 |  |  |         if (box.display().is_table_header_group()) | 
					
						
							|  |  |  |             builder.appendff(" {}table-header-group{}", table_color_on, color_off); | 
					
						
							|  |  |  |         if (box.display().is_table_footer_group()) | 
					
						
							|  |  |  |             builder.appendff(" {}table-footer-group{}", table_color_on, color_off); | 
					
						
							|  |  |  |         if (box.display().is_table_row()) | 
					
						
							|  |  |  |             builder.appendff(" {}table-row{}", table_color_on, color_off); | 
					
						
							|  |  |  |         if (box.display().is_table_cell()) | 
					
						
							|  |  |  |             builder.appendff(" {}table-cell{}", table_color_on, color_off); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:36:13 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (show_box_model) { | 
					
						
							|  |  |  |             // Dump the horizontal box properties
 | 
					
						
							| 
									
										
										
										
											2021-04-15 00:36:14 -07:00
										 |  |  |             builder.appendff(" [{}+{}+{} {} {}+{}+{}]", | 
					
						
							| 
									
										
										
										
											2020-12-12 21:02:06 +01:00
										 |  |  |                 box.box_model().margin.left, | 
					
						
							|  |  |  |                 box.box_model().border.left, | 
					
						
							|  |  |  |                 box.box_model().padding.left, | 
					
						
							| 
									
										
										
										
											2023-04-20 16:00:42 +01:00
										 |  |  |                 box.paintable_box() ? box.paintable_box()->content_width() : 0, | 
					
						
							| 
									
										
										
										
											2020-12-12 21:02:06 +01:00
										 |  |  |                 box.box_model().padding.right, | 
					
						
							|  |  |  |                 box.box_model().border.right, | 
					
						
							|  |  |  |                 box.box_model().margin.right); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:36:13 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             // And the vertical box properties
 | 
					
						
							| 
									
										
										
										
											2021-04-15 00:36:14 -07:00
										 |  |  |             builder.appendff(" [{}+{}+{} {} {}+{}+{}]", | 
					
						
							| 
									
										
										
										
											2020-12-12 21:02:06 +01:00
										 |  |  |                 box.box_model().margin.top, | 
					
						
							|  |  |  |                 box.box_model().border.top, | 
					
						
							|  |  |  |                 box.box_model().padding.top, | 
					
						
							| 
									
										
										
										
											2023-04-20 16:00:42 +01:00
										 |  |  |                 box.paintable_box() ? box.paintable_box()->content_height() : 0, | 
					
						
							| 
									
										
										
										
											2020-12-12 21:02:06 +01:00
										 |  |  |                 box.box_model().padding.bottom, | 
					
						
							|  |  |  |                 box.box_model().border.bottom, | 
					
						
							|  |  |  |                 box.box_model().margin.bottom); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:36:13 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-08-18 08:09:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-03 10:32:23 +02:00
										 |  |  |         if (auto formatting_context_type = Layout::FormattingContext::formatting_context_type_created_by_box(box); formatting_context_type.has_value()) { | 
					
						
							|  |  |  |             switch (formatting_context_type.value()) { | 
					
						
							|  |  |  |             case Layout::FormattingContext::Type::Block: | 
					
						
							|  |  |  |                 builder.appendff(" [{}BFC{}]", formatting_context_color_on, color_off); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             case Layout::FormattingContext::Type::Flex: | 
					
						
							|  |  |  |                 builder.appendff(" [{}FFC{}]", formatting_context_color_on, color_off); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             case Layout::FormattingContext::Type::Grid: | 
					
						
							|  |  |  |                 builder.appendff(" [{}GFC{}]", formatting_context_color_on, color_off); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             case Layout::FormattingContext::Type::Table: | 
					
						
							|  |  |  |                 builder.appendff(" [{}TFC{}]", formatting_context_color_on, color_off); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             case Layout::FormattingContext::Type::SVG: | 
					
						
							|  |  |  |                 builder.appendff(" [{}SVG{}]", formatting_context_color_on, color_off); | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             default: | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-26 00:10:36 +01:00
										 |  |  |         builder.appendff(" children: {}", box.children_are_inline() ? "inline" : "not-inline"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-05 00:16:35 +02:00
										 |  |  |         if (is<Layout::FrameBox>(box)) { | 
					
						
							|  |  |  |             auto const& frame_box = static_cast<Layout::FrameBox const&>(box); | 
					
						
							|  |  |  |             if (auto* nested_browsing_context = frame_box.dom_node().nested_browsing_context()) { | 
					
						
							|  |  |  |                 if (auto* document = nested_browsing_context->active_document()) { | 
					
						
							|  |  |  |                     builder.appendff(" (url: {})", document->url()); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |         builder.append("\n"sv); | 
					
						
							| 
									
										
										
										
											2019-10-15 16:48:38 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-06-21 20:54:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-21 07:02:41 +02:00
										 |  |  |     if (layout_node.dom_node() && is<HTML::HTMLImageElement>(*layout_node.dom_node())) { | 
					
						
							|  |  |  |         if (auto image_data = static_cast<HTML::HTMLImageElement const&>(*layout_node.dom_node()).current_request().image_data()) { | 
					
						
							|  |  |  |             if (is<SVG::SVGDecodedImageData>(*image_data)) { | 
					
						
							|  |  |  |                 auto& svg_data = verify_cast<SVG::SVGDecodedImageData>(*image_data); | 
					
						
							|  |  |  |                 if (svg_data.svg_document().layout_node()) { | 
					
						
							|  |  |  |                     ++indent; | 
					
						
							|  |  |  |                     for (size_t i = 0; i < indent; ++i) | 
					
						
							|  |  |  |                         builder.append("  "sv); | 
					
						
							|  |  |  |                     builder.append("(SVG-as-image isolated context)\n"sv); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     dump_tree(builder, *svg_data.svg_document().layout_node(), show_box_model, show_specified_style, interactive); | 
					
						
							|  |  |  |                     --indent; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-06 20:02:41 +02:00
										 |  |  |     if (is<Layout::BlockContainer>(layout_node) && static_cast<Layout::BlockContainer const&>(layout_node).children_are_inline()) { | 
					
						
							|  |  |  |         auto& block = static_cast<Layout::BlockContainer const&>(layout_node); | 
					
						
							| 
									
										
										
										
											2024-01-12 21:25:05 +01:00
										 |  |  |         for (size_t fragment_index = 0; block.paintable_with_lines() && fragment_index < block.paintable_with_lines()->fragments().size(); ++fragment_index) { | 
					
						
							|  |  |  |             auto const& fragment = block.paintable_with_lines()->fragments()[fragment_index]; | 
					
						
							| 
									
										
										
										
											2020-02-25 14:49:47 +01:00
										 |  |  |             for (size_t i = 0; i < indent; ++i) | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |                 builder.append("  "sv); | 
					
						
							| 
									
										
										
										
											2024-01-12 21:25:05 +01:00
										 |  |  |             builder.appendff("  {}frag {}{} from {} ", | 
					
						
							|  |  |  |                 fragment_color_on, | 
					
						
							|  |  |  |                 fragment_index, | 
					
						
							| 
									
										
										
										
											2020-12-08 22:11:02 +01:00
										 |  |  |                 color_off, | 
					
						
							| 
									
										
										
										
											2024-01-12 21:25:05 +01:00
										 |  |  |                 fragment.layout_node().class_name()); | 
					
						
							|  |  |  |             builder.appendff("start: {}, length: {}, rect: {} baseline: {}\n", | 
					
						
							|  |  |  |                 fragment.start(), | 
					
						
							|  |  |  |                 fragment.length(), | 
					
						
							|  |  |  |                 fragment.absolute_rect(), | 
					
						
							|  |  |  |                 fragment.baseline()); | 
					
						
							|  |  |  |             if (is<Layout::TextNode>(fragment.layout_node())) { | 
					
						
							| 
									
										
										
										
											2020-02-25 14:49:47 +01:00
										 |  |  |                 for (size_t i = 0; i < indent; ++i) | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |                     builder.append("  "sv); | 
					
						
							| 
									
										
										
										
											2024-01-12 21:25:05 +01:00
										 |  |  |                 auto const& layout_text = static_cast<Layout::TextNode const&>(fragment.layout_node()); | 
					
						
							|  |  |  |                 auto fragment_text = MUST(layout_text.text_for_rendering().substring_from_byte_offset(fragment.start(), fragment.length())); | 
					
						
							|  |  |  |                 builder.appendff("      \"{}\"\n", fragment_text); | 
					
						
							| 
									
										
										
										
											2019-10-03 15:20:13 +02:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-15 19:41:35 +01:00
										 |  |  |     if (show_specified_style && layout_node.dom_node() && layout_node.dom_node()->is_element() && verify_cast<DOM::Element>(layout_node.dom_node())->computed_css_values()) { | 
					
						
							| 
									
										
										
										
											2020-12-07 19:36:13 +01:00
										 |  |  |         struct NameAndValue { | 
					
						
							| 
									
										
										
										
											2023-11-20 23:17:14 +13:00
										 |  |  |             String name; | 
					
						
							|  |  |  |             String value; | 
					
						
							| 
									
										
										
										
											2020-12-07 19:36:13 +01:00
										 |  |  |         }; | 
					
						
							|  |  |  |         Vector<NameAndValue> properties; | 
					
						
							| 
									
										
										
										
											2022-03-15 19:41:35 +01:00
										 |  |  |         verify_cast<DOM::Element>(*layout_node.dom_node()).computed_css_values()->for_each_property([&](auto property_id, auto& value) { | 
					
						
							| 
									
										
										
										
											2023-11-20 23:17:14 +13:00
										 |  |  |             properties.append({ MUST(String::from_utf8(CSS::string_from_property_id(property_id))), value.to_string() }); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:36:13 +01:00
										 |  |  |         }); | 
					
						
							|  |  |  |         quick_sort(properties, [](auto& a, auto& b) { return a.name < b.name; }); | 
					
						
							| 
									
										
										
										
											2020-06-14 18:47:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-07 19:36:13 +01:00
										 |  |  |         for (auto& property : properties) { | 
					
						
							|  |  |  |             for (size_t i = 0; i < indent; ++i) | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |                 builder.append("    "sv); | 
					
						
							| 
									
										
										
										
											2021-05-07 20:47:25 +02:00
										 |  |  |             builder.appendff("  ({}: {})\n", property.name, property.value); | 
					
						
							| 
									
										
										
										
											2020-12-07 19:36:13 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-06-14 18:47:21 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-09-21 15:32:17 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-28 21:17:34 +02:00
										 |  |  |     ++indent; | 
					
						
							| 
									
										
										
										
											2020-12-08 22:11:02 +01:00
										 |  |  |     layout_node.for_each_child([&](auto& child) { | 
					
						
							|  |  |  |         dump_tree(builder, child, show_box_model, show_specified_style, interactive); | 
					
						
							| 
									
										
										
										
											2019-06-28 21:17:34 +02:00
										 |  |  |     }); | 
					
						
							|  |  |  |     --indent; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-12 14:13:29 +01:00
										 |  |  | void dump_selector(CSS::Selector const& selector) | 
					
						
							| 
									
										
										
										
											2019-06-27 20:40:21 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-17 15:59:13 +01:00
										 |  |  |     StringBuilder builder; | 
					
						
							|  |  |  |     dump_selector(builder, selector); | 
					
						
							|  |  |  |     dbgln("{}", builder.string_view()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-08 16:19:20 +01:00
										 |  |  | static void dump_qualified_name(StringBuilder& builder, CSS::Selector::SimpleSelector::QualifiedName const& qualified_name) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     StringView namespace_type; | 
					
						
							|  |  |  |     switch (qualified_name.namespace_type) { | 
					
						
							|  |  |  |     case CSS::Selector::SimpleSelector::QualifiedName::NamespaceType::Default: | 
					
						
							|  |  |  |         namespace_type = "Default"sv; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case CSS::Selector::SimpleSelector::QualifiedName::NamespaceType::None: | 
					
						
							|  |  |  |         namespace_type = "None"sv; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case CSS::Selector::SimpleSelector::QualifiedName::NamespaceType::Any: | 
					
						
							|  |  |  |         namespace_type = "Any"sv; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case CSS::Selector::SimpleSelector::QualifiedName::NamespaceType::Named: | 
					
						
							|  |  |  |         namespace_type = "Named"sv; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     builder.appendff("NamespaceType={}, Namespace='{}', Name='{}'", namespace_type, qualified_name.namespace_, qualified_name.name.name); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-12 14:13:29 +01:00
										 |  |  | void dump_selector(StringBuilder& builder, CSS::Selector const& selector) | 
					
						
							| 
									
										
										
										
											2021-02-17 15:59:13 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |     builder.append("  CSS::Selector:\n"sv); | 
					
						
							| 
									
										
										
										
											2019-11-27 20:37:36 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-23 15:24:33 +01:00
										 |  |  |     for (auto& relative_selector : selector.compound_selectors()) { | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |         builder.append("    "sv); | 
					
						
							| 
									
										
										
										
											2020-03-29 22:24:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-12 14:13:29 +01:00
										 |  |  |         char const* relation_description = ""; | 
					
						
							| 
									
										
										
										
											2021-07-23 15:24:33 +01:00
										 |  |  |         switch (relative_selector.combinator) { | 
					
						
							|  |  |  |         case CSS::Selector::Combinator::None: | 
					
						
							| 
									
										
										
										
											2020-03-29 22:45:38 +02:00
										 |  |  |             relation_description = "None"; | 
					
						
							| 
									
										
										
										
											2020-03-29 22:24:23 +02:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2021-07-23 15:24:33 +01:00
										 |  |  |         case CSS::Selector::Combinator::ImmediateChild: | 
					
						
							| 
									
										
										
										
											2020-03-29 22:24:23 +02:00
										 |  |  |             relation_description = "ImmediateChild"; | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2021-07-23 15:24:33 +01:00
										 |  |  |         case CSS::Selector::Combinator::Descendant: | 
					
						
							| 
									
										
										
										
											2020-03-29 22:24:23 +02:00
										 |  |  |             relation_description = "Descendant"; | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2021-07-23 15:24:33 +01:00
										 |  |  |         case CSS::Selector::Combinator::NextSibling: | 
					
						
							| 
									
										
										
										
											2020-03-29 22:24:23 +02:00
										 |  |  |             relation_description = "AdjacentSibling"; | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2021-07-23 15:24:33 +01:00
										 |  |  |         case CSS::Selector::Combinator::SubsequentSibling: | 
					
						
							| 
									
										
										
										
											2020-03-29 22:24:23 +02:00
										 |  |  |             relation_description = "GeneralSibling"; | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2021-07-23 15:24:33 +01:00
										 |  |  |         case CSS::Selector::Combinator::Column: | 
					
						
							| 
									
										
										
										
											2021-04-29 21:16:28 +02:00
										 |  |  |             relation_description = "Column"; | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2020-03-29 22:24:23 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-11-27 20:37:36 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-29 22:24:23 +02:00
										 |  |  |         if (*relation_description) | 
					
						
							| 
									
										
										
										
											2021-02-17 15:59:13 +01:00
										 |  |  |             builder.appendff("{{{}}} ", relation_description); | 
					
						
							| 
									
										
										
										
											2020-03-29 22:24:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-23 15:24:33 +01:00
										 |  |  |         for (size_t i = 0; i < relative_selector.simple_selectors.size(); ++i) { | 
					
						
							|  |  |  |             auto& simple_selector = relative_selector.simple_selectors[i]; | 
					
						
							| 
									
										
										
										
											2021-07-12 14:13:29 +01:00
										 |  |  |             char const* type_description = "Unknown"; | 
					
						
							| 
									
										
										
										
											2020-03-29 22:24:23 +02:00
										 |  |  |             switch (simple_selector.type) { | 
					
						
							| 
									
										
										
										
											2020-07-26 20:01:35 +02:00
										 |  |  |             case CSS::Selector::SimpleSelector::Type::Universal: | 
					
						
							| 
									
										
										
										
											2020-03-29 22:24:23 +02:00
										 |  |  |                 type_description = "Universal"; | 
					
						
							| 
									
										
										
										
											2019-10-06 09:28:10 +02:00
										 |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2020-07-26 20:01:35 +02:00
										 |  |  |             case CSS::Selector::SimpleSelector::Type::Id: | 
					
						
							| 
									
										
										
										
											2020-03-29 22:24:23 +02:00
										 |  |  |                 type_description = "Id"; | 
					
						
							| 
									
										
										
										
											2019-10-06 11:05:57 +02:00
										 |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2020-07-26 20:01:35 +02:00
										 |  |  |             case CSS::Selector::SimpleSelector::Type::Class: | 
					
						
							| 
									
										
										
										
											2020-03-29 22:24:23 +02:00
										 |  |  |                 type_description = "Class"; | 
					
						
							| 
									
										
										
										
											2019-10-06 19:59:07 +02:00
										 |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2020-07-26 20:01:35 +02:00
										 |  |  |             case CSS::Selector::SimpleSelector::Type::TagName: | 
					
						
							| 
									
										
										
										
											2020-03-29 22:24:23 +02:00
										 |  |  |                 type_description = "TagName"; | 
					
						
							|  |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2021-07-12 14:58:03 +01:00
										 |  |  |             case CSS::Selector::SimpleSelector::Type::Attribute: | 
					
						
							|  |  |  |                 type_description = "Attribute"; | 
					
						
							| 
									
										
										
										
											2021-04-29 21:16:28 +02:00
										 |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2021-07-12 16:18:00 +01:00
										 |  |  |             case CSS::Selector::SimpleSelector::Type::PseudoClass: | 
					
						
							| 
									
										
										
										
											2023-08-11 21:26:04 +01:00
										 |  |  |                 type_description = "PseudoClassSelector"; | 
					
						
							| 
									
										
										
										
											2021-05-23 20:59:26 +02:00
										 |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2021-07-12 16:34:18 +01:00
										 |  |  |             case CSS::Selector::SimpleSelector::Type::PseudoElement: | 
					
						
							|  |  |  |                 type_description = "PseudoElement"; | 
					
						
							|  |  |  |                 break; | 
					
						
							| 
									
										
										
										
											2020-06-13 00:43:06 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-21 15:43:59 +00:00
										 |  |  |             builder.appendff("{}:", type_description); | 
					
						
							| 
									
										
										
										
											2023-08-08 16:19:20 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-21 15:43:59 +00:00
										 |  |  |             // FIXME: This is goofy
 | 
					
						
							| 
									
										
										
										
											2023-08-08 15:11:48 +01:00
										 |  |  |             if (simple_selector.value.has<CSS::Selector::SimpleSelector::Name>()) { | 
					
						
							| 
									
										
										
										
											2022-03-21 15:43:59 +00:00
										 |  |  |                 builder.append(simple_selector.name()); | 
					
						
							| 
									
										
										
										
											2023-08-08 15:11:48 +01:00
										 |  |  |             } else if (simple_selector.value.has<CSS::Selector::SimpleSelector::QualifiedName>()) { | 
					
						
							| 
									
										
										
										
											2023-08-08 16:19:20 +01:00
										 |  |  |                 dump_qualified_name(builder, simple_selector.qualified_name()); | 
					
						
							| 
									
										
										
										
											2023-08-08 15:11:48 +01:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2021-07-12 16:18:00 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (simple_selector.type == CSS::Selector::SimpleSelector::Type::PseudoClass) { | 
					
						
							| 
									
										
										
										
											2022-03-21 15:43:59 +00:00
										 |  |  |                 auto const& pseudo_class = simple_selector.pseudo_class(); | 
					
						
							| 
									
										
										
										
											2021-07-12 16:18:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-11 21:26:04 +01:00
										 |  |  |                 builder.appendff(" pseudo_class={}", CSS::pseudo_class_name(pseudo_class.type)); | 
					
						
							|  |  |  |                 auto pseudo_class_metadata = CSS::pseudo_class_metadata(pseudo_class.type); | 
					
						
							| 
									
										
										
										
											2021-07-12 16:18:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-11 21:26:04 +01:00
										 |  |  |                 switch (pseudo_class_metadata.parameter_type) { | 
					
						
							|  |  |  |                 case CSS::PseudoClassMetadata::ParameterType::None: | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 case CSS::PseudoClassMetadata::ParameterType::ANPlusB: | 
					
						
							|  |  |  |                 case CSS::PseudoClassMetadata::ParameterType::ANPlusBOf: { | 
					
						
							| 
									
										
										
										
											2022-03-17 19:13:51 +00:00
										 |  |  |                     builder.appendff("(step={}, offset={}", pseudo_class.nth_child_pattern.step_size, pseudo_class.nth_child_pattern.offset); | 
					
						
							|  |  |  |                     if (!pseudo_class.argument_selector_list.is_empty()) { | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |                         builder.append(", selectors=["sv); | 
					
						
							| 
									
										
										
										
											2022-03-17 19:13:51 +00:00
										 |  |  |                         for (auto const& child_selector : pseudo_class.argument_selector_list) | 
					
						
							|  |  |  |                             dump_selector(builder, child_selector); | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |                         builder.append("]"sv); | 
					
						
							| 
									
										
										
										
											2022-03-17 19:13:51 +00:00
										 |  |  |                     } | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |                     builder.append(")"sv); | 
					
						
							| 
									
										
										
										
											2023-08-11 21:26:04 +01:00
										 |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2023-08-12 13:47:45 +01:00
										 |  |  |                 case CSS::PseudoClassMetadata::ParameterType::CompoundSelector: | 
					
						
							| 
									
										
										
										
											2023-08-11 21:26:04 +01:00
										 |  |  |                 case CSS::PseudoClassMetadata::ParameterType::ForgivingSelectorList: | 
					
						
							|  |  |  |                 case CSS::PseudoClassMetadata::ParameterType::SelectorList: { | 
					
						
							|  |  |  |                     builder.append("(["sv); | 
					
						
							|  |  |  |                     for (auto& selector : pseudo_class.argument_selector_list) | 
					
						
							|  |  |  |                         dump_selector(builder, selector); | 
					
						
							|  |  |  |                     builder.append("])"sv); | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2023-08-12 18:11:50 +01:00
										 |  |  |                 case CSS::PseudoClassMetadata::ParameterType::Ident: | 
					
						
							|  |  |  |                     builder.appendff("(ident={})", string_from_value_id(pseudo_class.identifier.value())); | 
					
						
							|  |  |  |                     break; | 
					
						
							| 
									
										
										
										
											2023-08-11 21:26:04 +01:00
										 |  |  |                 case CSS::PseudoClassMetadata::ParameterType::LanguageRanges: { | 
					
						
							|  |  |  |                     builder.append('('); | 
					
						
							|  |  |  |                     builder.join(',', pseudo_class.languages); | 
					
						
							|  |  |  |                     builder.append(')'); | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2021-07-12 16:18:00 +01:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2021-07-12 14:58:03 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-12 16:34:18 +01:00
										 |  |  |             if (simple_selector.type == CSS::Selector::SimpleSelector::Type::PseudoElement) { | 
					
						
							| 
									
										
										
										
											2023-12-10 21:00:03 +13:00
										 |  |  |                 builder.appendff(" pseudo_element={}", simple_selector.pseudo_element().name()); | 
					
						
							| 
									
										
										
										
											2021-07-12 16:34:18 +01:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-12 14:58:03 +01:00
										 |  |  |             if (simple_selector.type == CSS::Selector::SimpleSelector::Type::Attribute) { | 
					
						
							| 
									
										
										
										
											2022-03-21 15:43:59 +00:00
										 |  |  |                 auto const& attribute = simple_selector.attribute(); | 
					
						
							| 
									
										
										
										
											2021-07-12 14:58:03 +01:00
										 |  |  |                 char const* attribute_match_type_description = ""; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-21 15:43:59 +00:00
										 |  |  |                 switch (attribute.match_type) { | 
					
						
							| 
									
										
										
										
											2021-07-12 14:58:03 +01:00
										 |  |  |                 case CSS::Selector::SimpleSelector::Attribute::MatchType::HasAttribute: | 
					
						
							| 
									
										
										
										
											2021-07-24 13:28:45 +01:00
										 |  |  |                     attribute_match_type_description = "HasAttribute"; | 
					
						
							| 
									
										
										
										
											2021-07-12 14:58:03 +01:00
										 |  |  |                     break; | 
					
						
							|  |  |  |                 case CSS::Selector::SimpleSelector::Attribute::MatchType::ExactValueMatch: | 
					
						
							| 
									
										
										
										
											2021-07-24 13:28:45 +01:00
										 |  |  |                     attribute_match_type_description = "ExactValueMatch"; | 
					
						
							| 
									
										
										
										
											2021-07-12 14:58:03 +01:00
										 |  |  |                     break; | 
					
						
							|  |  |  |                 case CSS::Selector::SimpleSelector::Attribute::MatchType::ContainsWord: | 
					
						
							| 
									
										
										
										
											2021-07-24 13:28:45 +01:00
										 |  |  |                     attribute_match_type_description = "ContainsWord"; | 
					
						
							| 
									
										
										
										
											2021-07-12 14:58:03 +01:00
										 |  |  |                     break; | 
					
						
							|  |  |  |                 case CSS::Selector::SimpleSelector::Attribute::MatchType::ContainsString: | 
					
						
							| 
									
										
										
										
											2021-07-24 13:28:45 +01:00
										 |  |  |                     attribute_match_type_description = "ContainsString"; | 
					
						
							| 
									
										
										
										
											2021-07-12 14:58:03 +01:00
										 |  |  |                     break; | 
					
						
							|  |  |  |                 case CSS::Selector::SimpleSelector::Attribute::MatchType::StartsWithSegment: | 
					
						
							| 
									
										
										
										
											2021-07-24 13:28:45 +01:00
										 |  |  |                     attribute_match_type_description = "StartsWithSegment"; | 
					
						
							| 
									
										
										
										
											2021-07-12 14:58:03 +01:00
										 |  |  |                     break; | 
					
						
							|  |  |  |                 case CSS::Selector::SimpleSelector::Attribute::MatchType::StartsWithString: | 
					
						
							| 
									
										
										
										
											2021-07-24 13:28:45 +01:00
										 |  |  |                     attribute_match_type_description = "StartsWithString"; | 
					
						
							| 
									
										
										
										
											2021-07-12 14:58:03 +01:00
										 |  |  |                     break; | 
					
						
							|  |  |  |                 case CSS::Selector::SimpleSelector::Attribute::MatchType::EndsWithString: | 
					
						
							| 
									
										
										
										
											2021-07-24 13:28:45 +01:00
										 |  |  |                     attribute_match_type_description = "EndsWithString"; | 
					
						
							| 
									
										
										
										
											2021-07-12 14:58:03 +01:00
										 |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-08 16:19:20 +01:00
										 |  |  |                 builder.appendff(" [{}, ", attribute_match_type_description); | 
					
						
							|  |  |  |                 dump_qualified_name(builder, attribute.qualified_name); | 
					
						
							|  |  |  |                 builder.appendff(", value='{}']", attribute.value); | 
					
						
							| 
									
										
										
										
											2019-11-21 20:07:43 +01:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2020-03-29 22:24:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-23 15:24:33 +01:00
										 |  |  |             if (i != relative_selector.simple_selectors.size() - 1) | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |                 builder.append(", "sv); | 
					
						
							| 
									
										
										
										
											2019-06-27 20:40:21 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |         builder.append("\n"sv); | 
					
						
							| 
									
										
										
										
											2020-03-29 22:24:23 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 20:10:00 +01:00
										 |  |  | ErrorOr<void> dump_rule(CSS::CSSRule const& rule) | 
					
						
							| 
									
										
										
										
											2020-03-29 22:24:23 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-17 15:59:13 +01:00
										 |  |  |     StringBuilder builder; | 
					
						
							| 
									
										
										
										
											2023-01-13 20:10:00 +01:00
										 |  |  |     TRY(dump_rule(builder, rule)); | 
					
						
							| 
									
										
										
										
											2021-02-17 15:59:13 +01:00
										 |  |  |     dbgln("{}", builder.string_view()); | 
					
						
							| 
									
										
										
										
											2023-01-13 20:10:00 +01:00
										 |  |  |     return {}; | 
					
						
							| 
									
										
										
										
											2021-02-17 15:59:13 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 20:10:00 +01:00
										 |  |  | ErrorOr<void> dump_rule(StringBuilder& builder, CSS::CSSRule const& rule, int indent_levels) | 
					
						
							| 
									
										
										
										
											2021-02-21 13:45:26 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-29 12:48:04 +01:00
										 |  |  |     indent(builder, indent_levels); | 
					
						
							| 
									
										
										
										
											2021-02-21 13:45:26 +02:00
										 |  |  |     builder.appendff("{}:\n", rule.class_name()); | 
					
						
							| 
									
										
										
										
											2021-09-29 12:48:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-21 13:45:26 +02:00
										 |  |  |     switch (rule.type()) { | 
					
						
							| 
									
										
										
										
											2022-03-28 20:30:26 +01:00
										 |  |  |     case CSS::CSSRule::Type::FontFace: | 
					
						
							|  |  |  |         dump_font_face_rule(builder, verify_cast<CSS::CSSFontFaceRule const>(rule), indent_levels); | 
					
						
							| 
									
										
										
										
											2021-02-21 13:45:26 +02:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2021-02-21 18:36:34 +02:00
										 |  |  |     case CSS::CSSRule::Type::Import: | 
					
						
							| 
									
										
										
										
											2021-09-29 12:48:04 +01:00
										 |  |  |         dump_import_rule(builder, verify_cast<CSS::CSSImportRule const>(rule), indent_levels); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case CSS::CSSRule::Type::Media: | 
					
						
							| 
									
										
										
										
											2023-01-13 20:10:00 +01:00
										 |  |  |         TRY(dump_media_rule(builder, verify_cast<CSS::CSSMediaRule const>(rule), indent_levels)); | 
					
						
							| 
									
										
										
										
											2021-02-21 18:36:34 +02:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2022-03-28 20:30:26 +01:00
										 |  |  |     case CSS::CSSRule::Type::Style: | 
					
						
							| 
									
										
										
										
											2023-01-13 20:10:00 +01:00
										 |  |  |         TRY(dump_style_rule(builder, verify_cast<CSS::CSSStyleRule const>(rule), indent_levels)); | 
					
						
							| 
									
										
										
										
											2022-03-28 20:30:26 +01:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2021-10-08 17:48:14 +01:00
										 |  |  |     case CSS::CSSRule::Type::Supports: | 
					
						
							| 
									
										
										
										
											2023-01-13 20:10:00 +01:00
										 |  |  |         TRY(dump_supports_rule(builder, verify_cast<CSS::CSSSupportsRule const>(rule), indent_levels)); | 
					
						
							| 
									
										
										
										
											2021-10-08 17:48:14 +01:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2023-05-26 23:30:54 +03:30
										 |  |  |     case CSS::CSSRule::Type::Keyframe: | 
					
						
							|  |  |  |     case CSS::CSSRule::Type::Keyframes: | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2023-07-29 11:51:15 -05:00
										 |  |  |     case CSS::CSSRule::Type::Namespace: | 
					
						
							|  |  |  |         TRY(dump_namespace_rule(builder, verify_cast<CSS::CSSNamespaceRule const>(rule), indent_levels)); | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2021-02-21 13:45:26 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-01-13 20:10:00 +01:00
										 |  |  |     return {}; | 
					
						
							| 
									
										
										
										
											2021-02-21 13:45:26 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-28 20:30:26 +01:00
										 |  |  | void dump_font_face_rule(StringBuilder& builder, CSS::CSSFontFaceRule const& rule, int indent_levels) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto& font_face = rule.font_face(); | 
					
						
							|  |  |  |     indent(builder, indent_levels + 1); | 
					
						
							|  |  |  |     builder.appendff("font-family: {}\n", font_face.font_family()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-24 19:59:31 +02:00
										 |  |  |     if (font_face.weight().has_value()) { | 
					
						
							|  |  |  |         indent(builder, indent_levels + 1); | 
					
						
							|  |  |  |         builder.appendff("weight: {}\n", font_face.weight().value()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (font_face.slope().has_value()) { | 
					
						
							|  |  |  |         indent(builder, indent_levels + 1); | 
					
						
							|  |  |  |         builder.appendff("slope: {}\n", font_face.slope().value()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-28 20:30:26 +01:00
										 |  |  |     indent(builder, indent_levels + 1); | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |     builder.append("sources:\n"sv); | 
					
						
							| 
									
										
										
										
											2022-03-28 20:30:26 +01:00
										 |  |  |     for (auto const& source : font_face.sources()) { | 
					
						
							|  |  |  |         indent(builder, indent_levels + 2); | 
					
						
							| 
									
										
										
										
											2023-08-25 10:52:20 +02:00
										 |  |  |         if (source.local_or_url.has<AK::URL>()) | 
					
						
							|  |  |  |             builder.appendff("url={}, format={}\n", source.local_or_url.get<AK::URL>(), source.format.value_or("???"_string)); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             builder.appendff("local={}\n", source.local_or_url.get<AK::String>()); | 
					
						
							| 
									
										
										
										
											2022-03-28 20:30:26 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-03-31 16:39:52 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     indent(builder, indent_levels + 1); | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |     builder.append("unicode-ranges:\n"sv); | 
					
						
							| 
									
										
										
										
											2022-03-31 16:39:52 +01:00
										 |  |  |     for (auto const& unicode_range : font_face.unicode_ranges()) { | 
					
						
							|  |  |  |         indent(builder, indent_levels + 2); | 
					
						
							| 
									
										
										
										
											2023-08-22 12:25:30 +01:00
										 |  |  |         builder.appendff("{}\n", unicode_range.to_string()); | 
					
						
							| 
									
										
										
										
											2022-03-31 16:39:52 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-03-28 20:30:26 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-29 12:48:04 +01:00
										 |  |  | void dump_import_rule(StringBuilder& builder, CSS::CSSImportRule const& rule, int indent_levels) | 
					
						
							| 
									
										
										
										
											2021-02-21 18:36:34 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-09-29 12:48:04 +01:00
										 |  |  |     indent(builder, indent_levels); | 
					
						
							| 
									
										
										
										
											2021-02-21 18:36:34 +02:00
										 |  |  |     builder.appendff("  Document URL: {}\n", rule.url()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 20:10:00 +01:00
										 |  |  | ErrorOr<void> dump_media_rule(StringBuilder& builder, CSS::CSSMediaRule const& media, int indent_levels) | 
					
						
							| 
									
										
										
										
											2021-09-29 12:48:04 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     indent(builder, indent_levels); | 
					
						
							|  |  |  |     builder.appendff("  Media: {}\n  Rules ({}):\n", media.condition_text(), media.css_rules().length()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 20:10:00 +01:00
										 |  |  |     for (auto& rule : media.css_rules()) | 
					
						
							|  |  |  |         TRY(dump_rule(builder, rule, indent_levels + 1)); | 
					
						
							|  |  |  |     return {}; | 
					
						
							| 
									
										
										
										
											2021-09-29 12:48:04 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 20:10:00 +01:00
										 |  |  | ErrorOr<void> dump_supports_rule(StringBuilder& builder, CSS::CSSSupportsRule const& supports, int indent_levels) | 
					
						
							| 
									
										
										
										
											2021-10-08 17:48:14 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     indent(builder, indent_levels); | 
					
						
							|  |  |  |     builder.appendff("  Supports: {}\n  Rules ({}):\n", supports.condition_text(), supports.css_rules().length()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 20:10:00 +01:00
										 |  |  |     for (auto& rule : supports.css_rules()) | 
					
						
							|  |  |  |         TRY(dump_rule(builder, rule, indent_levels + 1)); | 
					
						
							|  |  |  |     return {}; | 
					
						
							| 
									
										
										
										
											2021-10-08 17:48:14 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 20:10:00 +01:00
										 |  |  | ErrorOr<void> dump_style_rule(StringBuilder& builder, CSS::CSSStyleRule const& rule, int indent_levels) | 
					
						
							| 
									
										
										
										
											2021-02-17 15:59:13 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-03-29 22:24:23 +02:00
										 |  |  |     for (auto& selector : rule.selectors()) { | 
					
						
							| 
									
										
										
										
											2021-02-17 15:59:13 +01:00
										 |  |  |         dump_selector(builder, selector); | 
					
						
							| 
									
										
										
										
											2019-06-27 20:40:21 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-09-29 12:48:04 +01:00
										 |  |  |     indent(builder, indent_levels); | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |     builder.append("  Declarations:\n"sv); | 
					
						
							| 
									
										
										
										
											2021-11-30 16:23:35 +00:00
										 |  |  |     auto& style_declaration = verify_cast<CSS::PropertyOwningCSSStyleDeclaration>(rule.declaration()); | 
					
						
							|  |  |  |     for (auto& property : style_declaration.properties()) { | 
					
						
							| 
									
										
										
										
											2021-09-29 12:48:04 +01:00
										 |  |  |         indent(builder, indent_levels); | 
					
						
							| 
									
										
										
										
											2023-08-22 14:08:15 +01:00
										 |  |  |         builder.appendff("    {}: '{}'", CSS::string_from_property_id(property.property_id), property.value->to_string()); | 
					
						
							| 
									
										
										
										
											2022-02-12 14:53:59 +00:00
										 |  |  |         if (property.important == CSS::Important::Yes) | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |             builder.append(" \033[31;1m!important\033[0m"sv); | 
					
						
							| 
									
										
										
										
											2021-09-21 11:29:44 +02:00
										 |  |  |         builder.append('\n'); | 
					
						
							| 
									
										
										
										
											2019-06-27 20:40:21 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-11-30 16:23:35 +00:00
										 |  |  |     for (auto& property : style_declaration.custom_properties()) { | 
					
						
							|  |  |  |         indent(builder, indent_levels); | 
					
						
							| 
									
										
										
										
											2023-08-22 14:08:15 +01:00
										 |  |  |         builder.appendff("    {}: '{}'", property.key, property.value.value->to_string()); | 
					
						
							| 
									
										
										
										
											2022-02-12 14:53:59 +00:00
										 |  |  |         if (property.value.important == CSS::Important::Yes) | 
					
						
							| 
									
										
										
										
											2022-07-11 17:32:29 +00:00
										 |  |  |             builder.append(" \033[31;1m!important\033[0m"sv); | 
					
						
							| 
									
										
										
										
											2021-11-30 16:23:35 +00:00
										 |  |  |         builder.append('\n'); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-01-13 20:10:00 +01:00
										 |  |  |     return {}; | 
					
						
							| 
									
										
										
										
											2019-06-27 20:40:21 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 20:10:00 +01:00
										 |  |  | ErrorOr<void> dump_sheet(CSS::StyleSheet const& sheet) | 
					
						
							| 
									
										
										
										
											2019-06-21 20:54:13 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-17 15:59:13 +01:00
										 |  |  |     StringBuilder builder; | 
					
						
							| 
									
										
										
										
											2023-01-13 20:10:00 +01:00
										 |  |  |     TRY(dump_sheet(builder, sheet)); | 
					
						
							| 
									
										
										
										
											2021-02-17 15:59:13 +01:00
										 |  |  |     dbgln("{}", builder.string_view()); | 
					
						
							| 
									
										
										
										
											2023-01-13 20:10:00 +01:00
										 |  |  |     return {}; | 
					
						
							| 
									
										
										
										
											2021-02-17 15:59:13 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 20:10:00 +01:00
										 |  |  | ErrorOr<void> dump_sheet(StringBuilder& builder, CSS::StyleSheet const& sheet) | 
					
						
							| 
									
										
										
										
											2021-02-17 15:59:13 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2021-06-24 21:13:09 +02:00
										 |  |  |     auto& css_stylesheet = verify_cast<CSS::CSSStyleSheet>(sheet); | 
					
						
							| 
									
										
										
										
											2019-06-25 06:31:47 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-28 16:18:20 +01:00
										 |  |  |     builder.appendff("CSSStyleSheet{{{}}}: {} rule(s)\n", &sheet, css_stylesheet.rules().length()); | 
					
						
							| 
									
										
										
										
											2021-03-07 16:14:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-13 20:10:00 +01:00
										 |  |  |     for (auto& rule : css_stylesheet.rules()) | 
					
						
							|  |  |  |         TRY(dump_rule(builder, rule)); | 
					
						
							|  |  |  |     return {}; | 
					
						
							| 
									
										
										
										
											2019-06-21 20:54:13 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-03-07 10:27:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-18 20:22:58 +01:00
										 |  |  | void dump_tree(Painting::Paintable const& paintable) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     StringBuilder builder; | 
					
						
							|  |  |  |     dump_tree(builder, paintable, true); | 
					
						
							|  |  |  |     dbgln("{}", builder.string_view()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void dump_tree(StringBuilder& builder, Painting::Paintable const& paintable, bool colorize, int indent) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for (int i = 0; i < indent; ++i) | 
					
						
							|  |  |  |         builder.append("  "sv); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     StringView paintable_with_lines_color_on = ""sv; | 
					
						
							|  |  |  |     StringView paintable_box_color_on = ""sv; | 
					
						
							|  |  |  |     StringView text_paintable_color_on = ""sv; | 
					
						
							|  |  |  |     StringView paintable_color_on = ""sv; | 
					
						
							|  |  |  |     StringView color_off = ""sv; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (colorize) { | 
					
						
							|  |  |  |         paintable_with_lines_color_on = "\033[34m"sv; | 
					
						
							|  |  |  |         paintable_box_color_on = "\033[33m"sv; | 
					
						
							|  |  |  |         text_paintable_color_on = "\033[35m"sv; | 
					
						
							|  |  |  |         paintable_color_on = "\033[32m"sv; | 
					
						
							|  |  |  |         color_off = "\033[0m"sv; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (is<Painting::PaintableWithLines>(paintable)) | 
					
						
							|  |  |  |         builder.append(paintable_with_lines_color_on); | 
					
						
							|  |  |  |     else if (is<Painting::PaintableBox>(paintable)) | 
					
						
							|  |  |  |         builder.append(paintable_box_color_on); | 
					
						
							|  |  |  |     else if (is<Painting::TextPaintable>(paintable)) | 
					
						
							|  |  |  |         builder.append(text_paintable_color_on); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         builder.append(paintable_color_on); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     builder.appendff("{}{} ({})", paintable.class_name(), color_off, paintable.layout_node().debug_description()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (paintable.layout_node().is_box()) { | 
					
						
							| 
									
										
										
										
											2023-04-20 16:02:16 +01:00
										 |  |  |         auto const& paintable_box = static_cast<Painting::PaintableBox const&>(paintable); | 
					
						
							|  |  |  |         builder.appendff(" {}", paintable_box.absolute_border_box_rect()); | 
					
						
							| 
									
										
										
										
											2023-05-29 07:23:23 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-12 18:55:23 +02:00
										 |  |  |         if (paintable_box.has_scrollable_overflow()) { | 
					
						
							|  |  |  |             builder.appendff(" overflow: {}", paintable_box.scrollable_overflow_rect()); | 
					
						
							| 
									
										
										
										
											2023-05-29 07:23:23 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-08-06 21:34:07 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (!paintable_box.scroll_offset().is_zero()) { | 
					
						
							|  |  |  |             builder.appendff(" scroll-offset: {}", paintable_box.scroll_offset()); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-03-18 20:22:58 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     builder.append("\n"sv); | 
					
						
							|  |  |  |     for (auto const* child = paintable.first_child(); child; child = child->next_sibling()) { | 
					
						
							|  |  |  |         dump_tree(builder, *child, colorize, indent + 1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-29 11:51:15 -05:00
										 |  |  | ErrorOr<void> dump_namespace_rule(StringBuilder& builder, CSS::CSSNamespaceRule const& namespace_, int indent_levels) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     indent(builder, indent_levels); | 
					
						
							|  |  |  |     TRY(builder.try_appendff("  Namespace: {}\n", namespace_.namespace_uri())); | 
					
						
							| 
									
										
										
										
											2023-10-10 15:00:58 +03:30
										 |  |  |     if (!namespace_.prefix().is_empty()) | 
					
						
							| 
									
										
										
										
											2023-07-29 11:51:15 -05:00
										 |  |  |         TRY(builder.try_appendff("  Prefix: {}\n", namespace_.prefix())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return {}; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-03-07 10:27:02 +01:00
										 |  |  | } |