From ad65ad92aefcd6eb66840ecde6be4db86a1f2755 Mon Sep 17 00:00:00 2001 From: Jonathan Watt Date: Fri, 1 Mar 2013 15:34:06 +0000 Subject: [PATCH] Bug 843725 - Add support for changing the value of using the up/down/left/right/pgup/pgdn/home/end keys. r=mounir, r=smaug. --- .../html/content/src/nsHTMLInputElement.cpp | 82 ++++++- content/html/content/test/forms/Makefile.in | 1 + .../forms/test_input_range_key_events.html | 206 ++++++++++++++++++ layout/style/forms.css | 6 +- 4 files changed, 292 insertions(+), 3 deletions(-) create mode 100644 content/html/content/test/forms/test_input_range_key_events.html diff --git a/content/html/content/src/nsHTMLInputElement.cpp b/content/html/content/src/nsHTMLInputElement.cpp index 44c4cdfded74..4f6164af993f 100644 --- a/content/html/content/src/nsHTMLInputElement.cpp +++ b/content/html/content/src/nsHTMLInputElement.cpp @@ -2569,6 +2569,17 @@ SelectTextFieldOnFocus() return gSelectTextFieldOnFocus == 1; } +static bool +IsLTR(Element* aElement) +{ + nsIFrame *frame = aElement->GetPrimaryFrame(); + if (frame) { + return frame->StyleVisibility()->mDirection == NS_STYLE_DIRECTION_LTR; + } + // at least for HTML, directionality is exclusively LTR or RTL + return aElement->GetDirectionality() == eDir_LTR; +} + nsresult nsHTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor) { @@ -2835,6 +2846,74 @@ nsHTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor) NS_ENSURE_SUCCESS(rv, rv); } + if (aVisitor.mEvent->message == NS_KEY_PRESS && + mType == NS_FORM_INPUT_RANGE && !keyEvent->IsAlt() && + !keyEvent->IsControl() && !keyEvent->IsMeta() && + (keyEvent->keyCode == NS_VK_LEFT || + keyEvent->keyCode == NS_VK_RIGHT || + keyEvent->keyCode == NS_VK_UP || + keyEvent->keyCode == NS_VK_DOWN || + keyEvent->keyCode == NS_VK_PAGE_UP || + keyEvent->keyCode == NS_VK_PAGE_DOWN || + keyEvent->keyCode == NS_VK_HOME || + keyEvent->keyCode == NS_VK_END)) { + double minimum = GetMinimum(); + double maximum = GetMaximum(); + MOZ_ASSERT(MOZ_DOUBLE_IS_FINITE(minimum) && + MOZ_DOUBLE_IS_FINITE(maximum)); + if (minimum < maximum) { // else the value is locked to the minimum + double value = GetValueAsDouble(); + double step = GetStep(); + if (step == kStepAny) { + step = GetDefaultStep(); + } + MOZ_ASSERT(MOZ_DOUBLE_IS_FINITE(value) && + MOZ_DOUBLE_IS_FINITE(step)); + double newValue; + switch (keyEvent->keyCode) { + case NS_VK_LEFT: + newValue = value + (IsLTR(this) ? -step : step); + break; + case NS_VK_RIGHT: + newValue = value + (IsLTR(this) ? step : -step); + break; + case NS_VK_UP: + // Even for horizontal range, "up" means "increase" + newValue = value + step; + break; + case NS_VK_DOWN: + // Even for horizontal range, "down" means "decrease" + newValue = value - step; + break; + case NS_VK_HOME: + newValue = minimum; + break; + case NS_VK_END: + newValue = maximum; + break; + case NS_VK_PAGE_UP: + // For PgUp/PgDn we jump 10% of the total range, unless step + // requires us to jump more. + newValue = value + std::max(step, 0.1 * (maximum - minimum)); + break; + case NS_VK_PAGE_DOWN: + newValue = value - std::max(step, 0.1 * (maximum - minimum)); + break; + } + MOZ_ASSERT(MOZ_DOUBLE_IS_FINITE(newValue)); + nsAutoString val; + ConvertNumberToString(newValue, val); + SetValueInternal(val, true, true); + nsIFrame* frame = GetPrimaryFrame(); + if (frame) { + // Trigger reflow to update the position of the thumb: + frame->PresContext()->GetPresShell()-> + FrameNeedsReflow(frame, nsIPresShell::eResize, NS_FRAME_IS_DIRTY); + } + aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault; + } + } + } break; // NS_KEY_PRESS || NS_KEY_UP case NS_MOUSE_BUTTON_DOWN: @@ -4353,7 +4432,8 @@ nsHTMLInputElement::IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t return true; } - if (IsSingleLineTextControl(false)) { + if (IsSingleLineTextControl(false) || + mType == NS_FORM_INPUT_RANGE) { *aIsFocusable = true; return false; } diff --git a/content/html/content/test/forms/Makefile.in b/content/html/content/test/forms/Makefile.in index 5f7a08373e69..7a7cf86be2fd 100644 --- a/content/html/content/test/forms/Makefile.in +++ b/content/html/content/test/forms/Makefile.in @@ -18,6 +18,7 @@ MOCHITEST_FILES = \ test_input_attributes_reflection.html \ test_input_list_attribute.html \ test_input_email.html \ + test_input_range_key_events.html \ test_input_url.html \ test_pattern_attribute.html \ test_required_attribute.html \ diff --git a/content/html/content/test/forms/test_input_range_key_events.html b/content/html/content/test/forms/test_input_range_key_events.html new file mode 100644 index 000000000000..c8f8d182d4f0 --- /dev/null +++ b/content/html/content/test/forms/test_input_range_key_events.html @@ -0,0 +1,206 @@ + + + + + Test key events for range + + + + + + +Mozilla Bug 843725 +

+
+
+
+
+
+ + diff --git a/layout/style/forms.css b/layout/style/forms.css index 0b49e90fb53d..a7ad31fe76f7 100644 --- a/layout/style/forms.css +++ b/layout/style/forms.css @@ -720,12 +720,14 @@ meter { input[type="range"] { -moz-appearance: none; display: inline-block !important; - cursor: default; width: 12em; height: 1.3em; + margin: 0 0.7em; + /* Override some rules that apply on all input types: */ + cursor: default; background: none; border: none; - margin: 0 0.7em; + -moz-binding: none; /* we don't want any of platformHTMLBindings.xml#inputFields */ } /**