Bug 1283022 - Implement the min and max attribute for <input type=month>. r=smaug
authorJessica Jong <jjong@mozilla.com>
Fri, 15 Jul 2016 00:07:00 +0200
changeset 330782 564fdbb916ba41e6186031ac633f733d5405ed92
parent 330781 c74b25c022b7318115a6e0c85d264d0b2808a4a2
child 330783 813a61c61c6ce325f60801b2c6cc377e1801fd59
push id9858
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 14:37:10 +0000
treeherdermozilla-aurora@203106ef6cb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1283022
milestone50.0a1
Bug 1283022 - Implement the min and max attribute for <input type=month>. r=smaug
dom/html/HTMLInputElement.cpp
dom/html/test/forms/test_max_attribute.html
dom/html/test/forms/test_min_attribute.html
testing/web-platform/meta/html/semantics/forms/constraints/form-validation-checkValidity.html.ini
testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-rangeOverflow.html.ini
testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-rangeUnderflow.html.ini
testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-valid.html.ini
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -7029,18 +7029,17 @@ HTMLInputElement::HasPatternMismatch() c
   nsIDocument* doc = OwnerDoc();
 
   return !nsContentUtils::IsPatternMatching(value, pattern, doc);
 }
 
 bool
 HTMLInputElement::IsRangeOverflow() const
 {
-  // TODO: this is temporary until bug 888324 is fixed.
-  if (!DoesMinMaxApply() || mType == NS_FORM_INPUT_MONTH) {
+  if (!DoesMinMaxApply()) {
     return false;
   }
 
   Decimal maximum = GetMaximum();
   if (maximum.isNaN()) {
     return false;
   }
 
@@ -7050,18 +7049,17 @@ HTMLInputElement::IsRangeOverflow() cons
   }
 
   return value > maximum;
 }
 
 bool
 HTMLInputElement::IsRangeUnderflow() const
 {
-  // TODO: this is temporary until bug 888324 is fixed.
-  if (!DoesMinMaxApply() || mType == NS_FORM_INPUT_MONTH) {
+  if (!DoesMinMaxApply()) {
     return false;
   }
 
   Decimal minimum = GetMinimum();
   if (minimum.isNaN()) {
     return false;
   }
 
@@ -7438,18 +7436,18 @@ HTMLInputElement::GetValidationMessage(n
         //We want to show the value as parsed when it's a number
         Decimal maximum = GetMaximum();
         MOZ_ASSERT(!maximum.isNaN());
 
         char buf[32];
         DebugOnly<bool> ok = maximum.toString(buf, ArrayLength(buf));
         maxStr.AssignASCII(buf);
         MOZ_ASSERT(ok, "buf not big enough");
-      } else if (mType == NS_FORM_INPUT_DATE || mType == NS_FORM_INPUT_TIME) {
-        msgTemplate = mType == NS_FORM_INPUT_DATE ? kDateOverTemplate : kTimeOverTemplate;
+      } else if (IsDateTimeInputType(mType)) {
+        msgTemplate = mType == NS_FORM_INPUT_TIME ? kTimeOverTemplate : kDateOverTemplate;
         GetAttr(kNameSpaceID_None, nsGkAtoms::max, maxStr);
       } else {
         msgTemplate = kNumberOverTemplate;
         NS_NOTREACHED("Unexpected input type");
       }
 
       const char16_t* params[] = { maxStr.get() };
       rv = nsContentUtils::FormatLocalizedString(nsContentUtils::eDOM_PROPERTIES,
@@ -7474,18 +7472,18 @@ HTMLInputElement::GetValidationMessage(n
 
         Decimal minimum = GetMinimum();
         MOZ_ASSERT(!minimum.isNaN());
 
         char buf[32];
         DebugOnly<bool> ok = minimum.toString(buf, ArrayLength(buf));
         minStr.AssignASCII(buf);
         MOZ_ASSERT(ok, "buf not big enough");
-      } else if (mType == NS_FORM_INPUT_DATE || mType == NS_FORM_INPUT_TIME) {
-        msgTemplate = mType == NS_FORM_INPUT_DATE ? kDateUnderTemplate : kTimeUnderTemplate;
+      } else if (IsDateTimeInputType(mType)) {
+        msgTemplate = mType == NS_FORM_INPUT_TIME ? kTimeUnderTemplate : kDateUnderTemplate;
         GetAttr(kNameSpaceID_None, nsGkAtoms::min, minStr);
       } else {
         msgTemplate = kNumberUnderTemplate;
         NS_NOTREACHED("Unexpected input type");
       }
 
       const char16_t* params[] = { minStr.get() };
       rv = nsContentUtils::FormatLocalizedString(nsContentUtils::eDOM_PROPERTIES,
@@ -8030,18 +8028,17 @@ HTMLInputElement::UpdateHasRange()
 {
   /*
    * There is a range if min/max applies for the type and if the element
    * currently have a valid min or max.
    */
 
   mHasRange = false;
 
-  // TODO: this is temporary until bug 888324 is fixed.
-  if (!DoesMinMaxApply() || mType == NS_FORM_INPUT_MONTH) {
+  if (!DoesMinMaxApply()) {
     return;
   }
 
   Decimal minimum = GetMinimum();
   if (!minimum.isNaN()) {
     mHasRange = true;
     return;
   }
--- a/dom/html/test/forms/test_max_attribute.html
+++ b/dom/html/test/forms/test_max_attribute.html
@@ -24,18 +24,17 @@ var data = [
   { type: 'text', apply: false },
   { type: 'search', apply: false },
   { type: 'tel', apply: false },
   { type: 'url', apply: false },
   { type: 'email', apply: false },
   { type: 'password', apply: false },
   { type: 'datetime', apply: true, todo: true },
   { type: 'date', apply: true },
-  // TODO: temporary set to false until bug 888324 is fixed.
-  { type: 'month', apply: false },
+  { type: 'month', apply: true },
   { type: 'week', apply: true, todo: true },
   { type: 'time', apply: true },
   { type: 'datetime-local', apply: true, todo: true },
   { type: 'number', apply: true },
   { type: 'range', apply: true },
   { type: 'color', apply: false },
   { type: 'checkbox', apply: false },
   { type: 'radio', apply: false },
@@ -66,17 +65,18 @@ function checkValidity(aElement, aValidi
 {
   aValidity = aApply ? aValidity : true;
 
   is(aElement.validity.valid, aValidity,
      "element validity should be " + aValidity);
   is(aElement.validity.rangeOverflow, !aValidity,
      "element overflow status should be " + !aValidity);
   var overflowMsg =
-        (aElement.type == "date" || aElement.type == "time") ?
+        (aElement.type == "date" || aElement.type == "time" ||
+         aElement.type == "month") ?
         ("Please select a value that is no later than " + aElement.max + ".") :
         ("Please select a value that is no more than " + aElement.max + ".");
   is(aElement.validationMessage,
      aValidity ? "" : overflowMsg, "Checking range overflow validation message");
 
   is(aElement.matches(":valid"), aElement.willValidate && aValidity,
      (aElement.willValidate && aValidity) ? ":valid should apply" : "valid shouldn't apply");
   is(aElement.matches(":invalid"), aElement.willValidate && !aValidity,
@@ -142,17 +142,17 @@ for (var test of data) {
       // range is special, since setting max to -1 will make it invalid since
       // it's default would then be 0, meaning it suffers from overflow.
       input.max = '-1';
       checkValidity(input, false, apply, apply);
       // Now make it something that won't cause an error below:
       input.max = '10';
       break;
     case 'month':
-      // TODO: this is temporary until bug 888324 is fixed.
+      input.max = '2016-12';
       break;
     default:
       ok(false, 'please, add a case for this new type (' + input.type + ')');
   }
 
   checkValidity(input, true, apply, apply);
 
   switch (input.type) {
@@ -338,16 +338,54 @@ for (var test of data) {
 
       input.max = '';
       checkValidity(input, true, apply, false);
 
       input.max = 'foo';
       checkValidity(input, true, apply, false);
 
       break;
+    case 'month':
+      input.value = '2016-06';
+      checkValidity(input, true, apply, apply);
+
+      input.value = '2016-12';
+      checkValidity(input, true, apply, apply);
+
+      input.value = 'foo';
+      checkValidity(input, true, apply, apply);
+
+      input.value = '2017-01';
+      checkValidity(input, false, apply, apply);
+
+      input.max = '2017-07';
+      checkValidity(input, true, apply, apply);
+
+      input.value = '2017-12';
+      checkValidity(input, false, apply, apply);
+
+      input.value = '1000-01';
+      checkValidity(input, true, apply, apply);
+
+      input.value = '20160-01';
+      checkValidity(input, false, apply, apply);
+
+      input.max = '0050-01';
+      checkValidity(input, false, apply, apply);
+
+      input.value = '0049-12';
+      checkValidity(input, true, apply, apply);
+
+      input.max = '';
+      checkValidity(input, true, apply, false);
+
+      input.max = 'foo';
+      checkValidity(input, true, apply, false);
+
+      break;
   }
 
   // Cleaning up,
   input.removeAttribute('max');
   input.value = '';
 }
 
 </script>
--- a/dom/html/test/forms/test_min_attribute.html
+++ b/dom/html/test/forms/test_min_attribute.html
@@ -24,18 +24,17 @@ var data = [
   { type: 'text', apply: false },
   { type: 'search', apply: false },
   { type: 'tel', apply: false },
   { type: 'url', apply: false },
   { type: 'email', apply: false },
   { type: 'password', apply: false },
   { type: 'datetime', apply: true, todo: true },
   { type: 'date', apply: true },
-  // TODO: temporary set to false until bug 888324 is fixed.
-  { type: 'month', apply: false },
+  { type: 'month', apply: true },
   { type: 'week', apply: true, todo: true },
   { type: 'time', apply: true },
   { type: 'datetime-local', apply: true, todo: true },
   { type: 'number', apply: true },
   { type: 'range', apply: true },
   { type: 'color', apply: false },
   { type: 'checkbox', apply: false },
   { type: 'radio', apply: false },
@@ -66,17 +65,18 @@ function checkValidity(aElement, aValidi
 {
   aValidity = aApply ? aValidity : true;
 
   is(aElement.validity.valid, aValidity,
      "element validity should be " + aValidity);
   is(aElement.validity.rangeUnderflow, !aValidity,
      "element underflow status should be " + !aValidity);
   var underflowMsg =
-        (aElement.type == "date" || aElement.type == "time") ?
+        (aElement.type == "date" || aElement.type == "time" ||
+         aElement.type == "month") ?
         ("Please select a value that is no earlier than " + aElement.min + ".") :
         ("Please select a value that is no less than " + aElement.min + ".");
   is(aElement.validationMessage,
      aValidity ? "" : underflowMsg, "Checking range underflow validation message");
 
   is(aElement.matches(":valid"), aElement.willValidate && aValidity,
      (aElement.willValidate && aValidity) ? ":valid should apply" : "valid shouldn't apply");
   is(aElement.matches(":invalid"), aElement.willValidate && !aValidity,
@@ -138,17 +138,17 @@ for (var test of data) {
       input.min = '20:20';
       break;
     case 'range':
       // range is special, since setting min to 999 will make it invalid since
       // it's default maximum is 100, its value would be 999, and it would
       // suffer from overflow.
       break;
     case 'month':
-      // TODO: this is temporary until bug 888324 is fixed.
+      input.min = '2016-06';
       break;
     default:
       ok(false, 'please, add a case for this new type (' + input.type + ')');
   }
 
   // The element should still be valid and range should apply if it can.
   checkValidity(input, true, apply, apply);
 
@@ -335,17 +335,51 @@ for (var test of data) {
 
       input.min = '';
       checkValidity(input, true, apply, false);
 
       input.min = 'foo';
       checkValidity(input, true, apply, false);
       break;
     case 'month':
-      // TODO: this is temporary until bug 888324 is fixed.
+      input.value = '2016-07';
+      checkValidity(input, true, apply, apply);
+
+      input.value = '2016-06';
+      checkValidity(input, true, apply, apply);
+
+      input.value = 'foo';
+      checkValidity(input, true, apply, apply);
+
+      input.value = '2016-05';
+      checkValidity(input, false, apply, apply);
+
+      input.min = '2016-01';
+      checkValidity(input, true, apply, apply);
+
+      input.value = '2015-12';
+      checkValidity(input, false, apply, apply);
+
+      input.value = '1000-01';
+      checkValidity(input, false, apply, apply);
+
+      input.value = '10000-01';
+      checkValidity(input, true, apply, apply);
+
+      input.min = '0010-01';
+      checkValidity(input, true, apply, apply);
+
+      input.value = '0001-01';
+      checkValidity(input, false, apply, apply);
+
+      input.min = '';
+      checkValidity(input, true, apply, false);
+
+      input.min = 'foo';
+      checkValidity(input, true, apply, false);
       break;
     default:
       ok(false, 'write tests for ' + input.type);
   }
 
   // Cleaning up,
   input.removeAttribute('min');
   input.value = '';
--- a/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-checkValidity.html.ini
+++ b/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-checkValidity.html.ini
@@ -34,28 +34,16 @@
     expected: FAIL
 
   [[INPUT in EMAIL status\] suffering from being too long (in a form)]
     expected: FAIL
 
   [[INPUT in DATETIME status\] The datetime type must be supported.]
     expected: FAIL
 
-  [[INPUT in MONTH status\] suffering from an overflow]
-    expected: FAIL
-
-  [[INPUT in MONTH status\] suffering from an overflow (in a form)]
-    expected: FAIL
-
-  [[INPUT in MONTH status\] suffering from an underflow]
-    expected: FAIL
-
-  [[INPUT in MONTH status\] suffering from an underflow (in a form)]
-    expected: FAIL
-
   [[INPUT in MONTH status\] suffering from a step mismatch]
     expected: FAIL
 
   [[INPUT in MONTH status\] suffering from a step mismatch (in a form)]
     expected: FAIL
 
   [[INPUT in WEEK status\] The week type must be supported.]
     expected: FAIL
--- a/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-rangeOverflow.html.ini
+++ b/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-rangeOverflow.html.ini
@@ -1,14 +1,8 @@
 [form-validation-validity-rangeOverflow.html]
   type: testharness
   [[INPUT in DATETIME status\] The datetime type must be supported.]
     expected: FAIL
 
-  [[INPUT in MONTH status\] The value attribute is greater than max attribute]
-    expected: FAIL
-
-  [[INPUT in MONTH status\] The value attribute is greater than max attribute(Year is 10000 should be valid)]
-    expected: FAIL
-
   [[INPUT in WEEK status\] The week type must be supported.]
     expected: FAIL
 
--- a/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-rangeUnderflow.html.ini
+++ b/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-rangeUnderflow.html.ini
@@ -1,14 +1,8 @@
 [form-validation-validity-rangeUnderflow.html]
   type: testharness
   [[INPUT in DATETIME status\] The datetime type must be supported.]
     expected: FAIL
 
-  [[INPUT in MONTH status\] The value attribute is less than min attribute]
-    expected: FAIL
-
-  [[INPUT in MONTH status\] The value attribute is less than min attribute(Year is 10000 should be valid)]
-    expected: FAIL
-
   [[INPUT in WEEK status\] The week type must be supported.]
     expected: FAIL
 
--- a/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-valid.html.ini
+++ b/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-valid.html.ini
@@ -16,20 +16,14 @@
     expected: FAIL
 
   [[INPUT in EMAIL status\] validity.valid must be false if validity.tooLong is true]
     expected: FAIL
 
   [[INPUT in DATETIME status\] The datetime type must be supported.]
     expected: FAIL
 
-  [[INPUT in MONTH status\] validity.valid must be false if validity.rangeOverflow is true]
-    expected: FAIL
-
-  [[INPUT in MONTH status\] validity.valid must be false if validity.rangeUnderflow is true]
-    expected: FAIL
-
   [[INPUT in MONTH status\] validity.valid must be false if validity.stepMismatch is true]
     expected: FAIL
 
   [[INPUT in WEEK status\] The week type must be supported.]
     expected: FAIL