servo: Merge #10953 - Implement text/plain form encoding (from KiChjang:text-plain-encoding); r=jdm
authorKeith Yeung <kungfukeith11@gmail.com>
Wed, 11 May 2016 19:43:37 -0700
changeset 338778 d8755ecef73619f80b23b478c3edd67309ac4a9c
parent 338777 8a6c443134eb73b1f806dbfce5792e2ce446a91c
child 338779 cb5b56f39f3f413d6b8d81be1ef0739c24e686d1
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdm
servo: Merge #10953 - Implement text/plain form encoding (from KiChjang:text-plain-encoding); r=jdm Fixes #3649. Source-Repo: https://github.com/servo/servo Source-Revision: 641b374f0b752671207d21941c3e5ff4e681d706
servo/components/script/dom/htmlformelement.rs
--- a/servo/components/script/dom/htmlformelement.rs
+++ b/servo/components/script/dom/htmlformelement.rs
@@ -265,19 +265,19 @@ impl HTMLFormElement {
             return candidate_encodings.next().unwrap_or(UTF_8);
         }
 
         // Step 1, 3
         document_from_node(self).encoding()
     }
 
     // https://html.spec.whatwg.org/multipage/#multipart/form-data-encoding-algorithm
-    fn encode_form_data(&self, form_data: &mut Vec<FormDatum>,
-                               encoding: Option<EncodingRef>,
-                               boundary: String) -> String {
+    fn encode_multipart_form_data(&self, form_data: &mut Vec<FormDatum>,
+                                  encoding: Option<EncodingRef>,
+                                  boundary: String) -> String {
         // Step 1
         let mut result = "".to_owned();
 
         // Step 2
         // (maybe take encoding as input)
         let encoding = encoding.unwrap_or(self.pick_encoding());
 
         //  Step 3
@@ -316,17 +316,47 @@ impl HTMLFormElement {
 
                     result.push_str(from_utf8(&f.upcast::<Blob>().get_data().get_bytes()).unwrap());
                 }
             }
         }
 
         result.push_str(&*format!("\r\n--{}--", boundary));
 
-        return result;
+        result
+    }
+
+    // https://html.spec.whatwg.org/multipage/#text/plain-encoding-algorithm
+    fn encode_plaintext(&self, form_data: &mut Vec<FormDatum>) -> String {
+        // Step 1
+        let mut result = String::new();
+
+        // Step 2
+        let encoding = self.pick_encoding();
+
+        // Step 3
+        let charset = &*encoding.whatwg_name().unwrap();
+
+        for entry in form_data.iter_mut() {
+            // Step 4
+            if entry.name == "_charset_" && entry.ty == "hidden" {
+                entry.value = FormDatumValue::String(DOMString::from(charset.clone()));
+            }
+
+            // Step 5
+            if entry.ty == "file" {
+                entry.value = FormDatumValue::String(DOMString::from(entry.value_str()));
+            }
+
+            // Step 6
+            result.push_str(&*format!("{}={}\r\n", entry.name, entry.value_str()));
+        }
+
+        // Step 7
+        result
     }
 
     /// [Form submission](https://html.spec.whatwg.org/multipage/#concept-form-submit)
     pub fn submit(&self, submit_method_flag: SubmittedFrom, submitter: FormSubmitter) {
         // Step 1
         let doc = document_from_node(self);
         let base = doc.url();
         // TODO: Handle browsing contexts
@@ -372,28 +402,32 @@ impl HTMLFormElement {
 
         let mut load_data = LoadData::new(action_components, doc.get_referrer_policy(), Some(doc.url().clone()));
 
         let parsed_data = match enctype {
             FormEncType::UrlEncoded => {
                 load_data.headers.set(ContentType::form_url_encoded());
 
                 form_urlencoded::Serializer::new(String::new())
+                    .encoding_override(Some(self.pick_encoding()))
                     .extend_pairs(form_data.into_iter().map(|field| (field.name.clone(), field.value_str())))
                     .finish()
             }
             FormEncType::FormDataEncoded => {
                 let boundary = self.generate_boundary();
                 let mime = mime!(Multipart / FormData; Boundary =(&boundary));
                 load_data.headers.set(ContentType(mime));
 
-                self.encode_form_data(&mut form_data, None, boundary)
+                self.encode_multipart_form_data(&mut form_data, None, boundary)
             }
-            // TODO: Support plain text encoding
-            FormEncType::TextPlainEncoded => "".to_owned()
+            FormEncType::TextPlainEncoded => {
+                load_data.headers.set(ContentType(mime!(Text / Plain)));
+
+                self.encode_plaintext(&mut form_data)
+            }
         };
 
         // Step 18
         let win = window_from_node(self);
         match (&*scheme, method) {
             // https://html.spec.whatwg.org/multipage/#submit-dialog
             (_, FormMethod::FormDialog) => return, // Unimplemented
             // https://html.spec.whatwg.org/multipage/#submit-mutate-action