зеркало из https://github.com/mozilla/gecko-dev.git
Bug 851090 - Make <input type=range> fire change/input events as appropriate. r=mounir.
This commit is contained in:
Родитель
a89969fc8e
Коммит
064f58dd92
|
@ -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";
|
||||
|
|
Загрузка…
Ссылка в новой задаче