diff options
Diffstat (limited to 'components/script/dom/htmlformelement.rs')
-rwxr-xr-x | components/script/dom/htmlformelement.rs | 668 |
1 files changed, 378 insertions, 290 deletions
diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index d13ac0e5c98..96f011bbb8e 100755 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -71,9 +71,11 @@ pub struct HTMLFormElement { } impl HTMLFormElement { - fn new_inherited(local_name: LocalName, - prefix: Option<Prefix>, - document: &Document) -> HTMLFormElement { + fn new_inherited( + local_name: LocalName, + prefix: Option<Prefix>, + document: &Document, + ) -> HTMLFormElement { HTMLFormElement { htmlelement: HTMLElement::new_inherited(local_name, prefix, document), marked_for_reset: Cell::new(false), @@ -84,12 +86,16 @@ impl HTMLFormElement { } #[allow(unrooted_must_root)] - pub fn new(local_name: LocalName, - prefix: Option<Prefix>, - document: &Document) -> DomRoot<HTMLFormElement> { - Node::reflect_node(Box::new(HTMLFormElement::new_inherited(local_name, prefix, document)), - document, - HTMLFormElementBinding::Wrap) + pub fn new( + local_name: LocalName, + prefix: Option<Prefix>, + document: &Document, + ) -> DomRoot<HTMLFormElement> { + Node::reflect_node( + Box::new(HTMLFormElement::new_inherited(local_name, prefix, document)), + document, + HTMLFormElementBinding::Wrap, + ) } } @@ -113,10 +119,12 @@ impl HTMLFormElementMethods for HTMLFormElement { make_setter!(SetAutocomplete, "autocomplete"); // https://html.spec.whatwg.org/multipage/#dom-fs-enctype - make_enumerated_getter!(Enctype, - "enctype", - "application/x-www-form-urlencoded", - "text/plain" | "multipart/form-data"); + make_enumerated_getter!( + Enctype, + "enctype", + "application/x-www-form-urlencoded", + "text/plain" | "multipart/form-data" + ); // https://html.spec.whatwg.org/multipage/#dom-fs-enctype make_setter!(SetEnctype, "enctype"); @@ -169,45 +177,45 @@ impl HTMLFormElementMethods for HTMLFormElement { fn Elements(&self) -> DomRoot<HTMLFormControlsCollection> { #[derive(JSTraceable, MallocSizeOf)] struct ElementsFilter { - form: DomRoot<HTMLFormElement> + form: DomRoot<HTMLFormElement>, } impl CollectionFilter for ElementsFilter { fn filter<'a>(&self, elem: &'a Element, _root: &'a Node) -> bool { let form_owner = match elem.upcast::<Node>().type_id() { - NodeTypeId::Element(ElementTypeId::HTMLElement(t)) => { - match t { - HTMLElementTypeId::HTMLButtonElement => { - elem.downcast::<HTMLButtonElement>().unwrap().form_owner() - } - HTMLElementTypeId::HTMLFieldSetElement => { - elem.downcast::<HTMLFieldSetElement>().unwrap().form_owner() - } - HTMLElementTypeId::HTMLInputElement => { - let input_elem = elem.downcast::<HTMLInputElement>().unwrap(); - if input_elem.input_type() == InputType::Image { - return false; - } - input_elem.form_owner() - } - HTMLElementTypeId::HTMLObjectElement => { - elem.downcast::<HTMLObjectElement>().unwrap().form_owner() - } - HTMLElementTypeId::HTMLOutputElement => { - elem.downcast::<HTMLOutputElement>().unwrap().form_owner() - } - HTMLElementTypeId::HTMLSelectElement => { - elem.downcast::<HTMLSelectElement>().unwrap().form_owner() - } - HTMLElementTypeId::HTMLTextAreaElement => { - elem.downcast::<HTMLTextAreaElement>().unwrap().form_owner() - } - _ => { - debug_assert!(!elem.downcast::<HTMLElement>().unwrap().is_listed_element() || - elem.local_name() == &local_name!("keygen")); + NodeTypeId::Element(ElementTypeId::HTMLElement(t)) => match t { + HTMLElementTypeId::HTMLButtonElement => { + elem.downcast::<HTMLButtonElement>().unwrap().form_owner() + }, + HTMLElementTypeId::HTMLFieldSetElement => { + elem.downcast::<HTMLFieldSetElement>().unwrap().form_owner() + }, + HTMLElementTypeId::HTMLInputElement => { + let input_elem = elem.downcast::<HTMLInputElement>().unwrap(); + if input_elem.input_type() == InputType::Image { return false; } - } - } + input_elem.form_owner() + }, + HTMLElementTypeId::HTMLObjectElement => { + elem.downcast::<HTMLObjectElement>().unwrap().form_owner() + }, + HTMLElementTypeId::HTMLOutputElement => { + elem.downcast::<HTMLOutputElement>().unwrap().form_owner() + }, + HTMLElementTypeId::HTMLSelectElement => { + elem.downcast::<HTMLSelectElement>().unwrap().form_owner() + }, + HTMLElementTypeId::HTMLTextAreaElement => { + elem.downcast::<HTMLTextAreaElement>().unwrap().form_owner() + }, + _ => { + debug_assert!( + !elem.downcast::<HTMLElement>().unwrap().is_listed_element() || + elem.local_name() == &local_name!("keygen") + ); + return false; + }, + }, _ => return false, }; @@ -218,7 +226,9 @@ impl HTMLFormElementMethods for HTMLFormElement { } } DomRoot::from_ref(self.elements.init_once(|| { - let filter = Box::new(ElementsFilter { form: DomRoot::from_ref(self) }); + let filter = Box::new(ElementsFilter { + form: DomRoot::from_ref(self), + }); let window = window_from_node(self); HTMLFormControlsCollection::new(&window, self.upcast(), filter) })) @@ -239,27 +249,31 @@ impl HTMLFormElementMethods for HTMLFormElement { #[derive(Clone, Copy, MallocSizeOf, PartialEq)] pub enum SubmittedFrom { FromForm, - NotFromForm + NotFromForm, } #[derive(Clone, Copy, MallocSizeOf)] pub enum ResetFrom { FromForm, - NotFromForm + NotFromForm, } - impl HTMLFormElement { // https://html.spec.whatwg.org/multipage/#picking-an-encoding-for-the-form fn pick_encoding(&self) -> &'static Encoding { // Step 2 - if self.upcast::<Element>().has_attribute(&local_name!("accept-charset")) { + if self + .upcast::<Element>() + .has_attribute(&local_name!("accept-charset")) + { // Substep 1 - let input = self.upcast::<Element>().get_string_attribute(&local_name!("accept-charset")); + let input = self + .upcast::<Element>() + .get_string_attribute(&local_name!("accept-charset")); // Substep 2, 3, 4 - let mut candidate_encodings = split_html_space_chars(&*input) - .filter_map(|c| Encoding::for_label(c.as_bytes())); + let mut candidate_encodings = + split_html_space_chars(&*input).filter_map(|c| Encoding::for_label(c.as_bytes())); // Substep 5, 6 return candidate_encodings.next().unwrap_or(UTF_8); @@ -299,9 +313,7 @@ impl HTMLFormElement { let base = doc.base_url(); // TODO: Handle browsing contexts (Step 2, 3) // Step 4 - if submit_method_flag == SubmittedFrom::NotFromForm && - !submitter.no_validate(self) - { + if submit_method_flag == SubmittedFrom::NotFromForm && !submitter.no_validate(self) { if self.interactive_validation().is_err() { // TODO: Implement event handlers on all form control elements self.upcast::<EventTarget>().fire_event(atom!("invalid")); @@ -310,7 +322,8 @@ impl HTMLFormElement { } // Step 5 if submit_method_flag == SubmittedFrom::NotFromForm { - let event = self.upcast::<EventTarget>() + let event = self + .upcast::<EventTarget>() .fire_bubbling_cancelable_event(atom!("submit")); if event.DefaultPrevented() { return; @@ -332,7 +345,7 @@ impl HTMLFormElement { // Step 10-11 let action_components = match base.join(&action) { Ok(url) => url, - Err(_) => return + Err(_) => return, }; // Step 12-15 let scheme = action_components.scheme().to_owned(); @@ -345,74 +358,94 @@ impl HTMLFormElement { let (maybe_chosen, _new) = source.choose_browsing_context(target_attribute_value, false); let chosen = match maybe_chosen { Some(proxy) => proxy, - None => return + None => return, }; let target_document = match chosen.document() { Some(doc) => doc, - None => return + None => return, }; let target_window = target_document.window(); - let mut load_data = LoadData::new(action_components, - None, - target_document.get_referrer_policy(), - Some(target_document.url())); + let mut load_data = LoadData::new( + action_components, + None, + target_document.get_referrer_policy(), + Some(target_document.url()), + ); // Step 18 match (&*scheme, method) { (_, FormMethod::FormDialog) => { // TODO: Submit dialog // https://html.spec.whatwg.org/multipage/#submit-dialog - } + }, // https://html.spec.whatwg.org/multipage/#submit-mutate-action - ("http", FormMethod::FormGet) | ("https", FormMethod::FormGet) | ("data", FormMethod::FormGet) => { + ("http", FormMethod::FormGet) | + ("https", FormMethod::FormGet) | + ("data", FormMethod::FormGet) => { load_data.headers.set(ContentType::form_url_encoded()); self.mutate_action_url(&mut form_data, load_data, encoding, &target_window); - } + }, // https://html.spec.whatwg.org/multipage/#submit-body ("http", FormMethod::FormPost) | ("https", FormMethod::FormPost) => { load_data.method = Method::Post; - self.submit_entity_body(&mut form_data, load_data, enctype, encoding, &target_window); - } + self.submit_entity_body( + &mut form_data, + load_data, + enctype, + encoding, + &target_window, + ); + }, // https://html.spec.whatwg.org/multipage/#submit-get-action - ("file", _) | ("about", _) | ("data", FormMethod::FormPost) | - ("ftp", _) | ("javascript", _) => { + ("file", _) | + ("about", _) | + ("data", FormMethod::FormPost) | + ("ftp", _) | + ("javascript", _) => { self.plan_to_navigate(load_data, &target_window); - } + }, ("mailto", FormMethod::FormPost) => { // TODO: Mail as body // https://html.spec.whatwg.org/multipage/#submit-mailto-body - } + }, ("mailto", FormMethod::FormGet) => { // TODO: Mail with headers // https://html.spec.whatwg.org/multipage/#submit-mailto-headers - } + }, _ => return, } } // https://html.spec.whatwg.org/multipage/#submit-mutate-action - fn mutate_action_url(&self, - form_data: &mut Vec<FormDatum>, - mut load_data: LoadData, - encoding: &'static Encoding, - target: &Window) { + fn mutate_action_url( + &self, + form_data: &mut Vec<FormDatum>, + mut load_data: LoadData, + encoding: &'static Encoding, + target: &Window, + ) { let charset = encoding.name(); self.set_encoding_override(load_data.url.as_mut_url().query_pairs_mut()) .clear() - .extend_pairs(form_data.into_iter() - .map(|field| (field.name.clone(), field.replace_value(charset)))); + .extend_pairs( + form_data + .into_iter() + .map(|field| (field.name.clone(), field.replace_value(charset))), + ); self.plan_to_navigate(load_data, target); } // https://html.spec.whatwg.org/multipage/#submit-body - fn submit_entity_body(&self, - form_data: &mut Vec<FormDatum>, - mut load_data: LoadData, - enctype: FormEncType, - encoding: &'static Encoding, - target: &Window) { + fn submit_entity_body( + &self, + form_data: &mut Vec<FormDatum>, + mut load_data: LoadData, + enctype: FormEncType, + encoding: &'static Encoding, + target: &Window, + ) { let boundary = generate_boundary(); let bytes = match enctype { FormEncType::UrlEncoded => { @@ -421,28 +454,33 @@ impl HTMLFormElement { self.set_encoding_override(load_data.url.as_mut_url().query_pairs_mut()) .clear() - .extend_pairs(form_data.into_iter() - .map(|field| (field.name.clone(), field.replace_value(charset)))); + .extend_pairs( + form_data + .into_iter() + .map(|field| (field.name.clone(), field.replace_value(charset))), + ); load_data.url.query().unwrap_or("").to_string().into_bytes() - } + }, FormEncType::FormDataEncoded => { let mime = mime!(Multipart / FormData; Boundary =(&boundary)); load_data.headers.set(ContentType(mime)); encode_multipart_form_data(form_data, boundary, encoding) - } + }, FormEncType::TextPlainEncoded => { load_data.headers.set(ContentType(mime!(Text / Plain))); self.encode_plaintext(form_data).into_bytes() - } + }, }; load_data.data = Some(bytes); self.plan_to_navigate(load_data, target); } - fn set_encoding_override<'a>(&self, mut serializer: Serializer<UrlQuery<'a>>) - -> Serializer<UrlQuery<'a>> { + fn set_encoding_override<'a>( + &self, + mut serializer: Serializer<UrlQuery<'a>>, + ) -> Serializer<UrlQuery<'a>> { let encoding = self.pick_encoding(); serializer.custom_encoding_override(move |s| encoding.encode(s).0); serializer @@ -473,7 +511,10 @@ impl HTMLFormElement { }); // Step 3. - target.dom_manipulation_task_source().queue(task, target.upcast()).unwrap(); + target + .dom_manipulation_task_source() + .queue(task, target.upcast()) + .unwrap(); } /// Interactively validate the constraints of form elements @@ -482,7 +523,7 @@ impl HTMLFormElement { // Step 1-3 let _unhandled_invalid_controls = match self.static_validation() { Ok(()) => return Ok(()), - Err(err) => err + Err(err) => err, }; // TODO: Report the problems with the constraints of at least one of // the elements given in unhandled invalid controls to the user @@ -497,36 +538,45 @@ impl HTMLFormElement { // FIXME(#3553): This is an incorrect way of getting controls owned by the // form, refactor this when html5ever's form owner PR lands // Step 1-3 - let invalid_controls = node.traverse_preorder().filter_map(|field| { - if let Some(el) = field.downcast::<Element>() { - if el.disabled_state() { - None - } else { - let validatable = match el.as_maybe_validatable() { - Some(v) => v, - None => return None - }; - if !validatable.is_instance_validatable() { - None - } else if validatable.validate(ValidationFlags::empty()) { + let invalid_controls = node + .traverse_preorder() + .filter_map(|field| { + if let Some(el) = field.downcast::<Element>() { + if el.disabled_state() { None } else { - Some(FormSubmittableElement::from_element(&el)) + let validatable = match el.as_maybe_validatable() { + Some(v) => v, + None => return None, + }; + if !validatable.is_instance_validatable() { + None + } else if validatable.validate(ValidationFlags::empty()) { + None + } else { + Some(FormSubmittableElement::from_element(&el)) + } } + } else { + None } - } else { - None - } - }).collect::<Vec<FormSubmittableElement>>(); + }).collect::<Vec<FormSubmittableElement>>(); // Step 4 - if invalid_controls.is_empty() { return Ok(()); } + if invalid_controls.is_empty() { + return Ok(()); + } // Step 5-6 - let unhandled_invalid_controls = invalid_controls.into_iter().filter_map(|field| { - let event = field.as_event_target() - .fire_cancelable_event(atom!("invalid")); - if !event.DefaultPrevented() { return Some(field); } - None - }).collect::<Vec<FormSubmittableElement>>(); + let unhandled_invalid_controls = invalid_controls + .into_iter() + .filter_map(|field| { + let event = field + .as_event_target() + .fire_cancelable_event(atom!("invalid")); + if !event.DefaultPrevented() { + return Some(field); + } + None + }).collect::<Vec<FormSubmittableElement>>(); // Step 7 Err(unhandled_invalid_controls) } @@ -544,8 +594,10 @@ impl HTMLFormElement { let child = child.upcast::<Node>(); // Step 3.1: The field element has a datalist element ancestor. - if child.ancestors() - .any(|a| DomRoot::downcast::<HTMLDataListElement>(a).is_some()) { + if child + .ancestors() + .any(|a| DomRoot::downcast::<HTMLDataListElement>(a).is_some()) + { continue; } if let NodeTypeId::Element(ElementTypeId::HTMLElement(element)) = child.type_id() { @@ -554,21 +606,21 @@ impl HTMLFormElement { let input = child.downcast::<HTMLInputElement>().unwrap(); data_set.append(&mut input.form_datums(submitter)); - } + }, HTMLElementTypeId::HTMLButtonElement => { let button = child.downcast::<HTMLButtonElement>().unwrap(); if let Some(datum) = button.form_datum(submitter) { data_set.push(datum); } - } + }, HTMLElementTypeId::HTMLObjectElement => { // Unimplemented () - } + }, HTMLElementTypeId::HTMLSelectElement => { let select = child.downcast::<HTMLSelectElement>().unwrap(); select.push_form_data(&mut data_set); - } + }, HTMLElementTypeId::HTMLTextAreaElement => { let textarea = child.downcast::<HTMLTextAreaElement>().unwrap(); let name = textarea.Name(); @@ -576,11 +628,11 @@ impl HTMLFormElement { data_set.push(FormDatum { ty: textarea.Type(), name: name, - value: FormDatumValue::String(textarea.Value()) + value: FormDatumValue::String(textarea.Value()), }); } - } - _ => () + }, + _ => (), } } } @@ -611,7 +663,7 @@ impl HTMLFormElement { buf.push('\n'); buf.push(ch); }, - _ => buf.push(ch) + _ => buf.push(ch), }; prev = ch; } @@ -632,11 +684,11 @@ impl HTMLFormElement { datum.name = clean_crlf(&datum.name); datum.value = FormDatumValue::String(clean_crlf(match datum.value { FormDatumValue::String(ref s) => s, - FormDatumValue::File(_) => unreachable!() + FormDatumValue::File(_) => unreachable!(), })); - } + }, } - }; + } // Step 5 ret } @@ -649,7 +701,8 @@ impl HTMLFormElement { self.marked_for_reset.set(true); } - let event = self.upcast::<EventTarget>() + let event = self + .upcast::<EventTarget>() .fire_bubbling_cancelable_event(atom!("reset")); if event.DefaultPrevented() { return; @@ -660,24 +713,32 @@ impl HTMLFormElement { let child = child.upcast::<Node>(); match child.type_id() { - NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) => { + NodeTypeId::Element(ElementTypeId::HTMLElement( + HTMLElementTypeId::HTMLInputElement, + )) => { child.downcast::<HTMLInputElement>().unwrap().reset(); - } + }, // TODO HTMLKeygenElement unimplemented //NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLKeygenElement)) => { // // Unimplemented // {} //} - NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSelectElement)) => { + NodeTypeId::Element(ElementTypeId::HTMLElement( + HTMLElementTypeId::HTMLSelectElement, + )) => { child.downcast::<HTMLSelectElement>().unwrap().reset(); - } - NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement)) => { + }, + NodeTypeId::Element(ElementTypeId::HTMLElement( + HTMLElementTypeId::HTMLTextAreaElement, + )) => { child.downcast::<HTMLTextAreaElement>().unwrap().reset(); - } - NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLOutputElement)) => { + }, + NodeTypeId::Element(ElementTypeId::HTMLElement( + HTMLElementTypeId::HTMLOutputElement, + )) => { // Unimplemented - } - _ => {} + }, + _ => {}, } } self.marked_for_reset.set(false); @@ -694,8 +755,10 @@ impl HTMLFormElement { fn remove_control<T: ?Sized + FormControl>(&self, control: &T) { let control = control.to_element(); let mut controls = self.controls.borrow_mut(); - controls.iter().position(|c| c.r() == control) - .map(|idx| controls.remove(idx)); + controls + .iter() + .position(|c| c.r() == control) + .map(|idx| controls.remove(idx)); } } @@ -703,14 +766,14 @@ impl HTMLFormElement { pub enum FormDatumValue { #[allow(dead_code)] File(DomRoot<File>), - String(DOMString) + String(DOMString), } #[derive(Clone, JSTraceable, MallocSizeOf)] pub struct FormDatum { pub ty: DOMString, pub name: DOMString, - pub value: FormDatumValue + pub value: FormDatumValue, } impl FormDatum { @@ -730,14 +793,14 @@ impl FormDatum { pub enum FormEncType { TextPlainEncoded, UrlEncoded, - FormDataEncoded + FormDataEncoded, } #[derive(Clone, Copy, MallocSizeOf)] pub enum FormMethod { FormGet, FormPost, - FormDialog + FormDialog, } #[derive(MallocSizeOf)] @@ -759,24 +822,20 @@ impl FormSubmittableElement { FormSubmittableElement::InputElement(ref input) => input.upcast(), FormSubmittableElement::ObjectElement(ref object) => object.upcast(), FormSubmittableElement::SelectElement(ref select) => select.upcast(), - FormSubmittableElement::TextAreaElement(ref textarea) => textarea.upcast() + FormSubmittableElement::TextAreaElement(ref textarea) => textarea.upcast(), } } fn from_element(element: &Element) -> FormSubmittableElement { if let Some(input) = element.downcast::<HTMLInputElement>() { FormSubmittableElement::InputElement(DomRoot::from_ref(&input)) - } - else if let Some(input) = element.downcast::<HTMLButtonElement>() { + } else if let Some(input) = element.downcast::<HTMLButtonElement>() { FormSubmittableElement::ButtonElement(DomRoot::from_ref(&input)) - } - else if let Some(input) = element.downcast::<HTMLObjectElement>() { + } else if let Some(input) = element.downcast::<HTMLObjectElement>() { FormSubmittableElement::ObjectElement(DomRoot::from_ref(&input)) - } - else if let Some(input) = element.downcast::<HTMLSelectElement>() { + } else if let Some(input) = element.downcast::<HTMLSelectElement>() { FormSubmittableElement::SelectElement(DomRoot::from_ref(&input)) - } - else if let Some(input) = element.downcast::<HTMLTextAreaElement>() { + } else if let Some(input) = element.downcast::<HTMLTextAreaElement>() { FormSubmittableElement::TextAreaElement(DomRoot::from_ref(&input)) } else { unreachable!() @@ -788,100 +847,100 @@ impl FormSubmittableElement { pub enum FormSubmitter<'a> { FormElement(&'a HTMLFormElement), InputElement(&'a HTMLInputElement), - ButtonElement(&'a HTMLButtonElement) - // TODO: image submit, etc etc + ButtonElement(&'a HTMLButtonElement), // TODO: image submit, etc etc } impl<'a> FormSubmitter<'a> { fn action(&self) -> DOMString { match *self { FormSubmitter::FormElement(form) => form.Action(), - FormSubmitter::InputElement(input_element) => { - input_element.get_form_attribute(&local_name!("formaction"), - |i| i.FormAction(), - |f| f.Action()) - }, - FormSubmitter::ButtonElement(button_element) => { - button_element.get_form_attribute(&local_name!("formaction"), - |i| i.FormAction(), - |f| f.Action()) - } + FormSubmitter::InputElement(input_element) => input_element.get_form_attribute( + &local_name!("formaction"), + |i| i.FormAction(), + |f| f.Action(), + ), + FormSubmitter::ButtonElement(button_element) => button_element.get_form_attribute( + &local_name!("formaction"), + |i| i.FormAction(), + |f| f.Action(), + ), } } fn enctype(&self) -> FormEncType { let attr = match *self { FormSubmitter::FormElement(form) => form.Enctype(), - FormSubmitter::InputElement(input_element) => { - input_element.get_form_attribute(&local_name!("formenctype"), - |i| i.FormEnctype(), - |f| f.Enctype()) - }, - FormSubmitter::ButtonElement(button_element) => { - button_element.get_form_attribute(&local_name!("formenctype"), - |i| i.FormEnctype(), - |f| f.Enctype()) - } + FormSubmitter::InputElement(input_element) => input_element.get_form_attribute( + &local_name!("formenctype"), + |i| i.FormEnctype(), + |f| f.Enctype(), + ), + FormSubmitter::ButtonElement(button_element) => button_element.get_form_attribute( + &local_name!("formenctype"), + |i| i.FormEnctype(), + |f| f.Enctype(), + ), }; match &*attr { "multipart/form-data" => FormEncType::FormDataEncoded, "text/plain" => FormEncType::TextPlainEncoded, // https://html.spec.whatwg.org/multipage/#attr-fs-enctype // urlencoded is the default - _ => FormEncType::UrlEncoded + _ => FormEncType::UrlEncoded, } } fn method(&self) -> FormMethod { let attr = match *self { FormSubmitter::FormElement(form) => form.Method(), - FormSubmitter::InputElement(input_element) => { - input_element.get_form_attribute(&local_name!("formmethod"), - |i| i.FormMethod(), - |f| f.Method()) - }, - FormSubmitter::ButtonElement(button_element) => { - button_element.get_form_attribute(&local_name!("formmethod"), - |i| i.FormMethod(), - |f| f.Method()) - } + FormSubmitter::InputElement(input_element) => input_element.get_form_attribute( + &local_name!("formmethod"), + |i| i.FormMethod(), + |f| f.Method(), + ), + FormSubmitter::ButtonElement(button_element) => button_element.get_form_attribute( + &local_name!("formmethod"), + |i| i.FormMethod(), + |f| f.Method(), + ), }; match &*attr { "dialog" => FormMethod::FormDialog, "post" => FormMethod::FormPost, - _ => FormMethod::FormGet + _ => FormMethod::FormGet, } } fn target(&self) -> DOMString { match *self { FormSubmitter::FormElement(form) => form.Target(), - FormSubmitter::InputElement(input_element) => { - input_element.get_form_attribute(&local_name!("formtarget"), - |i| i.FormTarget(), - |f| f.Target()) - }, - FormSubmitter::ButtonElement(button_element) => { - button_element.get_form_attribute(&local_name!("formtarget"), - |i| i.FormTarget(), - |f| f.Target()) - } + FormSubmitter::InputElement(input_element) => input_element.get_form_attribute( + &local_name!("formtarget"), + |i| i.FormTarget(), + |f| f.Target(), + ), + FormSubmitter::ButtonElement(button_element) => button_element.get_form_attribute( + &local_name!("formtarget"), + |i| i.FormTarget(), + |f| f.Target(), + ), } } fn no_validate(&self, _form_owner: &HTMLFormElement) -> bool { match *self { FormSubmitter::FormElement(form) => form.NoValidate(), - FormSubmitter::InputElement(input_element) => { - input_element.get_form_boolean_attribute(&local_name!("formnovalidate"), - |i| i.FormNoValidate(), - |f| f.NoValidate()) - } - FormSubmitter::ButtonElement(button_element) => { - button_element.get_form_boolean_attribute(&local_name!("formnovalidate"), - |i| i.FormNoValidate(), - |f| f.NoValidate()) - } + FormSubmitter::InputElement(input_element) => input_element.get_form_boolean_attribute( + &local_name!("formnovalidate"), + |i| i.FormNoValidate(), + |f| f.NoValidate(), + ), + FormSubmitter::ButtonElement(button_element) => button_element + .get_form_boolean_attribute( + &local_name!("formnovalidate"), + |i| i.FormNoValidate(), + |f| f.NoValidate(), + ), } } } @@ -915,9 +974,10 @@ pub trait FormControl: DomObject { let node = elem.upcast::<Node>(); let old_owner = self.form_owner(); let has_form_id = elem.has_attribute(&local_name!("form")); - let nearest_form_ancestor = node.ancestors() - .filter_map(DomRoot::downcast::<HTMLFormElement>) - .next(); + let nearest_form_ancestor = node + .ancestors() + .filter_map(DomRoot::downcast::<HTMLFormElement>) + .next(); // Step 1 if old_owner.is_some() && !(self.is_listed() && has_form_id) { @@ -930,7 +990,8 @@ pub trait FormControl: DomObject { // Step 3 let doc = document_from_node(node); let form_id = elem.get_string_attribute(&local_name!("form")); - doc.GetElementById(form_id).and_then(DomRoot::downcast::<HTMLFormElement>) + doc.GetElementById(form_id) + .and_then(DomRoot::downcast::<HTMLFormElement>) } else { // Step 4 nearest_form_ancestor @@ -1005,9 +1066,9 @@ pub trait FormControl: DomObject { fn unbind_form_control_from_tree(&self) { let elem = self.to_element(); let has_form_attr = elem.has_attribute(&local_name!("form")); - let same_subtree = self.form_owner().map_or(true, |form| { - elem.is_in_same_home_subtree(&*form) - }); + let same_subtree = self + .form_owner() + .map_or(true, |form| elem.is_in_same_home_subtree(&*form)); self.unregister_if_necessary(); @@ -1021,13 +1082,16 @@ pub trait FormControl: DomObject { } } - fn get_form_attribute<InputFn, OwnerFn>(&self, - attr: &LocalName, - input: InputFn, - owner: OwnerFn) - -> DOMString - where InputFn: Fn(&Self) -> DOMString, - OwnerFn: Fn(&HTMLFormElement) -> DOMString, Self: Sized + fn get_form_attribute<InputFn, OwnerFn>( + &self, + attr: &LocalName, + input: InputFn, + owner: OwnerFn, + ) -> DOMString + where + InputFn: Fn(&Self) -> DOMString, + OwnerFn: Fn(&HTMLFormElement) -> DOMString, + Self: Sized, { if self.to_element().has_attribute(attr) { input(self) @@ -1036,13 +1100,16 @@ pub trait FormControl: DomObject { } } - fn get_form_boolean_attribute<InputFn, OwnerFn>(&self, - attr: &LocalName, - input: InputFn, - owner: OwnerFn) - -> bool - where InputFn: Fn(&Self) -> bool, - OwnerFn: Fn(&HTMLFormElement) -> bool, Self: Sized + fn get_form_boolean_attribute<InputFn, OwnerFn>( + &self, + attr: &LocalName, + input: InputFn, + owner: OwnerFn, + ) -> bool + where + InputFn: Fn(&Self) -> bool, + OwnerFn: Fn(&HTMLFormElement) -> bool, + Self: Sized, { if self.to_element().has_attribute(attr) { input(self) @@ -1064,7 +1131,10 @@ impl VirtualMethods for HTMLFormElement { fn parse_plain_attribute(&self, name: &LocalName, value: DOMString) -> AttrValue { match name { &local_name!("name") => AttrValue::from_atomic(value.into()), - _ => self.super_type().unwrap().parse_plain_attribute(name, value), + _ => self + .super_type() + .unwrap() + .parse_plain_attribute(name, value), } } @@ -1074,14 +1144,19 @@ impl VirtualMethods for HTMLFormElement { // Collect the controls to reset because reset_form_owner // will mutably borrow self.controls rooted_vec!(let mut to_reset); - to_reset.extend(self.controls.borrow().iter() - .filter(|c| !c.is_in_same_home_subtree(self)) - .map(|c| c.clone())); + to_reset.extend( + self.controls + .borrow() + .iter() + .filter(|c| !c.is_in_same_home_subtree(self)) + .map(|c| c.clone()), + ); for control in to_reset.iter() { - control.as_maybe_form_control() - .expect("Element must be a form control") - .reset_form_owner(); + control + .as_maybe_form_control() + .expect("Element must be a form control") + .reset_form_owner(); } } } @@ -1095,46 +1170,47 @@ impl FormControlElementHelpers for Element { let node = self.upcast::<Node>(); match node.type_id() { - NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLButtonElement)) => { - Some(self.downcast::<HTMLButtonElement>().unwrap() as &FormControl) - }, - NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLFieldSetElement)) => { - Some(self.downcast::<HTMLFieldSetElement>().unwrap() as &FormControl) - }, - NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLImageElement)) => { - Some(self.downcast::<HTMLImageElement>().unwrap() as &FormControl) - }, - NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement)) => { - Some(self.downcast::<HTMLInputElement>().unwrap() as &FormControl) - }, - NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLabelElement)) => { - Some(self.downcast::<HTMLLabelElement>().unwrap() as &FormControl) - }, - NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLLegendElement)) => { - Some(self.downcast::<HTMLLegendElement>().unwrap() as &FormControl) - }, - NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLObjectElement)) => { - Some(self.downcast::<HTMLObjectElement>().unwrap() as &FormControl) - }, - NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLOutputElement)) => { - Some(self.downcast::<HTMLOutputElement>().unwrap() as &FormControl) - }, - NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLSelectElement)) => { - Some(self.downcast::<HTMLSelectElement>().unwrap() as &FormControl) - }, - NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement)) => { - Some(self.downcast::<HTMLTextAreaElement>().unwrap() as &FormControl) - }, - _ => { - None - } + NodeTypeId::Element(ElementTypeId::HTMLElement( + HTMLElementTypeId::HTMLButtonElement, + )) => Some(self.downcast::<HTMLButtonElement>().unwrap() as &FormControl), + NodeTypeId::Element(ElementTypeId::HTMLElement( + HTMLElementTypeId::HTMLFieldSetElement, + )) => Some(self.downcast::<HTMLFieldSetElement>().unwrap() as &FormControl), + NodeTypeId::Element(ElementTypeId::HTMLElement( + HTMLElementTypeId::HTMLImageElement, + )) => Some(self.downcast::<HTMLImageElement>().unwrap() as &FormControl), + NodeTypeId::Element(ElementTypeId::HTMLElement( + HTMLElementTypeId::HTMLInputElement, + )) => Some(self.downcast::<HTMLInputElement>().unwrap() as &FormControl), + NodeTypeId::Element(ElementTypeId::HTMLElement( + HTMLElementTypeId::HTMLLabelElement, + )) => Some(self.downcast::<HTMLLabelElement>().unwrap() as &FormControl), + NodeTypeId::Element(ElementTypeId::HTMLElement( + HTMLElementTypeId::HTMLLegendElement, + )) => Some(self.downcast::<HTMLLegendElement>().unwrap() as &FormControl), + NodeTypeId::Element(ElementTypeId::HTMLElement( + HTMLElementTypeId::HTMLObjectElement, + )) => Some(self.downcast::<HTMLObjectElement>().unwrap() as &FormControl), + NodeTypeId::Element(ElementTypeId::HTMLElement( + HTMLElementTypeId::HTMLOutputElement, + )) => Some(self.downcast::<HTMLOutputElement>().unwrap() as &FormControl), + NodeTypeId::Element(ElementTypeId::HTMLElement( + HTMLElementTypeId::HTMLSelectElement, + )) => Some(self.downcast::<HTMLSelectElement>().unwrap() as &FormControl), + NodeTypeId::Element(ElementTypeId::HTMLElement( + HTMLElementTypeId::HTMLTextAreaElement, + )) => Some(self.downcast::<HTMLTextAreaElement>().unwrap() as &FormControl), + _ => None, } } } // https://html.spec.whatwg.org/multipage/#multipart/form-data-encoding-algorithm -pub fn encode_multipart_form_data(form_data: &mut Vec<FormDatum>, - boundary: String, encoding: &'static Encoding) -> Vec<u8> { +pub fn encode_multipart_form_data( + form_data: &mut Vec<FormDatum>, + boundary: String, + encoding: &'static Encoding, +) -> Vec<u8> { // Step 1 let mut result = vec![]; @@ -1157,32 +1233,44 @@ pub fn encode_multipart_form_data(form_data: &mut Vec<FormDatum>, result.append(&mut boundary_bytes); let mut content_disposition = ContentDisposition { disposition: DispositionType::Ext("form-data".to_owned()), - parameters: vec![DispositionParam::Ext("name".to_owned(), String::from(entry.name.clone()))] + parameters: vec![DispositionParam::Ext( + "name".to_owned(), + String::from(entry.name.clone()), + )], }; match entry.value { FormDatumValue::String(ref s) => { - let mut bytes = format!("Content-Disposition: {}\r\n\r\n{}", - content_disposition, s).into_bytes(); + let mut bytes = + format!("Content-Disposition: {}\r\n\r\n{}", content_disposition, s) + .into_bytes(); result.append(&mut bytes); - } + }, FormDatumValue::File(ref f) => { - content_disposition.parameters.push( - DispositionParam::Filename(Charset::Ext(String::from(charset.clone())), - None, - f.name().clone().into())); + content_disposition + .parameters + .push(DispositionParam::Filename( + Charset::Ext(String::from(charset.clone())), + None, + f.name().clone().into(), + )); // https://tools.ietf.org/html/rfc7578#section-4.4 - let content_type = ContentType(f.upcast::<Blob>().Type() - .parse().unwrap_or(mime!(Text / Plain))); - let mut type_bytes = format!("Content-Disposition: {}\r\ncontent-type: {}\r\n\r\n", - content_disposition, - content_type).into_bytes(); + let content_type = ContentType( + f.upcast::<Blob>() + .Type() + .parse() + .unwrap_or(mime!(Text / Plain)), + ); + let mut type_bytes = format!( + "Content-Disposition: {}\r\ncontent-type: {}\r\n\r\n", + content_disposition, content_type + ).into_bytes(); result.append(&mut type_bytes); let mut bytes = f.upcast::<Blob>().get_bytes().unwrap_or(vec![]); result.append(&mut bytes); - } + }, } } |