Bug 1278737 - Add 'month' to the list of valid types attributes for <input>. r=smaug
☠☠ backed out by 304be069e80b ☠ ☠
authorJessica Jong <jjong@mozilla.com>
Wed, 29 Jun 2016 23:16:00 +0200
changeset 383196 444a4a7233f776cea47f2a9eabe6a7f301de4b51
parent 383195 b97c6b960d85c9b02c821ab87944a652d75174b8
child 383197 eb6de343924f07e384be029a11c2404b7ac5e3df
push id21963
push userdmitchell@mozilla.com
push dateFri, 01 Jul 2016 19:54:18 +0000
reviewerssmaug
bugs1278737
milestone50.0a1
Bug 1278737 - Add 'month' to the list of valid types attributes for <input>. r=smaug
browser/base/content/test/general/browser_contextmenu_input.js
dom/html/HTMLFormControlsCollection.cpp
dom/html/HTMLInputElement.cpp
dom/html/HTMLInputElement.h
dom/html/nsIFormControl.h
dom/html/test/forms/mochitest.ini
dom/html/test/forms/test_experimental_forms_pref.html
dom/html/test/forms/test_input_attributes_reflection.html
dom/html/test/forms/test_input_sanitization.html
dom/html/test/forms/test_input_types_pref.html
dom/html/test/forms/test_input_typing_sanitization.html
dom/html/test/forms/test_max_attribute.html
dom/html/test/forms/test_min_attribute.html
dom/html/test/forms/test_mozistextfield.html
dom/html/test/forms/test_pattern_attribute.html
dom/html/test/forms/test_required_attribute.html
dom/html/test/forms/test_step_attribute.html
dom/html/test/forms/test_valueasnumber_attribute.html
dom/html/test/test_bug590363.html
dom/html/test/test_bug598643.html
layout/base/nsCSSFrameConstructor.cpp
testing/profiles/prefs_general.js
testing/web-platform/meta/html/dom/reflection-forms.html.ini
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-stepMismatch.html.ini
testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-valid.html.ini
testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-valueMissing.html.ini
testing/web-platform/meta/html/semantics/forms/the-input-element/datetime.html.ini
testing/web-platform/meta/html/semantics/forms/the-input-element/month.html.ini
testing/web-platform/meta/html/semantics/forms/the-input-element/selection.html.ini
toolkit/components/satchel/test/test_form_autocomplete.html
--- a/browser/base/content/test/general/browser_contextmenu_input.js
+++ b/browser/base/content/test/general/browser_contextmenu_input.js
@@ -215,17 +215,17 @@ add_task(function* test_search_input() {
      "context-selectall",   null,
      "---",                 null,
      "spell-check-enabled", true],
     {skipFocusChange: true}
   );
 });
 
 add_task(function* test_datetime_month_week_datetimelocal_input_todos() {
-  for (let type of ["datetime", "month", "week", "datetime-local"]) {
+  for (let type of ["datetime", "week", "datetime-local"]) {
     let returnedType = yield ContentTask.spawn(gBrowser.selectedBrowser, type, function*(type) {
       let doc = content.document;
       let input = doc.getElementById("input_" + type);
       return input.type;
     });
     todo_is(returnedType, type, `TODO: add test for ${type} input fields`);
   }
 });
--- a/dom/html/HTMLFormControlsCollection.cpp
+++ b/dom/html/HTMLFormControlsCollection.cpp
@@ -42,16 +42,17 @@ HTMLFormControlsCollection::ShouldBeInEl
   case NS_FORM_INPUT_RESET :
   case NS_FORM_INPUT_PASSWORD :
   case NS_FORM_INPUT_RADIO :
   case NS_FORM_INPUT_SEARCH :
   case NS_FORM_INPUT_SUBMIT :
   case NS_FORM_INPUT_TEXT :
   case NS_FORM_INPUT_TEL :
   case NS_FORM_INPUT_URL :
+  case NS_FORM_INPUT_MONTH :
   case NS_FORM_INPUT_NUMBER :
   case NS_FORM_INPUT_RANGE :
   case NS_FORM_INPUT_DATE :
   case NS_FORM_INPUT_TIME :
   case NS_FORM_SELECT :
   case NS_FORM_TEXTAREA :
   case NS_FORM_FIELDSET :
   case NS_FORM_OBJECT :
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -160,31 +160,32 @@ static const nsAttrValue::EnumTable kInp
   { "checkbox", NS_FORM_INPUT_CHECKBOX },
   { "color", NS_FORM_INPUT_COLOR },
   { "date", NS_FORM_INPUT_DATE },
   { "email", NS_FORM_INPUT_EMAIL },
   { "file", NS_FORM_INPUT_FILE },
   { "hidden", NS_FORM_INPUT_HIDDEN },
   { "reset", NS_FORM_INPUT_RESET },
   { "image", NS_FORM_INPUT_IMAGE },
+  { "month", NS_FORM_INPUT_MONTH },
   { "number", NS_FORM_INPUT_NUMBER },
   { "password", NS_FORM_INPUT_PASSWORD },
   { "radio", NS_FORM_INPUT_RADIO },
   { "range", NS_FORM_INPUT_RANGE },
   { "search", NS_FORM_INPUT_SEARCH },
   { "submit", NS_FORM_INPUT_SUBMIT },
   { "tel", NS_FORM_INPUT_TEL },
   { "text", NS_FORM_INPUT_TEXT },
   { "time", NS_FORM_INPUT_TIME },
   { "url", NS_FORM_INPUT_URL },
   { 0 }
 };
 
 // Default type is 'text'.
-static const nsAttrValue::EnumTable* kInputDefaultType = &kInputTypeTable[16];
+static const nsAttrValue::EnumTable* kInputDefaultType = &kInputTypeTable[17];
 
 static const uint8_t NS_INPUT_INPUTMODE_AUTO              = 0;
 static const uint8_t NS_INPUT_INPUTMODE_NUMERIC           = 1;
 static const uint8_t NS_INPUT_INPUTMODE_DIGIT             = 2;
 static const uint8_t NS_INPUT_INPUTMODE_UPPERCASE         = 3;
 static const uint8_t NS_INPUT_INPUTMODE_LOWERCASE         = 4;
 static const uint8_t NS_INPUT_INPUTMODE_TITLECASE         = 5;
 static const uint8_t NS_INPUT_INPUTMODE_AUTOCAPITALIZED   = 6;
@@ -2131,19 +2132,19 @@ HTMLInputElement::SetWidth(uint32_t aWid
 NS_IMETHODIMP
 HTMLInputElement::GetValue(nsAString& aValue)
 {
   nsresult rv = GetValueInternal(aValue);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
-  // Don't return non-sanitized value for types that are experimental on mobile.
-  //  or date types
-  if (IsExperimentalMobileType(mType) || mType == NS_FORM_INPUT_DATE) {
+  // Don't return non-sanitized value for types that are experimental on mobile
+  // or datetime types
+  if (IsExperimentalMobileType(mType) || IsDateTimeInputType(mType)) {
     SanitizeValue(aValue);
   }
 
   return NS_OK;
 }
 
 nsresult
 HTMLInputElement::GetValueInternal(nsAString& aValue) const
@@ -2771,19 +2772,29 @@ HTMLInputElement::ApplyStep(int32_t aSte
 
   return rv;
 }
 
 /* static */
 bool
 HTMLInputElement::IsExperimentalMobileType(uint8_t aType)
 {
-  return aType == NS_FORM_INPUT_TIME ||
-    (aType == NS_FORM_INPUT_DATE &&
-     !Preferences::GetBool("dom.forms.datepicker", false));
+  return (aType == NS_FORM_INPUT_DATE &&
+    !Preferences::GetBool("dom.forms.datetime", false) &&
+    !Preferences::GetBool("dom.forms.datepicker", false)) ||
+    (aType == NS_FORM_INPUT_TIME &&
+     !Preferences::GetBool("dom.forms.datetime", false));
+}
+
+bool
+HTMLInputElement::IsDateTimeInputType(uint8_t aType)
+{
+  return aType == NS_FORM_INPUT_DATE || aType == NS_FORM_INPUT_TIME ||
+    aType == NS_FORM_INPUT_MONTH;
+
 }
 
 NS_IMETHODIMP
 HTMLInputElement::StepDown(int32_t n, uint8_t optional_argc)
 {
   return ApplyStep(optional_argc ? -n : -1);
 }
 
@@ -2964,18 +2975,18 @@ HTMLInputElement::MozSetDirectory(const 
   element->SetAsDirectory() = directory;
 
   SetFilesOrDirectories(array, true);
 }
 
 bool
 HTMLInputElement::MozIsTextField(bool aExcludePassword)
 {
-  // TODO: temporary until bug 773205 is fixed.
-  if (IsExperimentalMobileType(mType) || mType == NS_FORM_INPUT_DATE) {
+  // TODO: temporary until bug 888320 is fixed.
+  if (IsExperimentalMobileType(mType) || IsDateTimeInputType(mType)) {
     return false;
   }
 
   return IsSingleLineTextControl(aExcludePassword);
 }
 
 HTMLInputElement*
 HTMLInputElement::GetOwnerNumberControl()
@@ -4003,17 +4014,17 @@ HTMLInputElement::PreHandleEvent(EventCh
     GetValue(mFocusedValue);
   }
 
   // Fire onchange (if necessary), before we do the blur, bug 357684.
   if (aVisitor.mEvent->mMessage == eBlur) {
     // Experimental mobile types rely on the system UI to prevent users to not
     // set invalid values but we have to be extra-careful. Especially if the
     // option has been enabled on desktop.
-    if (IsExperimentalMobileType(mType) || mType == NS_FORM_INPUT_DATE) {
+    if (IsExperimentalMobileType(mType) || IsDateTimeInputType(mType)) {
       nsAutoString aValue;
       GetValueInternal(aValue);
       nsresult rv =
         SetValueInternal(aValue, nsTextEditorState::eSetValue_Internal);
       NS_ENSURE_SUCCESS(rv, rv);
     }
     FireChangeEventIfNeeded();
   }
@@ -4703,17 +4714,17 @@ HTMLInputElement::PostHandleEvent(EventC
            *     not submit, period.
            */
 
           if (aVisitor.mEvent->mMessage == eKeyPress &&
               keyEvent->mKeyCode == NS_VK_RETURN &&
                (IsSingleLineTextControl(false, mType) ||
                 mType == NS_FORM_INPUT_NUMBER ||
                 IsExperimentalMobileType(mType) ||
-                mType == NS_FORM_INPUT_DATE)) {
+                IsDateTimeInputType(mType))) {
             FireChangeEventIfNeeded();
             rv = MaybeSubmitForm(aVisitor.mPresContext);
             NS_ENSURE_SUCCESS(rv, rv);
           }
 
           if (aVisitor.mEvent->mMessage == eKeyPress &&
               mType == NS_FORM_INPUT_RANGE && !keyEvent->IsAlt() &&
               !keyEvent->IsControl() && !keyEvent->IsMeta() &&
@@ -5500,16 +5511,30 @@ HTMLInputElement::ParseTime(const nsAStr
                // NOTE: there is 10.0 instead of 10 and static_cast<int> because
                // some old [and stupid] compilers can't just do the right thing.
                fractionsSeconds * pow(10.0, static_cast<int>(3 - (aValue.Length() - 9)));
   }
 
   return true;
 }
 
+static bool
+IsDateTimeEnabled(int32_t aNewType)
+{
+  return (aNewType == NS_FORM_INPUT_DATE &&
+          (Preferences::GetBool("dom.forms.datetime", false) ||
+           Preferences::GetBool("dom.experimental_forms", false) ||
+           Preferences::GetBool("dom.forms.datepicker", false))) ||
+         (aNewType == NS_FORM_INPUT_TIME &&
+          (Preferences::GetBool("dom.forms.datetime", false) ||
+           Preferences::GetBool("dom.experimental_forms", false))) ||
+         (aNewType == NS_FORM_INPUT_MONTH &&
+          Preferences::GetBool("dom.forms.datetime", false));
+}
+
 bool
 HTMLInputElement::ParseAttribute(int32_t aNamespaceID,
                                  nsIAtom* aAttribute,
                                  const nsAString& aValue,
                                  nsAttrValue& aResult)
 {
   if (aNamespaceID == kNameSpaceID_None) {
     if (aAttribute == nsGkAtoms::type) {
@@ -5519,17 +5544,18 @@ HTMLInputElement::ParseAttribute(int32_t
       bool success = aResult.ParseEnumValue(aValue, kInputTypeTable, false);
       if (success) {
         newType = aResult.GetEnumValue();
         if ((IsExperimentalMobileType(newType) &&
              !Preferences::GetBool("dom.experimental_forms", false)) ||
             (newType == NS_FORM_INPUT_NUMBER &&
              !Preferences::GetBool("dom.forms.number", false)) ||
             (newType == NS_FORM_INPUT_COLOR &&
-             !Preferences::GetBool("dom.forms.color", false))) {
+             !Preferences::GetBool("dom.forms.color", false)) ||
+            (IsDateTimeInputType(newType) && !IsDateTimeEnabled(newType))) {
           newType = kInputDefaultType->value;
           aResult.SetTo(newType, &aValue);
         }
       } else {
         newType = kInputDefaultType->value;
       }
 
       if (newType != mType) {
@@ -6905,16 +6931,17 @@ HTMLInputElement::GetValueMode() const
     case NS_FORM_INPUT_TEL:
     case NS_FORM_INPUT_EMAIL:
     case NS_FORM_INPUT_URL:
     case NS_FORM_INPUT_NUMBER:
     case NS_FORM_INPUT_RANGE:
     case NS_FORM_INPUT_DATE:
     case NS_FORM_INPUT_TIME:
     case NS_FORM_INPUT_COLOR:
+    case NS_FORM_INPUT_MONTH:
       return VALUE_MODE_VALUE;
     default:
       NS_NOTYETIMPLEMENTED("Unexpected input type in GetValueMode()");
       return VALUE_MODE_VALUE;
 #else // DEBUG
     default:
       return VALUE_MODE_VALUE;
 #endif // DEBUG
@@ -6950,16 +6977,17 @@ HTMLInputElement::DoesReadOnlyApply() co
     case NS_FORM_INPUT_PASSWORD:
     case NS_FORM_INPUT_SEARCH:
     case NS_FORM_INPUT_TEL:
     case NS_FORM_INPUT_EMAIL:
     case NS_FORM_INPUT_URL:
     case NS_FORM_INPUT_NUMBER:
     case NS_FORM_INPUT_DATE:
     case NS_FORM_INPUT_TIME:
+    case NS_FORM_INPUT_MONTH:
       return true;
     default:
       NS_NOTYETIMPLEMENTED("Unexpected input type in DoesReadOnlyApply()");
       return true;
 #else // DEBUG
     default:
       return true;
 #endif // DEBUG
@@ -6987,58 +7015,59 @@ HTMLInputElement::DoesRequiredApply() co
     case NS_FORM_INPUT_PASSWORD:
     case NS_FORM_INPUT_SEARCH:
     case NS_FORM_INPUT_TEL:
     case NS_FORM_INPUT_EMAIL:
     case NS_FORM_INPUT_URL:
     case NS_FORM_INPUT_NUMBER:
     case NS_FORM_INPUT_DATE:
     case NS_FORM_INPUT_TIME:
+    case NS_FORM_INPUT_MONTH:
       return true;
     default:
       NS_NOTYETIMPLEMENTED("Unexpected input type in DoesRequiredApply()");
       return true;
 #else // DEBUG
     default:
       return true;
 #endif // DEBUG
   }
 }
 
 bool
 HTMLInputElement::PlaceholderApplies() const
 {
-  if (mType == NS_FORM_INPUT_DATE ||
-      mType == NS_FORM_INPUT_TIME) {
+  if (IsDateTimeInputType(mType)) {
     return false;
   }
 
   return IsSingleLineTextControl(false);
 }
 
 bool
 HTMLInputElement::DoesPatternApply() const
 {
   // TODO: temporary until bug 773205 is fixed.
-  if (IsExperimentalMobileType(mType)) {
+  if (IsExperimentalMobileType(mType) || IsDateTimeInputType(mType)) {
     return false;
   }
 
   return IsSingleLineTextControl(false);
 }
 
 bool
 HTMLInputElement::DoesMinMaxApply() const
 {
   switch (mType)
   {
     case NS_FORM_INPUT_NUMBER:
     case NS_FORM_INPUT_DATE:
     case NS_FORM_INPUT_TIME:
     case NS_FORM_INPUT_RANGE:
+    case NS_FORM_INPUT_MONTH:
     // TODO:
     // All date/time types.
       return true;
 #ifdef DEBUG
     case NS_FORM_INPUT_RESET:
     case NS_FORM_INPUT_SUBMIT:
     case NS_FORM_INPUT_IMAGE:
     case NS_FORM_INPUT_BUTTON:
@@ -7076,16 +7105,17 @@ HTMLInputElement::DoesAutocompleteApply(
     case NS_FORM_INPUT_TEL:
     case NS_FORM_INPUT_EMAIL:
     case NS_FORM_INPUT_PASSWORD:
     case NS_FORM_INPUT_DATE:
     case NS_FORM_INPUT_TIME:
     case NS_FORM_INPUT_NUMBER:
     case NS_FORM_INPUT_RANGE:
     case NS_FORM_INPUT_COLOR:
+    case NS_FORM_INPUT_MONTH:
       return true;
 #ifdef DEBUG
     case NS_FORM_INPUT_RESET:
     case NS_FORM_INPUT_SUBMIT:
     case NS_FORM_INPUT_IMAGE:
     case NS_FORM_INPUT_BUTTON:
     case NS_FORM_INPUT_RADIO:
     case NS_FORM_INPUT_CHECKBOX:
@@ -7253,17 +7283,18 @@ HTMLInputElement::HasPatternMismatch() c
   nsIDocument* doc = OwnerDoc();
 
   return !nsContentUtils::IsPatternMatching(value, pattern, doc);
 }
 
 bool
 HTMLInputElement::IsRangeOverflow() const
 {
-  if (!DoesMinMaxApply()) {
+  // TODO: this is temporary until bug 888324 is fixed.
+  if (!DoesMinMaxApply() || mType == NS_FORM_INPUT_MONTH) {
     return false;
   }
 
   Decimal maximum = GetMaximum();
   if (maximum.isNaN()) {
     return false;
   }
 
@@ -7273,17 +7304,18 @@ HTMLInputElement::IsRangeOverflow() cons
   }
 
   return value > maximum;
 }
 
 bool
 HTMLInputElement::IsRangeUnderflow() const
 {
-  if (!DoesMinMaxApply()) {
+  // TODO: this is temporary until bug 888324 is fixed.
+  if (!DoesMinMaxApply() || mType == NS_FORM_INPUT_MONTH) {
     return false;
   }
 
   Decimal minimum = GetMinimum();
   if (minimum.isNaN()) {
     return false;
   }
 
@@ -8252,17 +8284,18 @@ 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;
 
-  if (!DoesMinMaxApply()) {
+  // TODO: this is temporary until bug 888324 is fixed.
+  if (!DoesMinMaxApply() || mType == NS_FORM_INPUT_MONTH) {
     return;
   }
 
   Decimal minimum = GetMinimum();
   if (!minimum.isNaN()) {
     mHasRange = true;
     return;
   }
--- a/dom/html/HTMLInputElement.h
+++ b/dom/html/HTMLInputElement.h
@@ -1012,27 +1012,35 @@ protected:
   /**
    * Returns if the min and max attributes apply for the current type.
    */
   bool DoesMinMaxApply() const;
 
   /**
    * Returns if the step attribute apply for the current type.
    */
-  bool DoesStepApply() const { return DoesMinMaxApply(); }
+  bool DoesStepApply() const
+  {
+    // TODO: this is temporary until bug 888324 is fixed.
+    return DoesMinMaxApply() && mType != NS_FORM_INPUT_MONTH;
+  }
 
   /**
    * Returns if stepDown and stepUp methods apply for the current type.
    */
   bool DoStepDownStepUpApply() const { return DoesStepApply(); }
 
   /**
    * Returns if valueAsNumber attribute applies for the current type.
    */
-  bool DoesValueAsNumberApply() const { return DoesMinMaxApply(); }
+  bool DoesValueAsNumberApply() const
+  {
+    // TODO: this is temporary until bug 888324 is fixed.
+    return DoesMinMaxApply() && mType != NS_FORM_INPUT_MONTH;
+  }
 
   /**
    * Returns if autocomplete attribute applies for the current type.
    */
   bool DoesAutocompleteApply() const;
 
   /**
    * Returns if the maxlength attribute applies for the current type.
@@ -1246,16 +1254,22 @@ protected:
    */
   nsresult ApplyStep(int32_t aStep);
 
   /**
    * Returns if the current type is an experimental mobile type.
    */
   static bool IsExperimentalMobileType(uint8_t aType);
 
+  /*
+   * Returns if the current type is one of the date/time input types: date,
+   * time and month. TODO: week and datetime-local.
+   */
+  static bool IsDateTimeInputType(uint8_t aType);
+
   /**
    * Flushes the layout frame tree to make sure we have up-to-date frames.
    */
   void FlushFrames();
 
   /**
    * Returns true if the element should prevent dispatching another DOMActivate.
    * This is used in situations where the anonymous subtree should already have
--- a/dom/html/nsIFormControl.h
+++ b/dom/html/nsIFormControl.h
@@ -50,16 +50,17 @@ enum InputElementTypes {
   NS_FORM_INPUT_CHECKBOX,
   NS_FORM_INPUT_COLOR,
   NS_FORM_INPUT_DATE,
   NS_FORM_INPUT_EMAIL,
   NS_FORM_INPUT_FILE,
   NS_FORM_INPUT_HIDDEN,
   NS_FORM_INPUT_RESET,
   NS_FORM_INPUT_IMAGE,
+  NS_FORM_INPUT_MONTH,
   NS_FORM_INPUT_NUMBER,
   NS_FORM_INPUT_PASSWORD,
   NS_FORM_INPUT_RADIO,
   NS_FORM_INPUT_SEARCH,
   NS_FORM_INPUT_SUBMIT,
   NS_FORM_INPUT_TEL,
   NS_FORM_INPUT_TEXT,
   NS_FORM_INPUT_TIME,
@@ -261,16 +262,17 @@ nsIFormControl::IsSingleLineTextControl(
   return aType == NS_FORM_INPUT_TEXT ||
          aType == NS_FORM_INPUT_EMAIL ||
          aType == NS_FORM_INPUT_SEARCH ||
          aType == NS_FORM_INPUT_TEL ||
          aType == NS_FORM_INPUT_URL ||
          // TODO: those are temporary until bug 773205 is fixed.
          aType == NS_FORM_INPUT_DATE ||
          aType == NS_FORM_INPUT_TIME ||
+         aType == NS_FORM_INPUT_MONTH ||
          (!aExcludePassword && aType == NS_FORM_INPUT_PASSWORD);
 }
 
 bool
 nsIFormControl::IsSubmittableControl() const
 {
   // TODO: keygen should be in that list, see bug 101019.
   uint32_t type = GetType();
--- a/dom/html/test/forms/mochitest.ini
+++ b/dom/html/test/forms/mochitest.ini
@@ -6,17 +6,16 @@ support-files =
 
 [test_bug1039548.html]
 [test_button_attributes_reflection.html]
 [test_input_radio_radiogroup.html]
 [test_input_radio_required.html]
 [test_change_event.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
 [test_datalist_element.html]
-[test_experimental_forms_pref.html]
 [test_form_attribute-1.html]
 [test_form_attribute-2.html]
 [test_form_attribute-3.html]
 [test_form_attribute-4.html]
 [test_form_attributes_reflection.html]
 [test_form_named_getter_dynamic.html]
 [test_formaction_attribute.html]
 skip-if = buildapp == 'mulet'
@@ -56,16 +55,17 @@ skip-if = os == "android" || appname == 
 [test_input_range_key_events.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
 [test_input_range_mouse_and_touch_events.html]
 skip-if = (toolkit == 'gonk' && debug) #debug-only failure; bug 926546
 [test_input_range_rounding.html]
 skip-if = (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage
 [test_input_sanitization.html]
 [test_input_textarea_set_value_no_scroll.html]
+[test_input_types_pref.html]
 [test_input_typing_sanitization.html]
 skip-if = buildapp == 'mulet'
 [test_input_untrusted_key_events.html]
 [test_input_url.html]
 [test_interactive_content_in_label.html]
 [test_label_control_attribute.html]
 [test_label_input_controls.html]
 [test_max_attribute.html]
--- a/dom/html/test/forms/test_input_attributes_reflection.html
+++ b/dom/html/test/forms/test_input_attributes_reflection.html
@@ -229,20 +229,20 @@ reflectString({
 });
 
 // .type
 reflectLimitedEnumerated({
   element: document.createElement("input"),
   attribute: "type",
   validValues: [ "hidden", "text", "search", "tel", "url", "email", "password",
                  "checkbox", "radio", "file", "submit", "image", "reset",
-                 "button", "date", "time", "number", "range", "color" ],
+                 "button", "date", "time", "number", "range", "color", "month" ],
   invalidValues: [ "this-is-probably-a-wrong-type", "", "tulip" ],
   defaultValue: "text",
-  unsupportedValues: [ "datetime", "month", "week", "datetime-local" ]
+  unsupportedValues: [ "datetime", "week", "datetime-local" ]
 });
 
 // .defaultValue
 reflectString({
   element: document.createElement("input"),
   attribute: { idl: "defaultValue", content: "value" },
   otherValues: [ "foo\nbar", "foo\rbar", "foo\r\nbar" ],
 });
--- a/dom/html/test/forms/test_input_sanitization.html
+++ b/dom/html/test/forms/test_input_sanitization.html
@@ -74,17 +74,17 @@ var inputTypes =
 [
   "text", "password", "search", "tel", "hidden", "checkbox", "radio",
   "submit", "image", "reset", "button", "email", "url", "number", "date",
   "time", "range", "color"
 ];
 
 var todoTypes =
 [
-  "month", "week", "datetime", "datetime-local",
+  "week", "datetime", "datetime-local",
 ];
 
 var valueModeValue =
 [
   "text", "search", "url", "tel", "email", "password", "date", "datetime",
   "month", "week", "time", "datetime-local", "number", "range", "color",
 ];
 
rename from dom/html/test/forms/test_experimental_forms_pref.html
rename to dom/html/test/forms/test_input_types_pref.html
--- a/dom/html/test/forms/test_experimental_forms_pref.html
+++ b/dom/html/test/forms/test_input_types_pref.html
@@ -14,38 +14,85 @@ https://bugzilla.mozilla.org/show_bug.cg
 <p id="display"></p>
 <div id="content" style="display: none" >
 </div>
 <pre id="test">
 <script type="application/javascript">
 
   var input = document.createElement("input");
 
-  SimpleTest.waitForExplicitFinish();
-  SpecialPowers.pushPrefEnv({'set': [["dom.experimental_forms", false], ["dom.forms.datepicker",false]]}, function() {
-    input.type = "date";
-    is(input.type, "text", "input type shouldn't be date when the experimental forms are disabled");
-    is(input.getAttribute('type'), "date", "input 'type' attribute should not change");
+  var testData = [
+    {
+      prefs: [["dom.forms.number", false]],
+      inputType: "number",
+      expectedType: "text"
+    }, {
+      prefs: [["dom.forms.number", true]],
+      inputType: "number",
+      expectedType: "number"
+    }, {
+      prefs: [["dom.forms.color", false]],
+      inputType: "color",
+      expectedType: "text"
+    }, {
+      prefs: [["dom.forms.color", true]],
+      inputType: "color",
+      expectedType: "color"
+    }, {
+      prefs: [["dom.experimental_forms", false], ["dom.forms.datepicker", false],
+              ["dom.forms.datetime", false]],
+      inputType: "date",
+      expectedType: "text"
+    }, {
+      prefs: [["dom.experimental_forms", true], ["dom.forms.datepicker", false],
+              ["dom.forms.datetime", false]],
+      inputType: "date",
+      expectedType: "date"
+    }, {
+      prefs: [["dom.experimental_forms", false], ["dom.forms.datepicker", true],
+              ["dom.forms.datetime", false]],
+      inputType: "date",
+      expectedType: "date"
+    }, {
+      prefs: [["dom.experimental_forms", false], ["dom.forms.datepicker", false],
+              ["dom.forms.datetime", true]],
+      inputType: "date",
+      expectedType: "date"
+    }, {
+      prefs: [["dom.forms.datetime", false]],
+      inputType: "month",
+      expectedType: "text"
+    }, {
+      prefs: [["dom.forms.datetime", true]],
+      inputType: "month",
+      expectedType: "month"
+    }
+  ];
 
-    SpecialPowers.pushPrefEnv({'set': [["dom.experimental_forms",true], ["dom.forms.datepicker",false]]}, function() {
-      // Change the type of input to text and then back to date,
-      // so that HTMLInputElement::ParseAttribute gets called with the pref enabled.
-      input.type = "text";
-      input.type = "date";
-      is(input.type, "date", "input type should be date when the experimental forms are enabled");
-      is(input.getAttribute('type'), "date", "input 'type' attribute should not change");
-
-      SpecialPowers.pushPrefEnv({'set': [["dom.experimental_forms",false], ["dom.forms.datepicker",true]]}, function() {
-        // Change the type of input to text and then back to date,
+  function testInputTypePreference(aData) {
+    return SpecialPowers.pushPrefEnv({'set': aData.prefs})
+      .then(() => {
+        // Change the type of input to text and then back to the tested input type,
         // so that HTMLInputElement::ParseAttribute gets called with the pref enabled.
         input.type = "text";
-        input.type = "date";
-        is(input.type, "date", "input type should be date when the datepicker is enabled");
-        is(input.getAttribute('type'), "date", "input 'type' attribute should not change");
+        input.type = aData.inputType;
+        is(input.type, aData.expectedType, "input type should be '" +
+           aData.expectedType + "'' when pref " + aData.prefs + " is set");
+        is(input.getAttribute('type'), aData.inputType,
+           "input 'type' attribute should not change");
+      });
+  }
+
+  SimpleTest.waitForExplicitFinish();
 
-        SimpleTest.finish();
-      });
-    });
-  });
+  let promise = Promise.resolve();
+  for (let i = 0; i < testData.length; i++) {
+    let data = testData[i];
+    promise = promise.then(() => testInputTypePreference(data));
+  }
+
+  promise.catch(error => ok(false, "Promise reject: " + error))
+    .then(() => SimpleTest.finish());
+
 </script>
 </pre>
 </body>
 </html>
--- a/dom/html/test/forms/test_input_typing_sanitization.html
+++ b/dom/html/test/forms/test_input_typing_sanitization.html
@@ -177,17 +177,16 @@ function runTest()
         '00:00:00.',
         '00:60',
         '10:58:99',
         ':19:10',
         '23:08:09.1012',
       ]
     },
     { type: 'week', todo: true },
-    { type: 'month', todo: true },
     { type: 'datetime', todo: true },
     { type: 'datetime-local', todo: true },
   ];
 
   for (test of data) {
     gCurrentTest = test;
 
     if (test.todo) {
--- a/dom/html/test/forms/test_max_attribute.html
+++ b/dom/html/test/forms/test_max_attribute.html
@@ -24,17 +24,18 @@ 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 },
-  { type: 'month', apply: true, todo: true },
+  // TODO: temporary set to false until bug 888324 is fixed.
+  { type: 'month', apply: false },
   { 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 },
@@ -140,16 +141,19 @@ for (var test of data) {
     case 'range':
       // 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.
+      break;
     default:
       ok(false, 'please, add a case for this new type (' + input.type + ')');
   }
 
   checkValidity(input, true, apply, apply);
 
   switch (input.type) {
     case 'text':
--- a/dom/html/test/forms/test_min_attribute.html
+++ b/dom/html/test/forms/test_min_attribute.html
@@ -24,17 +24,18 @@ 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 },
-  { type: 'month', apply: true, todo: true },
+  // TODO: temporary set to false until bug 888324 is fixed.
+  { type: 'month', apply: false },
   { 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 },
@@ -136,16 +137,19 @@ for (var test of data) {
     case 'time':
       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.
+      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);
 
   switch (input.type) {
@@ -330,16 +334,19 @@ for (var test of data) {
       checkValidity(input, true, apply, apply);
 
       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.
+      break;
     default:
       ok(false, 'write tests for ' + input.type);
   }
 
   // Cleaning up,
   input.removeAttribute('min');
   input.value = '';
 }
--- a/dom/html/test/forms/test_mozistextfield.html
+++ b/dom/html/test/forms/test_mozistextfield.html
@@ -47,26 +47,26 @@ var gInputTestData = [
   ['search',   true],
   ['email',    true],
   ['url',      true],
   ['number',   false],
   ['range',    false],
   ['date',     false],
   ['time',     false],
   ['color',    false],
+  ['month',    false],
 ];
 
 /**
  * TODO: the next types are not yet in the tree.
  * The value is only a suggestion.
  */
 var gInputTodoData = [
 /* type        expected result */
   ['datetime', false],
-  ['month',    false],
   ['week',     false],
   ['datetime-local', false],
 ];
 
 function checkMozIsTextFieldDefined(aElement, aResult)
 {
   var element = document.createElement(aElement);
 
--- a/dom/html/test/forms/test_pattern_attribute.html
+++ b/dom/html/test/forms/test_pattern_attribute.html
@@ -293,18 +293,18 @@ function checkPatternValidity(element)
 }
 
 var input = document.getElementById('i');
 
 // |validTypes| are the types which accept @pattern
 // and |invalidTypes| are the ones which do not accept it.
 var validTypes = Array('text', 'password', 'search', 'tel', 'email', 'url');
 var barredTypes = Array('hidden', 'reset', 'button');
-var invalidTypes = Array('checkbox', 'radio', 'file', 'number', 'range', 'date', 'time', 'color', 'submit', 'image');
-// TODO: 'datetime', 'month', 'week', and 'datetime-local'
+var invalidTypes = Array('checkbox', 'radio', 'file', 'number', 'range', 'date', 'time', 'color', 'submit', 'image', 'month');
+// TODO: 'datetime', 'week', and 'datetime-local'
 //       do not accept the @pattern too but are not implemented yet.
 
 for (type of validTypes) {
   input.type = type;
   completeValidityCheck(input, false);
   checkPatternValidity(input);
 }
 
--- a/dom/html/test/forms/test_required_attribute.html
+++ b/dom/html/test/forms/test_required_attribute.html
@@ -169,16 +169,18 @@ function checkInputRequiredValidity(type
   } else if (element.type == 'url') {
     SpecialPowers.wrap(element).value = 'http://mozilla.org/';
   } else if (element.type == 'number') {
     SpecialPowers.wrap(element).value = '42';
   } else if (element.type == 'date') {
     SpecialPowers.wrap(element).value = '2010-10-10';
   } else if (element.type == 'time') {
     SpecialPowers.wrap(element).value = '21:21';
+  } else if (element.type = 'month') {
+    SpecialPowers.wrap(element).value = '2010-10';
   } else {
     SpecialPowers.wrap(element).value = 'foo';
   }
   checkNotSufferingFromBeingMissing(element);
 
   SpecialPowers.wrap(element).value = '';
   checkSufferingFromBeingMissing(element, true);
 
@@ -357,20 +359,20 @@ for (type of typeBarredFromConstraintVal
 
 // Then, checks for the types which do not use the required attribute.
 var typeRequireNotApply = ['range', 'color', 'submit', 'image'];
 for (type of typeRequireNotApply) {
   checkInputRequiredNotApply(type, false);
 }
 
 // Now, checking for all types which accept the required attribute.
-// TODO: check 'datetime', 'month', 'week' and 'datetime-local'
+// TODO: check 'datetime', 'week' and 'datetime-local'
 //       when they will be implemented.
 var typeRequireApply = ["text", "password", "search", "tel", "email", "url",
-                        "number", "date", "time"];
+                        "number", "date", "time", "month"];
 
 for (type of typeRequireApply) {
   checkInputRequiredValidity(type);
 }
 
 checkInputRequiredValidityForCheckbox();
 checkInputRequiredValidityForRadio();
 checkInputRequiredValidityForFile();
--- a/dom/html/test/forms/test_step_attribute.html
+++ b/dom/html/test/forms/test_step_attribute.html
@@ -24,17 +24,18 @@ 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 },
-  { type: 'month', apply: true, todo: true },
+  // TODO: temporary set to false until bug 888324 is fixed.
+  { type: 'month', apply: false },
   { 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 },
@@ -715,16 +716,19 @@ for (var test of data) {
           checkValidity(input, true, apply);
         } else {
           checkValidity(input, false, apply,
                         { low: test.low, high: test.high });
         }
       }
 
       break;
+    case 'month':
+      // TODO: this is temporary until bug 888324 is fixed.
+      break;
     default:
       ok(false, "Implement the tests for <input type='" + test.type + " >");
       break;
   }
 }
 
 </script>
 </pre>
--- a/dom/html/test/forms/test_valueasnumber_attribute.html
+++ b/dom/html/test/forms/test_valueasnumber_attribute.html
@@ -39,22 +39,23 @@ function checkAvailability()
     ["image", false],
     ["reset", false],
     ["button", false],
     ["number", true],
     ["range", true],
     ["date", true],
     ["time", true],
     ["color", false],
+    // TODO: temporary set to false until bug 888324 is fixed.
+    ["month", false],
   ];
 
   var todoList =
   [
     ["datetime", true],
-    ["month", true],
     ["week", true],
     ["datetime-local", true],
   ];
 
   var element = document.createElement('input');
 
   for (data of testData) {
     var exceptionCatched = false;
--- a/dom/html/test/test_bug590363.html
+++ b/dom/html/test/test_bug590363.html
@@ -34,21 +34,22 @@ var testData = [
   [ "email",    true ],
   [ "search",   true ],
   [ "password", true ],
   [ "number",   true ],
   [ "date",     true ],
   [ "time",     true ],
   [ "range",    true ],
   [ "color",    true ],
+  [ 'month',    true ]
   // 'file' is treated separatly.
 ];
 
 var todoTypes = [
-  "datetime", "month", "week", "datetime-local"
+  "datetime", "week", "datetime-local"
 ];
 
 var nonTrivialSanitizing = [ 'number', 'date', 'time', 'color' ];
 
 var length = testData.length;
 for (var i=0; i<length; ++i) {
   for (var j=0; j<length; ++j) {
     var e = document.createElement('input');
@@ -77,16 +78,18 @@ for (var i=0; i<length; ++i) {
                nonTrivialSanitizing.indexOf(testData[j][0]) != -1) {
       expectedValue = '';
     } else if (testData[i][0] == 'number' || testData[j][0] == 'number') {
       expectedValue = '42';
     } else if (testData[i][0] == 'date' || testData[j][0] == 'date') {
       expectedValue = '2012-12-21';
     } else if (testData[i][0] == 'time' || testData[j][0] == 'time') {
       expectedValue = '21:21';
+    } else if (testData[i][0] == 'month' || testData[j][0] == 'month') {
+      expectedValue = '2013-03';
     } else {
       expectedValue = "foo";
     }
     e.value = expectedValue;
 
     e.type = testData[j][0];
     is(e.value, expectedValue, ".value should still return the same value after " +
        "changing type from " + testData[i][0] + " to " + testData[j][0]);
--- a/dom/html/test/test_bug598643.html
+++ b/dom/html/test/test_bug598643.html
@@ -33,19 +33,19 @@ function testFileControl(aElement)
      "the file control shouldn't suffer from being too long");
 }
 
 var types = [
   // These types can be too long.
   [ "text", "email", "password", "url", "search", "tel" ],
   // These types can't be too long.
   [ "radio", "checkbox", "submit", "button", "reset", "image", "hidden",
-    'number', 'range', 'date', 'time', 'color' ],
+    'number', 'range', 'date', 'time', 'color', 'month' ],
   // These types can't be too long but are not implemented yet.
-  [ "datetime", "month", "week", 'datetime-local' ]
+  [ "datetime", "week", 'datetime-local' ]
 ];
 
 var input = document.createElement("input");
 input.maxLength = 1;
 input.value = "foo";
 
 // Too long types.
 for (type of types[0]) {
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -3691,20 +3691,22 @@ nsCSSFrameConstructor::FindInputData(Ele
     SIMPLE_INT_CREATE(NS_FORM_INPUT_URL, NS_NewTextControlFrame),
     SIMPLE_INT_CREATE(NS_FORM_INPUT_RANGE, NS_NewRangeFrame),
     SIMPLE_INT_CREATE(NS_FORM_INPUT_PASSWORD, NS_NewTextControlFrame),
     { NS_FORM_INPUT_COLOR,
       FCDATA_WITH_WRAPPING_BLOCK(0, NS_NewColorControlFrame,
                                  nsCSSAnonBoxes::buttonContent) },
     // TODO: this is temporary until a frame is written: bug 635240.
     SIMPLE_INT_CREATE(NS_FORM_INPUT_NUMBER, NS_NewNumberControlFrame),
-    // TODO: this is temporary until a frame is written: bug 773205.
+    // TODO: this is temporary until a frame is written: bug 888320.
     SIMPLE_INT_CREATE(NS_FORM_INPUT_DATE, NS_NewTextControlFrame),
-    // TODO: this is temporary until a frame is written: bug 773205
+    // TODO: this is temporary until a frame is written: bug 888320
     SIMPLE_INT_CREATE(NS_FORM_INPUT_TIME, NS_NewTextControlFrame),
+    // TODO: this is temporary until a frame is written: bug 888320
+    SIMPLE_INT_CREATE(NS_FORM_INPUT_MONTH, NS_NewTextControlFrame),
     { NS_FORM_INPUT_SUBMIT,
       FCDATA_WITH_WRAPPING_BLOCK(0, NS_NewGfxButtonControlFrame,
                                  nsCSSAnonBoxes::buttonContent) },
     { NS_FORM_INPUT_RESET,
       FCDATA_WITH_WRAPPING_BLOCK(0, NS_NewGfxButtonControlFrame,
                                  nsCSSAnonBoxes::buttonContent) },
     { NS_FORM_INPUT_BUTTON,
       FCDATA_WITH_WRAPPING_BLOCK(0, NS_NewGfxButtonControlFrame,
--- a/testing/profiles/prefs_general.js
+++ b/testing/profiles/prefs_general.js
@@ -6,16 +6,17 @@ user_pref("browser.firstrun.show.localep
 user_pref("browser.firstrun.show.uidiscovery", false);
 user_pref("browser.startup.page", 0); // use about:blank, not browser.startup.homepage
 user_pref("browser.ui.layout.tablet", 0); // force tablet UI off
 user_pref("dom.allow_scripts_to_close_windows", true);
 user_pref("dom.disable_open_during_load", false);
 user_pref("dom.experimental_forms", true); // on for testing
 user_pref("dom.forms.number", true); // on for testing
 user_pref("dom.forms.color", true); // on for testing
+user_pref("dom.forms.datetime", true); // on for testing
 user_pref("dom.max_script_run_time", 0); // no slow script dialogs
 user_pref("hangmonitor.timeout", 0); // no hang monitor
 user_pref("dom.max_chrome_script_run_time", 0);
 user_pref("dom.ipc.reportProcessHangs", false); // process hang monitor
 user_pref("dom.popup_maximum", -1);
 user_pref("dom.send_after_paint_to_content", true);
 user_pref("dom.successive_dialog_time_limit", 0);
 user_pref("signed.applets.codebase_principal_support", true);
--- a/testing/web-platform/meta/html/dom/reflection-forms.html.ini
+++ b/testing/web-platform/meta/html/dom/reflection-forms.html.ini
@@ -584,22 +584,16 @@
     expected: FAIL
 
   [input.type: setAttribute() to "datetime" followed by IDL get]
     expected: FAIL
 
   [input.type: setAttribute() to "DATETIME" followed by IDL get]
     expected: FAIL
 
-  [input.type: setAttribute() to "month" followed by IDL get]
-    expected: FAIL
-
-  [input.type: setAttribute() to "MONTH" followed by IDL get]
-    expected: FAIL
-
   [input.type: setAttribute() to "week" followed by IDL get]
     expected: FAIL
 
   [input.type: setAttribute() to "WEEK" followed by IDL get]
     expected: FAIL
 
   [input.type: setAttribute() to "datetime-local" followed by IDL get]
     expected: FAIL
@@ -608,22 +602,16 @@
     expected: FAIL
 
   [input.type: IDL set to "datetime" followed by IDL get]
     expected: FAIL
 
   [input.type: IDL set to "DATETIME" followed by IDL get]
     expected: FAIL
 
-  [input.type: IDL set to "month" followed by IDL get]
-    expected: FAIL
-
-  [input.type: IDL set to "MONTH" followed by IDL get]
-    expected: FAIL
-
   [input.type: IDL set to "week" followed by IDL get]
     expected: FAIL
 
   [input.type: IDL set to "WEEK" followed by IDL get]
     expected: FAIL
 
   [input.type: IDL set to "datetime-local" followed by IDL get]
     expected: FAIL
--- 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,14 +34,29 @@
     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\] The month type must be supported.]
+  [[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,11 +1,14 @@
 [form-validation-validity-rangeOverflow.html]
   type: testharness
   [[INPUT in DATETIME status\] The datetime type must be supported.]
     expected: FAIL
 
-  [[INPUT in MONTH status\] The month type must be supported.]
+  [[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,11 +1,14 @@
 [form-validation-validity-rangeUnderflow.html]
   type: testharness
   [[INPUT in DATETIME status\] The datetime type must be supported.]
     expected: FAIL
 
-  [[INPUT in MONTH status\] The month type must be supported.]
+  [[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-stepMismatch.html.ini
+++ b/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-stepMismatch.html.ini
@@ -1,17 +1,17 @@
 [form-validation-validity-stepMismatch.html]
   type: testharness
   [[INPUT in DATETIME status\] The datetime type must be supported.]
     expected: FAIL
 
   [[INPUT in DATE status\] The value must match the step]
     expected: FAIL
 
-  [[INPUT in MONTH status\] The month type must be supported.]
+  [[INPUT in MONTH status\] The value must mismatch the step]
     expected: FAIL
 
   [[INPUT in WEEK status\] The week type must be supported.]
     expected: FAIL
 
   [[INPUT in TIME status\] The value must match the step]
     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,14 +16,20 @@
     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\] The month type must be supported.]
+  [[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
 
--- a/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-valueMissing.html.ini
+++ b/testing/web-platform/meta/html/semantics/forms/constraints/form-validation-validity-valueMissing.html.ini
@@ -1,11 +1,23 @@
 [form-validation-validity-valueMissing.html]
   type: testharness
   [[INPUT in DATETIME status\] The datetime type must be supported.]
     expected: FAIL
 
-  [[INPUT in MONTH status\] The month type must be supported.]
+  [[INPUT in MONTH status\] The value attribute is a number(1234567)]
+    expected: FAIL
+
+  [[INPUT in MONTH status\] The value attribute is a Date object]
+    expected: FAIL
+
+  [[INPUT in MONTH status\] Invalid month string(2000-99)]
+    expected: FAIL
+
+  [[INPUT in MONTH status\] Invalid month string(37-01)]
+    expected: FAIL
+
+  [[INPUT in MONTH status\] Invalid month string(2000/01)]
     expected: FAIL
 
   [[INPUT in WEEK status\] The week type must be supported.]
     expected: FAIL
 
--- a/testing/web-platform/meta/html/semantics/forms/the-input-element/datetime.html.ini
+++ b/testing/web-platform/meta/html/semantics/forms/the-input-element/datetime.html.ini
@@ -1,11 +1,8 @@
 [datetime.html]
   type: testharness
   [datetime type support on input element]
     expected: FAIL
 
-  [month type support on input element]
-    expected: FAIL
-
   [week type support on input element]
     expected: FAIL
 
--- a/testing/web-platform/meta/html/semantics/forms/the-input-element/month.html.ini
+++ b/testing/web-platform/meta/html/semantics/forms/the-input-element/month.html.ini
@@ -1,13 +1,10 @@
 [month.html]
   type: testharness
-  [month type support on input element]
-    expected: FAIL
-
   [The value attribute, if specified and not empty, must have a value that is a valid month string]
     expected: FAIL
 
   [The min attribute, if specified, must have a value that is a valid month string.]
     expected: FAIL
 
   [The max attribute, if specified, must have a value that is a valid month string]
     expected: FAIL
--- a/testing/web-platform/meta/html/semantics/forms/the-input-element/selection.html.ini
+++ b/testing/web-platform/meta/html/semantics/forms/the-input-element/selection.html.ini
@@ -1,13 +1,10 @@
 [selection.html]
   type: testharness
-  [input type month should support the select() method]
-    expected: FAIL
-
   [input type week should support the select() method]
     expected: FAIL
 
   [input type datetime-local should support the select() method]
     expected: FAIL
 
   [input type hidden should not support the select() method]
     expected: FAIL
--- a/toolkit/components/satchel/test/test_form_autocomplete.html
+++ b/toolkit/components/satchel/test/test_form_autocomplete.html
@@ -112,16 +112,23 @@ Form History test: form field autocomple
   </form>
 
   <!-- form with input type='color' -->
   <form id="form17" onsubmit="return false;">
     <input  type="color" name="field14">
     <button type="submit">Submit</button>
   </form>
 
+  <!-- form with input type='month' -->
+  <form id="form18" onsubmit="return false;">
+    <input  type="month" name="field15">
+    <button type="submit">Submit</button>
+  </form>
+
+
 </div>
 
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for Form History autocomplete **/
 
 var input = $_(1, "field1");
@@ -158,17 +165,17 @@ function setupFormHistory(aCallback) {
     { op : "add", fieldname : "field12", value : "21:21" },
     { op : "add", fieldname : "field13", value : "32" },  // not used, since type=range doesn't have a drop down menu
     { op : "add", fieldname : "field14", value : "#ffffff" }, // not used, since type=color doesn't have autocomplete currently
     { op : "add", fieldname : "searchbar-history", value : "blacklist test" },
   ], aCallback);
 }
 
 // All these non-implemeted types might need autocomplete tests in the future.
-var todoTypes = [ "datetime", "month", "week", "datetime-local" ];
+var todoTypes = [ "datetime", "week", "datetime-local" ];
 var todoInput = document.createElement("input");
 for (var type of todoTypes) {
   todoInput.type = type;
   todo_is(todoInput.type, type, type + " type shouldn't be implemented");
 }
 
 
 function setForm(value) {