HTMLProgressElement.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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/Layout/BlockContainer.h>
  11. #include <LibWeb/Layout/Node.h>
  12. #include <LibWeb/Layout/Progress.h>
  13. namespace Web::HTML {
  14. JS_DEFINE_ALLOCATOR(HTMLProgressElement);
  15. HTMLProgressElement::HTMLProgressElement(DOM::Document& document, DOM::QualifiedName qualified_name)
  16. : HTMLElement(document, move(qualified_name))
  17. {
  18. }
  19. HTMLProgressElement::~HTMLProgressElement() = default;
  20. void HTMLProgressElement::initialize(JS::Realm& realm)
  21. {
  22. Base::initialize(realm);
  23. set_prototype(&Bindings::ensure_web_prototype<Bindings::HTMLProgressElementPrototype>(realm, "HTMLProgressElement"));
  24. }
  25. JS::GCPtr<Layout::Node> HTMLProgressElement::create_layout_node(NonnullRefPtr<CSS::StyleProperties> style)
  26. {
  27. if (style->appearance().value_or(CSS::Appearance::Auto) == CSS::Appearance::None)
  28. return HTMLElement::create_layout_node(style);
  29. return heap().allocate_without_realm<Layout::Progress>(document(), *this, move(style));
  30. }
  31. bool HTMLProgressElement::using_system_appearance() const
  32. {
  33. if (layout_node())
  34. return is<Layout::Progress>(*layout_node());
  35. return false;
  36. }
  37. void HTMLProgressElement::progress_position_updated()
  38. {
  39. if (using_system_appearance())
  40. layout_node()->set_needs_display();
  41. else
  42. document().invalidate_layout();
  43. }
  44. double HTMLProgressElement::value() const
  45. {
  46. auto const& value_characters = deprecated_attribute(HTML::AttributeNames::value);
  47. if (value_characters == nullptr)
  48. return 0;
  49. // https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#rules-for-parsing-floating-point-number-values
  50. // 6. Skip ASCII whitespace within input given position.
  51. auto maybe_double = value_characters.to_double(AK::TrimWhitespace::Yes);
  52. if (!maybe_double.has_value())
  53. return 0;
  54. if (!isfinite(maybe_double.value()) || maybe_double.value() < 0)
  55. return 0;
  56. return min(maybe_double.value(), max());
  57. }
  58. WebIDL::ExceptionOr<void> HTMLProgressElement::set_value(double value)
  59. {
  60. if (value < 0)
  61. return {};
  62. TRY(set_attribute(HTML::AttributeNames::value, MUST(String::number(value))));
  63. progress_position_updated();
  64. return {};
  65. }
  66. double HTMLProgressElement::max() const
  67. {
  68. auto const& max_characters = deprecated_attribute(HTML::AttributeNames::max);
  69. if (max_characters == nullptr)
  70. return 1;
  71. // https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#rules-for-parsing-floating-point-number-values
  72. // 6. Skip ASCII whitespace within input given position.
  73. auto double_or_none = max_characters.to_double(AK::TrimWhitespace::Yes);
  74. if (!double_or_none.has_value())
  75. return 1;
  76. if (!isfinite(double_or_none.value()) || double_or_none.value() <= 0)
  77. return 1;
  78. return double_or_none.value();
  79. }
  80. WebIDL::ExceptionOr<void> HTMLProgressElement::set_max(double value)
  81. {
  82. if (value <= 0)
  83. return {};
  84. TRY(set_attribute(HTML::AttributeNames::max, MUST(String::number(value))));
  85. progress_position_updated();
  86. return {};
  87. }
  88. double HTMLProgressElement::position() const
  89. {
  90. if (!is_determinate())
  91. return -1;
  92. return value() / max();
  93. }
  94. }