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