HTMLProgressElement.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /*
  2. * Copyright (c) 2020-2022, the SerenityOS developers.
  3. * Copyright (c) 2022, MacDue <macdue@dueutil.tech>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <LibWeb/DOM/Document.h>
  8. #include <LibWeb/DOM/ShadowRoot.h>
  9. #include <LibWeb/HTML/HTMLProgressElement.h>
  10. #include <LibWeb/HTML/Numbers.h>
  11. #include <LibWeb/Layout/BlockContainer.h>
  12. #include <LibWeb/Layout/Node.h>
  13. #include <LibWeb/Layout/Progress.h>
  14. namespace Web::HTML {
  15. JS_DEFINE_ALLOCATOR(HTMLProgressElement);
  16. HTMLProgressElement::HTMLProgressElement(DOM::Document& document, DOM::QualifiedName qualified_name)
  17. : HTMLElement(document, move(qualified_name))
  18. {
  19. }
  20. HTMLProgressElement::~HTMLProgressElement() = default;
  21. void HTMLProgressElement::initialize(JS::Realm& realm)
  22. {
  23. Base::initialize(realm);
  24. set_prototype(&Bindings::ensure_web_prototype<Bindings::HTMLProgressElementPrototype>(realm, "HTMLProgressElement"_fly_string));
  25. }
  26. JS::GCPtr<Layout::Node> HTMLProgressElement::create_layout_node(NonnullRefPtr<CSS::StyleProperties> style)
  27. {
  28. if (style->appearance().value_or(CSS::Appearance::Auto) == CSS::Appearance::None)
  29. return HTMLElement::create_layout_node(style);
  30. return heap().allocate_without_realm<Layout::Progress>(document(), *this, move(style));
  31. }
  32. bool HTMLProgressElement::using_system_appearance() const
  33. {
  34. if (layout_node())
  35. return is<Layout::Progress>(*layout_node());
  36. return false;
  37. }
  38. void HTMLProgressElement::progress_position_updated()
  39. {
  40. if (using_system_appearance())
  41. layout_node()->set_needs_display();
  42. else
  43. document().invalidate_layout();
  44. }
  45. // https://html.spec.whatwg.org/multipage/form-elements.html#dom-progress-value
  46. double HTMLProgressElement::value() const
  47. {
  48. auto maybe_value_string = get_attribute(HTML::AttributeNames::value);
  49. if (!maybe_value_string.has_value())
  50. return 0;
  51. auto maybe_value = parse_floating_point_number(maybe_value_string.value());
  52. if (!maybe_value.has_value())
  53. return 0;
  54. return clamp(maybe_value.value(), 0, max());
  55. }
  56. WebIDL::ExceptionOr<void> HTMLProgressElement::set_value(double value)
  57. {
  58. if (value < 0 || value > max())
  59. return {};
  60. TRY(set_attribute(HTML::AttributeNames::value, MUST(String::number(value))));
  61. progress_position_updated();
  62. return {};
  63. }
  64. // https://html.spec.whatwg.org/multipage/form-elements.html#dom-progress-max
  65. double HTMLProgressElement::max() const
  66. {
  67. auto maybe_max_string = get_attribute(HTML::AttributeNames::max);
  68. if (!maybe_max_string.has_value())
  69. return 1;
  70. auto maybe_max = parse_floating_point_number(maybe_max_string.value());
  71. if (!maybe_max.has_value())
  72. return 1;
  73. return AK::max(maybe_max.value(), 0);
  74. }
  75. WebIDL::ExceptionOr<void> HTMLProgressElement::set_max(double value)
  76. {
  77. if (value <= 0)
  78. return {};
  79. TRY(set_attribute(HTML::AttributeNames::max, MUST(String::number(value))));
  80. progress_position_updated();
  81. return {};
  82. }
  83. double HTMLProgressElement::position() const
  84. {
  85. if (!is_determinate())
  86. return -1;
  87. return value() / max();
  88. }
  89. }