mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
auto merge of #4133 : mttr/servo/form_resetting, r=jdm
We can reset `<input type=text>` fields! I wish I could've done something with checkboxes, but unfortunately, that's it for now. In addition to that, this PR implements `HTMLInputAttribute.defaultValue`, updates wpt-test to expect passing tests as a result of that implementation, and fixes an index error crash with text inputs. edit: also includes an html example where one may lazily watch form resets in action: ` tests/html/form_reset_handsfree.html`
This commit is contained in:
commit
5951056973
22 changed files with 376 additions and 446 deletions
|
@ -562,6 +562,13 @@ impl<'le> TElement<'le> for LayoutElement<'le> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_indeterminate_state(self) -> bool {
|
||||
unsafe {
|
||||
self.element.get_indeterminate_state_for_layout()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn has_class(self, name: &Atom) -> bool {
|
||||
unsafe {
|
||||
|
|
|
@ -35,7 +35,7 @@ use dom::event::Event;
|
|||
use dom::eventtarget::{EventTarget, NodeTargetTypeId, EventTargetHelpers};
|
||||
use dom::htmlbodyelement::{HTMLBodyElement, HTMLBodyElementHelpers};
|
||||
use dom::htmlcollection::HTMLCollection;
|
||||
use dom::htmlinputelement::{HTMLInputElement, RawLayoutHTMLInputElementHelpers};
|
||||
use dom::htmlinputelement::{HTMLInputElement, RawLayoutHTMLInputElementHelpers, HTMLInputElementHelpers};
|
||||
use dom::htmlserializer::serialize;
|
||||
use dom::htmltableelement::{HTMLTableElement, HTMLTableElementHelpers};
|
||||
use dom::htmltablecellelement::{HTMLTableCellElement, HTMLTableCellElementHelpers};
|
||||
|
@ -212,6 +212,7 @@ pub trait RawLayoutElementHelpers {
|
|||
unsafe fn get_integer_attribute_for_layout(&self, integer_attribute: IntegerAttribute)
|
||||
-> Option<i32>;
|
||||
unsafe fn get_checked_state_for_layout(&self) -> bool;
|
||||
unsafe fn get_indeterminate_state_for_layout(&self) -> bool;
|
||||
unsafe fn get_unsigned_integer_attribute_for_layout(&self, attribute: UnsignedIntegerAttribute)
|
||||
-> Option<u32>;
|
||||
unsafe fn get_simple_color_attribute_for_layout(&self, attribute: SimpleColorAttribute)
|
||||
|
@ -352,6 +353,18 @@ impl RawLayoutElementHelpers for Element {
|
|||
this.get_checked_state_for_layout()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(unrooted_must_root)]
|
||||
unsafe fn get_indeterminate_state_for_layout(&self) -> bool {
|
||||
// TODO progress elements can also be matched with :indeterminate
|
||||
if !self.is_htmlinputelement() {
|
||||
return false
|
||||
}
|
||||
let this: &HTMLInputElement = mem::transmute(self);
|
||||
this.get_indeterminate_state_for_layout()
|
||||
}
|
||||
|
||||
|
||||
unsafe fn get_unsigned_integer_attribute_for_layout(&self,
|
||||
attribute: UnsignedIntegerAttribute)
|
||||
-> Option<u32> {
|
||||
|
@ -1289,6 +1302,12 @@ impl<'a> style::TElement<'a> for JSRef<'a, Element> {
|
|||
None => false,
|
||||
}
|
||||
}
|
||||
fn get_indeterminate_state(self) -> bool {
|
||||
match HTMLInputElementCast::to_ref(self) {
|
||||
Some(input) => input.get_indeterminate_state(),
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
fn has_class(self, name: &Atom) -> bool {
|
||||
// FIXME(zwarich): Remove this when UFCS lands and there is a better way
|
||||
// of disambiguating methods.
|
||||
|
|
|
@ -2,23 +2,26 @@
|
|||
* 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::DocumentBinding::DocumentMethods;
|
||||
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::Bindings::HTMLInputElementBinding::HTMLInputElementMethods;
|
||||
use dom::bindings::codegen::InheritTypes::{EventTargetCast, HTMLFormElementDerived, NodeCast};
|
||||
use dom::bindings::codegen::InheritTypes::HTMLInputElementCast;
|
||||
use dom::bindings::codegen::InheritTypes::{HTMLInputElementCast, HTMLTextAreaElementCast, HTMLFormElementCast};
|
||||
use dom::bindings::global::Window;
|
||||
use dom::bindings::js::{JSRef, Temporary};
|
||||
use dom::bindings::js::{JSRef, Temporary, OptionalRootable};
|
||||
use dom::bindings::utils::{Reflectable, Reflector};
|
||||
use dom::document::{Document, DocumentHelpers};
|
||||
use dom::element::{Element, AttributeHandlers, HTMLFormElementTypeId, HTMLTextAreaElementTypeId, HTMLDataListElementTypeId};
|
||||
use dom::element::{HTMLInputElementTypeId, HTMLButtonElementTypeId, HTMLObjectElementTypeId, HTMLSelectElementTypeId};
|
||||
use dom::element::{HTMLOutputElementTypeId};
|
||||
use dom::event::{Event, EventHelpers, Bubbles, Cancelable};
|
||||
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
||||
use dom::htmlelement::HTMLElement;
|
||||
use dom::htmlinputelement::HTMLInputElement;
|
||||
use dom::htmltextareaelement::HTMLTextAreaElement;
|
||||
use dom::node::{Node, NodeHelpers, ElementNodeTypeId, document_from_node, window_from_node};
|
||||
use hyper::method::Post;
|
||||
use servo_msg::constellation_msg::LoadData;
|
||||
|
@ -29,9 +32,12 @@ use url::UrlParser;
|
|||
use url::form_urlencoded::serialize;
|
||||
use string_cache::Atom;
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
#[dom_struct]
|
||||
pub struct HTMLFormElement {
|
||||
htmlelement: HTMLElement,
|
||||
marked_for_reset: Cell<bool>,
|
||||
}
|
||||
|
||||
impl HTMLFormElementDerived for EventTarget {
|
||||
|
@ -43,7 +49,8 @@ impl HTMLFormElementDerived for EventTarget {
|
|||
impl HTMLFormElement {
|
||||
fn new_inherited(localName: DOMString, prefix: Option<DOMString>, document: JSRef<Document>) -> HTMLFormElement {
|
||||
HTMLFormElement {
|
||||
htmlelement: HTMLElement::new_inherited(HTMLFormElementTypeId, localName, prefix, document)
|
||||
htmlelement: HTMLElement::new_inherited(HTMLFormElementTypeId, localName, prefix, document),
|
||||
marked_for_reset: Cell::new(false),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,6 +124,11 @@ impl<'a> HTMLFormElementMethods for JSRef<'a, HTMLFormElement> {
|
|||
fn Submit(self) {
|
||||
self.submit(FromFormSubmitMethod, FormElement(self));
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#dom-form-reset
|
||||
fn Reset(self) {
|
||||
self.reset(FromFormResetMethod);
|
||||
}
|
||||
}
|
||||
|
||||
pub enum SubmittedFrom {
|
||||
|
@ -124,11 +136,18 @@ pub enum SubmittedFrom {
|
|||
NotFromFormSubmitMethod
|
||||
}
|
||||
|
||||
pub enum ResetFrom {
|
||||
FromFormResetMethod,
|
||||
NotFromFormResetMethod
|
||||
}
|
||||
|
||||
pub trait HTMLFormElementHelpers {
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#concept-form-submit
|
||||
fn submit(self, submit_method_flag: SubmittedFrom, 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>;
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#dom-form-reset
|
||||
fn reset(self, submit_method_flag: ResetFrom);
|
||||
}
|
||||
|
||||
impl<'a> HTMLFormElementHelpers for JSRef<'a, HTMLFormElement> {
|
||||
|
@ -316,6 +335,59 @@ impl<'a> HTMLFormElementHelpers for JSRef<'a, HTMLFormElement> {
|
|||
};
|
||||
ret
|
||||
}
|
||||
|
||||
fn reset(self, _reset_method_flag: ResetFrom) {
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#locked-for-reset
|
||||
if self.marked_for_reset.get() {
|
||||
return;
|
||||
} else {
|
||||
self.marked_for_reset.set(true);
|
||||
}
|
||||
|
||||
let win = window_from_node(self).root();
|
||||
let event = Event::new(Window(*win),
|
||||
"reset".to_string(),
|
||||
Bubbles, Cancelable).root();
|
||||
let target: JSRef<EventTarget> = EventTargetCast::from_ref(self);
|
||||
target.DispatchEvent(*event).ok();
|
||||
if event.DefaultPrevented() {
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
for child in node.traverse_preorder() {
|
||||
match child.type_id() {
|
||||
ElementNodeTypeId(HTMLInputElementTypeId) => {
|
||||
let input: JSRef<HTMLInputElement> = HTMLInputElementCast::to_ref(child)
|
||||
.unwrap();
|
||||
input.reset()
|
||||
}
|
||||
// TODO HTMLKeygenElement unimplemented
|
||||
//ElementNodeTypeID(HTMLKeygenElementTypeId) => {
|
||||
// // Unimplemented
|
||||
// {}
|
||||
//}
|
||||
ElementNodeTypeId(HTMLSelectElementTypeId) => {
|
||||
// Unimplemented
|
||||
{}
|
||||
}
|
||||
ElementNodeTypeId(HTMLTextAreaElementTypeId) => {
|
||||
let textarea: JSRef<HTMLTextAreaElement> = HTMLTextAreaElementCast::to_ref(child)
|
||||
.unwrap();
|
||||
textarea.reset()
|
||||
}
|
||||
ElementNodeTypeId(HTMLOutputElementTypeId) => {
|
||||
// Unimplemented
|
||||
{}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
};
|
||||
self.marked_for_reset.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
impl Reflectable for HTMLFormElement {
|
||||
|
@ -412,7 +484,30 @@ impl<'a> FormSubmitter<'a> {
|
|||
}
|
||||
|
||||
pub trait FormControl<'a> : Copy {
|
||||
fn form_owner(self) -> Option<Temporary<HTMLFormElement>>;
|
||||
// FIXME: This is wrong (https://github.com/servo/servo/issues/3553)
|
||||
// but we need html5ever to do it correctly
|
||||
fn form_owner(self) -> Option<Temporary<HTMLFormElement>> {
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#reset-the-form-owner
|
||||
let elem = self.to_element();
|
||||
let owner = elem.get_string_attribute(&atom!("form"));
|
||||
if !owner.is_empty() {
|
||||
let doc = document_from_node(elem).root();
|
||||
let owner = doc.GetElementById(owner).root();
|
||||
match owner {
|
||||
Some(o) => {
|
||||
let maybe_form: Option<JSRef<HTMLFormElement>> = HTMLFormElementCast::to_ref(*o);
|
||||
if maybe_form.is_some() {
|
||||
return maybe_form.map(Temporary::from_rooted);
|
||||
}
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
let node: JSRef<Node> = NodeCast::from_ref(elem);
|
||||
node.ancestors().filter_map(|a| HTMLFormElementCast::to_ref(a)).next()
|
||||
.map(Temporary::from_rooted)
|
||||
}
|
||||
|
||||
fn get_form_attribute(self,
|
||||
attr: &Atom,
|
||||
input: |Self| -> DOMString,
|
||||
|
@ -426,4 +521,5 @@ pub trait FormControl<'a> : Copy {
|
|||
fn to_element(self) -> JSRef<'a, Element>;
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#concept-fe-mutable
|
||||
fn mutable(self) -> bool;
|
||||
fn reset(self);
|
||||
}
|
||||
|
|
|
@ -7,12 +7,11 @@ use dom::attr::{Attr, AttrValue, UIntAttrValue};
|
|||
use dom::attr::AttrHelpers;
|
||||
use dom::bindings::cell::DOMRefCell;
|
||||
use dom::bindings::codegen::Bindings::AttrBinding::AttrMethods;
|
||||
use dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
|
||||
use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
|
||||
use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
|
||||
use dom::bindings::codegen::Bindings::HTMLInputElementBinding;
|
||||
use dom::bindings::codegen::Bindings::HTMLInputElementBinding::HTMLInputElementMethods;
|
||||
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, HTMLFormElementCast, HTMLInputElementCast, NodeCast};
|
||||
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, HTMLInputElementCast, NodeCast};
|
||||
use dom::bindings::codegen::InheritTypes::{HTMLInputElementDerived, HTMLFieldSetElementDerived, EventTargetCast};
|
||||
use dom::bindings::codegen::InheritTypes::KeyboardEventCast;
|
||||
use dom::bindings::global::Window;
|
||||
|
@ -27,7 +26,7 @@ use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
|||
use dom::htmlelement::HTMLElement;
|
||||
use dom::keyboardevent::KeyboardEvent;
|
||||
use dom::htmlformelement::{InputElement, FormControl, HTMLFormElement, HTMLFormElementHelpers};
|
||||
use dom::htmlformelement::{NotFromFormSubmitMethod};
|
||||
use dom::htmlformelement::{NotFromFormSubmitMethod, NotFromFormResetMethod};
|
||||
use dom::node::{DisabledStateHelpers, Node, NodeHelpers, ElementNodeTypeId, OtherNodeDamage};
|
||||
use dom::node::{document_from_node, window_from_node};
|
||||
use dom::virtualmethods::VirtualMethods;
|
||||
|
@ -63,7 +62,9 @@ pub struct HTMLInputElement {
|
|||
htmlelement: HTMLElement,
|
||||
input_type: Cell<InputType>,
|
||||
checked: Cell<bool>,
|
||||
checked_changed: Cell<bool>,
|
||||
indeterminate: Cell<bool>,
|
||||
value_changed: Cell<bool>,
|
||||
size: Cell<u32>,
|
||||
textinput: DOMRefCell<TextInput>,
|
||||
activation_state: DOMRefCell<InputActivationState>,
|
||||
|
@ -74,6 +75,7 @@ pub struct HTMLInputElement {
|
|||
struct InputActivationState {
|
||||
indeterminate: bool,
|
||||
checked: bool,
|
||||
checked_changed: bool,
|
||||
checked_radio: MutNullableJS<HTMLInputElement>,
|
||||
// In case mutability changed
|
||||
was_mutable: bool,
|
||||
|
@ -86,6 +88,7 @@ impl InputActivationState {
|
|||
InputActivationState {
|
||||
indeterminate: false,
|
||||
checked: false,
|
||||
checked_changed: false,
|
||||
checked_radio: Default::default(),
|
||||
was_mutable: false,
|
||||
old_type: InputText
|
||||
|
@ -108,6 +111,8 @@ impl HTMLInputElement {
|
|||
input_type: Cell::new(InputText),
|
||||
checked: Cell::new(false),
|
||||
indeterminate: Cell::new(false),
|
||||
checked_changed: Cell::new(false),
|
||||
value_changed: Cell::new(false),
|
||||
size: Cell::new(DEFAULT_INPUT_SIZE),
|
||||
textinput: DOMRefCell::new(TextInput::new(Single, "".to_string())),
|
||||
activation_state: DOMRefCell::new(InputActivationState::new())
|
||||
|
@ -128,6 +133,7 @@ pub trait LayoutHTMLInputElementHelpers {
|
|||
|
||||
pub trait RawLayoutHTMLInputElementHelpers {
|
||||
unsafe fn get_checked_state_for_layout(&self) -> bool;
|
||||
unsafe fn get_indeterminate_state_for_layout(&self) -> bool;
|
||||
unsafe fn get_size_for_layout(&self) -> u32;
|
||||
}
|
||||
|
||||
|
@ -170,6 +176,11 @@ impl RawLayoutHTMLInputElementHelpers for HTMLInputElement {
|
|||
self.checked.get()
|
||||
}
|
||||
|
||||
#[allow(unrooted_must_root)]
|
||||
unsafe fn get_indeterminate_state_for_layout(&self) -> bool {
|
||||
self.indeterminate.get()
|
||||
}
|
||||
|
||||
#[allow(unrooted_must_root)]
|
||||
unsafe fn get_size_for_layout(&self) -> u32 {
|
||||
self.size.get()
|
||||
|
@ -183,6 +194,12 @@ impl<'a> HTMLInputElementMethods for JSRef<'a, HTMLInputElement> {
|
|||
// http://www.whatwg.org/html/#dom-fe-disabled
|
||||
make_bool_setter!(SetDisabled, "disabled")
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-defaultchecked
|
||||
make_bool_getter!(DefaultChecked, "checked")
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-defaultchecked
|
||||
make_bool_setter!(SetDefaultChecked, "checked")
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-checked
|
||||
fn Checked(self) -> bool {
|
||||
self.checked.get()
|
||||
|
@ -190,7 +207,7 @@ impl<'a> HTMLInputElementMethods for JSRef<'a, HTMLInputElement> {
|
|||
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-checked
|
||||
fn SetChecked(self, checked: bool) {
|
||||
self.update_checked_state(checked);
|
||||
self.update_checked_state(checked, true);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-readonly
|
||||
|
@ -223,7 +240,17 @@ impl<'a> HTMLInputElementMethods for JSRef<'a, HTMLInputElement> {
|
|||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-value
|
||||
make_setter!(SetValue, "value")
|
||||
fn SetValue(self, value: DOMString) {
|
||||
self.textinput.borrow_mut().set_content(value);
|
||||
self.value_changed.set(true);
|
||||
self.force_relayout();
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-defaultvalue
|
||||
make_getter!(DefaultValue, "value")
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-defaultvalue
|
||||
make_setter!(SetDefaultValue, "value")
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#attr-fe-name
|
||||
make_getter!(Name)
|
||||
|
@ -262,7 +289,6 @@ impl<'a> HTMLInputElementMethods for JSRef<'a, HTMLInputElement> {
|
|||
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-indeterminate
|
||||
fn SetIndeterminate(self, val: bool) {
|
||||
// FIXME #4079 this should change the appearance
|
||||
self.indeterminate.set(val)
|
||||
}
|
||||
}
|
||||
|
@ -271,8 +297,9 @@ pub trait HTMLInputElementHelpers {
|
|||
fn force_relayout(self);
|
||||
fn radio_group_updated(self, group: Option<&str>);
|
||||
fn get_radio_group_name(self) -> Option<String>;
|
||||
fn update_checked_state(self, checked: bool);
|
||||
fn update_checked_state(self, checked: bool, dirty: bool);
|
||||
fn get_size(&self) -> u32;
|
||||
fn get_indeterminate_state(self) -> bool;
|
||||
}
|
||||
|
||||
fn broadcast_radio_checked(broadcaster: JSRef<HTMLInputElement>, group: Option<&str>) {
|
||||
|
@ -331,8 +358,13 @@ impl<'a> HTMLInputElementHelpers for JSRef<'a, HTMLInputElement> {
|
|||
.map(|name| name.Value())
|
||||
}
|
||||
|
||||
fn update_checked_state(self, checked: bool) {
|
||||
fn update_checked_state(self, checked: bool, dirty: bool) {
|
||||
self.checked.set(checked);
|
||||
|
||||
if dirty {
|
||||
self.checked_changed.set(true);
|
||||
}
|
||||
|
||||
if self.input_type.get() == InputRadio && checked {
|
||||
broadcast_radio_checked(self,
|
||||
self.get_radio_group_name()
|
||||
|
@ -346,6 +378,10 @@ impl<'a> HTMLInputElementHelpers for JSRef<'a, HTMLInputElement> {
|
|||
fn get_size(&self) -> u32 {
|
||||
self.size.get()
|
||||
}
|
||||
|
||||
fn get_indeterminate_state(self) -> bool {
|
||||
self.indeterminate.get()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
|
||||
|
@ -367,7 +403,10 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
|
|||
node.set_enabled_state(false);
|
||||
}
|
||||
&atom!("checked") => {
|
||||
self.update_checked_state(true);
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#the-input-element:concept-input-checked-dirty
|
||||
if !self.checked_changed.get() {
|
||||
self.update_checked_state(true, false);
|
||||
}
|
||||
}
|
||||
&atom!("size") => {
|
||||
match *attr.value() {
|
||||
|
@ -396,9 +435,11 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
|
|||
self.force_relayout();
|
||||
}
|
||||
&atom!("value") => {
|
||||
if !self.value_changed.get() {
|
||||
self.textinput.borrow_mut().set_content(attr.value().as_slice().to_string());
|
||||
self.force_relayout();
|
||||
}
|
||||
}
|
||||
&atom!("name") => {
|
||||
if self.input_type.get() == InputRadio {
|
||||
let value = attr.value();
|
||||
|
@ -423,7 +464,10 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
|
|||
node.check_ancestors_disabled_state_for_form_control();
|
||||
}
|
||||
&atom!("checked") => {
|
||||
self.update_checked_state(false);
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#the-input-element:concept-input-checked-dirty
|
||||
if !self.checked_changed.get() {
|
||||
self.update_checked_state(false, false);
|
||||
}
|
||||
}
|
||||
&atom!("size") => {
|
||||
self.size.set(DEFAULT_INPUT_SIZE);
|
||||
|
@ -440,9 +484,11 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
|
|||
self.force_relayout();
|
||||
}
|
||||
&atom!("value") => {
|
||||
if !self.value_changed.get() {
|
||||
self.textinput.borrow_mut().set_content("".to_string());
|
||||
self.force_relayout();
|
||||
}
|
||||
}
|
||||
&atom!("name") => {
|
||||
if self.input_type.get() == InputRadio {
|
||||
self.radio_group_updated(None);
|
||||
|
@ -493,7 +539,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
|
|||
|
||||
if "click" == event.Type().as_slice() && !event.DefaultPrevented() {
|
||||
match self.input_type.get() {
|
||||
InputRadio => self.SetChecked(true),
|
||||
InputRadio => self.update_checked_state(true, true),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
@ -511,6 +557,7 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
|
|||
match self.textinput.borrow_mut().handle_keydown(keyevent) {
|
||||
TriggerDefaultAction => (),
|
||||
DispatchInput => {
|
||||
self.value_changed.set(true);
|
||||
self.force_relayout();
|
||||
event.PreventDefault();
|
||||
}
|
||||
|
@ -528,30 +575,6 @@ impl Reflectable for HTMLInputElement {
|
|||
}
|
||||
|
||||
impl<'a> FormControl<'a> for JSRef<'a, HTMLInputElement> {
|
||||
// FIXME: This is wrong (https://github.com/servo/servo/issues/3553)
|
||||
// but we need html5ever to do it correctly
|
||||
fn form_owner(self) -> Option<Temporary<HTMLFormElement>> {
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#reset-the-form-owner
|
||||
let elem: JSRef<Element> = ElementCast::from_ref(self);
|
||||
let owner = elem.get_string_attribute(&atom!("form"));
|
||||
if !owner.is_empty() {
|
||||
let doc = document_from_node(self).root();
|
||||
let owner = doc.GetElementById(owner).root();
|
||||
match owner {
|
||||
Some(o) => {
|
||||
let maybe_form: Option<JSRef<HTMLFormElement>> = HTMLFormElementCast::to_ref(*o);
|
||||
if maybe_form.is_some() {
|
||||
return maybe_form.map(Temporary::from_rooted);
|
||||
}
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
let node: JSRef<Node> = NodeCast::from_ref(self);
|
||||
node.ancestors().filter_map(|a| HTMLFormElementCast::to_ref(a)).next()
|
||||
.map(Temporary::from_rooted)
|
||||
}
|
||||
|
||||
fn to_element(self) -> JSRef<'a, Element> {
|
||||
ElementCast::from_ref(self)
|
||||
}
|
||||
|
@ -562,6 +585,21 @@ impl<'a> FormControl<'a> for JSRef<'a, HTMLInputElement> {
|
|||
// https://html.spec.whatwg.org/multipage/forms.html#the-readonly-attribute:concept-fe-mutable
|
||||
!(self.Disabled() || self.ReadOnly())
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#the-input-element:concept-form-reset-control
|
||||
fn reset(self) {
|
||||
match self.input_type.get() {
|
||||
InputRadio | InputCheckbox => {
|
||||
self.update_checked_state(self.DefaultChecked(), false);
|
||||
self.checked_changed.set(false);
|
||||
},
|
||||
InputImage => (),
|
||||
_ => ()
|
||||
}
|
||||
|
||||
self.SetValue(self.DefaultValue());
|
||||
self.value_changed.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -580,12 +618,15 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
|
|||
match ty {
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#submit-button-state-(type=submit):activation-behavior
|
||||
// InputSubmit => (), // No behavior defined
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#reset-button-state-(type=reset):activation-behavior
|
||||
// InputSubmit => (), // No behavior defined
|
||||
InputCheckbox => {
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#checkbox-state-(type=checkbox):pre-click-activation-steps
|
||||
// cache current values of `checked` and `indeterminate`
|
||||
// we may need to restore them later
|
||||
cache.indeterminate = self.Indeterminate();
|
||||
cache.checked = self.Checked();
|
||||
cache.checked_changed = self.checked_changed.get();
|
||||
self.SetIndeterminate(false);
|
||||
self.SetChecked(!cache.checked);
|
||||
},
|
||||
|
@ -606,6 +647,7 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
|
|||
.find(|r| r.Checked())
|
||||
};
|
||||
cache.checked_radio.assign(checked_member);
|
||||
cache.checked_changed = self.checked_changed.get();
|
||||
self.SetChecked(true);
|
||||
}
|
||||
_ => ()
|
||||
|
@ -625,12 +667,15 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
|
|||
match ty {
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#submit-button-state-(type=submit):activation-behavior
|
||||
// InputSubmit => (), // No behavior defined
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#reset-button-state-(type=reset):activation-behavior
|
||||
// InputReset => (), // No behavior defined
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#checkbox-state-(type=checkbox):canceled-activation-steps
|
||||
InputCheckbox => {
|
||||
// We want to restore state only if the element had been changed in the first place
|
||||
if cache.was_mutable {
|
||||
self.SetIndeterminate(cache.indeterminate);
|
||||
self.SetChecked(cache.checked);
|
||||
self.checked_changed.set(cache.checked_changed);
|
||||
}
|
||||
},
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#radio-button-state-(type=radio):canceled-activation-steps
|
||||
|
@ -654,6 +699,7 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
|
|||
},
|
||||
None => self.SetChecked(false)
|
||||
};
|
||||
self.checked_changed.set(cache.checked_changed);
|
||||
}
|
||||
}
|
||||
_ => ()
|
||||
|
@ -678,6 +724,15 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
|
|||
});
|
||||
}
|
||||
},
|
||||
InputReset => {
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#reset-button-state-(type=reset):activation-behavior
|
||||
// FIXME (Manishearth): support document owners (needs ability to get parent browsing context)
|
||||
if self.mutable() /* and document owner is fully active */ {
|
||||
self.form_owner().map(|o| {
|
||||
o.root().reset(NotFromFormResetMethod)
|
||||
});
|
||||
}
|
||||
},
|
||||
InputCheckbox | InputRadio => {
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#checkbox-state-(type=checkbox):activation-behavior
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#radio-button-state-(type=radio):activation-behavior
|
||||
|
|
|
@ -12,13 +12,14 @@ use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
|||
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast, NodeCast};
|
||||
use dom::bindings::codegen::InheritTypes::{HTMLTextAreaElementDerived, HTMLFieldSetElementDerived};
|
||||
use dom::bindings::codegen::InheritTypes::{KeyboardEventCast, TextDerived};
|
||||
use dom::bindings::js::{JS, JSRef, Temporary};
|
||||
use dom::bindings::js::{JS, JSRef, Temporary, OptionalRootable};
|
||||
use dom::bindings::utils::{Reflectable, Reflector};
|
||||
use dom::document::{Document, DocumentHelpers};
|
||||
use dom::element::{AttributeHandlers, HTMLTextAreaElementTypeId};
|
||||
use dom::element::{AttributeHandlers, HTMLTextAreaElementTypeId, Element};
|
||||
use dom::event::Event;
|
||||
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
|
||||
use dom::htmlelement::HTMLElement;
|
||||
use dom::htmlformelement::FormControl;
|
||||
use dom::keyboardevent::KeyboardEvent;
|
||||
use dom::node::{DisabledStateHelpers, Node, NodeHelpers, OtherNodeDamage, ElementNodeTypeId};
|
||||
use dom::node::{document_from_node};
|
||||
|
@ -124,6 +125,12 @@ impl<'a> HTMLTextAreaElementMethods for JSRef<'a, HTMLTextAreaElement> {
|
|||
// https://html.spec.whatwg.org/multipage/forms.html#dom-textarea-placeholder
|
||||
make_setter!(SetPlaceholder, "placeholder")
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#attr-textarea-readonly
|
||||
make_bool_getter!(ReadOnly)
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#attr-textarea-readonly
|
||||
make_bool_setter!(SetReadOnly, "readonly")
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#dom-textarea-required
|
||||
make_bool_getter!(Required)
|
||||
|
||||
|
@ -161,7 +168,7 @@ impl<'a> HTMLTextAreaElementMethods for JSRef<'a, HTMLTextAreaElement> {
|
|||
// if the element's dirty value flag is false, then the element's
|
||||
// raw value must be set to the value of the element's textContent IDL attribute
|
||||
if !self.value_changed.get() {
|
||||
self.SetValue(node.GetTextContent().unwrap());
|
||||
self.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,7 +179,9 @@ impl<'a> HTMLTextAreaElementMethods for JSRef<'a, HTMLTextAreaElement> {
|
|||
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#dom-textarea-value
|
||||
fn SetValue(self, value: DOMString) {
|
||||
// TODO move the cursor to the end of the field
|
||||
self.textinput.borrow_mut().set_content(value);
|
||||
self.value_changed.set(true);
|
||||
self.force_relayout();
|
||||
}
|
||||
}
|
||||
|
@ -286,8 +295,8 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLTextAreaElement> {
|
|||
_ => (),
|
||||
}
|
||||
|
||||
if child.is_text() {
|
||||
self.SetValue(self.DefaultValue());
|
||||
if child.is_text() && !self.value_changed.get() {
|
||||
self.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -326,3 +335,21 @@ impl Reflectable for HTMLTextAreaElement {
|
|||
self.htmlelement.reflector()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> FormControl<'a> for JSRef<'a, HTMLTextAreaElement> {
|
||||
fn to_element(self) -> JSRef<'a, Element> {
|
||||
ElementCast::from_ref(self)
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#concept-fe-mutable
|
||||
fn mutable(self) -> bool {
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#the-textarea-element:concept-fe-mutable
|
||||
!(self.Disabled() || self.ReadOnly())
|
||||
}
|
||||
|
||||
fn reset(self) {
|
||||
// https://html.spec.whatwg.org/multipage/forms.html#the-textarea-element:concept-form-reset-control
|
||||
self.SetValue(self.DefaultValue());
|
||||
self.value_changed.set(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ interface HTMLFormElement : HTMLElement {
|
|||
//getter (RadioNodeList or Element) (DOMString name);
|
||||
|
||||
void submit();
|
||||
//void reset();
|
||||
void reset();
|
||||
//boolean checkValidity();
|
||||
//boolean reportValidity();
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ interface HTMLInputElement : HTMLElement {
|
|||
// attribute DOMString alt;
|
||||
// attribute DOMString autocomplete;
|
||||
// attribute boolean autofocus;
|
||||
// attribute boolean defaultChecked;
|
||||
attribute boolean defaultChecked;
|
||||
attribute boolean checked;
|
||||
// attribute DOMString dirName;
|
||||
attribute boolean disabled;
|
||||
|
@ -38,7 +38,7 @@ interface HTMLInputElement : HTMLElement {
|
|||
// attribute DOMString src;
|
||||
// attribute DOMString step;
|
||||
attribute DOMString type;
|
||||
// attribute DOMString defaultValue;
|
||||
attribute DOMString defaultValue;
|
||||
[TreatNullAs=EmptyString] attribute DOMString value;
|
||||
// attribute Date? valueAsDate;
|
||||
// attribute unrestricted double valueAsNumber;
|
||||
|
|
|
@ -16,7 +16,7 @@ interface HTMLTextAreaElement : HTMLElement {
|
|||
// attribute long minLength;
|
||||
attribute DOMString name;
|
||||
attribute DOMString placeholder;
|
||||
// attribute boolean readOnly;
|
||||
attribute boolean readOnly;
|
||||
attribute boolean required;
|
||||
attribute unsigned long rows;
|
||||
attribute DOMString wrap;
|
||||
|
|
|
@ -295,6 +295,12 @@ impl TextInput {
|
|||
vec!(content)
|
||||
};
|
||||
self.edit_point.line = min(self.edit_point.line, self.lines.len() - 1);
|
||||
|
||||
if self.current_line_length() == 0 {
|
||||
self.edit_point.index = 0;
|
||||
}
|
||||
else {
|
||||
self.edit_point.index = min(self.edit_point.index, self.current_line_length() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ pub trait TElement<'a> : Copy {
|
|||
fn get_disabled_state(self) -> bool;
|
||||
fn get_enabled_state(self) -> bool;
|
||||
fn get_checked_state(self) -> bool;
|
||||
fn get_indeterminate_state(self) -> bool;
|
||||
fn has_class(self, name: &Atom) -> bool;
|
||||
fn has_nonzero_border(self) -> bool;
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ use properties::{PropertyDeclaration, PropertyDeclarationBlock};
|
|||
use selectors::{After, AnyLink, AttrDashMatch, AttrEqual};
|
||||
use selectors::{AttrExists, AttrIncludes, AttrPrefixMatch};
|
||||
use selectors::{AttrSubstringMatch, AttrSuffixMatch, Before, CaseInsensitive, CaseSensitive};
|
||||
use selectors::{Checked, Child, ClassSelector};
|
||||
use selectors::{Checked, Child, ClassSelector, Indeterminate};
|
||||
use selectors::{CompoundSelector, Descendant, Disabled, Enabled, FirstChild, FirstOfType};
|
||||
use selectors::{Hover, IDSelector, LastChild, LastOfType};
|
||||
use selectors::{LaterSibling, LocalName, LocalNameSelector};
|
||||
|
@ -972,6 +972,12 @@ pub fn matches_simple_selector<'a,E,N>(selector: &SimpleSelector,
|
|||
let elem = element.as_element();
|
||||
elem.get_checked_state()
|
||||
}
|
||||
// https://html.spec.whatwg.org/multipage/scripting.html#selector-indeterminate
|
||||
Indeterminate => {
|
||||
*shareable = false;
|
||||
let elem = element.as_element();
|
||||
elem.get_indeterminate_state()
|
||||
}
|
||||
FirstChild => {
|
||||
*shareable = false;
|
||||
matches_first_child(element)
|
||||
|
|
|
@ -75,6 +75,7 @@ pub enum SimpleSelector {
|
|||
Disabled,
|
||||
Enabled,
|
||||
Checked,
|
||||
Indeterminate,
|
||||
FirstChild, LastChild, OnlyChild,
|
||||
// Empty,
|
||||
Root,
|
||||
|
@ -167,7 +168,7 @@ fn compute_specificity(mut selector: &CompoundSelector,
|
|||
| &AttrExists(..) | &AttrEqual(..) | &AttrIncludes(..) | &AttrDashMatch(..)
|
||||
| &AttrPrefixMatch(..) | &AttrSubstringMatch(..) | &AttrSuffixMatch(..)
|
||||
| &AnyLink | &Link | &Visited | &Hover | &Disabled | &Enabled
|
||||
| &FirstChild | &LastChild | &OnlyChild | &Root | &Checked
|
||||
| &FirstChild | &LastChild | &OnlyChild | &Root | &Checked | &Indeterminate
|
||||
// | &Empty | &Lang(*)
|
||||
| &NthChild(..) | &NthLastChild(..)
|
||||
| &NthOfType(..) | &NthLastOfType(..)
|
||||
|
@ -568,6 +569,7 @@ fn parse_simple_pseudo_class(context: &ParserContext, name: &str) -> Result<Simp
|
|||
"disabled" => Ok(Disabled),
|
||||
"enabled" => Ok(Enabled),
|
||||
"checked" => Ok(Checked),
|
||||
"indeterminate" => Ok(Indeterminate),
|
||||
"first-child" => Ok(FirstChild),
|
||||
"last-child" => Ok(LastChild),
|
||||
"only-child" => Ok(OnlyChild),
|
||||
|
|
|
@ -11,6 +11,7 @@ input[type="radio"] { font-family: monospace !important; border: none !impor
|
|||
|
||||
input[type="checkbox"]::before { content: "[ ]"; padding: 0; }
|
||||
input[type="checkbox"]:checked::before { content: "[✓]"; }
|
||||
input[type="checkbox"]:indeterminate::before { content: "[-]"; }
|
||||
input[type="radio"]::before { content: "( )"; padding: 0; }
|
||||
input[type="radio"]:checked::before { content: "(●)"; }
|
||||
|
||||
|
|
16
tests/html/form_reset.html
Normal file
16
tests/html/form_reset.html
Normal file
|
@ -0,0 +1,16 @@
|
|||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<form>
|
||||
<input name=bar type=checkbox checked>
|
||||
<input name=baz value="baz1" type=radio checked>
|
||||
<input name=baz value="baz2" type=radio>
|
||||
<input type=text id=hi name=bye value="hi!">
|
||||
<input type=text id=aloha name=empty value="">
|
||||
<input type=text id=welcome name=reallyempty>
|
||||
<textarea id=textarea>Hello
|
||||
TextArea!</textarea>
|
||||
<input type=reset>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
25
tests/html/form_reset_handsfree.html
Normal file
25
tests/html/form_reset_handsfree.html
Normal file
|
@ -0,0 +1,25 @@
|
|||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<form 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 id=hi name=bye value="hi!">
|
||||
<input type=text id=aloha name=empty value="">
|
||||
<input type=text id=welcome name=reallyempty>
|
||||
<textarea id=textarea>Hello
|
||||
TextArea!</textarea>
|
||||
<script>
|
||||
// setTimeout because https://github.com/servo/servo/issues/3628
|
||||
setTimeout(function(){
|
||||
document.getElementById("hi").value=("bloop");
|
||||
document.getElementById("aloha").value=("bloop");
|
||||
document.getElementById("welcome").value=("bloop");
|
||||
document.getElementById("textarea").value=("bloop");
|
||||
setTimeout(function(){document.getElementById("foo").reset()},2000);
|
||||
},2000)
|
||||
</script>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -1,12 +1,47 @@
|
|||
<style>
|
||||
</style>
|
||||
<form>
|
||||
<div><input type="checkbox"></div>
|
||||
<div><input type="text" size="30" value="placeholder"></div>
|
||||
<div><input type="text" size="10" value="whefghijklmnopqrstuvwxyzabcdefg"></div>
|
||||
<div><input type="text" value=""><div>
|
||||
<div><input id=bar1 type="text" value=""></div>
|
||||
<div><button id=setdefaultvalue type=button>setDefaultValue</button>
|
||||
<button id=setvalue type=button>setValue</button></div>
|
||||
<div><input id=foo1 type="checkbox"></div>
|
||||
<div><input id=foo2 type="checkbox"></div>
|
||||
<div><input id=foo3 type="checkbox"></div>
|
||||
<div><button id=setdefault type=button>setDefaultChecked</button></div>
|
||||
<div><input type="submit"><input type="reset"><div>
|
||||
<div><input type="checkbox"></div>
|
||||
<div><input type="checkbox" checked></div>
|
||||
<div><input id=ch type="checkbox" checked></div>
|
||||
<div><input id=unch type="checkbox"></div>
|
||||
<script>
|
||||
document.getElementById("ch").indeterminate = true;
|
||||
document.getElementById("unch").indeterminate = true;
|
||||
var checkboxes = [document.getElementById("foo1"),
|
||||
document.getElementById("foo2"),
|
||||
document.getElementById("foo3")];
|
||||
var textinput = document.getElementById("bar1");
|
||||
var set_default_checked = document.getElementById("setdefault");
|
||||
var set_default_value = document.getElementById("setdefaultvalue");
|
||||
var set_value = document.getElementById("setvalue");
|
||||
var x = 0;
|
||||
|
||||
set_default_checked.addEventListener("click", function () {
|
||||
for (var i = 0; i < 3; i++) {
|
||||
checkboxes[i].defaultChecked = (i == x);
|
||||
}
|
||||
x = (x + 1) % 3;
|
||||
});
|
||||
|
||||
set_default_value.addEventListener("click", function () {
|
||||
textinput.defaultValue = x;
|
||||
x = (x + 1) % 3;
|
||||
});
|
||||
|
||||
set_value.addEventListener("click", function () {
|
||||
textinput.value = "new value!";
|
||||
});
|
||||
</script>
|
||||
<div>group 1
|
||||
<div><input type="radio"></div>
|
||||
<div><input type="radio" checked></div>
|
||||
|
@ -15,3 +50,4 @@
|
|||
<div><input type="radio" name="a" checked></div>
|
||||
<div><input type="radio" name="a"></div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -1,6 +1,25 @@
|
|||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<textarea name="textarea">Write something here
|
||||
<form>
|
||||
<textarea id="textarea">Write something here
|
||||
and maybe here</textarea>
|
||||
<button id=setcontent type=button>setContent</button>
|
||||
<button id=setvalue type=button>setValue</button>
|
||||
<input type=reset>
|
||||
<script>
|
||||
var text_area = document.getElementById("textarea");
|
||||
var set_c = document.getElementById("setcontent");
|
||||
var value = document.getElementById("setvalue");
|
||||
var x = 0;
|
||||
|
||||
set_c.addEventListener("click", function () {
|
||||
text_area.textContent = x;
|
||||
x++;
|
||||
});
|
||||
|
||||
value.addEventListener("click", function () {
|
||||
text_area.value = "new value!";
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -4662,9 +4662,6 @@
|
|||
[HTMLFormElement interface: attribute length]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLFormElement interface: operation reset()]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLFormElement interface: operation checkValidity()]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -4680,9 +4677,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 "reset" with the proper type (14)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLFormElement interface: document.createElement("form") must inherit property "checkValidity" with the proper type (15)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -4728,9 +4722,6 @@
|
|||
[HTMLInputElement interface: attribute autofocus]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLInputElement interface: attribute defaultChecked]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLInputElement interface: attribute dirName]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -4782,9 +4773,6 @@
|
|||
[HTMLInputElement interface: attribute step]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLInputElement interface: attribute defaultValue]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLInputElement interface: attribute valueAsDate]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -4866,9 +4854,6 @@
|
|||
[HTMLInputElement interface: document.createElement("input") must inherit property "autofocus" with the proper type (3)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLInputElement interface: document.createElement("input") must inherit property "defaultChecked" with the proper type (4)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLInputElement interface: document.createElement("input") must inherit property "dirName" with the proper type (6)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -4920,9 +4905,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 "defaultValue" with the proper type (33)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLInputElement interface: document.createElement("input") must inherit property "valueAsDate" with the proper type (35)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -5319,9 +5301,6 @@
|
|||
[HTMLTextAreaElement interface: attribute minLength]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLTextAreaElement interface: attribute readOnly]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLTextAreaElement interface: attribute textLength]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -5388,9 +5367,6 @@
|
|||
[HTMLTextAreaElement interface: document.createElement("textarea") must inherit property "minLength" with the proper type (8)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLTextAreaElement interface: document.createElement("textarea") must inherit property "readOnly" with the proper type (11)]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLTextAreaElement interface: document.createElement("textarea") must inherit property "textLength" with the proper type (18)]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -4170,114 +4170,6 @@
|
|||
[input.autofocus: IDL set to object "test-valueOf" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): typeof IDL attribute]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): IDL get with DOM attribute unset]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): setAttribute() to "" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): setAttribute() to " foo " followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): setAttribute() to undefined followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): setAttribute() to null followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): setAttribute() to 7 followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): setAttribute() to 1.5 followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): setAttribute() to true followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): setAttribute() to false followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): setAttribute() to object "[object Object\]" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): setAttribute() to NaN followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): setAttribute() to Infinity followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): setAttribute() to -Infinity followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): setAttribute() to "\\0" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): setAttribute() to object "test-toString" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): setAttribute() to object "test-valueOf" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): setAttribute() to "checked" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): IDL set to "" followed by hasAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): IDL set to "" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): IDL set to " foo " followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): IDL set to undefined followed by hasAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): IDL set to undefined followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): IDL set to null followed by hasAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): IDL set to null followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): IDL set to 7 followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): IDL set to 1.5 followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): IDL set to false followed by hasAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): IDL set to object "[object Object\]" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): IDL set to NaN followed by hasAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): IDL set to NaN followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): IDL set to Infinity followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): IDL set to -Infinity followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): IDL set to "\\0" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): IDL set to object "test-toString" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultChecked (<input checked>): IDL set to object "test-valueOf" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.dirName: typeof IDL attribute]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -6369,135 +6261,6 @@
|
|||
[input.step: IDL set to object "test-valueOf" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): typeof IDL attribute]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL get with DOM attribute unset]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): setAttribute() to "" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): 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
|
||||
|
||||
[input.defaultValue (<input value>): setAttribute() to undefined followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): setAttribute() to 7 followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): setAttribute() to 1.5 followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): setAttribute() to true followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): setAttribute() to false followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): setAttribute() to object "[object Object\]" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): setAttribute() to NaN followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): setAttribute() to Infinity followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): setAttribute() to -Infinity followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): setAttribute() to "\\0" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): setAttribute() to null followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): setAttribute() to object "test-toString" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): setAttribute() to object "test-valueOf" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to "" followed by getAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): 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
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to undefined followed by getAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to undefined followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to 7 followed by getAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to 7 followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to 1.5 followed by getAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to 1.5 followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to true followed by getAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to true followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to false followed by getAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to false followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to object "[object Object\]" followed by getAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to object "[object Object\]" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to NaN followed by getAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to NaN followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to Infinity followed by getAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to Infinity followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to -Infinity followed by getAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to -Infinity followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to "\\0" followed by getAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to null followed by getAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to null followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to object "test-toString" followed by getAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to object "test-toString" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.defaultValue (<input value>): IDL set to object "test-valueOf" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[input.align: typeof IDL attribute]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -14244,114 +14007,6 @@
|
|||
[textarea.maxLength: IDL set to 2147483647 followed by getAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: typeof IDL attribute]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: IDL get with DOM attribute unset]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: setAttribute() to "" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: setAttribute() to " foo " followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: setAttribute() to undefined followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: setAttribute() to null followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: setAttribute() to 7 followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: setAttribute() to 1.5 followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: setAttribute() to true followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: setAttribute() to false followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: setAttribute() to object "[object Object\]" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: setAttribute() to NaN followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: setAttribute() to Infinity followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: setAttribute() to -Infinity followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: setAttribute() to "\\0" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: setAttribute() to object "test-toString" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: setAttribute() to object "test-valueOf" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: setAttribute() to "readOnly" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: IDL set to "" followed by hasAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: IDL set to "" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: IDL set to " foo " followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: IDL set to undefined followed by hasAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: IDL set to undefined followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: IDL set to null followed by hasAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: IDL set to null followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: IDL set to 7 followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: IDL set to 1.5 followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: IDL set to false followed by hasAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: IDL set to object "[object Object\]" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: IDL set to NaN followed by hasAttribute()]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: IDL set to NaN followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: IDL set to Infinity followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: IDL set to -Infinity followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: IDL set to "\\0" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: IDL set to object "test-toString" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.readOnly: IDL set to object "test-valueOf" followed by IDL get]
|
||||
expected: FAIL
|
||||
|
||||
[textarea.rows: IDL get with DOM attribute unset]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -5,7 +5,3 @@
|
|||
|
||||
[sanitization algorithm strips line breaks]
|
||||
expected: FAIL
|
||||
|
||||
[Setting value changes the current value for password, but not the value content attribute]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,20 +1,10 @@
|
|||
[reset.html]
|
||||
type: testharness
|
||||
[reset button only resets the form owner]
|
||||
expected: FAIL
|
||||
|
||||
[the element is barred from constraint validation]
|
||||
expected: FAIL
|
||||
|
||||
[clicking on a disabled reset does nothing]
|
||||
expected: FAIL
|
||||
|
||||
[reset button resets controls associated with their form using the form element pointer]
|
||||
expected: FAIL
|
||||
|
||||
[reset button resets controls associated with a form using the form attribute]
|
||||
expected: FAIL
|
||||
|
||||
[reset button associated with a form using the form attribute resets all the form\'s controls]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -9,9 +9,6 @@
|
|||
[click on radio4 which is in the indeterminate state]
|
||||
expected: FAIL
|
||||
|
||||
[adding a value to progress1 should put it in a determinate state]
|
||||
expected: FAIL
|
||||
|
||||
[removing progress2\'s value should put it in an indeterminate state]
|
||||
expected: FAIL
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue