Skip to content

Commit

Permalink
Implement attributes for the <meter> element (#32230)
Browse files Browse the repository at this point in the history
* Implement attributes for the meter element

* Remove checks for min < max before clamping
  • Loading branch information
shanehandley committed May 11, 2024
1 parent c2325cd commit 2904c32
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 743 deletions.
128 changes: 127 additions & 1 deletion components/script/dom/htmlmeterelement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand Down Expand Up @@ -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());
}
}
24 changes: 12 additions & 12 deletions components/script/dom/webidls/HTMLMeterElement.webidl
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

This file was deleted.

36 changes: 0 additions & 36 deletions tests/wpt/meta-legacy-layout/html/dom/idlharness.https.html.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2790,9 +2790,6 @@
[HTMLTableSectionElement interface: document.createElement("tfoot") must inherit property "align" with the proper type]
expected: FAIL

[HTMLMeterElement interface: document.createElement("meter") must inherit property "low" with the proper type]
expected: FAIL

[HTMLInputElement interface: createInput("time") must inherit property "useMap" with the proper type]
expected: FAIL

Expand All @@ -2802,9 +2799,6 @@
[HTMLInputElement interface: createInput("hidden") must inherit property "align" with the proper type]
expected: FAIL

[HTMLMeterElement interface: attribute value]
expected: FAIL

[HTMLTableSectionElement interface: document.createElement("thead") must inherit property "chOff" with the proper type]
expected: FAIL

Expand Down Expand Up @@ -3216,18 +3210,12 @@
[HTMLIFrameElement interface: attribute align]
expected: FAIL

[HTMLMeterElement interface: document.createElement("meter") must inherit property "max" with the proper type]
expected: FAIL

[HTMLTableCellElement interface: document.createElement("th") must inherit property "noWrap" with the proper type]
expected: FAIL

[HTMLAreaElement interface: document.createElement("area") must inherit property "shape" with the proper type]
expected: FAIL

[HTMLMeterElement interface: attribute low]
expected: FAIL

[HTMLEmbedElement interface: attribute height]
expected: FAIL

Expand Down Expand Up @@ -3318,12 +3306,6 @@
[HTMLImageElement interface: document.createElement("img") must inherit property "sizes" with the proper type]
expected: FAIL

[HTMLMeterElement interface: document.createElement("meter") must inherit property "optimum" with the proper type]
expected: FAIL

[HTMLMeterElement interface: document.createElement("meter") must inherit property "value" with the proper type]
expected: FAIL

[HTMLEmbedElement interface: attribute align]
expected: FAIL

Expand Down Expand Up @@ -3489,9 +3471,6 @@
[HTMLInputElement interface: createInput("color") must inherit property "useMap" with the proper type]
expected: FAIL
[HTMLMeterElement interface: attribute optimum]
expected: FAIL
[HTMLInputElement interface: createInput("password") must inherit property "useMap" with the proper type]
expected: FAIL
Expand Down Expand Up @@ -3642,9 +3621,6 @@
[HTMLOListElement interface: attribute compact]
expected: FAIL
[HTMLMeterElement interface: attribute high]
expected: FAIL
[HTMLInputElement interface: createInput("reset") must inherit property "useMap" with the proper type]
expected: FAIL
Expand All @@ -3660,18 +3636,12 @@
[HTMLAreaElement interface: attribute download]
expected: FAIL
[HTMLMeterElement interface: attribute max]
expected: FAIL
[HTMLInputElement interface: createInput("hidden") must inherit property "width" with the proper type]
expected: FAIL
[HTMLInputElement interface: createInput("text") must inherit property "align" with the proper type]
expected: FAIL
[HTMLMeterElement interface: document.createElement("meter") must inherit property "high" with the proper type]
expected: FAIL
[HTMLParagraphElement interface: document.createElement("p") must inherit property "align" with the proper type]
expected: FAIL
Expand Down Expand Up @@ -3840,9 +3810,6 @@
[HTMLTableCellElement interface: document.createElement("th") must inherit property "scope" with the proper type]
expected: FAIL

[HTMLMeterElement interface: document.createElement("meter") must inherit property "min" with the proper type]
expected: FAIL

[HTMLLinkElement interface: attribute as]
expected: FAIL

Expand Down Expand Up @@ -4434,9 +4401,6 @@
[HTMLObjectElement interface: document.createElement("object") must inherit property "data" with the proper type]
expected: FAIL

[HTMLMeterElement interface: attribute min]
expected: FAIL

[HTMLElement interface: document.createElement("noscript") must inherit property "onsecuritypolicyviolation" with the proper type]
expected: FAIL

Expand Down

0 comments on commit 2904c32

Please sign in to comment.