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;