aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <metajack+bors@gmail.com>2014-10-11 07:45:39 -0600
committerbors-servo <metajack+bors@gmail.com>2014-10-11 07:45:39 -0600
commit9dfd5e7fcd2011a411b219e8c45aadc0ecb270bd (patch)
tree766433d45e69aa6d8abfdbd447d59bcda43461e5
parente048f3f940e124d45b43a53a850177c45907822d (diff)
parentca2d5d328d18878e369dd010236754ae207dab7d (diff)
downloadservo-9dfd5e7fcd2011a411b219e8c45aadc0ecb270bd.tar.gz
servo-9dfd5e7fcd2011a411b219e8c45aadc0ecb270bd.zip
auto merge of #3642 : Manishearth/servo/form-submit, r=jdm
This is missing a lot of parts, so it doesn't really make any real-world form submission work yet. It provides a skeleton on which the missing bits can be filled in. What works: - `<input>` elements except for `type=file` - GET/POST methods - URLencoded `enctype`s (default) - Submission via `<form>.submit()` only Stuff that needs to be done for most simple real-world cases to work: - [Working text input](https://github.com/servo/servo/pull/3585) - Click handlers for `<submit>` - Possibly `<textarea>` support - Support for the other two enctypes (#3649) Todo: - Correctly implement [planned navigation](https://html.spec.whatwg.org/multipage/forms.html#planned-navigation) using `TrustedFormAddress` (#3648) - [Correctly implement form owners.](https://github.com/servo/servo/issues/3553) Requires html5ever and some discussion of the spec. - `<input type=file>` support - Image submit support - Browsing contexts/targets - Support for non-`<input>` controls - Validation (?) - Dirname (?)
-rw-r--r--components/script/dom/htmlbuttonelement.rs19
-rw-r--r--components/script/dom/htmlformelement.rs279
-rw-r--r--components/script/dom/htmlinputelement.rs29
-rw-r--r--components/script/dom/htmlobjectelement.rs6
-rw-r--r--components/script/dom/htmlselectelement.rs14
-rw-r--r--components/script/dom/htmltextareaelement.rs5
-rw-r--r--components/script/dom/webidls/HTMLButtonElement.webidl2
-rw-r--r--components/script/dom/webidls/HTMLFormElement.webidl2
-rw-r--r--components/script/dom/webidls/HTMLInputElement.webidl2
-rw-r--r--components/script/dom/webidls/HTMLObjectElement.webidl2
-rw-r--r--components/script/dom/webidls/HTMLSelectElement.webidl2
-rw-r--r--components/script/dom/webidls/HTMLTextAreaElement.webidl2
-rw-r--r--components/script/dom/window.rs3
-rw-r--r--components/script/script_task.rs8
-rw-r--r--tests/html/form_submission_handsfree.html16
-rw-r--r--tests/wpt/metadata/html/dom/interfaces.html.ini33
-rw-r--r--tests/wpt/metadata/html/dom/reflection-embedded.html.ini129
-rw-r--r--tests/wpt/metadata/html/semantics/embedded-content/the-img-element/srcset/select-an-image-source.html.ini3
-rw-r--r--tests/wpt/metadata/html/semantics/forms/the-input-element/date.html.ini3
-rw-r--r--tests/wpt/metadata/html/semantics/forms/the-input-element/datetime.html.ini15
-rw-r--r--tests/wpt/metadata/html/semantics/forms/the-input-element/month.html.ini3
-rw-r--r--tests/wpt/metadata/html/semantics/forms/the-input-element/range-2.html.ini3
-rw-r--r--tests/wpt/metadata/html/semantics/forms/the-input-element/range.html.ini3
-rw-r--r--tests/wpt/metadata/html/semantics/forms/the-input-element/search_input.html.ini3
-rw-r--r--tests/wpt/metadata/html/semantics/forms/the-input-element/telephone.html.ini3
-rw-r--r--tests/wpt/metadata/html/semantics/forms/the-input-element/time.html.ini3
-rw-r--r--tests/wpt/metadata/html/semantics/forms/the-input-element/url.html.ini3
-rw-r--r--tests/wpt/metadata/html/semantics/forms/the-textarea-element/textarea-type.html.ini5
28 files changed, 368 insertions, 232 deletions
diff --git a/components/script/dom/htmlbuttonelement.rs b/components/script/dom/htmlbuttonelement.rs
index baf3fba6c93..f12035d148e 100644
--- a/components/script/dom/htmlbuttonelement.rs
+++ b/components/script/dom/htmlbuttonelement.rs
@@ -4,18 +4,19 @@
use dom::bindings::codegen::Bindings::HTMLButtonElementBinding;
use dom::bindings::codegen::Bindings::HTMLButtonElementBinding::HTMLButtonElementMethods;
-use dom::bindings::codegen::InheritTypes::{HTMLElementCast, NodeCast};
+use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, NodeCast};
use dom::bindings::codegen::InheritTypes::{HTMLButtonElementDerived, HTMLFieldSetElementDerived};
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::utils::{Reflectable, Reflector};
use dom::document::Document;
-use dom::element::{AttributeHandlers, HTMLButtonElementTypeId};
+use dom::element::{AttributeHandlers, Element, HTMLButtonElementTypeId};
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::node::{DisabledStateHelpers, Node, NodeHelpers, ElementNodeTypeId, window_from_node};
use dom::validitystate::ValidityState;
use dom::virtualmethods::VirtualMethods;
+use std::ascii::OwnedStrAsciiExt;
use servo_util::str::DOMString;
use string_cache::Atom;
@@ -56,6 +57,20 @@ impl<'a> HTMLButtonElementMethods for JSRef<'a, HTMLButtonElement> {
// http://www.whatwg.org/html/#dom-fe-disabled
make_bool_setter!(SetDisabled, "disabled")
+
+ // https://html.spec.whatwg.org/multipage/forms.html#dom-button-type
+ fn Type(self) -> DOMString {
+ let elem: JSRef<Element> = ElementCast::from_ref(self);
+ let ty = elem.get_string_attribute("type").into_ascii_lower();
+ // https://html.spec.whatwg.org/multipage/forms.html#attr-button-type
+ match ty.as_slice() {
+ "reset" | "button" | "menu" => ty,
+ _ => "submit".to_string()
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/forms.html#dom-button-type
+ make_setter!(SetType, "type")
}
impl<'a> VirtualMethods for JSRef<'a, HTMLButtonElement> {
diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs
index 7b2ee466bab..03bd593cb64 100644
--- a/components/script/dom/htmlformelement.rs
+++ b/components/script/dom/htmlformelement.rs
@@ -2,19 +2,32 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
+use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
use dom::bindings::codegen::Bindings::HTMLFormElementBinding;
use dom::bindings::codegen::Bindings::HTMLFormElementBinding::HTMLFormElementMethods;
-use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLFormElementDerived};
+use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementMethods;
+use dom::bindings::codegen::InheritTypes::{ElementCast, EventTargetCast, HTMLFormElementDerived, NodeCast};
+use dom::bindings::codegen::InheritTypes::HTMLInputElementCast;
+use dom::bindings::global::Window;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::utils::{Reflectable, Reflector};
-use dom::document::Document;
-use dom::element::{Element, AttributeHandlers, HTMLFormElementTypeId};
+use dom::document::{Document, DocumentHelpers};
+use dom::element::{Element, AttributeHandlers, HTMLFormElementTypeId, HTMLTextAreaElementTypeId, HTMLDataListElementTypeId};
+use dom::element::{HTMLInputElementTypeId, HTMLButtonElementTypeId, HTMLObjectElementTypeId, HTMLSelectElementTypeId};
+use dom::event::Event;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
-use dom::node::{Node, ElementNodeTypeId, window_from_node};
+use dom::htmlinputelement::HTMLInputElement;
+use dom::node::{Node, NodeHelpers, ElementNodeTypeId, document_from_node, window_from_node};
+use http::method::Post;
+use servo_msg::constellation_msg::LoadData;
use servo_util::str::DOMString;
+use script_task::{ScriptChan, TriggerLoadMsg};
use std::ascii::OwnedStrAsciiExt;
-
+use std::str::StrSlice;
+use url::UrlParser;
+use url::form_urlencoded::serialize;
#[jstraceable]
#[must_root]
@@ -52,7 +65,7 @@ impl<'a> HTMLFormElementMethods for JSRef<'a, HTMLFormElement> {
// https://html.spec.whatwg.org/multipage/forms.html#dom-fs-action
fn Action(self) -> DOMString {
let element: JSRef<Element> = ElementCast::from_ref(self);
- let url = element.get_url_attribute("src");
+ let url = element.get_url_attribute("action");
match url.as_slice() {
"" => {
let window = window_from_node(self).root();
@@ -135,6 +148,196 @@ impl<'a> HTMLFormElementMethods for JSRef<'a, HTMLFormElement> {
// https://html.spec.whatwg.org/multipage/forms.html#dom-fs-target
make_setter!(SetTarget, "target")
+
+ // https://html.spec.whatwg.org/multipage/forms.html#the-form-element:concept-form-submit
+ fn Submit(self) {
+ self.submit(true, FormElement(self));
+ }
+}
+
+pub trait HTMLFormElementHelpers {
+ // https://html.spec.whatwg.org/multipage/forms.html#concept-form-submit
+ fn submit(self, from_submit_method: bool, submitter: FormSubmitter);
+ // https://html.spec.whatwg.org/multipage/forms.html#constructing-the-form-data-set
+ fn get_form_dataset(self, submitter: Option<FormSubmitter>) -> Vec<FormDatum>;
+}
+
+impl<'a> HTMLFormElementHelpers for JSRef<'a, HTMLFormElement> {
+ fn submit(self, _from_submit_method: bool, submitter: FormSubmitter) {
+ // Step 1
+ let doc = document_from_node(self).root();
+ let win = window_from_node(self).root();
+ let base = doc.url();
+ // TODO: Handle browsing contexts
+ // TODO: Handle validation
+ let event = Event::new(&Window(*win),
+ "submit".to_string(),
+ true, true).root();
+ let target: JSRef<EventTarget> = EventTargetCast::from_ref(self);
+ target.DispatchEvent(*event).ok();
+ if event.DefaultPrevented() {
+ return;
+ }
+ // Step 6
+ let form_data = self.get_form_dataset(Some(submitter));
+ // Step 7-8
+ let mut action = submitter.action();
+ if action.is_empty() {
+ action = base.serialize();
+ }
+ // TODO: Resolve the url relative to the submitter element
+ // Step 10-15
+ let action_components = UrlParser::new().base_url(base).parse(action.as_slice()).unwrap_or(base.clone());
+ let _action = action_components.serialize();
+ let scheme = action_components.scheme.clone();
+ let enctype = submitter.enctype();
+ let method = submitter.method();
+ let _target = submitter.target();
+ // TODO: Handle browsing contexts, partially loaded documents (step 16-17)
+
+ let parsed_data = match enctype {
+ UrlEncoded => serialize(form_data.iter().map(|d| (d.name.as_slice(), d.value.as_slice())), None),
+ _ => "".to_string() // TODO: Add serializers for the other encoding types
+ };
+
+ let mut load_data = LoadData::new(action_components);
+ // Step 18
+ match (scheme.as_slice(), method) {
+ (_, FormDialog) => return, // Unimplemented
+ ("http", FormGet) | ("https", FormGet) => {
+ load_data.url.query = Some(parsed_data);
+ },
+ ("http", FormPost) | ("https", FormPost) => {
+ load_data.method = Post;
+ load_data.data = Some(parsed_data.into_bytes());
+ },
+ // https://html.spec.whatwg.org/multipage/forms.html#submit-get-action
+ ("ftp", _) | ("javascript", _) | ("data", FormGet) => (),
+ _ => return // Unimplemented (data and mailto)
+ }
+
+ // This is wrong. https://html.spec.whatwg.org/multipage/forms.html#planned-navigation
+ let ScriptChan(ref script_chan) = win.script_chan;
+ script_chan.send(TriggerLoadMsg(win.page.id, load_data));
+ }
+
+ fn get_form_dataset(self, _submitter: Option<FormSubmitter>) -> Vec<FormDatum> {
+ fn clean_crlf(s: &str) -> DOMString {
+ // https://html.spec.whatwg.org/multipage/forms.html#constructing-the-form-data-set
+ // Step 4
+ let mut buf = "".to_string();
+ let mut prev = ' ';
+ for ch in s.chars() {
+ match ch {
+ '\n' if prev != '\r' => {
+ buf.push_char('\r');
+ buf.push_char('\n');
+ },
+ '\n' => {
+ buf.push_char('\n');
+ },
+ // This character isn't LF but is
+ // preceded by CR
+ _ if prev == '\r' => {
+ buf.push_char('\r');
+ buf.push_char('\n');
+ buf.push_char(ch);
+ },
+ _ => buf.push_char(ch)
+ };
+ prev = ch;
+ }
+ // In case the last character was CR
+ if prev == '\r' {
+ buf.push_char('\n');
+ }
+ buf
+ }
+
+ let node: JSRef<Node> = NodeCast::from_ref(self);
+ // TODO: This is an incorrect way of getting controls owned
+ // by the form, but good enough until html5ever lands
+ let mut data_set = node.traverse_preorder().filter_map(|child| {
+ if child.get_disabled_state() {
+ return None;
+ }
+ if child.ancestors().any(|a| a.type_id() == ElementNodeTypeId(HTMLDataListElementTypeId)) {
+ return None;
+ }
+ // XXXManishearth don't include it if it is a button but not the submitter
+ match child.type_id() {
+ ElementNodeTypeId(HTMLInputElementTypeId) => {
+ let input: JSRef<HTMLInputElement> = HTMLInputElementCast::to_ref(child).unwrap();
+ let ty = input.Type();
+ let name = input.Name();
+ match ty.as_slice() {
+ "radio" | "checkbox" => {
+ if !input.Checked() || name.is_empty() {
+ return None;
+ }
+ },
+ "image" => (),
+ _ => {
+ if name.is_empty() {
+ return None;
+ }
+ }
+ }
+
+ let mut value = input.Value();
+ match ty.as_slice() {
+ "image" => None, // Unimplemented
+ "radio" | "checkbox" => {
+ if value.is_empty() {
+ value = "on".to_string();
+ }
+ Some(FormDatum {
+ ty: ty,
+ name: name,
+ value: value
+ })
+ },
+ "file" => None, // Unimplemented
+ _ => Some(FormDatum {
+ ty: ty,
+ name: name,
+ value: input.Value()
+ })
+ }
+ }
+ ElementNodeTypeId(HTMLButtonElementTypeId) => {
+ // Unimplemented
+ None
+ }
+ ElementNodeTypeId(HTMLSelectElementTypeId) => {
+ // Unimplemented
+ None
+ }
+ ElementNodeTypeId(HTMLObjectElementTypeId) => {
+ // Unimplemented
+ None
+ }
+ ElementNodeTypeId(HTMLTextAreaElementTypeId) => {
+ // Unimplemented
+ None
+ }
+ _ => None
+ }
+ });
+ // TODO: Handle `dirnames` (needs directionality support)
+ // https://html.spec.whatwg.org/multipage/dom.html#the-directionality
+ let mut ret: Vec<FormDatum> = data_set.collect();
+ for mut datum in ret.iter_mut() {
+ match datum.ty.as_slice() {
+ "file" | "textarea" => (),
+ _ => {
+ datum.name = clean_crlf(datum.name.as_slice());
+ datum.value = clean_crlf(datum.value.as_slice());
+ }
+ }
+ };
+ ret
+ }
}
impl Reflectable for HTMLFormElement {
@@ -142,3 +345,67 @@ impl Reflectable for HTMLFormElement {
self.htmlelement.reflector()
}
}
+
+// TODO: add file support
+pub struct FormDatum {
+ pub ty: DOMString,
+ pub name: DOMString,
+ pub value: DOMString
+}
+
+pub enum FormEncType {
+ TextPlainEncoded,
+ UrlEncoded,
+ FormDataEncoded
+}
+
+pub enum FormMethod {
+ FormGet,
+ FormPost,
+ FormDialog
+}
+
+pub enum FormSubmitter<'a> {
+ FormElement(JSRef<'a, HTMLFormElement>)
+ // TODO: Submit buttons, image submit, etc etc
+}
+
+impl<'a> FormSubmitter<'a> {
+ fn action(&self) -> DOMString {
+ match *self {
+ FormElement(form) => form.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
+ }
+ }
+ }
+ }
+
+ fn method(&self) -> FormMethod {
+ match *self {
+ FormElement(form) => {
+ match form.Method().as_slice() {
+ "dialog" => FormDialog,
+ "post" => FormPost,
+ _ => FormGet
+ }
+ }
+ }
+ }
+
+ fn target(&self) -> DOMString {
+ match *self {
+ FormElement(form) => form.Target()
+ }
+ }
+}
diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs
index 9908807a713..ab9818d99f0 100644
--- a/components/script/dom/htmlinputelement.rs
+++ b/components/script/dom/htmlinputelement.rs
@@ -24,6 +24,7 @@ use dom::virtualmethods::VirtualMethods;
use servo_util::str::{DOMString, parse_unsigned_integer};
use string_cache::Atom;
+use std::ascii::OwnedStrAsciiExt;
use std::cell::{Cell, RefCell};
use std::mem;
@@ -120,7 +121,9 @@ impl<'a> HTMLInputElementMethods for JSRef<'a, HTMLInputElement> {
make_bool_setter!(SetDisabled, "disabled")
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-checked
- make_bool_getter!(Checked)
+ fn Checked(self) -> bool {
+ self.checked.get()
+ }
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-checked
make_bool_setter!(SetChecked, "checked")
@@ -131,8 +134,30 @@ impl<'a> HTMLInputElementMethods for JSRef<'a, HTMLInputElement> {
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-size
make_uint_setter!(SetSize, "size")
+ // https://html.spec.whatwg.org/multipage/forms.html#dom-input-type
+ fn Type(self) -> DOMString {
+ let elem: JSRef<Element> = ElementCast::from_ref(self);
+ let ty = elem.get_string_attribute("type").into_ascii_lower();
+ // https://html.spec.whatwg.org/multipage/forms.html#attr-input-type
+ match ty.as_slice() {
+ "hidden" | "search" | "tel" |
+ "url" | "email" | "password" |
+ "datetime" | "date" | "month" |
+ "week" | "time" | "datetime-local" |
+ "number" | "range" | "color" |
+ "checkbox" | "radio" | "file" |
+ "submit" | "image" | "reset" | "button" => ty,
+ _ => "text".to_string()
+ }
+ }
+
+ // https://html.spec.whatwg.org/multipage/forms.html#dom-input-type
+ make_setter!(SetType, "type")
+
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-value
- make_getter!(Value)
+ fn Value(self) -> DOMString {
+ self.value.borrow().clone().unwrap_or("".to_string())
+ }
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-value
make_setter!(SetValue, "value")
diff --git a/components/script/dom/htmlobjectelement.rs b/components/script/dom/htmlobjectelement.rs
index f5aadd3c956..1d39c3a07f5 100644
--- a/components/script/dom/htmlobjectelement.rs
+++ b/components/script/dom/htmlobjectelement.rs
@@ -86,6 +86,12 @@ impl<'a> HTMLObjectElementMethods for JSRef<'a, HTMLObjectElement> {
let window = window_from_node(self).root();
ValidityState::new(*window)
}
+
+ // https://html.spec.whatwg.org/multipage/embedded-content.html#dom-object-type
+ make_getter!(Type)
+
+ // https://html.spec.whatwg.org/multipage/embedded-content.html#dom-object-type
+ make_setter!(SetType, "type")
}
impl<'a> VirtualMethods for JSRef<'a, HTMLObjectElement> {
diff --git a/components/script/dom/htmlselectelement.rs b/components/script/dom/htmlselectelement.rs
index 53f8ce3efff..8c86318c38c 100644
--- a/components/script/dom/htmlselectelement.rs
+++ b/components/script/dom/htmlselectelement.rs
@@ -5,13 +5,13 @@
use dom::bindings::codegen::Bindings::HTMLSelectElementBinding;
use dom::bindings::codegen::Bindings::HTMLSelectElementBinding::HTMLSelectElementMethods;
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, NodeCast};
-use dom::bindings::codegen::InheritTypes::{HTMLSelectElementDerived, HTMLFieldSetElementDerived};
+use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLSelectElementDerived, HTMLFieldSetElementDerived};
use dom::bindings::codegen::UnionTypes::HTMLElementOrLong::HTMLElementOrLong;
use dom::bindings::codegen::UnionTypes::HTMLOptionElementOrHTMLOptGroupElement::HTMLOptionElementOrHTMLOptGroupElement;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::utils::{Reflectable, Reflector};
use dom::document::Document;
-use dom::element::{AttributeHandlers, HTMLSelectElementTypeId};
+use dom::element::{AttributeHandlers, Element, HTMLSelectElementTypeId};
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::node::{DisabledStateHelpers, Node, NodeHelpers, ElementNodeTypeId, window_from_node};
@@ -62,6 +62,16 @@ impl<'a> HTMLSelectElementMethods for JSRef<'a, HTMLSelectElement> {
// http://www.whatwg.org/html/#dom-fe-disabled
make_bool_setter!(SetDisabled, "disabled")
+
+ // https://html.spec.whatwg.org/multipage/forms.html#dom-select-type
+ fn Type(self) -> DOMString {
+ let elem: JSRef<Element> = ElementCast::from_ref(self);
+ if elem.has_attribute("multiple") {
+ "select-multiple".to_string()
+ } else {
+ "select-one".to_string()
+ }
+ }
}
impl<'a> VirtualMethods for JSRef<'a, HTMLSelectElement> {
diff --git a/components/script/dom/htmltextareaelement.rs b/components/script/dom/htmltextareaelement.rs
index 5dd688782cf..d109a26c524 100644
--- a/components/script/dom/htmltextareaelement.rs
+++ b/components/script/dom/htmltextareaelement.rs
@@ -50,6 +50,11 @@ impl<'a> HTMLTextAreaElementMethods for JSRef<'a, HTMLTextAreaElement> {
// http://www.whatwg.org/html/#dom-fe-disabled
make_bool_setter!(SetDisabled, "disabled")
+
+ // https://html.spec.whatwg.org/multipage/forms.html#dom-textarea-type
+ fn Type(self) -> DOMString {
+ "textarea".to_string()
+ }
}
impl<'a> VirtualMethods for JSRef<'a, HTMLTextAreaElement> {
diff --git a/components/script/dom/webidls/HTMLButtonElement.webidl b/components/script/dom/webidls/HTMLButtonElement.webidl
index ad21e11370f..622abbd1cf5 100644
--- a/components/script/dom/webidls/HTMLButtonElement.webidl
+++ b/components/script/dom/webidls/HTMLButtonElement.webidl
@@ -14,7 +14,7 @@ interface HTMLButtonElement : HTMLElement {
// attribute boolean formNoValidate;
// attribute DOMString formTarget;
// attribute DOMString name;
- // attribute DOMString type;
+ attribute DOMString type;
// attribute DOMString value;
// attribute HTMLMenuElement? menu;
diff --git a/components/script/dom/webidls/HTMLFormElement.webidl b/components/script/dom/webidls/HTMLFormElement.webidl
index 0878a6931a2..1971680b5be 100644
--- a/components/script/dom/webidls/HTMLFormElement.webidl
+++ b/components/script/dom/webidls/HTMLFormElement.webidl
@@ -21,7 +21,7 @@ interface HTMLFormElement : HTMLElement {
//getter Element (unsigned long index);
//getter (RadioNodeList or Element) (DOMString name);
- //void submit();
+ void submit();
//void reset();
//boolean checkValidity();
//boolean reportValidity();
diff --git a/components/script/dom/webidls/HTMLInputElement.webidl b/components/script/dom/webidls/HTMLInputElement.webidl
index a418f50928c..f2b888dca47 100644
--- a/components/script/dom/webidls/HTMLInputElement.webidl
+++ b/components/script/dom/webidls/HTMLInputElement.webidl
@@ -37,7 +37,7 @@ interface HTMLInputElement : HTMLElement {
attribute unsigned long size;
// attribute DOMString src;
// attribute DOMString step;
- // attribute DOMString type; //XXXjdm need binaryName
+ attribute DOMString type;
// attribute DOMString defaultValue;
[TreatNullAs=EmptyString] attribute DOMString value;
// attribute Date? valueAsDate;
diff --git a/components/script/dom/webidls/HTMLObjectElement.webidl b/components/script/dom/webidls/HTMLObjectElement.webidl
index 56fc290e546..e2f6aa3cb75 100644
--- a/components/script/dom/webidls/HTMLObjectElement.webidl
+++ b/components/script/dom/webidls/HTMLObjectElement.webidl
@@ -6,7 +6,7 @@
// http://www.whatwg.org/html/#htmlobjectelement
interface HTMLObjectElement : HTMLElement {
// attribute DOMString data;
- // attribute DOMString type;
+ attribute DOMString type;
// attribute boolean typeMustMatch;
// attribute DOMString name;
// attribute DOMString useMap;
diff --git a/components/script/dom/webidls/HTMLSelectElement.webidl b/components/script/dom/webidls/HTMLSelectElement.webidl
index 91d4c3b0917..6b36b65e709 100644
--- a/components/script/dom/webidls/HTMLSelectElement.webidl
+++ b/components/script/dom/webidls/HTMLSelectElement.webidl
@@ -13,7 +13,7 @@ interface HTMLSelectElement : HTMLElement {
// attribute boolean required;
// attribute unsigned long size;
- //readonly attribute DOMString type;
+ readonly attribute DOMString type;
//readonly attribute HTMLOptionsCollection options;
// attribute unsigned long length;
diff --git a/components/script/dom/webidls/HTMLTextAreaElement.webidl b/components/script/dom/webidls/HTMLTextAreaElement.webidl
index 534bb87a0e5..f3fb5b3cf40 100644
--- a/components/script/dom/webidls/HTMLTextAreaElement.webidl
+++ b/components/script/dom/webidls/HTMLTextAreaElement.webidl
@@ -21,7 +21,7 @@ interface HTMLTextAreaElement : HTMLElement {
// attribute unsigned long rows;
// attribute DOMString wrap;
- //readonly attribute DOMString type;
+ readonly attribute DOMString type;
// attribute DOMString defaultValue;
//[TreatNullAs=EmptyString] attribute DOMString value;
//readonly attribute unsigned long textLength;
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index 02166f328e4..f3edfc04943 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -24,6 +24,7 @@ use script_task::{ExitWindowMsg, FireTimerMsg, ScriptChan, TriggerLoadMsg, Trigg
use script_traits::ScriptControlChan;
use servo_msg::compositor_msg::ScriptListener;
+use servo_msg::constellation_msg::LoadData;
use servo_net::image_cache_task::ImageCacheTask;
use servo_util::str::{DOMString,HTML_SPACE_CHARACTERS};
use servo_util::task::{spawn_named};
@@ -432,7 +433,7 @@ impl<'a> WindowHelpers for JSRef<'a, Window> {
if href.as_slice().starts_with("#") {
script_chan.send(TriggerFragmentMsg(self.page.id, url));
} else {
- script_chan.send(TriggerLoadMsg(self.page.id, url));
+ script_chan.send(TriggerLoadMsg(self.page.id, LoadData::new(url)));
}
}
diff --git a/components/script/script_task.rs b/components/script/script_task.rs
index 29e1fec40ba..e62c818943c 100644
--- a/components/script/script_task.rs
+++ b/components/script/script_task.rs
@@ -81,7 +81,7 @@ pub enum ScriptMsg {
TriggerFragmentMsg(PipelineId, Url),
/// Begins a content-initiated load on the specified pipeline (only
/// dispatched to ScriptTask).
- TriggerLoadMsg(PipelineId, Url),
+ TriggerLoadMsg(PipelineId, LoadData),
/// Instructs the script task to send a navigate message to
/// the constellation (only dispatched to ScriptTask).
NavigateMsg(NavigationDirection),
@@ -494,7 +494,7 @@ impl ScriptTask {
// TODO(tkuehn) need to handle auxiliary layouts for iframes
FromConstellation(AttachLayoutMsg(_)) => fail!("should have handled AttachLayoutMsg already"),
FromConstellation(LoadMsg(id, load_data)) => self.load(id, load_data),
- FromScript(TriggerLoadMsg(id, url)) => self.trigger_load(id, url),
+ FromScript(TriggerLoadMsg(id, load_data)) => self.trigger_load(id, load_data),
FromScript(TriggerFragmentMsg(id, url)) => self.trigger_fragment(id, url),
FromConstellation(SendEventMsg(id, event)) => self.handle_event(id, event),
FromScript(FireTimerMsg(id, timer_id)) => self.handle_fire_timer_msg(id, timer_id),
@@ -1067,9 +1067,9 @@ impl ScriptTask {
/// The entry point for content to notify that a new load has been requested
/// for the given pipeline.
- fn trigger_load(&self, pipeline_id: PipelineId, url: Url) {
+ fn trigger_load(&self, pipeline_id: PipelineId, load_data: LoadData) {
let ConstellationChan(ref const_chan) = self.constellation_chan;
- const_chan.send(LoadUrlMsg(pipeline_id, LoadData::new(url)));
+ const_chan.send(LoadUrlMsg(pipeline_id, load_data));
}
/// The entry point for content to notify that a fragment url has been requested
diff --git a/tests/html/form_submission_handsfree.html b/tests/html/form_submission_handsfree.html
new file mode 100644
index 00000000000..cc729d2ea79
--- /dev/null
+++ b/tests/html/form_submission_handsfree.html
@@ -0,0 +1,16 @@
+<html>
+<head></head>
+<body>
+<!-- Run with nc -l 8000 -->
+<form action="http://localhost:8000" method=get id="foo">
+<input name=bar type=checkbox checked>
+<input name=baz value="baz1" type=radio checked>
+<input name=baz value="baz2" type=radio>
+<input type=text name=bye value="hi!">
+</form>
+<script>
+// setTimeout because https://github.com/servo/servo/issues/3628
+setTimeout(function(){document.getElementById("foo").submit()},5000)
+</script>
+</body>
+</html>
diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini
index 2f50c0d40be..2c8e63fc1b0 100644
--- a/tests/wpt/metadata/html/dom/interfaces.html.ini
+++ b/tests/wpt/metadata/html/dom/interfaces.html.ini
@@ -3123,9 +3123,6 @@
[HTMLObjectElement interface: attribute data]
expected: FAIL
- [HTMLObjectElement interface: attribute type]
- expected: FAIL
-
[HTMLObjectElement interface: attribute typeMustMatch]
expected: FAIL
@@ -5403,9 +5400,6 @@
[HTMLFormElement interface: attribute length]
expected: FAIL
- [HTMLFormElement interface: operation submit()]
- expected: FAIL
-
[HTMLFormElement interface: operation reset()]
expected: FAIL
@@ -5424,9 +5418,6 @@
[HTMLFormElement interface: document.createElement("form") must inherit property "length" with the proper type (10)]
expected: FAIL
- [HTMLFormElement interface: document.createElement("form") must inherit property "submit" with the proper type (13)]
- expected: FAIL
-
[HTMLFormElement interface: document.createElement("form") must inherit property "reset" with the proper type (14)]
expected: FAIL
@@ -5541,9 +5532,6 @@
[HTMLInputElement interface: attribute step]
expected: FAIL
- [HTMLInputElement interface: attribute type]
- expected: FAIL
-
[HTMLInputElement interface: attribute defaultValue]
expected: FAIL
@@ -5700,9 +5688,6 @@
[HTMLInputElement interface: document.createElement("input") must inherit property "step" with the proper type (31)]
expected: FAIL
- [HTMLInputElement interface: document.createElement("input") must inherit property "type" with the proper type (32)]
- expected: FAIL
-
[HTMLInputElement interface: document.createElement("input") must inherit property "defaultValue" with the proper type (33)]
expected: FAIL
@@ -5817,9 +5802,6 @@
[HTMLButtonElement interface: attribute name]
expected: FAIL
- [HTMLButtonElement interface: attribute type]
- expected: FAIL
-
[HTMLButtonElement interface: attribute value]
expected: FAIL
@@ -5868,9 +5850,6 @@
[HTMLButtonElement interface: document.createElement("button") must inherit property "name" with the proper type (8)]
expected: FAIL
- [HTMLButtonElement interface: document.createElement("button") must inherit property "type" with the proper type (9)]
- expected: FAIL
-
[HTMLButtonElement interface: document.createElement("button") must inherit property "value" with the proper type (10)]
expected: FAIL
@@ -5919,9 +5898,6 @@
[HTMLSelectElement interface: attribute size]
expected: FAIL
- [HTMLSelectElement interface: attribute type]
- expected: FAIL
-
[HTMLSelectElement interface: attribute options]
expected: FAIL
@@ -5991,9 +5967,6 @@
[HTMLSelectElement interface: document.createElement("select") must inherit property "size" with the proper type (7)]
expected: FAIL
- [HTMLSelectElement interface: document.createElement("select") must inherit property "type" with the proper type (8)]
- expected: FAIL
-
[HTMLSelectElement interface: document.createElement("select") must inherit property "options" with the proper type (9)]
expected: FAIL
@@ -6129,9 +6102,6 @@
[HTMLTextAreaElement interface: attribute wrap]
expected: FAIL
- [HTMLTextAreaElement interface: attribute type]
- expected: FAIL
-
[HTMLTextAreaElement interface: attribute defaultValue]
expected: FAIL
@@ -6225,9 +6195,6 @@
[HTMLTextAreaElement interface: document.createElement("textarea") must inherit property "wrap" with the proper type (14)]
expected: FAIL
- [HTMLTextAreaElement interface: document.createElement("textarea") must inherit property "type" with the proper type (15)]
- expected: FAIL
-
[HTMLTextAreaElement interface: document.createElement("textarea") must inherit property "defaultValue" with the proper type (16)]
expected: FAIL
diff --git a/tests/wpt/metadata/html/dom/reflection-embedded.html.ini b/tests/wpt/metadata/html/dom/reflection-embedded.html.ini
index 114f4de8aa9..77ef21a33a1 100644
--- a/tests/wpt/metadata/html/dom/reflection-embedded.html.ini
+++ b/tests/wpt/metadata/html/dom/reflection-embedded.html.ini
@@ -7494,135 +7494,6 @@
[object.data: IDL set to object "test-valueOf" followed by IDL get]
expected: FAIL
- [object.type: typeof IDL attribute]
- expected: FAIL
-
- [object.type: IDL get with DOM attribute unset]
- expected: FAIL
-
- [object.type: setAttribute() to "" followed by IDL get]
- expected: FAIL
-
- [object.type: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by IDL get]
- expected: FAIL
-
- [object.type: setAttribute() to undefined followed by IDL get]
- expected: FAIL
-
- [object.type: setAttribute() to 7 followed by IDL get]
- expected: FAIL
-
- [object.type: setAttribute() to 1.5 followed by IDL get]
- expected: FAIL
-
- [object.type: setAttribute() to true followed by IDL get]
- expected: FAIL
-
- [object.type: setAttribute() to false followed by IDL get]
- expected: FAIL
-
- [object.type: setAttribute() to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [object.type: setAttribute() to NaN followed by IDL get]
- expected: FAIL
-
- [object.type: setAttribute() to Infinity followed by IDL get]
- expected: FAIL
-
- [object.type: setAttribute() to -Infinity followed by IDL get]
- expected: FAIL
-
- [object.type: setAttribute() to "\\0" followed by IDL get]
- expected: FAIL
-
- [object.type: setAttribute() to null followed by IDL get]
- expected: FAIL
-
- [object.type: setAttribute() to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [object.type: setAttribute() to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
- [object.type: IDL set to "" followed by getAttribute()]
- expected: FAIL
-
- [object.type: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by getAttribute()]
- expected: FAIL
-
- [object.type: IDL set to undefined followed by getAttribute()]
- expected: FAIL
-
- [object.type: IDL set to undefined followed by IDL get]
- expected: FAIL
-
- [object.type: IDL set to 7 followed by getAttribute()]
- expected: FAIL
-
- [object.type: IDL set to 7 followed by IDL get]
- expected: FAIL
-
- [object.type: IDL set to 1.5 followed by getAttribute()]
- expected: FAIL
-
- [object.type: IDL set to 1.5 followed by IDL get]
- expected: FAIL
-
- [object.type: IDL set to true followed by getAttribute()]
- expected: FAIL
-
- [object.type: IDL set to true followed by IDL get]
- expected: FAIL
-
- [object.type: IDL set to false followed by getAttribute()]
- expected: FAIL
-
- [object.type: IDL set to false followed by IDL get]
- expected: FAIL
-
- [object.type: IDL set to object "[object Object\]" followed by getAttribute()]
- expected: FAIL
-
- [object.type: IDL set to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [object.type: IDL set to NaN followed by getAttribute()]
- expected: FAIL
-
- [object.type: IDL set to NaN followed by IDL get]
- expected: FAIL
-
- [object.type: IDL set to Infinity followed by getAttribute()]
- expected: FAIL
-
- [object.type: IDL set to Infinity followed by IDL get]
- expected: FAIL
-
- [object.type: IDL set to -Infinity followed by getAttribute()]
- expected: FAIL
-
- [object.type: IDL set to -Infinity followed by IDL get]
- expected: FAIL
-
- [object.type: IDL set to "\\0" followed by getAttribute()]
- expected: FAIL
-
- [object.type: IDL set to null followed by getAttribute()]
- expected: FAIL
-
- [object.type: IDL set to null followed by IDL get]
- expected: FAIL
-
- [object.type: IDL set to object "test-toString" followed by getAttribute()]
- expected: FAIL
-
- [object.type: IDL set to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [object.type: IDL set to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
[object.typeMustMatch: typeof IDL attribute]
expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/srcset/select-an-image-source.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/srcset/select-an-image-source.html.ini
index 73c44b2aafe..2bd003bb1c9 100644
--- a/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/srcset/select-an-image-source.html.ini
+++ b/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/srcset/select-an-image-source.html.ini
@@ -27,9 +27,6 @@
["data:,a , data:,b"]
expected: FAIL
- ["data:,a foo, data:,b bar"]
- expected: FAIL
-
["data:,a 1w, data:,b 1x" sizes="1px"]
expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/forms/the-input-element/date.html.ini b/tests/wpt/metadata/html/semantics/forms/the-input-element/date.html.ini
index d4e30764fff..cb88126c193 100644
--- a/tests/wpt/metadata/html/semantics/forms/the-input-element/date.html.ini
+++ b/tests/wpt/metadata/html/semantics/forms/the-input-element/date.html.ini
@@ -1,8 +1,5 @@
[date.html]
type: testharness
- [date type support on input element]
- expected: FAIL
-
[The value attribute, if specified and not empty, must have a value that is a valid date string.]
expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/forms/the-input-element/datetime.html.ini b/tests/wpt/metadata/html/semantics/forms/the-input-element/datetime.html.ini
index 3df255b1df9..2636975bd2a 100644
--- a/tests/wpt/metadata/html/semantics/forms/the-input-element/datetime.html.ini
+++ b/tests/wpt/metadata/html/semantics/forms/the-input-element/datetime.html.ini
@@ -1,8 +1,5 @@
[datetime.html]
type: testharness
- [date type support on input element]
- expected: FAIL
-
[[date\] The min attribute must have a value that is a valid global date and time string]
expected: FAIL
@@ -18,9 +15,6 @@
[[date\] stepDown method support on input \'date\' element]
expected: FAIL
- [[time\] time type support on input element]
- expected: FAIL
-
[[time\] The min attribute must have a value that is a valid global date and time string]
expected: FAIL
@@ -36,9 +30,6 @@
[[time\] stepDown method support on input \'time\' element]
expected: FAIL
- [datetime type support on input element]
- expected: FAIL
-
[[datetime\] The min attribute must have a value that is a valid global date and time string]
expected: FAIL
@@ -54,9 +45,6 @@
[[datetime\] stepDown method support on input \'datetime\' element]
expected: FAIL
- [month type support on input element]
- expected: FAIL
-
[[month\] The min attribute must have a value that is a valid global date and time string]
expected: FAIL
@@ -72,9 +60,6 @@
[[month\] stepDown method support on input \'month\' element]
expected: FAIL
- [week type support on input element]
- expected: FAIL
-
[[week\] The min attribute must have a value that is a valid global date and time string]
expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/forms/the-input-element/month.html.ini b/tests/wpt/metadata/html/semantics/forms/the-input-element/month.html.ini
index d705c5eff0c..5bf6d677388 100644
--- a/tests/wpt/metadata/html/semantics/forms/the-input-element/month.html.ini
+++ b/tests/wpt/metadata/html/semantics/forms/the-input-element/month.html.ini
@@ -1,8 +1,5 @@
[month.html]
type: testharness
- [month type support on input element]
- expected: FAIL
-
[The value attribute, if specified and not empty, must have a value that is a valid month string]
expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/forms/the-input-element/range-2.html.ini b/tests/wpt/metadata/html/semantics/forms/the-input-element/range-2.html.ini
index 0f5a9775cab..828547f72bd 100644
--- a/tests/wpt/metadata/html/semantics/forms/the-input-element/range-2.html.ini
+++ b/tests/wpt/metadata/html/semantics/forms/the-input-element/range-2.html.ini
@@ -3,9 +3,6 @@
[range input value set to \'\']
expected: FAIL
- [range input value set to an integer]
- expected: FAIL
-
[range input value equals 50]
expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/forms/the-input-element/range.html.ini b/tests/wpt/metadata/html/semantics/forms/the-input-element/range.html.ini
index 1e65929716f..5b161f4a92e 100644
--- a/tests/wpt/metadata/html/semantics/forms/the-input-element/range.html.ini
+++ b/tests/wpt/metadata/html/semantics/forms/the-input-element/range.html.ini
@@ -1,8 +1,5 @@
[range.html]
type: testharness
- [range type support on input element]
- expected: FAIL
-
[min attribute support on input element]
expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/forms/the-input-element/search_input.html.ini b/tests/wpt/metadata/html/semantics/forms/the-input-element/search_input.html.ini
index c0e39d628e7..49b9be48239 100644
--- a/tests/wpt/metadata/html/semantics/forms/the-input-element/search_input.html.ini
+++ b/tests/wpt/metadata/html/semantics/forms/the-input-element/search_input.html.ini
@@ -1,8 +1,5 @@
[search_input.html]
type: testharness
- [search type support on input element]
- expected: FAIL
-
[placeholder attribute support on input element]
expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/forms/the-input-element/telephone.html.ini b/tests/wpt/metadata/html/semantics/forms/the-input-element/telephone.html.ini
index 2cae9ba8c66..0d7fa2f7654 100644
--- a/tests/wpt/metadata/html/semantics/forms/the-input-element/telephone.html.ini
+++ b/tests/wpt/metadata/html/semantics/forms/the-input-element/telephone.html.ini
@@ -1,8 +1,5 @@
[telephone.html]
type: testharness
- [tel type supported on input element]
- expected: FAIL
-
[User agents must not allow users to insert "LF" (U+000A)]
expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/forms/the-input-element/time.html.ini b/tests/wpt/metadata/html/semantics/forms/the-input-element/time.html.ini
index c4cbe43fee8..b2368ef46ea 100644
--- a/tests/wpt/metadata/html/semantics/forms/the-input-element/time.html.ini
+++ b/tests/wpt/metadata/html/semantics/forms/the-input-element/time.html.ini
@@ -9,9 +9,6 @@
[min attribute on default value check]
expected: FAIL
- [type attribute support on input element]
- expected: FAIL
-
[max attribute support on input element]
expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/forms/the-input-element/url.html.ini b/tests/wpt/metadata/html/semantics/forms/the-input-element/url.html.ini
index e756878e339..5dc56d7e1e3 100644
--- a/tests/wpt/metadata/html/semantics/forms/the-input-element/url.html.ini
+++ b/tests/wpt/metadata/html/semantics/forms/the-input-element/url.html.ini
@@ -1,8 +1,5 @@
[url.html]
type: testharness
- [url type supported on input element]
- expected: FAIL
-
[The value must not be set with "LF" (U+000A) or "CR" (U+000D)]
expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/forms/the-textarea-element/textarea-type.html.ini b/tests/wpt/metadata/html/semantics/forms/the-textarea-element/textarea-type.html.ini
deleted file mode 100644
index 62c14c198bb..00000000000
--- a/tests/wpt/metadata/html/semantics/forms/the-textarea-element/textarea-type.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[textarea-type.html]
- type: testharness
- [Textarea\'s type attribute should return \'textarea\']
- expected: FAIL
-