HTMLTableElement.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /*
  2. * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibWeb/CSS/Parser/DeprecatedCSSParser.h>
  7. #include <LibWeb/DOM/ElementFactory.h>
  8. #include <LibWeb/DOM/HTMLCollection.h>
  9. #include <LibWeb/HTML/HTMLTableElement.h>
  10. #include <LibWeb/HTML/HTMLTableRowElement.h>
  11. #include <LibWeb/Namespace.h>
  12. namespace Web::HTML {
  13. HTMLTableElement::HTMLTableElement(DOM::Document& document, QualifiedName qualified_name)
  14. : HTMLElement(document, move(qualified_name))
  15. {
  16. }
  17. HTMLTableElement::~HTMLTableElement()
  18. {
  19. }
  20. void HTMLTableElement::apply_presentational_hints(CSS::StyleProperties& style) const
  21. {
  22. for_each_attribute([&](auto& name, auto& value) {
  23. if (name == HTML::AttributeNames::width) {
  24. if (auto parsed_value = parse_html_length(document(), value))
  25. style.set_property(CSS::PropertyID::Width, parsed_value.release_nonnull());
  26. return;
  27. }
  28. if (name == HTML::AttributeNames::height) {
  29. if (auto parsed_value = parse_html_length(document(), value))
  30. style.set_property(CSS::PropertyID::Height, parsed_value.release_nonnull());
  31. return;
  32. }
  33. if (name == HTML::AttributeNames::bgcolor) {
  34. auto color = Color::from_string(value);
  35. if (color.has_value())
  36. style.set_property(CSS::PropertyID::BackgroundColor, CSS::ColorStyleValue::create(color.value()));
  37. return;
  38. }
  39. });
  40. }
  41. NonnullRefPtr<DOM::HTMLCollection> HTMLTableElement::rows()
  42. {
  43. HTMLTableElement* table_node = this;
  44. // FIXME: The elements in the collection must be ordered such that those elements whose parent is a thead are
  45. // included first, in tree order, followed by those elements whose parent is either a table or tbody
  46. // element, again in tree order, followed finally by those elements whose parent is a tfoot element,
  47. // still in tree order.
  48. // How do you sort HTMLCollection?
  49. return DOM::HTMLCollection::create(*this, [table_node](DOM::Element const& element) {
  50. // Only match TR elements which are:
  51. // * children of the table element
  52. // * children of the thead, tbody, or tfoot elements that are themselves children of the table element
  53. if (!is<HTMLTableRowElement>(element)) {
  54. return false;
  55. }
  56. if (element.parent_element() == table_node)
  57. return true;
  58. if (element.parent_element() && (element.parent_element()->tag_name() == TagNames::thead || element.parent_element()->tag_name() == TagNames::tbody || element.parent_element()->tag_name() == TagNames::tfoot)
  59. && element.parent()->parent() == table_node) {
  60. return true;
  61. }
  62. return false;
  63. });
  64. }
  65. DOM::ExceptionOr<NonnullRefPtr<HTMLTableRowElement>> HTMLTableElement::insert_row(long index)
  66. {
  67. auto rows = this->rows();
  68. auto rows_length = rows->length();
  69. if (index < -1 || index >= (long)rows_length) {
  70. return DOM::IndexSizeError::create("Index is negative or greater than the number of rows");
  71. }
  72. auto tr = static_cast<NonnullRefPtr<HTMLTableRowElement>>(DOM::create_element(document(), TagNames::tr, Namespace::HTML));
  73. if (rows_length == 0 && !has_child_of_type<HTMLTableRowElement>()) {
  74. auto tbody = DOM::create_element(document(), TagNames::tbody, Namespace::HTML);
  75. tbody->append_child(tr);
  76. append_child(tbody);
  77. } else if (rows_length == 0) {
  78. auto tbody = last_child_of_type<HTMLTableRowElement>();
  79. tbody->append_child(tr);
  80. } else if (index == -1 || index == (long)rows_length) {
  81. auto parent_of_last_tr = rows->item(rows_length - 1)->parent_element();
  82. parent_of_last_tr->append_child(tr);
  83. } else {
  84. rows->item(index)->parent_element()->insert_before(tr, rows->item(index));
  85. }
  86. return tr;
  87. }
  88. DOM::ExceptionOr<void> HTMLTableElement::delete_row(long index)
  89. {
  90. auto rows = this->rows();
  91. auto rows_length = rows->length();
  92. if (index < -1 || index >= (long)rows_length) {
  93. return DOM::IndexSizeError::create("Index is negative or greater than the number of rows");
  94. }
  95. if (index == -1 && rows_length > 0) {
  96. auto row_to_remove = rows->item(rows_length - 1);
  97. row_to_remove->remove(false);
  98. } else {
  99. auto row_to_remove = rows->item(index);
  100. row_to_remove->remove(false);
  101. }
  102. return {};
  103. }
  104. }