Bug 769385 - Add type attribute date for <input> behind "dom.experimental_forms" pref. r=mounir
authorRaphael Catolino <rcatolino@mozilla.com>
Thu, 27 Dec 2012 16:06:53 +0000
changeset 126215 0ec205214f5f4d20cd178c92544e9e37b0ac2de0
parent 126214 f2a500997116e854815a068ea70c6a6b74759d1b
child 126216 d44a92b2cbf774a0fdc4b0ce33add7a7dd608a59
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmounir
bugs769385
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 769385 - Add type attribute date for <input> behind "dom.experimental_forms" pref. r=mounir
b2g/chrome/content/forms.js
content/events/src/nsEventStateManager.cpp
content/html/content/public/nsIFormControl.h
content/html/content/src/nsHTMLFormElement.cpp
content/html/content/src/nsHTMLInputElement.cpp
content/html/content/src/nsHTMLInputElement.h
content/html/content/test/forms/test_input_attributes_reflection.html
content/html/content/test/forms/test_mozistextfield.html
content/html/content/test/forms/test_pattern_attribute.html
content/html/content/test/forms/test_required_attribute.html
content/html/content/test/test_bug549475.html
content/html/content/test/test_bug590363.html
embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp
layout/base/nsCSSFrameConstructor.cpp
toolkit/components/satchel/test/test_form_autocomplete.html
--- a/b2g/chrome/content/forms.js
+++ b/b2g/chrome/content/forms.js
@@ -277,24 +277,22 @@ function getJSON(element) {
   // Treat contenteditble element as a special text field
   if (element.contentEditable && element.contentEditable == "true") {
     type = "text";
     value = element.textContent;
   }
 
   // Until the input type=date/datetime/time have been implemented
   // let's return their real type even if the platform returns 'text'
-  // Related to Bug 769352 - Implement <input type=date>
   // Related to Bug 777279 - Implement <input type=time>
   let attributeType = element.getAttribute("type") || "";
 
   if (attributeType) {
     var typeLowerCase = attributeType.toLowerCase(); 
     switch (typeLowerCase) {
-      case "date":
       case "time":
       case "datetime":
       case "datetime-local":
         type = typeLowerCase;
         break;
     }
   }
 
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -1894,16 +1894,17 @@ nsEventStateManager::FireContextClick()
         allowedToDispatch = (type == NS_FORM_INPUT_TEXT ||
                              type == NS_FORM_INPUT_EMAIL ||
                              type == NS_FORM_INPUT_SEARCH ||
                              type == NS_FORM_INPUT_TEL ||
                              type == NS_FORM_INPUT_URL ||
                              type == NS_FORM_INPUT_PASSWORD ||
                              type == NS_FORM_INPUT_FILE ||
                              type == NS_FORM_INPUT_NUMBER ||
+                             type == NS_FORM_INPUT_DATE ||
                              type == NS_FORM_TEXTAREA);
       }
       else if (tag == nsGkAtoms::applet ||
                tag == nsGkAtoms::embed  ||
                tag == nsGkAtoms::object) {
         allowedToDispatch = false;
       }
     }
--- a/content/html/content/public/nsIFormControl.h
+++ b/content/html/content/public/nsIFormControl.h
@@ -43,16 +43,17 @@ enum ButtonElementTypes {
   NS_FORM_BUTTON_RESET,
   NS_FORM_BUTTON_SUBMIT,
   eButtonElementTypesMax
 };
 
 enum InputElementTypes {
   NS_FORM_INPUT_BUTTON = NS_FORM_INPUT_ELEMENT + 1,
   NS_FORM_INPUT_CHECKBOX,
+  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_NUMBER,
   NS_FORM_INPUT_PASSWORD,
   NS_FORM_INPUT_RADIO,
@@ -227,16 +228,18 @@ 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: this is temporary until bug 635240 is fixed.
          aType == NS_FORM_INPUT_NUMBER ||
+         // TODO: this is temporary until bug 773205 is fixed.
+         aType == NS_FORM_INPUT_DATE ||
          (!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/content/html/content/src/nsHTMLFormElement.cpp
+++ b/content/html/content/src/nsHTMLFormElement.cpp
@@ -179,16 +179,17 @@ ShouldBeInElements(nsIFormControl* aForm
   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_NUMBER :
+  case NS_FORM_INPUT_DATE :
   case NS_FORM_SELECT :
   case NS_FORM_TEXTAREA :
   case NS_FORM_FIELDSET :
   case NS_FORM_OBJECT :
   case NS_FORM_OUTPUT :
     return true;
   }
 
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -112,16 +112,17 @@ static NS_DEFINE_CID(kXULControllersCID,
 // whether textfields should be selected once focused:
 //  -1: no, 1: yes, 0: uninitialized
 static int32_t gSelectTextFieldOnFocus;
 UploadLastDir* nsHTMLInputElement::gUploadLastDir;
 
 static const nsAttrValue::EnumTable kInputTypeTable[] = {
   { "button", NS_FORM_INPUT_BUTTON },
   { "checkbox", NS_FORM_INPUT_CHECKBOX },
+  { "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 },
   { "number", NS_FORM_INPUT_NUMBER },
   { "password", NS_FORM_INPUT_PASSWORD },
   { "radio", NS_FORM_INPUT_RADIO },
@@ -129,17 +130,17 @@ static const nsAttrValue::EnumTable kInp
   { "submit", NS_FORM_INPUT_SUBMIT },
   { "tel", NS_FORM_INPUT_TEL },
   { "text", NS_FORM_INPUT_TEXT },
   { "url", NS_FORM_INPUT_URL },
   { 0 }
 };
 
 // Default type is 'text'.
-static const nsAttrValue::EnumTable* kInputDefaultType = &kInputTypeTable[13];
+static const nsAttrValue::EnumTable* kInputDefaultType = &kInputTypeTable[14];
 
 static const uint8_t NS_INPUT_AUTOCOMPLETE_OFF     = 0;
 static const uint8_t NS_INPUT_AUTOCOMPLETE_ON      = 1;
 static const uint8_t NS_INPUT_AUTOCOMPLETE_DEFAULT = 2;
 
 static const nsAttrValue::EnumTable kInputAutocompleteTable[] = {
   { "", NS_INPUT_AUTOCOMPLETE_DEFAULT },
   { "on", NS_INPUT_AUTOCOMPLETE_ON },
@@ -691,16 +692,17 @@ nsHTMLInputElement::Clone(nsINodeInfo *a
   switch (mType) {
     case NS_FORM_INPUT_EMAIL:
     case NS_FORM_INPUT_SEARCH:
     case NS_FORM_INPUT_TEXT:
     case NS_FORM_INPUT_PASSWORD:
     case NS_FORM_INPUT_TEL:
     case NS_FORM_INPUT_URL:
     case NS_FORM_INPUT_NUMBER:
+    case NS_FORM_INPUT_DATE:
       if (mValueChanged) {
         // We don't have our default value anymore.  Set our value on
         // the clone.
         nsAutoString value;
         GetValueInternal(value);
         // SetValueInternal handles setting the VALUE_CHANGED bit for us
         it->SetValueInternal(value, false, true);
       }
@@ -1368,18 +1370,18 @@ nsHTMLInputElement::MozSetFileNameArray(
   SetFiles(files, true);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLInputElement::MozIsTextField(bool aExcludePassword, bool* aResult)
 {
-  // TODO: temporary until bug 635240 is fixed.
-  if (mType == NS_FORM_INPUT_NUMBER) {
+  // TODO: temporary until bug 635240 and 773205 are fixed.
+  if (mType == NS_FORM_INPUT_NUMBER || mType == NS_FORM_INPUT_DATE) {
     *aResult = false;
     return NS_OK;
   }
 
   *aResult = IsSingleLineTextControl(aExcludePassword);
 
   return NS_OK;
 }
@@ -2455,17 +2457,18 @@ nsHTMLInputElement::PostHandleEvent(nsEv
            * (c) if there is more than one text input and no submit buttons, do
            *     not submit, period.
            */
 
           if (aVisitor.mEvent->message == NS_KEY_PRESS &&
               (keyEvent->keyCode == NS_VK_RETURN ||
                keyEvent->keyCode == NS_VK_ENTER) &&
                (IsSingleLineTextControl(false, mType) ||
-                mType == NS_FORM_INPUT_NUMBER)) {
+                mType == NS_FORM_INPUT_NUMBER ||
+                mType == NS_FORM_INPUT_DATE)) {
             FireChangeEventIfNeeded();   
             rv = MaybeSubmitForm(aVisitor.mPresContext);
             NS_ENSURE_SUCCESS(rv, rv);
           }
 
         } break; // NS_KEY_PRESS || NS_KEY_UP
 
         case NS_MOUSE_BUTTON_DOWN:
@@ -2766,18 +2769,19 @@ nsHTMLInputElement::ParseAttribute(int32
   if (aNamespaceID == kNameSpaceID_None) {
     if (aAttribute == nsGkAtoms::type) {
       // XXX ARG!! This is major evilness. ParseAttribute
       // shouldn't set members. Override SetAttr instead
       int32_t newType;
       bool success = aResult.ParseEnumValue(aValue, kInputTypeTable, false);
       if (success) {
         newType = aResult.GetEnumValue();
-        if (newType == NS_FORM_INPUT_NUMBER && 
-          !Preferences::GetBool("dom.experimental_forms", false)) {
+        if ((newType == NS_FORM_INPUT_NUMBER ||
+             newType == NS_FORM_INPUT_DATE) && 
+            !Preferences::GetBool("dom.experimental_forms", false)) {
           newType = kInputDefaultType->value;
           aResult.SetTo(newType, &aValue);
         }
       } else {
         newType = kInputDefaultType->value;
       }
 
       if (newType != mType) {
@@ -3392,16 +3396,17 @@ nsHTMLInputElement::SaveState()
       break;
     case NS_FORM_INPUT_EMAIL:
     case NS_FORM_INPUT_SEARCH:
     case NS_FORM_INPUT_TEXT:
     case NS_FORM_INPUT_TEL:
     case NS_FORM_INPUT_URL:
     case NS_FORM_INPUT_HIDDEN:
     case NS_FORM_INPUT_NUMBER:
+    case NS_FORM_INPUT_DATE:
       {
         if (mValueChanged) {
           inputState = new nsHTMLInputElementState();
           nsAutoString value;
           GetValue(value);
           DebugOnly<nsresult> rv =
             nsLinebreakConverter::ConvertStringLineBreaks(
                  value,
@@ -3576,16 +3581,17 @@ nsHTMLInputElement::RestoreState(nsPresS
 
       case NS_FORM_INPUT_EMAIL:
       case NS_FORM_INPUT_SEARCH:
       case NS_FORM_INPUT_TEXT:
       case NS_FORM_INPUT_TEL:
       case NS_FORM_INPUT_URL:
       case NS_FORM_INPUT_HIDDEN:
       case NS_FORM_INPUT_NUMBER:
+      case NS_FORM_INPUT_DATE:
         {
           SetValueInternal(inputState->GetValue(), false, true);
           break;
         }
       case NS_FORM_INPUT_FILE:
         {
           const nsCOMArray<nsIDOMFile>& files = inputState->GetFiles();
           SetFiles(files, true);
@@ -3800,16 +3806,17 @@ nsHTMLInputElement::GetValueMode() const
 #ifdef DEBUG
     case NS_FORM_INPUT_TEXT:
     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:
       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
@@ -3844,16 +3851,17 @@ nsHTMLInputElement::DoesReadOnlyApply() 
 #ifdef DEBUG
     case NS_FORM_INPUT_TEXT:
     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:
       return true;
     default:
       NS_NOTYETIMPLEMENTED("Unexpected input type in DoesReadOnlyApply()");
       return true;
 #else // DEBUG
     default:
       return true;
 #endif // DEBUG
@@ -3880,44 +3888,56 @@ nsHTMLInputElement::DoesRequiredApply() 
     case NS_FORM_INPUT_FILE:
     case NS_FORM_INPUT_TEXT:
     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:
       return true;
     default:
       NS_NOTYETIMPLEMENTED("Unexpected input type in DoesRequiredApply()");
       return true;
 #else // DEBUG
     default:
       return true;
 #endif // DEBUG
   }
 }
 
 bool
+nsHTMLInputElement::PlaceholderApplies() const
+{
+  if (mType == NS_FORM_INPUT_DATE) {
+    return false;
+  }
+
+  return IsSingleLineTextControl(false);
+}
+
+bool
 nsHTMLInputElement::DoesPatternApply() const
 {
   // TODO: temporary until bug 635240 is fixed.
-  if (mType == NS_FORM_INPUT_NUMBER) {
+  if (mType == NS_FORM_INPUT_NUMBER || mType == NS_FORM_INPUT_DATE) {
     return false;
   }
 
   return IsSingleLineTextControl(false);
 }
 
 bool
 nsHTMLInputElement::DoesMinMaxApply() const
 {
   switch (mType)
   {
     case NS_FORM_INPUT_NUMBER:
+    case NS_FORM_INPUT_DATE:
     // TODO:
     // case NS_FORM_INPUT_RANGE:
     // All date/time types.
       return true;
 #ifdef DEBUG
     case NS_FORM_INPUT_RESET:
     case NS_FORM_INPUT_SUBMIT:
     case NS_FORM_INPUT_IMAGE:
@@ -4104,17 +4124,18 @@ nsHTMLInputElement::HasPatternMismatch()
   nsIDocument* doc = OwnerDoc();
 
   return !nsContentUtils::IsPatternMatching(value, pattern, doc);
 }
 
 bool
 nsHTMLInputElement::IsRangeOverflow() const
 {
-  if (!DoesMinMaxApply()) {
+  // Ignore <input type=date> until bug 769355 is fixed.
+  if (!DoesMinMaxApply() || mType == NS_FORM_INPUT_DATE) {
     return false;
   }
 
   double max = GetMaxAsDouble();
   if (MOZ_DOUBLE_IS_NaN(max)) {
     return false;
   }
 
@@ -4124,17 +4145,18 @@ nsHTMLInputElement::IsRangeOverflow() co
   }
 
   return value > max;
 }
 
 bool
 nsHTMLInputElement::IsRangeUnderflow() const
 {
-  if (!DoesMinMaxApply()) {
+  // Ignore <input type=date> until bug 769357 is fixed.
+  if (!DoesMinMaxApply() || mType == NS_FORM_INPUT_DATE) {
     return false;
   }
 
   double min = GetMinAsDouble();
   if (MOZ_DOUBLE_IS_NaN(min)) {
     return false;
   }
 
--- a/content/html/content/src/nsHTMLInputElement.h
+++ b/content/html/content/src/nsHTMLInputElement.h
@@ -497,17 +497,17 @@ protected:
    * Sanitize the value of the element depending of its current type.
    * See: http://www.whatwg.org/specs/web-apps/current-work/#value-sanitization-algorithm
    */
   void SanitizeValue(nsAString& aValue);
 
   /**
    * Returns whether the placeholder attribute applies for the current type.
    */
-  bool PlaceholderApplies() const { return IsSingleLineTextControl(false, mType); }
+  bool PlaceholderApplies() const;
 
   /**
    * Set the current default value to the value of the input element.
    * @note You should not call this method if GetValueMode() doesn't return
    * VALUE_MODE_VALUE.
    */
   nsresult SetDefaultValueAsValue();
 
--- a/content/html/content/test/forms/test_input_attributes_reflection.html
+++ b/content/html/content/test/forms/test_input_attributes_reflection.html
@@ -196,20 +196,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", "number" ],
+                 "button", "date", "number" ],
   invalidValues: [ "this-is-probably-a-wrong-type", "", "tulip" ],
   defaultValue: "text",
-  unsupportedValues: [ "datetime", "date", "month", "week", "time",
+  unsupportedValues: [ "datetime", "month", "week", "time",
                        "datetime-local", "range", "color" ]
 });
 
 // .defaultValue
 reflectString({
   element: document.createElement("input"),
   attribute: { idl: "defaultValue", content: "value" },
   otherValues: [ "foo\nbar", "foo\rbar", "foo\r\nbar" ],
--- a/content/html/content/test/forms/test_mozistextfield.html
+++ b/content/html/content/test/forms/test_mozistextfield.html
@@ -43,27 +43,27 @@ var gInputTestData = [
   ['reset',    false],
   ['image',    false],
   ['radio',    false],
   ['submit',   false],
   ['search',   true],
   ['email',    true],
   ['url',      true],
   ['number',   false],
+  ['date',     false],
 ];
 
 /**
  * TODO: the next types are not yet in the tree.
  * The value is only a suggestion.
  */
 var gInputTodoData = [
 /* type        expected result */
   ['range',    false],
   ['color',    false],
-  ['date',     false],
   ['datetime', false],
   ['month',    false],
   ['week',     false],
   ['time',     false],
   ['datetime-local', false],
 ];
 
 function checkMozIsTextFieldDefined(aElement, aResult)
--- a/content/html/content/test/forms/test_pattern_attribute.html
+++ b/content/html/content/test/forms/test_pattern_attribute.html
@@ -256,18 +256,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', 'submit', 'image');
-var invalidTypes = Array('checkbox', 'radio', 'file', 'number');
-// TODO: 'datetime', 'date', 'month', 'week', 'time', 'datetime-local',
+var invalidTypes = Array('checkbox', 'radio', 'file', 'number', 'date');
+// TODO: 'datetime', 'month', 'week', 'time', 'datetime-local',
 //       'range', and 'color' do not accept the @pattern too but are not
 //       implemented yet.
 
 SimpleTest.waitForExplicitFinish();
 SpecialPowers.pushPrefEnv({'set': [["dom.experimental_forms", true]]}, function() {
 for (type of validTypes) {
   input.type = type;
   completeValidityCheck(input, false);
--- a/content/html/content/test/forms/test_required_attribute.html
+++ b/content/html/content/test/forms/test_required_attribute.html
@@ -159,16 +159,18 @@ function checkInputRequiredValidity(type
   checkSufferingFromBeingMissing(element, true);
 
   if (element.type == 'email') {
     element.value = 'foo@bar.com';
   } else if (element.type == 'url') {
     element.value = 'http://mozilla.org/';
   } else if (element.type == 'number') {
     element.value = '42';
+  } else if (element.type == 'date') {
+    element.value = '2010-10-10';
   } else {
     element.value = 'foo';
   }
   checkNotSufferingFromBeingMissing(element);
 
   element.value = '';
   checkSufferingFromBeingMissing(element, true);
 
@@ -347,16 +349,19 @@ function checkInputRequiredValidityForFi
 
   element.required = true;
   element.value = '';
   file.remove(false);
   document.forms[0].removeChild(element);
   checkNotSufferingFromBeingMissing(element);
 }
 
+SimpleTest.waitForExplicitFinish();
+SpecialPowers.pushPrefEnv({'set': [["dom.experimental_forms", true]]}, function() {
+
 checkTextareaRequiredValidity();
 
 // The require attribute behavior depend of the input type.
 // First of all, checks for types that make the element barred from
 // constraint validation.
 var typeBarredFromConstraintValidation = ["hidden", "button", "reset", "submit", "image"];
 for (type of typeBarredFromConstraintValidation) {
   checkInputRequiredNotApply(type, true);
@@ -365,25 +370,28 @@ for (type of typeBarredFromConstraintVal
 // Then, checks for the types which do not use the required attribute.
 // TODO: check 'color' and 'range' when they will be implemented.
 var typeRequireNotApply = [];
 for (type of typeRequireNotApply) {
   checkInputRequiredNotApply(type, false);
 }
 
 // Now, checking for all types which accept the required attribute.
-// TODO: check 'datetime', 'date', 'month', 'week', 'time' and 'datetime-local'
+// TODO: check 'datetime', 'month', 'week', 'time' and 'datetime-local'
 //       when they will be implemented.
 var typeRequireApply = ["text", "password", "search", "tel", "email", "url",
-                        "number"];
+                        "number", "date"];
 
 for (type of typeRequireApply) {
   checkInputRequiredValidity(type);
 }
 
 checkInputRequiredValidityForCheckbox();
 checkInputRequiredValidityForRadio();
 checkInputRequiredValidityForFile();
 
+SimpleTest.finish();
+});
+
 </script>
 </pre>
 </body>
 </html>
--- a/content/html/content/test/test_bug549475.html
+++ b/content/html/content/test/test_bug549475.html
@@ -20,23 +20,23 @@ https://bugzilla.mozilla.org/show_bug.cg
 
 /** Test for Bug 549475 **/
 
 // We are excluding "file" because it's too different from the other types.
 // And it has no sanitizing algorithm.
 var inputTypes =
 [
   "text", "password", "search", "tel", "hidden", "checkbox", "radio",
-  "submit", "image", "reset", "button", "email", "url", "number",
+  "submit", "image", "reset", "button", "email", "url", "number", "date",
 ];
 
 var todoTypes =
 [
   "range", "color",
-  "date", "month", "week", "time", "datetime", "datetime-local",
+  "month", "week", "time", "datetime", "datetime-local",
 ];
 
 var valueModeValue =
 [
   "text", "search", "url", "tel", "email", "password", "date", "datetime",
   "month", "week", "time", "datetime-local", "number", "range", "color",
 ];
 
--- a/content/html/content/test/test_bug590363.html
+++ b/content/html/content/test/test_bug590363.html
@@ -30,21 +30,22 @@ var testData = [
   [ "submit",   false ],
   [ "tel",      true ],
   [ "text",     true ],
   [ "url",      true ],
   [ "email",    true ],
   [ "search",   true ],
   [ "password", true ],
   [ "number",   true ],
+  [ "date",     true ],
   // 'file' is treated separatly.
 ];
 
 var todoTypes = [
-  "datetime", "date", "month", "week", "time", "datetime-local", "range", "color"
+  "datetime", "month", "week", "time", "datetime-local", "range", "color"
 ];
 
 var length = testData.length;
 for (var i=0; i<length; ++i) {
   for (var j=0; j<length; ++j) {
     var e = document.createElement('input');
     e.type = testData[i][0];
 
--- a/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp
+++ b/embedding/components/webbrowserpersist/src/nsWebBrowserPersist.cpp
@@ -3259,16 +3259,17 @@ nsWebBrowserPersist::CloneNodeWithFixedU
             nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(*aNodeOut);
             switch (formControl->GetType()) {
                 case NS_FORM_INPUT_EMAIL:
                 case NS_FORM_INPUT_SEARCH:
                 case NS_FORM_INPUT_TEXT:
                 case NS_FORM_INPUT_TEL:
                 case NS_FORM_INPUT_URL:
                 case NS_FORM_INPUT_NUMBER:
+                case NS_FORM_INPUT_DATE:
                     nodeAsInput->GetValue(valueStr);
                     // Avoid superfluous value="" serialization
                     if (valueStr.IsEmpty())
                       outElt->RemoveAttribute(valueAttr);
                     else
                       outElt->SetAttribute(valueAttr, valueStr);
                     break;
                 case NS_FORM_INPUT_CHECKBOX:
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -3427,16 +3427,18 @@ nsCSSFrameConstructor::FindInputData(Ele
     SIMPLE_INT_CREATE(NS_FORM_INPUT_EMAIL, NS_NewTextControlFrame),
     SIMPLE_INT_CREATE(NS_FORM_INPUT_SEARCH, NS_NewTextControlFrame),
     SIMPLE_INT_CREATE(NS_FORM_INPUT_TEXT, NS_NewTextControlFrame),
     SIMPLE_INT_CREATE(NS_FORM_INPUT_TEL, NS_NewTextControlFrame),
     SIMPLE_INT_CREATE(NS_FORM_INPUT_URL, NS_NewTextControlFrame),
     SIMPLE_INT_CREATE(NS_FORM_INPUT_PASSWORD, NS_NewTextControlFrame),
     // TODO: this is temporary until a frame is written: bug 635240.
     SIMPLE_INT_CREATE(NS_FORM_INPUT_NUMBER, NS_NewTextControlFrame),
+    // TODO: this is temporary until a frame is written: bug 773205.
+    SIMPLE_INT_CREATE(NS_FORM_INPUT_DATE, 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/toolkit/components/satchel/test/test_form_autocomplete.html
+++ b/toolkit/components/satchel/test/test_form_autocomplete.html
@@ -87,16 +87,22 @@ Form History test: form field autocomple
   </form>
 
   <!-- normal, basic form (with fieldname='searchbar-history') -->
   <form id="form13" onsubmit="return false;">
     <input  type="text" name="searchbar-history">
     <button type="submit">Submit</button>
   </form>
 
+  <!-- form with input type='date' -->
+  <form id="form14" onsubmit="return false;">
+    <input  type="date" name="field11">
+    <button type="submit">Submit</button>
+  </form>
+
 </div>
 
 <pre id="test">
 <script class="testbody" type="text/javascript">
 
 /** Test for Form History autocomplete **/
 
 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
@@ -129,20 +135,21 @@ fh.addEntry("field5", "1");
 fh.addEntry("field5", "12");
 fh.addEntry("field5", "123");
 fh.addEntry("field5", "1234");
 fh.addEntry("field6", "value");
 fh.addEntry("field7", "value");
 fh.addEntry("field8", "value");
 fh.addEntry("field9", "value");
 fh.addEntry("field10", "42");
+fh.addEntry("field11", "2010-10-10");
 fh.addEntry("searchbar-history", "blacklist test");
 
 // All these non-implemeted types might need autocomplete tests in the future.
-var todoTypes = [ "datetime", "date", "month", "week", "time", "datetime-local",
+var todoTypes = [ "datetime", "month", "week", "time", "datetime-local",
                   "range", "color" ];
 var todoInput = document.createElement("input");
 for (var type of todoTypes) {
   todoInput.type = type;
   todo_is(todoInput.type, type, type + " type shouldn't be implemented");
 }
 
 
@@ -725,16 +732,27 @@ function runTest(testNum) {
         break;
 
     case 404:
         checkMenuEntries(["42"]);
         doKey("down");
         doKey("return");
         checkForm("42");
 
+        input = $_(14, "field11");
+        restoreForm();
+        doKey("down");
+        break;
+
+    case 405:
+        checkMenuEntries(["2010-10-10"]);
+        doKey("down");
+        doKey("return");
+        checkForm("2010-10-10");
+
         // Go to test 500.
         fh.addEntry("field1", "value1");
         input = $_(1, "field1");
         testNum = 499;
 
         restoreForm();
         doKey("down");
         break;