diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs
index 43986c493879..8fec745e8708 100644
--- a/components/script/dom/htmlformelement.rs
+++ b/components/script/dom/htmlformelement.rs
@@ -65,6 +65,8 @@ use style::attr::AttrValue;
use style::str::split_html_space_chars;
use crate::dom::bindings::codegen::UnionTypes::RadioNodeListOrElement;
+use crate::dom::radionodelist::RadioNodeList;
+use std::collections::HashMap;
#[derive(Clone, Copy, JSTraceable, MallocSizeOf, PartialEq)]
pub struct GenerationId(u32);
@@ -78,6 +80,7 @@ pub struct HTMLFormElement {
elements: DomOnceCell,
generation_id: Cell,
controls: DomRefCell>>,
+ past_names_map: DomRefCell>>,
}
impl HTMLFormElement {
@@ -93,6 +96,7 @@ impl HTMLFormElement {
elements: Default::default(),
generation_id: Cell::new(GenerationId(0)),
controls: DomRefCell::new(Vec::new()),
+ past_names_map: DomRefCell::new(HashMap::new()),
}
}
@@ -258,8 +262,83 @@ impl HTMLFormElementMethods for HTMLFormElement {
// https://html.spec.whatwg.org/multipage/#the-form-element%3Adetermine-the-value-of-a-named-property
fn NamedGetter(&self, name: DOMString) -> Option {
- // return Option::Some::;
- unimplemented!();
+ // unimplemented!();
+ let window = window_from_node(self);
+
+ // Q2. ERROR in the following declaration - check the attached screenshot (image2)
+ let mut candidates: Vec> = Vec::new();
+
+ // let mut candidates: RadioNodeList = RadioNodeList::new(&window, Dom);
+
+ let controls = self.controls.borrow();
+
+ for child in controls.iter() {
+ if child
+ .downcast::()
+ .map_or(false, |c| c.is_listed_element())
+ {
+ if child.has_attribute(&local_name!("id")) ||
+ (child.has_attribute(&local_name!("name")) &&
+ child.get_string_attribute(&local_name!("name")) == name)
+ {
+ // println!("{:?}", child.what_is_this());
+ candidates.push(Dom::from_ref(&*child.downcast::().unwrap()));
+ }
+ }
+ }
+
+ if candidates.len() == 0 {
+ for child in controls.iter() {
+ if child.is::() {
+ if child.has_attribute(&local_name!("id")) ||
+ (child.has_attribute(&local_name!("name")) &&
+ child.get_string_attribute(&local_name!("name")) == name)
+ {
+ candidates.push(Dom::from_ref(&*child.downcast::().unwrap()));
+ }
+ }
+ }
+ }
+
+ let mut past_names_map = self.past_names_map.borrow_mut();
+
+ if candidates.len() == 0 {
+ for (key, val) in past_names_map.iter() {
+ if *key == name {
+ // println!("{:?}", val.what_is_this());
+ return Some(RadioNodeListOrElement::Element(DomRoot::from_ref(
+ &*val.upcast::(),
+ )));
+ }
+ }
+ }
+
+ if candidates.len() > 1 {
+ let mut candidatesDomRoot: Vec> = Vec::new();
+ for cand in candidates.iter() {
+ // println!("{:?}", cand.what_is_this());
+ candidatesDomRoot.push(DomRoot::from_ref(&*cand.upcast::()));
+ }
+
+ // Q1. ERROR in the following line - check the attached screenshot (image1)
+ // Related link for potential fix: https://stackoverflow.com/a/26953620/11978763
+ // we are unsure of how to incorporate this
+ return Some(RadioNodeListOrElement::RadioNodeList(
+ RadioNodeList::new_simple_list(&window, candidatesDomRoot.iter()),
+ ));
+ }
+
+ let element_node = &candidates[0];
+ if past_names_map.contains_key(&name) {
+ let stat = past_names_map.entry(name).or_insert(element_node.clone());
+ *stat = element_node.clone();
+ } else {
+ past_names_map.insert(name, element_node.clone());
+ }
+
+ return Some(RadioNodeListOrElement::Element(DomRoot::from_ref(
+ &*element_node.upcast::(),
+ )));
}
// https://html.spec.whatwg.org/multipage/#the-form-element:supported-property-names
@@ -285,7 +364,10 @@ impl HTMLFormElementMethods for HTMLFormElement {
// controls - list of form elements
// check all listed elements first, push to sourcedNamesVec as per spec
for child in controls.iter() {
- if child.downcast::().map_or(false, |c| c.is_listed_element()) {
+ if child
+ .downcast::()
+ .map_or(false, |c| c.is_listed_element())
+ {
// if child.is_listed()
if child.has_attribute(&local_name!("id")) {