Bug 851090 - Make <input type=range> fire change/input events as appropriate. r=mounir.

This commit is contained in:
Jonathan Watt 2013-03-16 05:49:41 +00:00
Родитель a89969fc8e
Коммит 064f58dd92
3 изменённых файлов: 59 добавлений и 9 удалений

Просмотреть файл

@ -1218,7 +1218,7 @@ nsHTMLInputElement::SetValue(const nsAString& aValue)
}
}
else {
if (IsSingleLineTextControl(false)) {
if (MayFireChangeOnBlur()) {
// If the value has been set by a script, we basically want to keep the
// current change event state. If the element is ready to fire a change
// event, we should keep it that way. Otherwise, we should make sure the
@ -1948,7 +1948,7 @@ nsHTMLInputElement::FireChangeEventIfNeeded()
nsString value;
GetValueInternal(value);
if (!IsSingleLineTextControl(false) || mFocusedValue.Equals(value)) {
if (!MayFireChangeOnBlur() || mFocusedValue.Equals(value)) {
return;
}
@ -2577,6 +2577,7 @@ nsHTMLInputElement::FinishRangeThumbDrag(nsGUIEvent* aEvent)
SetValueOfRangeForUserEvent(rangeFrame->GetValueAtEventPoint(aEvent));
}
mIsDraggingRange = false;
FireChangeEventIfNeeded();
}
void
@ -2603,6 +2604,10 @@ nsHTMLInputElement::SetValueOfRangeForUserEvent(double aValue)
if (frame) {
frame->UpdateThumbPositionForValueChange();
}
nsContentUtils::DispatchTrustedEvent(OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(this),
NS_LITERAL_STRING("input"), true,
false);
}
static bool
@ -2644,7 +2649,7 @@ nsHTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
if (aVisitor.mEvent->message == NS_FOCUS_CONTENT ||
aVisitor.mEvent->message == NS_BLUR_CONTENT) {
if (aVisitor.mEvent->message == NS_FOCUS_CONTENT &&
IsSingleLineTextControl(false)) {
MayFireChangeOnBlur()) {
GetValueInternal(mFocusedValue);
}
@ -3303,12 +3308,11 @@ nsHTMLInputElement::HandleTypeChange(uint8_t aNewType)
}
// Updating mFocusedValue in consequence:
// If the new type is a single line text control but the previous wasn't, we
// should set mFocusedValue to the current value.
// Otherwise, if the new type isn't a text control but the previous was, we
// should clear out mFocusedValue.
if (IsSingleLineTextControl(mType, false) &&
!IsSingleLineTextControl(oldType, false)) {
// If the new type fires a change event on blur, but the previous type
// doesn't, we should set mFocusedValue to the current value.
// Otherwise, if the new type doesn't fire a change event on blur, but the
// previous type does, we should clear out mFocusedValue.
if (MayFireChangeOnBlur(mType) && !MayFireChangeOnBlur(oldType)) {
GetValueInternal(mFocusedValue);
} else if (!IsSingleLineTextControl(mType, false) &&
IsSingleLineTextControl(oldType, false)) {

Просмотреть файл

@ -819,6 +819,20 @@ protected:
bool mIsDraggingRange : 1;
private:
/**
* Returns true if this input's type will fire a DOM "change" event when it
* loses focus if its value has changed since it gained focus.
*/
bool MayFireChangeOnBlur() const {
return MayFireChangeOnBlur(mType);
}
static bool MayFireChangeOnBlur(uint8_t aType) {
return IsSingleLineTextControl(false, aType) ||
aType == NS_FORM_INPUT_RANGE;
}
struct nsFilePickerFilter {
nsFilePickerFilter()
: mFilterMask(0), mIsTrusted(false) {}

Просмотреть файл

@ -29,6 +29,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=722599
<input type="reset" id="input_reset" onchange="++NonTextInputChange[3];"></input>
<input type="radio" id="input_radio" onchange="++NonTextInputChange[4];"></input>
<input type="checkbox" id="input_checkbox" onchange="++NonTextInputChange[5];"></input>
<input type="range" id="input_range" onchange="++rangeChange;" oninput="++rangeInput;"></input>
</div>
<pre id="test">
@ -44,6 +45,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=722599
var NonTextInputTypes = ["button", "submit", "image", "reset", "radio", "checkbox"];
var NonTextInputChange = [0, 0, 0, 0, 0, 0];
var rangeChange = 0;
var rangeInput = 0;
var blurTestCalled = false; //Sentinel to prevent infinite loop.
SimpleTest.waitForExplicitFinish();
@ -161,6 +165,34 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=722599
}
}
// Special case type=range
var range = document.getElementById("input_range");
range.focus();
synthesizeKey("a", {});
range.blur();
is(rangeChange, 0, "Change event shouldn't be dispatched on range input element for key changes that don't change its value");
is(rangeInput, 0, "Input event shouldn't be dispatched on range input element for key changes that don't change its value");
range.focus();
synthesizeKey("VK_HOME", {});
is(rangeChange, 0, "Change event shouldn't be dispatched on range input element for key changes until it is looses focus");
is(rangeInput, 1, "Input event should be dispatched on range input element for key changes");
range.blur();
is(rangeChange, 1, "Change event should be dispatched on range input element on blur");
is(rangeInput, 1, "Input event shouldn't be dispatched on range input element on blur if the value hasn't changed");
range.focus();
var bcr = range.getBoundingClientRect();
var centerOfRangeX = bcr.width / 2;
var centerOfRangeY = bcr.height / 2;
synthesizeMouse(range, centerOfRangeX - 10, centerOfRangeY, { type: "mousedown" });
is(rangeChange, 1, "Change event shouldn't be dispatched on range input element for mousedown");
is(rangeInput, 2, "Input event should be dispatched on range input element on mousedown if the value changes");
synthesizeMouse(range, centerOfRangeX - 5, centerOfRangeY, { type: "mousemove" });
is(rangeChange, 1, "Change event shouldn't be dispatched on range input element during drag of thumb");
is(rangeInput, 3, "Input event should be dispatched on range input element during a drag");
synthesizeMouse(range, centerOfRangeX, centerOfRangeY, { type: "mouseup" });
is(rangeChange, 2, "Change event should be dispatched on range input element at end of drag");
is(rangeInput, 4, "Input event should be dispatched on range input element at the end of a drag");
//Input type change test.
input = document.getElementById("input_checkbox");
input.type = "text";