Bug 1431041: Fix placeholder-shown when the value of the input is invalid. r?smaug
Wow, the setup for <input type="number"> is really weird :(.
Looking at the callers, this should be sane.
MozReview-Commit-ID: C0ZNNSdg0Hb
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -6595,27 +6595,45 @@ HTMLInputElement::IntrinsicState() const
GetValidityState(VALIDITY_STATE_RANGE_UNDERFLOW))
? NS_EVENT_STATE_OUTOFRANGE
: NS_EVENT_STATE_INRANGE;
}
}
if (PlaceholderApplies() &&
HasAttr(kNameSpaceID_None, nsGkAtoms::placeholder) &&
- IsValueEmpty()) {
+ ShouldShowPlaceholder()) {
state |= NS_EVENT_STATE_PLACEHOLDERSHOWN;
}
if (mForm && !mForm->GetValidity() && IsSubmitControl()) {
state |= NS_EVENT_STATE_MOZ_SUBMITINVALID;
}
return state;
}
+bool
+HTMLInputElement::ShouldShowPlaceholder() const
+{
+ MOZ_ASSERT(PlaceholderApplies());
+
+ if (IsValueEmpty()) {
+ return true;
+ }
+
+ // For number controls, even though the (sanitized) value is empty, there may
+ // be text in the anon text control.
+ if (nsNumberControlFrame* frame = do_QueryFrame(GetPrimaryFrame())) {
+ return frame->AnonTextControlIsEmpty();
+ }
+
+ return false;
+}
+
void
HTMLInputElement::AddStates(EventStates aStates)
{
if (mType == NS_FORM_INPUT_TEXT) {
EventStates focusStates(aStates & (NS_EVENT_STATE_FOCUS |
NS_EVENT_STATE_FOCUSRING));
if (!focusStates.IsEmpty()) {
HTMLInputElement* ownerNumberControl = GetOwnerNumberControl();
--- a/dom/html/HTMLInputElement.h
+++ b/dom/html/HTMLInputElement.h
@@ -1054,16 +1054,21 @@ protected:
/**
* Returns whether the current value is the empty string. This only makes
* sense for some input types; does NOT make sense for file inputs.
*
* @return whether the current value is the empty string.
*/
bool IsValueEmpty() const;
+ /**
+ * Returns whether the current placeholder value should be shown.
+ */
+ bool ShouldShowPlaceholder() const;
+
void ClearFiles(bool aSetValueChanged);
void SetIndeterminateInternal(bool aValue,
bool aShouldInvalidate);
/**
* Called when an attribute is about to be changed
*/
--- a/dom/html/test/forms/mochitest.ini
+++ b/dom/html/test/forms/mochitest.ini
@@ -53,16 +53,17 @@ skip-if = os == "android"
# Not run on Firefox for Android where the spin buttons are hidden:
skip-if = os == "android"
[test_input_number_rounding.html]
skip-if = os == "android"
[test_input_number_validation.html]
# We don't build ICU for Firefox for Android:
skip-if = os == "android"
[test_input_number_focus.html]
+[test_input_number_placeholder_shown.html]
[test_input_range_attr_order.html]
[test_input_range_key_events.html]
[test_input_range_mouse_and_touch_events.html]
[test_input_range_rounding.html]
[test_input_sanitization.html]
skip-if = os == 'android' && debug # Extremely slow on debug android
[test_input_textarea_set_value_no_scroll.html]
[test_input_time_key_events.html]
new file mode 100644
--- /dev/null
+++ b/dom/html/test/forms/test_input_number_placeholder_shown.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<title>Test for :placeholder-shown on input elements and invalid values.</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script src="/tests/SimpleTest/EventUtils.js"></script>
+<style>
+input {
+ border: 1px solid purple;
+}
+input:placeholder-shown {
+ border-color: blue;
+}
+</style>
+<input type="number" placeholder="foo">
+<script>
+ SimpleTest.waitForExplicitFinish();
+ SimpleTest.waitForFocus(function() {
+ test();
+ SimpleTest.finish();
+ });
+
+ function test() {
+ let input = document.querySelector('input');
+ input.focus();
+ is(getComputedStyle(input).borderLeftColor, "rgb(0, 0, 255)",
+ ":placeholder-shown should apply")
+ synthesizeKey('x', {});
+ isnot(getComputedStyle(input).borderLeftColor, "rgb(0, 0, 255)",
+ ":placeholder-shown should not apply, even though the value is invalid")
+ }
+</script>