From 05134e6d1fa93c1068322b0cf3b548ba4b98e849 Mon Sep 17 00:00:00 2001 From: Rohan Prinja Date: Sat, 11 Oct 2014 17:29:15 +0530 Subject: [PATCH] Add form submission via input element --- components/script/dom/htmlformelement.rs | 65 ++++++++++++++----- components/script/dom/htmlinputelement.rs | 52 ++++++++++++++- .../dom/webidls/HTMLInputElement.webidl | 8 +-- 3 files changed, 103 insertions(+), 22 deletions(-) diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs index d8b0ad76695..678a090e69b 100644 --- a/components/script/dom/htmlformelement.rs +++ b/components/script/dom/htmlformelement.rs @@ -367,46 +367,77 @@ pub enum FormMethod { } pub enum FormSubmitter<'a> { - FormElement(JSRef<'a, HTMLFormElement>) + FormElement(JSRef<'a, HTMLFormElement>), + InputElement(JSRef<'a, HTMLInputElement>) // TODO: Submit buttons, image submit, etc etc } impl<'a> FormSubmitter<'a> { fn action(&self) -> DOMString { match *self { - FormElement(form) => form.Action() + FormElement(form) => form.Action(), + InputElement(input_element) => { + let element: JSRef = ElementCast::from_ref(input_element); + if element.has_attribute("formaction") { + input_element.FormAction() + } else { + input_element.form_owner().map_or("".to_string(), |f_o| f_o.Action()) + } + } } } fn enctype(&self) -> FormEncType { - match *self { - FormElement(form) => { - match form.Enctype().as_slice() { - "multipart/form-data" => FormDataEncoded, - "text/plain" => TextPlainEncoded, - // https://html.spec.whatwg.org/multipage/forms.html#attr-fs-enctype - // urlencoded is the default - _ => UrlEncoded + let attr = match *self { + FormElement(form) => form.Enctype(), + InputElement(input_element) => { + let element: JSRef = ElementCast::from_ref(input_element); + if element.has_attribute("formenctype") { + input_element.FormEnctype() + } else { + input_element.form_owner().map_or("".to_string(), |f_o| f_o.Enctype()) } } + }; + match attr.as_slice() { + "multipart/form-data" => FormDataEncoded, + "text/plain" => TextPlainEncoded, + // https://html.spec.whatwg.org/multipage/forms.html#attr-fs-enctype + // urlencoded is the default + _ => UrlEncoded } } fn method(&self) -> FormMethod { - match *self { - FormElement(form) => { - match form.Method().as_slice() { - "dialog" => FormDialog, - "post" => FormPost, - _ => FormGet + let attr = match *self { + FormElement(form) => form.Method(), + InputElement(input_element) => { + let element: JSRef = ElementCast::from_ref(input_element); + if element.has_attribute("formmethod") { + input_element.FormMethod() + } else { + input_element.form_owner().map_or("".to_string(), |f_o| f_o.Method()) } } + }; + match attr.as_slice() { + "dialog" => FormDialog, + "post" => FormPost, + _ => FormGet } } fn target(&self) -> DOMString { match *self { - FormElement(form) => form.Target() + FormElement(form) => form.Target(), + InputElement(input_element) => { + let element: JSRef = ElementCast::from_ref(input_element); + if element.has_attribute("formtarget") { + input_element.FormTarget() + } else { + input_element.form_owner().map_or("".to_string(), |f_o| f_o.Target()) + } + } } } } diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 20d8beb5390..14468721e0c 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -19,7 +19,7 @@ use dom::event::Event; use dom::eventtarget::{EventTarget, NodeTargetTypeId}; use dom::htmlelement::HTMLElement; use dom::htmlformelement::{FormOwner, HTMLFormElement}; -use dom::node::{DisabledStateHelpers, Node, NodeHelpers, ElementNodeTypeId, document_from_node}; +use dom::node::{DisabledStateHelpers, Node, NodeHelpers, ElementNodeTypeId, document_from_node, window_from_node}; use dom::virtualmethods::VirtualMethods; use servo_util::str::{DOMString, parse_unsigned_integer}; @@ -169,6 +169,56 @@ impl<'a> HTMLInputElementMethods for JSRef<'a, HTMLInputElement> { // https://html.spec.whatwg.org/multipage/forms.html#attr-fe-name make_setter!(SetName, "name") + + // https://html.spec.whatwg.org/multipage/forms.html#dom-input-formaction + fn FormAction(self) -> DOMString { + let element: JSRef = ElementCast::from_ref(self); + let url = element.get_url_attribute("formaction"); + match url.as_slice() { + "" => { + let window = window_from_node(self).root(); + window.get_url().serialize() + }, + _ => url + } + } + + // https://html.spec.whatwg.org/multipage/forms.html#dom-input-formaction + make_setter!(SetFormAction, "formaction") + + // https://html.spec.whatwg.org/multipage/forms.html#dom-input-formenctype + fn FormEnctype(self) -> DOMString { + let elem: JSRef = ElementCast::from_ref(self); + let enctype = elem.get_string_attribute("formenctype").into_ascii_lower(); + // https://html.spec.whatwg.org/multipage/forms.html#attr-fs-enctype + match enctype.as_slice() { + "text/plain" | "multipart/form-data" => enctype, + _ => "application/x-www-form-urlencoded".to_string() + } + } + + // https://html.spec.whatwg.org/multipage/forms.html#dom-input-formenctype + make_setter!(SetFormEnctype, "formenctype") + + // https://html.spec.whatwg.org/multipage/forms.html#dom-input-formmethod + fn FormMethod(self) -> DOMString { + let elem: JSRef = ElementCast::from_ref(self); + let method = elem.get_string_attribute("formmethod").into_ascii_lower(); + // https://html.spec.whatwg.org/multipage/forms.html#attr-fs-method + match method.as_slice() { + "post" | "dialog" => method, + _ => "get".to_string() + } + } + + // https://html.spec.whatwg.org/multipage/forms.html#dom-input-formmethod + make_setter!(SetFormMethod, "formmethod") + + // https://html.spec.whatwg.org/multipage/forms.html#dom-input-formtarget + make_getter!(FormTarget) + + // https://html.spec.whatwg.org/multipage/forms.html#dom-input-formtarget + make_setter!(SetFormTarget, "formtarget") } trait HTMLInputElementHelpers { diff --git a/components/script/dom/webidls/HTMLInputElement.webidl b/components/script/dom/webidls/HTMLInputElement.webidl index f2b888dca47..b69d8fcf4ff 100644 --- a/components/script/dom/webidls/HTMLInputElement.webidl +++ b/components/script/dom/webidls/HTMLInputElement.webidl @@ -15,11 +15,11 @@ interface HTMLInputElement : HTMLElement { attribute boolean disabled; //readonly attribute HTMLFormElement? form; //readonly attribute FileList? files; - // attribute DOMString formAction; - // attribute DOMString formEnctype; - // attribute DOMString formMethod; + attribute DOMString formAction; + attribute DOMString formEnctype; + attribute DOMString formMethod; // attribute boolean formNoValidate; - // attribute DOMString formTarget; + attribute DOMString formTarget; // attribute unsigned long height; // attribute boolean indeterminate; // attribute DOMString inputMode;