mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-26 22:38:51 +00:00
No functional impact intended. This is just a more complicated way of writing what we have now. The goal of this commit is so that we are able to store the 'name' of a pseudo element for use in serializing 'unknown -webkit- pseudo-elements', see: https://www.w3.org/TR/selectors-4/#compat This is quite awkward, as in pretty much all cases just the selector type enum is enough, but we will need to cache the name for serializing these unknown selectors. I can't figure out any reason why we would need this name anywhere else in the engine, so pretty much everywhere is still just passing around this raw enum. But this change will allow us to easily store the name inside of this new struct for when it is needed for serialization, once those webkit unknown elements are supported by our engine.
122 lines
3.7 KiB
C++
122 lines
3.7 KiB
C++
/*
|
|
* Copyright (c) 2020-2022, the SerenityOS developers.
|
|
* Copyright (c) 2022, MacDue <macdue@dueutil.tech>
|
|
* Copyright (c) 2023, Bastiaan van der Plaat <bastiaan.v.d.plaat@gmail.com>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <LibWeb/DOM/Document.h>
|
|
#include <LibWeb/DOM/ElementFactory.h>
|
|
#include <LibWeb/DOM/ShadowRoot.h>
|
|
#include <LibWeb/HTML/HTMLProgressElement.h>
|
|
#include <LibWeb/HTML/Numbers.h>
|
|
#include <LibWeb/Namespace.h>
|
|
|
|
namespace Web::HTML {
|
|
|
|
JS_DEFINE_ALLOCATOR(HTMLProgressElement);
|
|
|
|
HTMLProgressElement::HTMLProgressElement(DOM::Document& document, DOM::QualifiedName qualified_name)
|
|
: HTMLElement(document, move(qualified_name))
|
|
{
|
|
}
|
|
|
|
HTMLProgressElement::~HTMLProgressElement() = default;
|
|
|
|
void HTMLProgressElement::initialize(JS::Realm& realm)
|
|
{
|
|
Base::initialize(realm);
|
|
set_prototype(&Bindings::ensure_web_prototype<Bindings::HTMLProgressElementPrototype>(realm, "HTMLProgressElement"_fly_string));
|
|
}
|
|
|
|
void HTMLProgressElement::visit_edges(Cell::Visitor& visitor)
|
|
{
|
|
Base::visit_edges(visitor);
|
|
visitor.visit(m_progress_value_element);
|
|
}
|
|
|
|
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-progress-value
|
|
double HTMLProgressElement::value() const
|
|
{
|
|
if (auto value_string = get_attribute(HTML::AttributeNames::value); value_string.has_value()) {
|
|
if (auto value = parse_floating_point_number(*value_string); value.has_value())
|
|
return clamp(*value, 0, max());
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
WebIDL::ExceptionOr<void> HTMLProgressElement::set_value(double value)
|
|
{
|
|
if (value < 0 || value > max())
|
|
return {};
|
|
|
|
TRY(set_attribute(HTML::AttributeNames::value, MUST(String::number(value))));
|
|
update_progress_value_element();
|
|
document().invalidate_layout();
|
|
return {};
|
|
}
|
|
|
|
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-progress-max
|
|
double HTMLProgressElement::max() const
|
|
{
|
|
if (auto max_string = get_attribute(HTML::AttributeNames::max); max_string.has_value()) {
|
|
if (auto max = parse_floating_point_number(*max_string); max.has_value())
|
|
return AK::max(*max, 0);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
WebIDL::ExceptionOr<void> HTMLProgressElement::set_max(double value)
|
|
{
|
|
if (value <= 0)
|
|
return {};
|
|
|
|
TRY(set_attribute(HTML::AttributeNames::max, MUST(String::number(value))));
|
|
update_progress_value_element();
|
|
document().invalidate_layout();
|
|
return {};
|
|
}
|
|
|
|
double HTMLProgressElement::position() const
|
|
{
|
|
if (!is_determinate())
|
|
return -1;
|
|
|
|
return value() / max();
|
|
}
|
|
|
|
void HTMLProgressElement::inserted()
|
|
{
|
|
create_shadow_tree_if_needed();
|
|
}
|
|
|
|
void HTMLProgressElement::removed_from(DOM::Node*)
|
|
{
|
|
set_shadow_root(nullptr);
|
|
}
|
|
|
|
void HTMLProgressElement::create_shadow_tree_if_needed()
|
|
{
|
|
if (shadow_root_internal())
|
|
return;
|
|
|
|
auto shadow_root = heap().allocate<DOM::ShadowRoot>(realm(), document(), *this, Bindings::ShadowRootMode::Closed);
|
|
set_shadow_root(shadow_root);
|
|
|
|
auto progress_bar_element = MUST(DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML));
|
|
progress_bar_element->set_use_pseudo_element(CSS::Selector::PseudoElement::Type::ProgressBar);
|
|
MUST(shadow_root->append_child(*progress_bar_element));
|
|
|
|
m_progress_value_element = MUST(DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML));
|
|
m_progress_value_element->set_use_pseudo_element(CSS::Selector::PseudoElement::Type::ProgressValue);
|
|
MUST(progress_bar_element->append_child(*m_progress_value_element));
|
|
update_progress_value_element();
|
|
}
|
|
|
|
void HTMLProgressElement::update_progress_value_element()
|
|
{
|
|
MUST(m_progress_value_element->style_for_bindings()->set_property(CSS::PropertyID::Width, MUST(String::formatted("{}%", position() * 100))));
|
|
}
|
|
|
|
}
|