Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implements basic form resetting #4133

Merged
merged 12 commits into from Dec 16, 2014

Implements dirty value/checked flags for input

And modifies test-inputs.html to test.

Fixes wpt breaking mistake
  • Loading branch information
mttr committed Dec 16, 2014
commit 0c8e1aeda338c4fc6397e3e413fa8d93b7bad50c
@@ -63,7 +63,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 +76,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 +89,7 @@ impl InputActivationState {
InputActivationState {
indeterminate: false,
checked: false,
checked_changed: false,
checked_radio: Default::default(),
was_mutable: false,
old_type: InputText
@@ -108,6 +112,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())
@@ -196,7 +202,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
@@ -231,6 +237,7 @@ impl<'a> HTMLInputElementMethods for JSRef<'a, HTMLInputElement> {
// https://html.spec.whatwg.org/multipage/forms.html#dom-input-value
fn SetValue(self, value: DOMString) {
self.textinput.borrow_mut().set_content(value);
self.value_changed.set(true);
self.force_relayout();
}

@@ -286,7 +293,7 @@ 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;
}

@@ -346,8 +353,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()
@@ -382,7 +394,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() {
@@ -411,8 +426,10 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
self.force_relayout();
}
&atom!("value") => {
self.textinput.borrow_mut().set_content(attr.value().as_slice().to_string());
self.force_relayout();
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 {
@@ -438,7 +455,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);
@@ -455,8 +475,10 @@ impl<'a> VirtualMethods for JSRef<'a, HTMLInputElement> {
self.force_relayout();
}
&atom!("value") => {
self.textinput.borrow_mut().set_content("".to_string());
self.force_relayout();
if !self.value_changed.get() {
self.textinput.borrow_mut().set_content("".to_string());
self.force_relayout();
}
}
&atom!("name") => {
if self.input_type.get() == InputRadio {
@@ -508,7 +530,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),
_ => {}
}

@@ -526,6 +548,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();
}
@@ -581,13 +604,15 @@ impl<'a> FormControl<'a> for JSRef<'a, HTMLInputElement> {
fn reset(self) {
match self.input_type.get() {
InputRadio | InputCheckbox => {
self.SetChecked(self.DefaultChecked());
self.update_checked_state(self.DefaultChecked(), false);
self.checked_changed.set(false);
},
InputImage => (),
_ => ()
}

self.SetValue(self.DefaultValue());
self.value_changed.set(false);
}
}

@@ -613,6 +638,7 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
// 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);
},
@@ -633,6 +659,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);
}
_ => ()
@@ -658,6 +685,7 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
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
@@ -681,6 +709,7 @@ impl<'a> Activatable for JSRef<'a, HTMLInputElement> {
},
None => self.SetChecked(false)
};
self.checked_changed.set(cache.checked_changed);
}
}
_ => ()
@@ -109,7 +109,7 @@ impl<'a> HTMLTextAreaElementMethods for JSRef<'a, HTMLTextAreaElement> {
make_bool_getter!(ReadOnly)

// https://html.spec.whatwg.org/multipage/forms.html#attr-textarea-readonly
make_bool_setter!(SetReadOnly, "readOnly")
make_bool_setter!(SetReadOnly, "readonly")

// https://html.spec.whatwg.org/multipage/forms.html#dom-textarea-required
make_bool_getter!(Required)
@@ -1,12 +1,43 @@
<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>
<script>
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 +46,4 @@
<div><input type="radio" name="a" checked></div>
<div><input type="radio" name="a"></div>
</div>
</form>
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.