From 50fdae7a8c4f3f513d88b358e87dc8361e3df179 Mon Sep 17 00:00:00 2001 From: Anshul Jethvani Date: Thu, 5 Dec 2019 14:43:29 -0500 Subject: [PATCH] implemented NamedGetter and other suggestions --- components/script/dom/htmlformelement.rs | 88 +++++++++++++++++++++++- 1 file changed, 85 insertions(+), 3 deletions(-) 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")) {