diff --git a/components/script/dom/htmlprogresselement.rs b/components/script/dom/htmlprogresselement.rs
index dcd2f018734..718d1999256 100644
--- a/components/script/dom/htmlprogresselement.rs
+++ b/components/script/dom/htmlprogresselement.rs
@@ -4,8 +4,10 @@
use crate::dom::bindings::codegen::Bindings::HTMLProgressElementBinding::HTMLProgressElementMethods;
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;
@@ -48,4 +50,76 @@ impl HTMLProgressElement {
impl HTMLProgressElementMethods for HTMLProgressElement {
// https://html.spec.whatwg.org/multipage/#dom-lfe-labels
make_labels_getter!(Labels, labels_node_list);
+
+ // https://html.spec.whatwg.org/multipage/#dom-progress-value
+ fn Value(&self) -> Finite {
+ // In case of missing `value`, parse error, or negative `value`, `value` should be
+ // interpreted as 0. As `get_string_attribute` returns an empty string in case the
+ // attribute is missing, this case is handeled as the default of the `map_or` function.
+ //
+ // It is safe to wrap the number coming from `parse_floating_point_number` as it will
+ // return Err on inf and nan
+ self.upcast::()
+ .get_string_attribute(&local_name!("value"))
+ .parse_floating_point_number()
+ .map_or(Finite::wrap(0.0), |v| {
+ if v < 0.0 {
+ Finite::wrap(0.0)
+ } else {
+ Finite::wrap(v.min(*self.Max()))
+ }
+ })
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-progress-value
+ fn SetValue(&self, new_val: Finite) {
+ if 0.0 <= *new_val {
+ self.upcast::()
+ .set_string_attribute(&local_name!("value"), (*new_val).to_string().into());
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-progress-max
+ fn Max(&self) -> Finite {
+ // In case of missing `max`, parse error, or negative `max`, `max` should be interpreted as
+ // 1.0. As `get_string_attribute` returns an empty string in case the attribute is missing,
+ // these cases are handeled by `map_or`
+ self.upcast::()
+ .get_string_attribute(&local_name!("max"))
+ .parse_floating_point_number()
+ .map_or(Finite::wrap(1.0), |m| {
+ if m <= 0.0 {
+ Finite::wrap(1.0)
+ } else {
+ Finite::wrap(m)
+ }
+ })
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-progress-max
+ fn SetMax(&self, new_val: Finite) {
+ self.upcast::()
+ .set_string_attribute(&local_name!("max"), (*new_val).to_string().into());
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-progress-position
+ fn Position(&self) -> Finite {
+ let value = self
+ .upcast::()
+ .get_string_attribute(&local_name!("value"));
+ if value.is_empty() {
+ Finite::wrap(-1.0)
+ } else {
+ let value = self.Value();
+ let max = self.Max();
+ // An unsafe Finite constructor might be nice here, as it's unlikely for the
+ // compiler to infer the following guarantees. It is probably premature
+ // optimization though.
+ //
+ // Safety: `ret` have to be a finite, defined number. This is the case since both
+ // value and max is finite, max > 0, and a value >> max cannot exist, as
+ // Self::Value(&self) enforces value <= max.
+ Finite::wrap(*value / *max)
+ }
+ }
}
diff --git a/components/script/dom/webidls/HTMLProgressElement.webidl b/components/script/dom/webidls/HTMLProgressElement.webidl
index c901e379659..0c25d86977a 100644
--- a/components/script/dom/webidls/HTMLProgressElement.webidl
+++ b/components/script/dom/webidls/HTMLProgressElement.webidl
@@ -7,10 +7,10 @@
interface HTMLProgressElement : HTMLElement {
[HTMLConstructor] constructor();
- // [CEReactions]
- // attribute double value;
- // [CEReactions]
- // attribute double max;
- // readonly attribute double position;
+ [CEReactions]
+ attribute double value;
+ [CEReactions]
+ attribute double max;
+ readonly attribute double position;
readonly attribute NodeList labels;
};
diff --git a/tests/wpt/metadata/custom-elements/reactions/HTMLProgressElement.html.ini b/tests/wpt/metadata/custom-elements/reactions/HTMLProgressElement.html.ini
index 19974beabaf..73f6be71795 100644
--- a/tests/wpt/metadata/custom-elements/reactions/HTMLProgressElement.html.ini
+++ b/tests/wpt/metadata/custom-elements/reactions/HTMLProgressElement.html.ini
@@ -1,13 +1 @@
-[HTMLProgressElement.html]
- [max on HTMLProgressElement must enqueue an attributeChanged reaction when replacing an existing attribute]
- expected: FAIL
-
- [max on HTMLProgressElement must enqueue an attributeChanged reaction when adding max content attribute]
- expected: FAIL
-
- [value on HTMLProgressElement must enqueue an attributeChanged reaction when adding value content attribute]
- expected: FAIL
-
- [value on HTMLProgressElement must enqueue an attributeChanged reaction when replacing an existing attribute]
- expected: FAIL
-
+[HTMLProgressElement.html]
\ No newline at end of file
diff --git a/tests/wpt/metadata/html/dom/idlharness.https.html.ini b/tests/wpt/metadata/html/dom/idlharness.https.html.ini
index f2a27054b52..e710581f2e7 100644
--- a/tests/wpt/metadata/html/dom/idlharness.https.html.ini
+++ b/tests/wpt/metadata/html/dom/idlharness.https.html.ini
@@ -2313,9 +2313,6 @@
[HTMLAudioElement interface: named constructor without 'new']
expected: FAIL
- [HTMLProgressElement interface: document.createElement("progress") must inherit property "value" with the proper type]
- expected: FAIL
-
[HTMLEmbedElement interface: attribute name]
expected: FAIL
@@ -2343,12 +2340,6 @@
[HTMLInputElement interface: createInput("tel") must inherit property "align" with the proper type]
expected: FAIL
- [HTMLProgressElement interface: document.createElement("progress") must inherit property "position" with the proper type]
- expected: FAIL
-
- [HTMLProgressElement interface: attribute position]
- expected: FAIL
-
[HTMLAreaElement interface: attribute shape]
expected: FAIL
@@ -2490,9 +2481,6 @@
[HTMLInputElement interface: createInput("month") must inherit property "autofocus" with the proper type]
expected: FAIL
- [HTMLProgressElement interface: document.createElement("progress") must inherit property "max" with the proper type]
- expected: FAIL
-
[HTMLMediaElement interface: document.createElement("audio") must inherit property "seekable" with the proper type]
expected: FAIL
@@ -2727,9 +2715,6 @@
[HTMLInputElement interface: createInput("reset") must inherit property "useMap" with the proper type]
expected: FAIL
- [HTMLProgressElement interface: attribute max]
- expected: FAIL
-
[HTMLBRElement interface: attribute clear]
expected: FAIL
@@ -3627,9 +3612,6 @@
[HTMLAreaElement interface: document.createElement("area") must inherit property "download" with the proper type]
expected: FAIL
- [HTMLProgressElement interface: attribute value]
- expected: FAIL
-
[HTMLTableSectionElement interface: document.createElement("tbody") must inherit property "chOff" with the proper type]
expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/forms/the-progress-element/progress-2.html.ini b/tests/wpt/metadata/html/semantics/forms/the-progress-element/progress-2.html.ini
index 4c7bbd6a7e2..86b2b7a9c59 100644
--- a/tests/wpt/metadata/html/semantics/forms/the-progress-element/progress-2.html.ini
+++ b/tests/wpt/metadata/html/semantics/forms/the-progress-element/progress-2.html.ini
@@ -1,14 +1,2 @@
[progress-2.html]
type: testharness
- [progress position equals -1]
- expected: FAIL
-
- [progress value equals 0]
- expected: FAIL
-
- [progress value equals .5]
- expected: FAIL
-
- [progress position equals 0]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/semantics/forms/the-progress-element/progress.window.js.ini b/tests/wpt/metadata/html/semantics/forms/the-progress-element/progress.window.js.ini
index 63a0690d30f..6de39c99fe5 100644
--- a/tests/wpt/metadata/html/semantics/forms/the-progress-element/progress.window.js.ini
+++ b/tests/wpt/metadata/html/semantics/forms/the-progress-element/progress.window.js.ini
@@ -1,8 +1,2 @@
[progress.window.html]
type: testharness
- [If value > max, then current value = max]
- expected: FAIL
-
- [If value < max, then current value = value]
- expected: FAIL
-