aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/atoms/static_atoms.txt1
-rw-r--r--components/script/dom/htmlelement.rs4
-rwxr-xr-xcomponents/script/dom/htmlformelement.rs4
-rwxr-xr-xcomponents/script/dom/htmlinputelement.rs341
-rw-r--r--components/script/dom/radionodelist.rs21
-rw-r--r--tests/wpt/metadata/html/semantics/forms/the-input-element/clone.html.ini3
6 files changed, 234 insertions, 140 deletions
diff --git a/components/atoms/static_atoms.txt b/components/atoms/static_atoms.txt
index b6f65ab9ed4..db8f234faab 100644
--- a/components/atoms/static_atoms.txt
+++ b/components/atoms/static_atoms.txt
@@ -55,6 +55,7 @@ playing
print
progress
radio
+range
readystatechange
reftest-wait
reset
diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs
index cb423ca37a3..89b0c0d9de2 100644
--- a/components/script/dom/htmlelement.rs
+++ b/components/script/dom/htmlelement.rs
@@ -22,7 +22,7 @@ use dom::eventtarget::EventTarget;
use dom::htmlbodyelement::HTMLBodyElement;
use dom::htmlframesetelement::HTMLFrameSetElement;
use dom::htmlhtmlelement::HTMLHtmlElement;
-use dom::htmlinputelement::HTMLInputElement;
+use dom::htmlinputelement::{HTMLInputElement, InputType};
use dom::htmllabelelement::HTMLLabelElement;
use dom::node::{Node, NodeFlags};
use dom::node::{document_from_node, window_from_node};
@@ -497,7 +497,7 @@ impl HTMLElement {
NodeTypeId::Element(ElementTypeId::HTMLElement(type_id)) =>
match type_id {
HTMLElementTypeId::HTMLInputElement =>
- self.downcast::<HTMLInputElement>().unwrap().type_() != atom!("hidden"),
+ self.downcast::<HTMLInputElement>().unwrap().input_type() != InputType::Hidden,
HTMLElementTypeId::HTMLButtonElement |
HTMLElementTypeId::HTMLMeterElement |
HTMLElementTypeId::HTMLOutputElement |
diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs
index e4ce6dfef43..27a64d00cda 100755
--- a/components/script/dom/htmlformelement.rs
+++ b/components/script/dom/htmlformelement.rs
@@ -30,7 +30,7 @@ use dom::htmlelement::HTMLElement;
use dom::htmlfieldsetelement::HTMLFieldSetElement;
use dom::htmlformcontrolscollection::HTMLFormControlsCollection;
use dom::htmlimageelement::HTMLImageElement;
-use dom::htmlinputelement::HTMLInputElement;
+use dom::htmlinputelement::{HTMLInputElement, InputType};
use dom::htmllabelelement::HTMLLabelElement;
use dom::htmllegendelement::HTMLLegendElement;
use dom::htmlobjectelement::HTMLObjectElement;
@@ -183,7 +183,7 @@ impl HTMLFormElementMethods for HTMLFormElement {
}
HTMLElementTypeId::HTMLInputElement => {
let input_elem = elem.downcast::<HTMLInputElement>().unwrap();
- if input_elem.type_() == atom!("image") {
+ if input_elem.input_type() == InputType::Image {
return false;
}
input_elem.form_owner()
diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs
index cbf4f483e0c..d748919914e 100755
--- a/components/script/dom/htmlinputelement.rs
+++ b/components/script/dom/htmlinputelement.rs
@@ -63,16 +63,118 @@ const PASSWORD_REPLACEMENT_CHAR: char = '●';
#[derive(Clone, Copy, JSTraceable, PartialEq)]
#[allow(dead_code)]
#[derive(MallocSizeOf)]
-enum InputType {
- InputSubmit,
- InputReset,
- InputButton,
- InputText,
- InputFile,
- InputImage,
- InputCheckbox,
- InputRadio,
- InputPassword
+pub enum InputType {
+ Button,
+ Checkbox,
+ Color,
+ Date,
+ Datetime,
+ DatetimeLocal,
+ Email,
+ File,
+ Hidden,
+ Image,
+ Month,
+ Number,
+ Password,
+ Radio,
+ Range,
+ Reset,
+ Search,
+ Submit,
+ Tel,
+ Text,
+ Time,
+ Url,
+ Week,
+}
+
+impl InputType {
+ // Note that Password is not included here since it is handled
+ // slightly differently, with placeholder characters shown rather
+ // than the underlying value.
+ fn is_textual(&self) -> bool {
+ match *self {
+ InputType::Color | InputType::Date | InputType::Datetime
+ | InputType::DatetimeLocal | InputType::Email | InputType::Hidden
+ | InputType::Month | InputType::Number | InputType::Range
+ | InputType::Search | InputType::Tel | InputType::Text
+ | InputType::Time | InputType::Url | InputType::Week => {
+ true
+ }
+
+ _ => false
+ }
+ }
+
+ fn is_textual_or_password(&self) -> bool {
+ self.is_textual() || *self == InputType::Password
+ }
+
+ fn to_str(&self) -> &str {
+ match *self {
+ InputType::Button => "button",
+ InputType::Checkbox => "checkbox",
+ InputType::Color => "color",
+ InputType::Date => "date",
+ InputType::Datetime => "datetime",
+ InputType::DatetimeLocal => "datetime-local",
+ InputType::Email => "email",
+ InputType::File => "file",
+ InputType::Hidden => "hidden",
+ InputType::Image => "image",
+ InputType::Month => "month",
+ InputType::Number => "number",
+ InputType::Password => "password",
+ InputType::Radio => "radio",
+ InputType::Range => "range",
+ InputType::Reset => "reset",
+ InputType::Search => "search",
+ InputType::Submit => "submit",
+ InputType::Tel => "tel",
+ InputType::Text => "text",
+ InputType::Time => "time",
+ InputType::Url => "url",
+ InputType::Week => "week",
+ }
+ }
+}
+
+impl<'a> From<&'a Atom> for InputType {
+ fn from(value: &Atom) -> InputType {
+ match value.to_ascii_lowercase() {
+ atom!("button") => InputType::Button,
+ atom!("checkbox") => InputType::Checkbox,
+ atom!("color") => InputType::Color,
+ atom!("date") => InputType::Date,
+ atom!("datetime") => InputType::Datetime,
+ atom!("datetime-local") => InputType::DatetimeLocal,
+ atom!("email") => InputType::Email,
+ atom!("file") => InputType::File,
+ atom!("hidden") => InputType::Hidden,
+ atom!("image") => InputType::Image,
+ atom!("month") => InputType::Month,
+ atom!("number") => InputType::Number,
+ atom!("password") => InputType::Password,
+ atom!("radio") => InputType::Radio,
+ atom!("range") => InputType::Range,
+ atom!("reset") => InputType::Reset,
+ atom!("search") => InputType::Search,
+ atom!("submit") => InputType::Submit,
+ atom!("tel") => InputType::Tel,
+ atom!("text") => InputType::Text,
+ atom!("time") => InputType::Time,
+ atom!("url") => InputType::Url,
+ atom!("week") => InputType::Week,
+ _ => Self::default()
+ }
+ }
+}
+
+impl Default for InputType {
+ fn default() -> InputType {
+ InputType::Text
+ }
}
#[derive(Debug, PartialEq)]
@@ -125,7 +227,7 @@ impl InputActivationState {
checked_changed: false,
checked_radio: None,
was_mutable: false,
- old_type: InputType::InputText
+ old_type: Default::default()
}
}
}
@@ -142,7 +244,7 @@ impl HTMLInputElement {
HTMLElement::new_inherited_with_state(ElementState::IN_ENABLED_STATE |
ElementState::IN_READ_WRITE_STATE,
local_name, prefix, document),
- input_type: Cell::new(InputType::InputText),
+ input_type: Cell::new(Default::default()),
placeholder: DomRefCell::new(DOMString::new()),
checked_changed: Cell::new(false),
value_changed: Cell::new(false),
@@ -171,26 +273,35 @@ impl HTMLInputElement {
HTMLInputElementBinding::Wrap)
}
- pub fn type_(&self) -> Atom {
- self.upcast::<Element>()
- .get_attribute(&ns!(), &local_name!("type"))
- .map_or_else(|| atom!(""), |a| a.value().as_atom().to_owned())
- }
-
// https://html.spec.whatwg.org/multipage/#dom-input-value
+ // https://html.spec.whatwg.org/multipage/#concept-input-apply
fn value_mode(&self) -> ValueMode {
- match self.input_type.get() {
- InputType::InputSubmit |
- InputType::InputReset |
- InputType::InputButton |
- InputType::InputImage => ValueMode::Default,
- InputType::InputCheckbox |
- InputType::InputRadio => ValueMode::DefaultOn,
- InputType::InputPassword |
- InputType::InputText => ValueMode::Value,
- InputType::InputFile => ValueMode::Filename,
+ match self.input_type() {
+ InputType::Submit | InputType::Reset | InputType::Button
+ | InputType::Image | InputType::Hidden => {
+ ValueMode::Default
+ },
+
+ InputType::Checkbox | InputType::Radio => {
+ ValueMode::DefaultOn
+ },
+
+ InputType::Color | InputType::Date | InputType::Datetime
+ | InputType::DatetimeLocal | InputType::Email | InputType::Month
+ | InputType::Number | InputType::Password | InputType::Range
+ | InputType::Search | InputType::Tel | InputType::Text
+ | InputType::Time | InputType::Url | InputType::Week => {
+ ValueMode::Value
+ }
+
+ InputType::File => ValueMode::Filename,
}
}
+
+ #[inline]
+ pub fn input_type(&self) -> InputType {
+ self.input_type.get()
+ }
}
pub trait LayoutHTMLInputElementHelpers {
@@ -223,13 +334,13 @@ impl LayoutHTMLInputElementHelpers for LayoutDom<HTMLInputElement> {
String::from(value)
}
- match (*self.unsafe_get()).input_type.get() {
- InputType::InputCheckbox | InputType::InputRadio => String::new(),
- InputType::InputFile | InputType::InputImage => String::new(),
- InputType::InputButton => get_raw_attr_value(self, ""),
- InputType::InputSubmit => get_raw_attr_value(self, DEFAULT_SUBMIT_VALUE),
- InputType::InputReset => get_raw_attr_value(self, DEFAULT_RESET_VALUE),
- InputType::InputPassword => {
+ match (*self.unsafe_get()).input_type() {
+ InputType::Checkbox | InputType::Radio => String::new(),
+ InputType::File | InputType::Image => String::new(),
+ InputType::Button => get_raw_attr_value(self, ""),
+ InputType::Submit => get_raw_attr_value(self, DEFAULT_SUBMIT_VALUE),
+ InputType::Reset => get_raw_attr_value(self, DEFAULT_RESET_VALUE),
+ InputType::Password => {
let text = get_raw_textinput_value(self);
if !text.is_empty() {
text.chars().map(|_| PASSWORD_REPLACEMENT_CHAR).collect()
@@ -263,8 +374,8 @@ impl LayoutHTMLInputElementHelpers for LayoutDom<HTMLInputElement> {
let textinput = (*self.unsafe_get()).textinput.borrow_for_layout();
- match (*self.unsafe_get()).input_type.get() {
- InputType::InputPassword => {
+ match (*self.unsafe_get()).input_type() {
+ InputType::Password => {
let text = get_raw_textinput_value(self);
let sel = textinput.get_absolute_selection_range();
@@ -275,7 +386,7 @@ impl LayoutHTMLInputElementHelpers for LayoutDom<HTMLInputElement> {
let bytes_per_char = PASSWORD_REPLACEMENT_CHAR.len_utf8();
Some(char_start * bytes_per_char .. char_end * bytes_per_char)
}
- InputType::InputText => Some(textinput.get_absolute_selection_range()),
+ input_type if input_type.is_textual() => Some(textinput.get_absolute_selection_range()),
_ => None
}
}
@@ -366,16 +477,9 @@ impl HTMLInputElementMethods for HTMLInputElement {
make_limited_uint_setter!(SetSize, "size", DEFAULT_INPUT_SIZE);
// https://html.spec.whatwg.org/multipage/#dom-input-type
- make_enumerated_getter!(Type,
- "type",
- "text",
- "hidden" | "search" | "tel" |
- "url" | "email" | "password" |
- "datetime" | "date" | "month" |
- "week" | "time" | "datetime-local" |
- "number" | "range" | "color" |
- "checkbox" | "radio" | "file" |
- "submit" | "image" | "reset" | "button");
+ fn Type(&self) -> DOMString {
+ DOMString::from(self.input_type().to_str())
+ }
// https://html.spec.whatwg.org/multipage/#dom-input-type
make_atomic_setter!(SetType, "type");
@@ -566,7 +670,7 @@ impl HTMLInputElementMethods for HTMLInputElement {
// https://html.spec.whatwg.org/multipage/#dom-lfe-labels
fn Labels(&self) -> DomRoot<NodeList> {
- if self.type_() == atom!("hidden") {
+ if self.input_type() == InputType::Hidden {
let window = window_from_node(self);
NodeList::empty(&window)
} else {
@@ -614,7 +718,7 @@ impl HTMLInputElementMethods for HTMLInputElement {
// used for test purpose.
// check-tidy: no specs after this line
fn SelectFiles(&self, paths: Vec<DOMString>) {
- if self.input_type.get() == InputType::InputFile {
+ if self.input_type() == InputType::File {
self.select_files(Some(paths));
}
}
@@ -655,7 +759,7 @@ fn broadcast_radio_checked(broadcaster: &HTMLInputElement, group: Option<&Atom>)
// https://html.spec.whatwg.org/multipage/#radio-button-group
fn in_same_group(other: &HTMLInputElement, owner: Option<&HTMLFormElement>,
group: Option<&Atom>) -> bool {
- other.input_type.get() == InputType::InputRadio &&
+ other.input_type() == InputType::Radio &&
// TODO Both a and b are in the same home subtree.
other.form_owner().r() == owner &&
match (other.radio_group_name(), group) {
@@ -677,7 +781,8 @@ impl HTMLInputElement {
// 3.1: disabled state check is in get_unclean_dataset
// Step 3.2
- let ty = self.type_();
+ let ty = self.Type();
+
// Step 3.4
let name = self.Name();
let is_submitter = match submitter {
@@ -687,25 +792,26 @@ impl HTMLInputElement {
_ => false
};
- match ty {
+ match self.input_type() {
// Step 3.1: it's a button but it is not submitter.
- atom!("submit") | atom!("button") | atom!("reset") if !is_submitter => return vec![],
+ InputType::Submit | InputType::Button | InputType::Reset if !is_submitter => return vec![],
+
// Step 3.1: it's the "Checkbox" or "Radio Button" and whose checkedness is false.
- atom!("radio") | atom!("checkbox") => if !self.Checked() || name.is_empty() {
+ InputType::Radio | InputType::Checkbox => if !self.Checked() || name.is_empty() {
return vec![];
},
- atom!("file") => {
+
+ InputType::File => {
let mut datums = vec![];
// Step 3.2-3.7
let name = self.Name();
- let type_ = self.Type();
match self.GetFiles() {
Some(fl) => {
for f in fl.iter_files() {
datums.push(FormDatum {
- ty: type_.clone(),
+ ty: ty.clone(),
name: name.clone(),
value: FormDatumValue::File(DomRoot::from_ref(&f)),
});
@@ -715,7 +821,7 @@ impl HTMLInputElement {
datums.push(FormDatum {
// XXX(izgzhen): Spec says 'application/octet-stream' as the type,
// but this is _type_ of element rather than content right?
- ty: type_.clone(),
+ ty: ty.clone(),
name: name.clone(),
value: FormDatumValue::String(DOMString::from("")),
})
@@ -724,7 +830,9 @@ impl HTMLInputElement {
return datums;
}
- atom!("image") => return vec![], // Unimplemented
+
+ InputType::Image => return vec![], // Unimplemented
+
// Step 3.1: it's not the "Image Button" and doesn't have a name attribute.
_ => if name.is_empty() {
return vec![];
@@ -734,7 +842,7 @@ impl HTMLInputElement {
// Step 3.9
vec![FormDatum {
- ty: DOMString::from(&*ty), // FIXME(ajeffrey): Convert directly from Atoms to DOMStrings
+ ty: ty.clone(),
name: name,
value: FormDatumValue::String(self.Value())
}]
@@ -755,7 +863,7 @@ impl HTMLInputElement {
self.checked_changed.set(true);
}
- if self.input_type.get() == InputType::InputRadio && checked {
+ if self.input_type() == InputType::Radio && checked {
broadcast_radio_checked(self,
self.radio_group_name().as_ref());
}
@@ -773,12 +881,12 @@ impl HTMLInputElement {
// https://html.spec.whatwg.org/multipage/#the-input-element:concept-form-reset-control
pub fn reset(&self) {
- match self.input_type.get() {
- InputType::InputRadio | InputType::InputCheckbox => {
+ match self.input_type() {
+ InputType::Radio | InputType::Checkbox => {
self.update_checked_state(self.DefaultChecked(), false);
self.checked_changed.set(false);
},
- InputType::InputImage => (),
+ InputType::Image => (),
_ => ()
}
@@ -790,13 +898,14 @@ impl HTMLInputElement {
}
fn update_placeholder_shown_state(&self) {
- match self.input_type.get() {
- InputType::InputText | InputType::InputPassword => {},
- _ => return,
+ if !self.input_type().is_textual_or_password() {
+ return
}
+
let has_placeholder = !self.placeholder.borrow().is_empty();
let has_value = !self.textinput.borrow().is_empty();
let el = self.upcast::<Element>();
+
el.set_placeholder_shown_state(has_placeholder && !has_value);
}
@@ -865,29 +974,29 @@ impl HTMLInputElement {
// https://html.spec.whatwg.org/multipage/#value-sanitization-algorithm
fn sanitize_value(&self) {
- match self.type_() {
- atom!("text") | atom!("search") | atom!("tel") | atom!("password") => {
+ match self.input_type() {
+ InputType::Text | InputType::Search | InputType::Tel | InputType::Password => {
self.textinput.borrow_mut().single_line_content_mut().strip_newlines();
}
- atom!("url") => {
+ InputType::Url => {
let mut textinput = self.textinput.borrow_mut();
let content = textinput.single_line_content_mut();
content.strip_newlines();
content.strip_leading_and_trailing_ascii_whitespace();
}
- atom!("date") => {
+ InputType::Date => {
let mut textinput = self.textinput.borrow_mut();
if !textinput.single_line_content().is_valid_date_string() {
*textinput.single_line_content_mut() = "".into();
}
}
- atom!("month") => {
+ InputType::Month => {
let mut textinput = self.textinput.borrow_mut();
if !textinput.single_line_content().is_valid_month_string() {
*textinput.single_line_content_mut() = "".into();
}
}
- atom!("color") => {
+ InputType::Color => {
let mut textinput = self.textinput.borrow_mut();
let is_valid = {
@@ -907,7 +1016,7 @@ impl HTMLInputElement {
textinput.set_content("#000000".into());
}
}
- atom!("time") => {
+ InputType::Time => {
let mut textinput = self.textinput.borrow_mut();
if ! textinput.single_line_content().is_valid_time_string() {
@@ -943,7 +1052,7 @@ impl VirtualMethods for HTMLInputElement {
el.set_enabled_state(!disabled_state);
el.check_ancestors_disabled_state_for_form_control();
- if self.input_type.get() == InputType::InputText {
+ if self.input_type().is_textual() {
let read_write = !(self.ReadOnly() || el.disabled_state());
el.set_read_write_state(read_write);
}
@@ -969,29 +1078,20 @@ impl VirtualMethods for HTMLInputElement {
let el = self.upcast::<Element>();
match mutation {
AttributeMutation::Set(_) => {
- let new_type = match attr.value().as_atom() {
- &atom!("button") => InputType::InputButton,
- &atom!("submit") => InputType::InputSubmit,
- &atom!("reset") => InputType::InputReset,
- &atom!("file") => InputType::InputFile,
- &atom!("radio") => InputType::InputRadio,
- &atom!("checkbox") => InputType::InputCheckbox,
- &atom!("password") => InputType::InputPassword,
- _ => InputType::InputText,
- };
+ let new_type = InputType::from(attr.value().as_atom());
// https://html.spec.whatwg.org/multipage/#input-type-change
let (old_value_mode, old_idl_value) = (self.value_mode(), self.Value());
self.input_type.set(new_type);
- if new_type == InputType::InputText {
+ if new_type.is_textual() {
let read_write = !(self.ReadOnly() || el.disabled_state());
el.set_read_write_state(read_write);
} else {
el.set_read_write_state(false);
}
- if new_type == InputType::InputFile {
+ if new_type == InputType::File {
let window = window_from_node(self);
let filelist = FileList::new(&window, vec![]);
self.filelist.set(Some(&filelist));
@@ -1026,7 +1126,7 @@ impl VirtualMethods for HTMLInputElement {
}
// Step 5
- if new_type == InputType::InputRadio {
+ if new_type == InputType::Radio {
self.radio_group_updated(
self.radio_group_name().as_ref());
}
@@ -1035,12 +1135,12 @@ impl VirtualMethods for HTMLInputElement {
self.sanitize_value();
},
AttributeMutation::Removed => {
- if self.input_type.get() == InputType::InputRadio {
+ if self.input_type() == InputType::Radio {
broadcast_radio_checked(
self,
self.radio_group_name().as_ref());
}
- self.input_type.set(InputType::InputText);
+ self.input_type.set(InputType::default());
let el = self.upcast::<Element>();
let read_write = !(self.ReadOnly() || el.disabled_state());
@@ -1057,7 +1157,7 @@ impl VirtualMethods for HTMLInputElement {
self.sanitize_value();
self.update_placeholder_shown_state();
},
- &local_name!("name") if self.input_type.get() == InputType::InputRadio => {
+ &local_name!("name") if self.input_type() == InputType::Radio => {
self.radio_group_updated(
mutation.new_value(attr).as_ref().map(|name| name.as_atom()));
},
@@ -1096,7 +1196,7 @@ impl VirtualMethods for HTMLInputElement {
}
self.update_placeholder_shown_state();
},
- &local_name!("readonly") if self.input_type.get() == InputType::InputText => {
+ &local_name!("readonly") if self.input_type().is_textual() => {
let el = self.upcast::<Element>();
match mutation {
AttributeMutation::Set(_) => {
@@ -1157,8 +1257,7 @@ impl VirtualMethods for HTMLInputElement {
//TODO: set the editing position for text inputs
document_from_node(self).request_focus(self.upcast());
- if (self.input_type.get() == InputType::InputText ||
- self.input_type.get() == InputType::InputPassword) &&
+ if self.input_type().is_textual_or_password() &&
// Check if we display a placeholder. Layout doesn't know about this.
!self.textinput.borrow().is_empty() {
if let Some(mouse_event) = event.downcast::<MouseEvent>() {
@@ -1181,8 +1280,7 @@ impl VirtualMethods for HTMLInputElement {
}
}
} else if event.type_() == atom!("keydown") && !event.DefaultPrevented() &&
- (self.input_type.get() == InputType::InputText ||
- self.input_type.get() == InputType::InputPassword) {
+ self.input_type().is_textual_or_password() {
if let Some(keyevent) = event.downcast::<KeyboardEvent>() {
// This can't be inlined, as holding on to textinput.borrow_mut()
// during self.implicit_submission will cause a panic.
@@ -1208,8 +1306,7 @@ impl VirtualMethods for HTMLInputElement {
}
}
} else if event.type_() == atom!("keypress") && !event.DefaultPrevented() &&
- (self.input_type.get() == InputType::InputText ||
- self.input_type.get() == InputType::InputPassword) {
+ self.input_type().is_textual_or_password() {
if event.IsTrusted() {
let window = window_from_node(self);
let _ = window.user_interaction_task_source()
@@ -1254,13 +1351,13 @@ impl Activatable for HTMLInputElement {
}
fn is_instance_activatable(&self) -> bool {
- match self.input_type.get() {
+ match self.input_type() {
// https://html.spec.whatwg.org/multipage/#submit-button-state-%28type=submit%29:activation-behaviour-2
// https://html.spec.whatwg.org/multipage/#reset-button-state-%28type=reset%29:activation-behaviour-2
// https://html.spec.whatwg.org/multipage/#checkbox-state-%28type=checkbox%29:activation-behaviour-2
// https://html.spec.whatwg.org/multipage/#radio-button-state-%28type=radio%29:activation-behaviour-2
- InputType::InputSubmit | InputType::InputReset | InputType::InputFile
- | InputType::InputCheckbox | InputType::InputRadio => self.is_mutable(),
+ InputType::Submit | InputType::Reset | InputType::File
+ | InputType::Checkbox | InputType::Radio => self.is_mutable(),
_ => false
}
}
@@ -1269,16 +1366,16 @@ impl Activatable for HTMLInputElement {
#[allow(unsafe_code)]
fn pre_click_activation(&self) {
let mut cache = self.activation_state.borrow_mut();
- let ty = self.input_type.get();
+ let ty = self.input_type();
cache.old_type = ty;
cache.was_mutable = self.is_mutable();
if cache.was_mutable {
match ty {
// https://html.spec.whatwg.org/multipage/#submit-button-state-(type=submit):activation-behavior
- // InputType::InputSubmit => (), // No behavior defined
+ // InputType::Submit => (), // No behavior defined
// https://html.spec.whatwg.org/multipage/#reset-button-state-(type=reset):activation-behavior
- // InputType::InputSubmit => (), // No behavior defined
- InputType::InputCheckbox => {
+ // InputType::Submit => (), // No behavior defined
+ InputType::Checkbox => {
/*
https://html.spec.whatwg.org/multipage/#checkbox-state-(type=checkbox):pre-click-activation-steps
cache current values of `checked` and `indeterminate`
@@ -1291,7 +1388,7 @@ impl Activatable for HTMLInputElement {
self.SetChecked(!cache.checked);
},
// https://html.spec.whatwg.org/multipage/#radio-button-state-(type=radio):pre-click-activation-steps
- InputType::InputRadio => {
+ InputType::Radio => {
//TODO: if not in document, use root ancestor instead of document
let owner = self.form_owner();
let doc = document_from_node(self);
@@ -1318,7 +1415,7 @@ impl Activatable for HTMLInputElement {
// https://html.spec.whatwg.org/multipage/#run-canceled-activation-steps
fn canceled_activation(&self) {
let cache = self.activation_state.borrow();
- let ty = self.input_type.get();
+ let ty = self.input_type();
if cache.old_type != ty {
// Type changed, abandon ship
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=27414
@@ -1326,11 +1423,11 @@ impl Activatable for HTMLInputElement {
}
match ty {
// https://html.spec.whatwg.org/multipage/#submit-button-state-(type=submit):activation-behavior
- // InputType::InputSubmit => (), // No behavior defined
+ // InputType::Submit => (), // No behavior defined
// https://html.spec.whatwg.org/multipage/#reset-button-state-(type=reset):activation-behavior
- // InputType::InputReset => (), // No behavior defined
+ // InputType::Reset => (), // No behavior defined
// https://html.spec.whatwg.org/multipage/#checkbox-state-(type=checkbox):canceled-activation-steps
- InputType::InputCheckbox => {
+ InputType::Checkbox => {
// We want to restore state only if the element had been changed in the first place
if cache.was_mutable {
self.SetIndeterminate(cache.indeterminate);
@@ -1339,7 +1436,7 @@ impl Activatable for HTMLInputElement {
}
},
// https://html.spec.whatwg.org/multipage/#radio-button-state-(type=radio):canceled-activation-steps
- InputType::InputRadio => {
+ InputType::Radio => {
// We want to restore state only if the element had been changed in the first place
if cache.was_mutable {
match cache.checked_radio.r() {
@@ -1363,14 +1460,14 @@ impl Activatable for HTMLInputElement {
// https://html.spec.whatwg.org/multipage/#run-post-click-activation-steps
fn activation_behavior(&self, _event: &Event, _target: &EventTarget) {
- let ty = self.input_type.get();
+ let ty = self.input_type();
if self.activation_state.borrow().old_type != ty || !self.is_mutable() {
// Type changed or input is immutable, abandon ship
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=27414
return;
}
match ty {
- InputType::InputSubmit => {
+ InputType::Submit => {
// https://html.spec.whatwg.org/multipage/#submit-button-state-(type=submit):activation-behavior
// FIXME (Manishearth): support document owners (needs ability to get parent browsing context)
// Check if document owner is fully active
@@ -1379,7 +1476,7 @@ impl Activatable for HTMLInputElement {
FormSubmitter::InputElement(self.clone()))
});
},
- InputType::InputReset => {
+ InputType::Reset => {
// https://html.spec.whatwg.org/multipage/#reset-button-state-(type=reset):activation-behavior
// FIXME (Manishearth): support document owners (needs ability to get parent browsing context)
// Check if document owner is fully active
@@ -1387,7 +1484,7 @@ impl Activatable for HTMLInputElement {
o.reset(ResetFrom::NotFromForm)
});
},
- InputType::InputCheckbox | InputType::InputRadio => {
+ InputType::Checkbox | InputType::Radio => {
// https://html.spec.whatwg.org/multipage/#checkbox-state-(type=checkbox):activation-behavior
// https://html.spec.whatwg.org/multipage/#radio-button-state-(type=radio):activation-behavior
// Check if document owner is fully active
@@ -1395,7 +1492,7 @@ impl Activatable for HTMLInputElement {
target.fire_bubbling_event(atom!("input"));
target.fire_bubbling_event(atom!("change"));
},
- InputType::InputFile => self.select_files(None),
+ InputType::File => self.select_files(None),
_ => ()
}
}
@@ -1433,11 +1530,11 @@ impl Activatable for HTMLInputElement {
let inputs = node.query_selector_iter(DOMString::from("input")).unwrap()
.filter_map(DomRoot::downcast::<HTMLInputElement>)
.filter(|input| {
- input.form_owner() == owner && match input.type_() {
- atom!("text") | atom!("search") | atom!("url") | atom!("tel") |
- atom!("email") | atom!("password") | atom!("datetime") |
- atom!("date") | atom!("month") | atom!("week") | atom!("time") |
- atom!("datetime-local") | atom!("number")
+ input.form_owner() == owner && match input.input_type() {
+ InputType::Text | InputType::Search | InputType::Url | InputType::Tel
+ | InputType::Email | InputType::Password | InputType::Datetime
+ | InputType::Date | InputType::Month | InputType::Week | InputType::Time
+ | InputType::DatetimeLocal | InputType::Number
=> true,
_ => false
}
diff --git a/components/script/dom/radionodelist.rs b/components/script/dom/radionodelist.rs
index 8c8cd88b742..4a4a19cd646 100644
--- a/components/script/dom/radionodelist.rs
+++ b/components/script/dom/radionodelist.rs
@@ -10,7 +10,7 @@ use dom::bindings::inheritance::Castable;
use dom::bindings::reflector::reflect_dom_object;
use dom::bindings::root::{Dom, DomRoot};
use dom::bindings::str::DOMString;
-use dom::htmlinputelement::HTMLInputElement;
+use dom::htmlinputelement::{HTMLInputElement, InputType};
use dom::node::Node;
use dom::nodelist::{NodeList, NodeListType};
use dom::window::Window;
@@ -55,13 +55,12 @@ impl RadioNodeListMethods for RadioNodeList {
self.upcast::<NodeList>().as_simple_list().iter().filter_map(|node| {
// Step 1
node.downcast::<HTMLInputElement>().and_then(|input| {
- match input.type_() {
- atom!("radio") if input.Checked() => {
- // Step 3-4
- let value = input.Value();
- Some(if value.is_empty() { DOMString::from("on") } else { value })
- }
- _ => None
+ if input.input_type() == InputType::Radio && input.Checked() {
+ // Step 3-4
+ let value = input.Value();
+ Some(if value.is_empty() { DOMString::from("on") } else { value })
+ } else {
+ None
}
})
}).next()
@@ -74,8 +73,8 @@ impl RadioNodeListMethods for RadioNodeList {
for node in self.upcast::<NodeList>().as_simple_list().iter() {
// Step 1
if let Some(input) = node.downcast::<HTMLInputElement>() {
- match input.type_() {
- atom!("radio") if value == DOMString::from("on") => {
+ match input.input_type() {
+ InputType::Radio if value == DOMString::from("on") => {
// Step 2
let val = input.Value();
if val.is_empty() || val == value {
@@ -83,7 +82,7 @@ impl RadioNodeListMethods for RadioNodeList {
return;
}
}
- atom!("radio") => {
+ InputType::Radio => {
// Step 2
if input.Value() == value {
input.SetChecked(true);
diff --git a/tests/wpt/metadata/html/semantics/forms/the-input-element/clone.html.ini b/tests/wpt/metadata/html/semantics/forms/the-input-element/clone.html.ini
index b4e6db3e89b..04df058a43f 100644
--- a/tests/wpt/metadata/html/semantics/forms/the-input-element/clone.html.ini
+++ b/tests/wpt/metadata/html/semantics/forms/the-input-element/clone.html.ini
@@ -12,9 +12,6 @@
[Radiobutton must retain unchecked state.]
expected: FAIL
- [Hidden field must retain changed value.]
- expected: FAIL
-
[Text field must retain changed value.]
expected: FAIL