LayoutTreeBuilder.cpp 2.0 KB

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