diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs
index bc34b1fd243..26b2eab46b9 100644
--- a/components/script/dom/htmlformelement.rs
+++ b/components/script/dom/htmlformelement.rs
@@ -20,10 +20,11 @@ use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId};
use crate::dom::bindings::refcounted::Trusted;
use crate::dom::bindings::reflector::DomObject;
-use crate::dom::bindings::root::{Dom, DomOnceCell, DomRoot};
+use crate::dom::bindings::root::{Dom, DomOnceCell, DomRoot, MutNullableDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::blob::Blob;
use crate::dom::document::Document;
+use crate::dom::domtokenlist::DOMTokenList;
use crate::dom::element::{AttributeMutation, Element};
use crate::dom::event::{Event, EventBubbles, EventCancelable};
use crate::dom::eventtarget::EventTarget;
@@ -68,6 +69,7 @@ use servo_atoms::Atom;
use servo_rand::random;
use std::borrow::ToOwned;
use std::cell::Cell;
+use style::attr::AttrValue;
use style::str::split_html_space_chars;
use crate::dom::bindings::codegen::UnionTypes::RadioNodeListOrElement;
@@ -90,6 +92,7 @@ pub struct HTMLFormElement {
controls: DomRefCell>>,
past_names_map: DomRefCell, Tm)>>,
firing_submission_events: Cell,
+ rel_list: MutNullableDom,
}
impl HTMLFormElement {
@@ -107,6 +110,7 @@ impl HTMLFormElement {
controls: DomRefCell::new(Vec::new()),
past_names_map: DomRefCell::new(HashMap::new()),
firing_submission_events: Cell::new(false),
+ rel_list: Default::default(),
}
}
@@ -241,6 +245,9 @@ impl HTMLFormElementMethods for HTMLFormElement {
// https://html.spec.whatwg.org/multipage/#dom-fs-target
make_setter!(SetTarget, "target");
+ // https://html.spec.whatwg.org/multipage/#dom-a-rel
+ make_getter!(Rel, "rel");
+
// https://html.spec.whatwg.org/multipage/#the-form-element:concept-form-submit
fn Submit(&self) {
self.submit(SubmittedFrom::FromForm, FormSubmitter::FormElement(self));
@@ -434,6 +441,18 @@ impl HTMLFormElementMethods for HTMLFormElement {
)));
}
+ // https://html.spec.whatwg.org/multipage/#dom-a-rel
+ fn SetRel(&self, rel: DOMString) {
+ self.upcast::()
+ .set_tokenlist_attribute(&local_name!("rel"), rel);
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-a-rellist
+ fn RelList(&self) -> DomRoot {
+ self.rel_list
+ .or_init(|| DOMTokenList::new(self.upcast(), &local_name!("rel")))
+ }
+
// https://html.spec.whatwg.org/multipage/#the-form-element:supported-property-names
#[allow(non_snake_case)]
fn SupportedPropertyNames(&self) -> Vec {
@@ -1636,6 +1655,16 @@ impl VirtualMethods for HTMLFormElement {
.reset_form_owner();
}
}
+
+ fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue {
+ match name {
+ &local_name!("rel") => AttrValue::from_serialized_tokenlist(value.into()),
+ _ => self
+ .super_type()
+ .unwrap()
+ .parse_plain_attribute(name, value),
+ }
+ }
}
pub trait FormControlElementHelpers {
diff --git a/components/script/dom/webidls/HTMLFormElement.webidl b/components/script/dom/webidls/HTMLFormElement.webidl
index 78d7e96ec39..8bd872eba95 100644
--- a/components/script/dom/webidls/HTMLFormElement.webidl
+++ b/components/script/dom/webidls/HTMLFormElement.webidl
@@ -25,6 +25,9 @@ interface HTMLFormElement : HTMLElement {
attribute boolean noValidate;
[CEReactions]
attribute DOMString target;
+ [CEReactions]
+ attribute DOMString rel;
+ [SameObject, PutForwards=value] readonly attribute DOMTokenList relList;
[SameObject] readonly attribute HTMLFormControlsCollection elements;
readonly attribute unsigned long length;
diff --git a/tests/wpt/metadata/WebIDL/ecmascript-binding/put-forwards.html.ini b/tests/wpt/metadata/WebIDL/ecmascript-binding/put-forwards.html.ini
deleted file mode 100644
index b3236e1ee55..00000000000
--- a/tests/wpt/metadata/WebIDL/ecmascript-binding/put-forwards.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[put-forwards.html]
- type: testharness
- [Setting form.relList to noreferrer is reflected in rel]
- expected: FAIL
diff --git a/tests/wpt/metadata/html/dom/idlharness.https.html.ini b/tests/wpt/metadata/html/dom/idlharness.https.html.ini
index 6f4b20ee287..323b1708306 100644
--- a/tests/wpt/metadata/html/dom/idlharness.https.html.ini
+++ b/tests/wpt/metadata/html/dom/idlharness.https.html.ini
@@ -1911,9 +1911,6 @@
[HTMLElement interface: attribute accessKey]
expected: FAIL
- [HTMLFormElement interface: attribute rel]
- expected: FAIL
-
[HTMLObjectElement interface: document.createElement("object") must inherit property "vspace" with the proper type]
expected: FAIL
@@ -2547,9 +2544,6 @@
[HTMLInputElement interface: createInput("password") must inherit property "useMap" with the proper type]
expected: FAIL
- [HTMLFormElement interface: attribute relList]
- expected: FAIL
-
[HTMLElement interface: document.createElement("noscript") must inherit property "onauxclick" with the proper type]
expected: FAIL
@@ -3237,9 +3231,6 @@
[HTMLInputElement interface: createInput("radio") must inherit property "useMap" with the proper type]
expected: FAIL
- [HTMLFormElement interface: document.createElement("form") must inherit property "rel" with the proper type]
- expected: FAIL
-
[HTMLIFrameElement interface: attribute allowPaymentRequest]
expected: FAIL
@@ -3375,9 +3366,6 @@
[HTMLAreaElement interface: document.createElement("area") must inherit property "username" with the proper type]
expected: FAIL
- [HTMLFormElement interface: document.createElement("form") must inherit property "relList" with the proper type]
- expected: FAIL
-
[HTMLInputElement interface: createInput("search") must inherit property "height" with the proper type]
expected: FAIL