LayoutTreeBuilder.cpp 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. #include <LibHTML/DOM/Document.h>
  2. #include <LibHTML/DOM/ParentNode.h>
  3. #include <LibHTML/Layout/LayoutNode.h>
  4. #include <LibHTML/Layout/LayoutText.h>
  5. #include <LibHTML/Layout/LayoutTreeBuilder.h>
  6. LayoutTreeBuilder::LayoutTreeBuilder()
  7. {
  8. }
  9. static RefPtr<LayoutNode> create_layout_tree(Node& node, const StyleProperties* parent_style)
  10. {
  11. auto layout_node = node.create_layout_node(parent_style);
  12. if (!layout_node)
  13. return nullptr;
  14. if (!node.has_children())
  15. return layout_node;
  16. NonnullRefPtrVector<LayoutNode> layout_children;
  17. bool have_inline_children = false;
  18. bool have_block_children = false;
  19. to<ParentNode>(node).for_each_child([&](Node& child) {
  20. auto layout_child = create_layout_tree(child, &layout_node->style());
  21. if (!layout_child)
  22. return;
  23. if (layout_child->is_inline())
  24. have_inline_children = true;
  25. if (layout_child->is_block())
  26. have_block_children = true;
  27. layout_children.append(layout_child.release_nonnull());
  28. });
  29. for (auto& layout_child : layout_children) {
  30. if (have_block_children && have_inline_children && layout_child.is_inline()) {
  31. if (is<LayoutText>(layout_child) && to<LayoutText>(layout_child).text_for_style(*parent_style) == " ")
  32. continue;
  33. layout_node->inline_wrapper().append_child(layout_child);
  34. } else {
  35. layout_node->append_child(layout_child);
  36. }
  37. }
  38. if (have_inline_children && !have_block_children)
  39. layout_node->set_children_are_inline(true);
  40. return layout_node;
  41. }
  42. RefPtr<LayoutNode> LayoutTreeBuilder::build(Node& node)
  43. {
  44. // FIXME: Support building partial trees.
  45. ASSERT(is<Document>(node));
  46. return create_layout_tree(node, nullptr);
  47. }