mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
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 (?)
This commit is contained in:
commit
9dfd5e7fcd
28 changed files with 368 additions and 232 deletions
|
@ -4,18 +4,19 @@
|
||||||
|
|
||||||
use dom::bindings::codegen::Bindings::HTMLButtonElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLButtonElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLButtonElementBinding::HTMLButtonElementMethods;
|
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::codegen::InheritTypes::{HTMLButtonElementDerived, HTMLFieldSetElementDerived};
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::{JSRef, Temporary};
|
||||||
use dom::bindings::utils::{Reflectable, Reflector};
|
use dom::bindings::utils::{Reflectable, Reflector};
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::{AttributeHandlers, HTMLButtonElementTypeId};
|
use dom::element::{AttributeHandlers, Element, HTMLButtonElementTypeId};
|
||||||
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::node::{DisabledStateHelpers, Node, NodeHelpers, ElementNodeTypeId, window_from_node};
|
use dom::node::{DisabledStateHelpers, Node, NodeHelpers, ElementNodeTypeId, window_from_node};
|
||||||
use dom::validitystate::ValidityState;
|
use dom::validitystate::ValidityState;
|
||||||
use dom::virtualmethods::VirtualMethods;
|
use dom::virtualmethods::VirtualMethods;
|
||||||
|
|
||||||
|
use std::ascii::OwnedStrAsciiExt;
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
use string_cache::Atom;
|
use string_cache::Atom;
|
||||||
|
|
||||||
|
@ -56,6 +57,20 @@ impl<'a> HTMLButtonElementMethods for JSRef<'a, HTMLButtonElement> {
|
||||||
|
|
||||||
// http://www.whatwg.org/html/#dom-fe-disabled
|
// http://www.whatwg.org/html/#dom-fe-disabled
|
||||||
make_bool_setter!(SetDisabled, "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> {
|
impl<'a> VirtualMethods for JSRef<'a, HTMLButtonElement> {
|
||||||
|
|
|
@ -2,19 +2,32 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* 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;
|
||||||
use dom::bindings::codegen::Bindings::HTMLFormElementBinding::HTMLFormElementMethods;
|
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::js::{JSRef, Temporary};
|
||||||
use dom::bindings::utils::{Reflectable, Reflector};
|
use dom::bindings::utils::{Reflectable, Reflector};
|
||||||
use dom::document::Document;
|
use dom::document::{Document, DocumentHelpers};
|
||||||
use dom::element::{Element, AttributeHandlers, HTMLFormElementTypeId};
|
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::eventtarget::{EventTarget, NodeTargetTypeId};
|
||||||
use dom::htmlelement::HTMLElement;
|
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 servo_util::str::DOMString;
|
||||||
|
use script_task::{ScriptChan, TriggerLoadMsg};
|
||||||
use std::ascii::OwnedStrAsciiExt;
|
use std::ascii::OwnedStrAsciiExt;
|
||||||
|
use std::str::StrSlice;
|
||||||
|
use url::UrlParser;
|
||||||
|
use url::form_urlencoded::serialize;
|
||||||
|
|
||||||
#[jstraceable]
|
#[jstraceable]
|
||||||
#[must_root]
|
#[must_root]
|
||||||
|
@ -52,7 +65,7 @@ impl<'a> HTMLFormElementMethods for JSRef<'a, HTMLFormElement> {
|
||||||
// https://html.spec.whatwg.org/multipage/forms.html#dom-fs-action
|
// https://html.spec.whatwg.org/multipage/forms.html#dom-fs-action
|
||||||
fn Action(self) -> DOMString {
|
fn Action(self) -> DOMString {
|
||||||
let element: JSRef<Element> = ElementCast::from_ref(self);
|
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() {
|
match url.as_slice() {
|
||||||
"" => {
|
"" => {
|
||||||
let window = window_from_node(self).root();
|
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
|
// https://html.spec.whatwg.org/multipage/forms.html#dom-fs-target
|
||||||
make_setter!(SetTarget, "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 {
|
impl Reflectable for HTMLFormElement {
|
||||||
|
@ -142,3 +345,67 @@ impl Reflectable for HTMLFormElement {
|
||||||
self.htmlelement.reflector()
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ use dom::virtualmethods::VirtualMethods;
|
||||||
use servo_util::str::{DOMString, parse_unsigned_integer};
|
use servo_util::str::{DOMString, parse_unsigned_integer};
|
||||||
use string_cache::Atom;
|
use string_cache::Atom;
|
||||||
|
|
||||||
|
use std::ascii::OwnedStrAsciiExt;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
|
@ -120,7 +121,9 @@ impl<'a> HTMLInputElementMethods for JSRef<'a, HTMLInputElement> {
|
||||||
make_bool_setter!(SetDisabled, "disabled")
|
make_bool_setter!(SetDisabled, "disabled")
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-checked
|
// 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
|
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-checked
|
||||||
make_bool_setter!(SetChecked, "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
|
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-size
|
||||||
make_uint_setter!(SetSize, "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
|
// 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
|
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-value
|
||||||
make_setter!(SetValue, "value")
|
make_setter!(SetValue, "value")
|
||||||
|
|
|
@ -86,6 +86,12 @@ impl<'a> HTMLObjectElementMethods for JSRef<'a, HTMLObjectElement> {
|
||||||
let window = window_from_node(self).root();
|
let window = window_from_node(self).root();
|
||||||
ValidityState::new(*window)
|
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> {
|
impl<'a> VirtualMethods for JSRef<'a, HTMLObjectElement> {
|
||||||
|
|
|
@ -5,13 +5,13 @@
|
||||||
use dom::bindings::codegen::Bindings::HTMLSelectElementBinding;
|
use dom::bindings::codegen::Bindings::HTMLSelectElementBinding;
|
||||||
use dom::bindings::codegen::Bindings::HTMLSelectElementBinding::HTMLSelectElementMethods;
|
use dom::bindings::codegen::Bindings::HTMLSelectElementBinding::HTMLSelectElementMethods;
|
||||||
use dom::bindings::codegen::InheritTypes::{HTMLElementCast, NodeCast};
|
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::HTMLElementOrLong::HTMLElementOrLong;
|
||||||
use dom::bindings::codegen::UnionTypes::HTMLOptionElementOrHTMLOptGroupElement::HTMLOptionElementOrHTMLOptGroupElement;
|
use dom::bindings::codegen::UnionTypes::HTMLOptionElementOrHTMLOptGroupElement::HTMLOptionElementOrHTMLOptGroupElement;
|
||||||
use dom::bindings::js::{JSRef, Temporary};
|
use dom::bindings::js::{JSRef, Temporary};
|
||||||
use dom::bindings::utils::{Reflectable, Reflector};
|
use dom::bindings::utils::{Reflectable, Reflector};
|
||||||
use dom::document::Document;
|
use dom::document::Document;
|
||||||
use dom::element::{AttributeHandlers, HTMLSelectElementTypeId};
|
use dom::element::{AttributeHandlers, Element, HTMLSelectElementTypeId};
|
||||||
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
||||||
use dom::htmlelement::HTMLElement;
|
use dom::htmlelement::HTMLElement;
|
||||||
use dom::node::{DisabledStateHelpers, Node, NodeHelpers, ElementNodeTypeId, window_from_node};
|
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
|
// http://www.whatwg.org/html/#dom-fe-disabled
|
||||||
make_bool_setter!(SetDisabled, "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> {
|
impl<'a> VirtualMethods for JSRef<'a, HTMLSelectElement> {
|
||||||
|
|
|
@ -50,6 +50,11 @@ impl<'a> HTMLTextAreaElementMethods for JSRef<'a, HTMLTextAreaElement> {
|
||||||
|
|
||||||
// http://www.whatwg.org/html/#dom-fe-disabled
|
// http://www.whatwg.org/html/#dom-fe-disabled
|
||||||
make_bool_setter!(SetDisabled, "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> {
|
impl<'a> VirtualMethods for JSRef<'a, HTMLTextAreaElement> {
|
||||||
|
|
|
@ -14,7 +14,7 @@ interface HTMLButtonElement : HTMLElement {
|
||||||
// attribute boolean formNoValidate;
|
// attribute boolean formNoValidate;
|
||||||
// attribute DOMString formTarget;
|
// attribute DOMString formTarget;
|
||||||
// attribute DOMString name;
|
// attribute DOMString name;
|
||||||
// attribute DOMString type;
|
attribute DOMString type;
|
||||||
// attribute DOMString value;
|
// attribute DOMString value;
|
||||||
// attribute HTMLMenuElement? menu;
|
// attribute HTMLMenuElement? menu;
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ interface HTMLFormElement : HTMLElement {
|
||||||
//getter Element (unsigned long index);
|
//getter Element (unsigned long index);
|
||||||
//getter (RadioNodeList or Element) (DOMString name);
|
//getter (RadioNodeList or Element) (DOMString name);
|
||||||
|
|
||||||
//void submit();
|
void submit();
|
||||||
//void reset();
|
//void reset();
|
||||||
//boolean checkValidity();
|
//boolean checkValidity();
|
||||||
//boolean reportValidity();
|
//boolean reportValidity();
|
||||||
|
|
|
@ -37,7 +37,7 @@ interface HTMLInputElement : HTMLElement {
|
||||||
attribute unsigned long size;
|
attribute unsigned long size;
|
||||||
// attribute DOMString src;
|
// attribute DOMString src;
|
||||||
// attribute DOMString step;
|
// attribute DOMString step;
|
||||||
// attribute DOMString type; //XXXjdm need binaryName
|
attribute DOMString type;
|
||||||
// attribute DOMString defaultValue;
|
// attribute DOMString defaultValue;
|
||||||
[TreatNullAs=EmptyString] attribute DOMString value;
|
[TreatNullAs=EmptyString] attribute DOMString value;
|
||||||
// attribute Date? valueAsDate;
|
// attribute Date? valueAsDate;
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
// http://www.whatwg.org/html/#htmlobjectelement
|
// http://www.whatwg.org/html/#htmlobjectelement
|
||||||
interface HTMLObjectElement : HTMLElement {
|
interface HTMLObjectElement : HTMLElement {
|
||||||
// attribute DOMString data;
|
// attribute DOMString data;
|
||||||
// attribute DOMString type;
|
attribute DOMString type;
|
||||||
// attribute boolean typeMustMatch;
|
// attribute boolean typeMustMatch;
|
||||||
// attribute DOMString name;
|
// attribute DOMString name;
|
||||||
// attribute DOMString useMap;
|
// attribute DOMString useMap;
|
||||||
|
|
|
@ -13,7 +13,7 @@ interface HTMLSelectElement : HTMLElement {
|
||||||
// attribute boolean required;
|
// attribute boolean required;
|
||||||
// attribute unsigned long size;
|
// attribute unsigned long size;
|
||||||
|
|
||||||
//readonly attribute DOMString type;
|
readonly attribute DOMString type;
|
||||||
|
|
||||||
//readonly attribute HTMLOptionsCollection options;
|
//readonly attribute HTMLOptionsCollection options;
|
||||||
// attribute unsigned long length;
|
// attribute unsigned long length;
|
||||||
|
|
|
@ -21,7 +21,7 @@ interface HTMLTextAreaElement : HTMLElement {
|
||||||
// attribute unsigned long rows;
|
// attribute unsigned long rows;
|
||||||
// attribute DOMString wrap;
|
// attribute DOMString wrap;
|
||||||
|
|
||||||
//readonly attribute DOMString type;
|
readonly attribute DOMString type;
|
||||||
// attribute DOMString defaultValue;
|
// attribute DOMString defaultValue;
|
||||||
//[TreatNullAs=EmptyString] attribute DOMString value;
|
//[TreatNullAs=EmptyString] attribute DOMString value;
|
||||||
//readonly attribute unsigned long textLength;
|
//readonly attribute unsigned long textLength;
|
||||||
|
|
|
@ -24,6 +24,7 @@ use script_task::{ExitWindowMsg, FireTimerMsg, ScriptChan, TriggerLoadMsg, Trigg
|
||||||
use script_traits::ScriptControlChan;
|
use script_traits::ScriptControlChan;
|
||||||
|
|
||||||
use servo_msg::compositor_msg::ScriptListener;
|
use servo_msg::compositor_msg::ScriptListener;
|
||||||
|
use servo_msg::constellation_msg::LoadData;
|
||||||
use servo_net::image_cache_task::ImageCacheTask;
|
use servo_net::image_cache_task::ImageCacheTask;
|
||||||
use servo_util::str::{DOMString,HTML_SPACE_CHARACTERS};
|
use servo_util::str::{DOMString,HTML_SPACE_CHARACTERS};
|
||||||
use servo_util::task::{spawn_named};
|
use servo_util::task::{spawn_named};
|
||||||
|
@ -432,7 +433,7 @@ impl<'a> WindowHelpers for JSRef<'a, Window> {
|
||||||
if href.as_slice().starts_with("#") {
|
if href.as_slice().starts_with("#") {
|
||||||
script_chan.send(TriggerFragmentMsg(self.page.id, url));
|
script_chan.send(TriggerFragmentMsg(self.page.id, url));
|
||||||
} else {
|
} else {
|
||||||
script_chan.send(TriggerLoadMsg(self.page.id, url));
|
script_chan.send(TriggerLoadMsg(self.page.id, LoadData::new(url)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ pub enum ScriptMsg {
|
||||||
TriggerFragmentMsg(PipelineId, Url),
|
TriggerFragmentMsg(PipelineId, Url),
|
||||||
/// Begins a content-initiated load on the specified pipeline (only
|
/// Begins a content-initiated load on the specified pipeline (only
|
||||||
/// dispatched to ScriptTask).
|
/// dispatched to ScriptTask).
|
||||||
TriggerLoadMsg(PipelineId, Url),
|
TriggerLoadMsg(PipelineId, LoadData),
|
||||||
/// Instructs the script task to send a navigate message to
|
/// Instructs the script task to send a navigate message to
|
||||||
/// the constellation (only dispatched to ScriptTask).
|
/// the constellation (only dispatched to ScriptTask).
|
||||||
NavigateMsg(NavigationDirection),
|
NavigateMsg(NavigationDirection),
|
||||||
|
@ -494,7 +494,7 @@ impl ScriptTask {
|
||||||
// TODO(tkuehn) need to handle auxiliary layouts for iframes
|
// TODO(tkuehn) need to handle auxiliary layouts for iframes
|
||||||
FromConstellation(AttachLayoutMsg(_)) => fail!("should have handled AttachLayoutMsg already"),
|
FromConstellation(AttachLayoutMsg(_)) => fail!("should have handled AttachLayoutMsg already"),
|
||||||
FromConstellation(LoadMsg(id, load_data)) => self.load(id, load_data),
|
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),
|
FromScript(TriggerFragmentMsg(id, url)) => self.trigger_fragment(id, url),
|
||||||
FromConstellation(SendEventMsg(id, event)) => self.handle_event(id, event),
|
FromConstellation(SendEventMsg(id, event)) => self.handle_event(id, event),
|
||||||
FromScript(FireTimerMsg(id, timer_id)) => self.handle_fire_timer_msg(id, timer_id),
|
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
|
/// The entry point for content to notify that a new load has been requested
|
||||||
/// for the given pipeline.
|
/// 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;
|
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
|
/// The entry point for content to notify that a fragment url has been requested
|
||||||
|
|
16
tests/html/form_submission_handsfree.html
Normal file
16
tests/html/form_submission_handsfree.html
Normal file
|
@ -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>
|
|
@ -3123,9 +3123,6 @@
|
||||||
[HTMLObjectElement interface: attribute data]
|
[HTMLObjectElement interface: attribute data]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[HTMLObjectElement interface: attribute type]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[HTMLObjectElement interface: attribute typeMustMatch]
|
[HTMLObjectElement interface: attribute typeMustMatch]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -5403,9 +5400,6 @@
|
||||||
[HTMLFormElement interface: attribute length]
|
[HTMLFormElement interface: attribute length]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[HTMLFormElement interface: operation submit()]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[HTMLFormElement interface: operation reset()]
|
[HTMLFormElement interface: operation reset()]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -5424,9 +5418,6 @@
|
||||||
[HTMLFormElement interface: document.createElement("form") must inherit property "length" with the proper type (10)]
|
[HTMLFormElement interface: document.createElement("form") must inherit property "length" with the proper type (10)]
|
||||||
expected: FAIL
|
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)]
|
[HTMLFormElement interface: document.createElement("form") must inherit property "reset" with the proper type (14)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -5541,9 +5532,6 @@
|
||||||
[HTMLInputElement interface: attribute step]
|
[HTMLInputElement interface: attribute step]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[HTMLInputElement interface: attribute type]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[HTMLInputElement interface: attribute defaultValue]
|
[HTMLInputElement interface: attribute defaultValue]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -5700,9 +5688,6 @@
|
||||||
[HTMLInputElement interface: document.createElement("input") must inherit property "step" with the proper type (31)]
|
[HTMLInputElement interface: document.createElement("input") must inherit property "step" with the proper type (31)]
|
||||||
expected: FAIL
|
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)]
|
[HTMLInputElement interface: document.createElement("input") must inherit property "defaultValue" with the proper type (33)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -5817,9 +5802,6 @@
|
||||||
[HTMLButtonElement interface: attribute name]
|
[HTMLButtonElement interface: attribute name]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[HTMLButtonElement interface: attribute type]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[HTMLButtonElement interface: attribute value]
|
[HTMLButtonElement interface: attribute value]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -5868,9 +5850,6 @@
|
||||||
[HTMLButtonElement interface: document.createElement("button") must inherit property "name" with the proper type (8)]
|
[HTMLButtonElement interface: document.createElement("button") must inherit property "name" with the proper type (8)]
|
||||||
expected: FAIL
|
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)]
|
[HTMLButtonElement interface: document.createElement("button") must inherit property "value" with the proper type (10)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -5919,9 +5898,6 @@
|
||||||
[HTMLSelectElement interface: attribute size]
|
[HTMLSelectElement interface: attribute size]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[HTMLSelectElement interface: attribute type]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[HTMLSelectElement interface: attribute options]
|
[HTMLSelectElement interface: attribute options]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -5991,9 +5967,6 @@
|
||||||
[HTMLSelectElement interface: document.createElement("select") must inherit property "size" with the proper type (7)]
|
[HTMLSelectElement interface: document.createElement("select") must inherit property "size" with the proper type (7)]
|
||||||
expected: FAIL
|
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)]
|
[HTMLSelectElement interface: document.createElement("select") must inherit property "options" with the proper type (9)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -6129,9 +6102,6 @@
|
||||||
[HTMLTextAreaElement interface: attribute wrap]
|
[HTMLTextAreaElement interface: attribute wrap]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[HTMLTextAreaElement interface: attribute type]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[HTMLTextAreaElement interface: attribute defaultValue]
|
[HTMLTextAreaElement interface: attribute defaultValue]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -6225,9 +6195,6 @@
|
||||||
[HTMLTextAreaElement interface: document.createElement("textarea") must inherit property "wrap" with the proper type (14)]
|
[HTMLTextAreaElement interface: document.createElement("textarea") must inherit property "wrap" with the proper type (14)]
|
||||||
expected: FAIL
|
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)]
|
[HTMLTextAreaElement interface: document.createElement("textarea") must inherit property "defaultValue" with the proper type (16)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -7494,135 +7494,6 @@
|
||||||
[object.data: IDL set to object "test-valueOf" followed by IDL get]
|
[object.data: IDL set to object "test-valueOf" followed by IDL get]
|
||||||
expected: FAIL
|
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]
|
[object.typeMustMatch: typeof IDL attribute]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,6 @@
|
||||||
["data:,a , data:,b"]
|
["data:,a , data:,b"]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
["data:,a foo, data:,b bar"]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
["data:,a 1w, data:,b 1x" sizes="1px"]
|
["data:,a 1w, data:,b 1x" sizes="1px"]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
[date.html]
|
[date.html]
|
||||||
type: testharness
|
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.]
|
[The value attribute, if specified and not empty, must have a value that is a valid date string.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
[datetime.html]
|
[datetime.html]
|
||||||
type: testharness
|
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]
|
[[date\] The min attribute must have a value that is a valid global date and time string]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -18,9 +15,6 @@
|
||||||
[[date\] stepDown method support on input \'date\' element]
|
[[date\] stepDown method support on input \'date\' element]
|
||||||
expected: FAIL
|
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]
|
[[time\] The min attribute must have a value that is a valid global date and time string]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -36,9 +30,6 @@
|
||||||
[[time\] stepDown method support on input \'time\' element]
|
[[time\] stepDown method support on input \'time\' element]
|
||||||
expected: FAIL
|
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]
|
[[datetime\] The min attribute must have a value that is a valid global date and time string]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -54,9 +45,6 @@
|
||||||
[[datetime\] stepDown method support on input \'datetime\' element]
|
[[datetime\] stepDown method support on input \'datetime\' element]
|
||||||
expected: FAIL
|
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]
|
[[month\] The min attribute must have a value that is a valid global date and time string]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -72,9 +60,6 @@
|
||||||
[[month\] stepDown method support on input \'month\' element]
|
[[month\] stepDown method support on input \'month\' element]
|
||||||
expected: FAIL
|
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]
|
[[week\] The min attribute must have a value that is a valid global date and time string]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
[month.html]
|
[month.html]
|
||||||
type: testharness
|
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]
|
[The value attribute, if specified and not empty, must have a value that is a valid month string]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,6 @@
|
||||||
[range input value set to \'\']
|
[range input value set to \'\']
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[range input value set to an integer]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[range input value equals 50]
|
[range input value equals 50]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
[range.html]
|
[range.html]
|
||||||
type: testharness
|
type: testharness
|
||||||
[range type support on input element]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[min attribute support on input element]
|
[min attribute support on input element]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
[search_input.html]
|
[search_input.html]
|
||||||
type: testharness
|
type: testharness
|
||||||
[search type support on input element]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[placeholder attribute support on input element]
|
[placeholder attribute support on input element]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
[telephone.html]
|
[telephone.html]
|
||||||
type: testharness
|
type: testharness
|
||||||
[tel type supported on input element]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[User agents must not allow users to insert "LF" (U+000A)]
|
[User agents must not allow users to insert "LF" (U+000A)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,6 @@
|
||||||
[min attribute on default value check]
|
[min attribute on default value check]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[type attribute support on input element]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[max attribute support on input element]
|
[max attribute support on input element]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
[url.html]
|
[url.html]
|
||||||
type: testharness
|
type: testharness
|
||||||
[url type supported on input element]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[The value must not be set with "LF" (U+000A) or "CR" (U+000D)]
|
[The value must not be set with "LF" (U+000A) or "CR" (U+000D)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[textarea-type.html]
|
|
||||||
type: testharness
|
|
||||||
[Textarea\'s type attribute should return \'textarea\']
|
|
||||||
expected: FAIL
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue