Implement attributes for the <meter> element (#32230)

* Implement attributes for the meter element

* Remove checks for min < max before clamping
This commit is contained in:
shanehandley 2024-05-11 15:06:44 +10:00 committed by GitHub
parent c2325cd738
commit 2904c32e05
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 139 additions and 743 deletions

View file

@ -2,14 +2,18 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::ops::{Add, Div};
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use html5ever::{local_name, LocalName, Prefix};
use js::rust::HandleObject;
use crate::dom::bindings::codegen::Bindings::HTMLMeterElementBinding::HTMLMeterElementMethods;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::num::Finite;
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
use crate::dom::document::Document;
use crate::dom::element::Element;
use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::Node;
use crate::dom::nodelist::NodeList;
@ -20,6 +24,7 @@ pub struct HTMLMeterElement {
labels_node_list: MutNullableDom<NodeList>,
}
/// <https://html.spec.whatwg.org/multipage/#the-meter-element>
impl HTMLMeterElement {
fn new_inherited(
local_name: LocalName,
@ -52,4 +57,125 @@ impl HTMLMeterElement {
impl HTMLMeterElementMethods for HTMLMeterElement {
// https://html.spec.whatwg.org/multipage/#dom-lfe-labels
make_labels_getter!(Labels, labels_node_list);
/// <https://html.spec.whatwg.org/multipage/#concept-meter-actual>
fn Value(&self) -> Finite<f64> {
let min = *self.Min();
let max = *self.Max();
Finite::wrap(
self.upcast::<Element>()
.get_string_attribute(&local_name!("value"))
.parse_floating_point_number()
.map_or(0.0, |candidate_actual_value| {
candidate_actual_value.clamp(min, max)
}),
)
}
/// <https://html.spec.whatwg.org/multipage/#dom-meter-value>
fn SetValue(&self, value: Finite<f64>) {
self.upcast::<Element>()
.set_string_attribute(&local_name!("value"), (*value).to_string().into());
}
/// <https://html.spec.whatwg.org/multipage/#concept-meter-minimum>
fn Min(&self) -> Finite<f64> {
Finite::wrap(
self.upcast::<Element>()
.get_string_attribute(&local_name!("min"))
.parse_floating_point_number()
.unwrap_or(0.0),
)
}
/// <https://html.spec.whatwg.org/multipage/#dom-meter-min>
fn SetMin(&self, value: Finite<f64>) {
self.upcast::<Element>()
.set_string_attribute(&local_name!("min"), (*value).to_string().into());
}
/// <https://html.spec.whatwg.org/multipage/#concept-meter-maximum>
fn Max(&self) -> Finite<f64> {
Finite::wrap(
self.upcast::<Element>()
.get_string_attribute(&local_name!("max"))
.parse_floating_point_number()
.unwrap_or(1.0)
.max(*self.Min()),
)
}
/// <https://html.spec.whatwg.org/multipage/#concept-meter-maximum>
fn SetMax(&self, value: Finite<f64>) {
self.upcast::<Element>()
.set_string_attribute(&local_name!("max"), (*value).to_string().into());
}
/// <https://html.spec.whatwg.org/multipage/#concept-meter-low>
fn Low(&self) -> Finite<f64> {
let min = *self.Min();
let max = *self.Max();
Finite::wrap(
self.upcast::<Element>()
.get_string_attribute(&local_name!("low"))
.parse_floating_point_number()
.map_or(min, |candidate_low_boundary| {
candidate_low_boundary.clamp(min, max)
}),
)
}
/// <https://html.spec.whatwg.org/multipage/#dom-meter-low>
fn SetLow(&self, value: Finite<f64>) {
self.upcast::<Element>()
.set_string_attribute(&local_name!("low"), (*value).to_string().into());
}
/// <https://html.spec.whatwg.org/multipage/#concept-meter-high>
fn High(&self) -> Finite<f64> {
let max: f64 = *self.Max();
let low: f64 = *self.Low();
Finite::wrap(
self.upcast::<Element>()
.get_string_attribute(&local_name!("high"))
.parse_floating_point_number()
.map_or(max, |candidate_high_boundary| {
if candidate_high_boundary < low {
return low;
}
candidate_high_boundary.clamp(*self.Min(), max)
}),
)
}
/// <https://html.spec.whatwg.org/multipage/#dom-meter-high>
fn SetHigh(&self, value: Finite<f64>) {
self.upcast::<Element>()
.set_string_attribute(&local_name!("high"), (*value).to_string().into());
}
/// <https://html.spec.whatwg.org/multipage/#concept-meter-optimum>
fn Optimum(&self) -> Finite<f64> {
let max = *self.Max();
let min = *self.Min();
Finite::wrap(
self.upcast::<Element>()
.get_string_attribute(&local_name!("optimum"))
.parse_floating_point_number()
.map_or(max.add(min).div(2.0), |candidate_optimum_point| {
candidate_optimum_point.clamp(min, max)
}),
)
}
/// <https://html.spec.whatwg.org/multipage/#dom-meter-optimum>
fn SetOptimum(&self, value: Finite<f64>) {
self.upcast::<Element>()
.set_string_attribute(&local_name!("optimum"), (*value).to_string().into());
}
}

View file

@ -7,17 +7,17 @@
interface HTMLMeterElement : HTMLElement {
[HTMLConstructor] constructor();
// [CEReactions]
// attribute double value;
// [CEReactions]
// attribute double min;
// [CEReactions]
// attribute double max;
// [CEReactions]
// attribute double low;
// [CEReactions]
// attribute double high;
// [CEReactions]
// attribute double optimum;
[CEReactions]
attribute double value;
[CEReactions]
attribute double min;
[CEReactions]
attribute double max;
[CEReactions]
attribute double low;
[CEReactions]
attribute double high;
[CEReactions]
attribute double optimum;
readonly attribute NodeList labels;
};