Bug 787095 - Update formMethod and formEnctype reflection to have the empty string as default value and correct invalid values. r=mounir
authorBenedict Singer <singerb.dev@gmail.com>
Tue, 22 Jan 2013 20:35:57 -0500
changeset 119609 840023db4d12346523c5f67c931154eeca917b15
parent 119608 73c201cb091268ab56797cec3216bf6117a53c38
child 119610 55b63d585275e5e09725481f672ce7ef7079d471
push id24208
push userryanvm@gmail.com
push dateWed, 23 Jan 2013 16:13:14 +0000
treeherdermozilla-central@35e0c12f4332 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmounir
bugs787095
milestone21.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 787095 - Update formMethod and formEnctype reflection to have the empty string as default value and correct invalid values. r=mounir
content/html/content/src/nsGenericHTMLElement.cpp
content/html/content/src/nsGenericHTMLElement.h
content/html/content/src/nsHTMLInputElement.cpp
content/html/content/test/forms/test_input_attributes_reflection.html
content/html/content/test/reflect.js
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -2023,24 +2023,39 @@ nsGenericHTMLElement::GetURIListAttr(nsI
   return NS_OK;
 }
 
 void
 nsGenericHTMLElement::GetEnumAttr(nsIAtom* aAttr,
                                   const char* aDefault,
                                   nsAString& aResult) const
 {
+  GetEnumAttr(aAttr, aDefault, aDefault, aResult);
+}
+
+void
+nsGenericHTMLElement::GetEnumAttr(nsIAtom* aAttr,
+                                  const char* aDefaultMissing,
+                                  const char* aDefaultInvalid,
+                                  nsAString& aResult) const
+{
   const nsAttrValue* attrVal = mAttrsAndChildren.GetAttr(aAttr);
 
   aResult.Truncate();
 
-  if (attrVal && attrVal->Type() == nsAttrValue::eEnum) {
-    attrVal->GetEnumString(aResult, true);
-  } else if (aDefault) {
-    AppendASCIItoUTF16(nsDependentCString(aDefault), aResult);
+  if (!attrVal) {
+    if (aDefaultMissing) {
+      AppendASCIItoUTF16(nsDependentCString(aDefaultMissing), aResult);
+    }
+  } else {
+    if (attrVal->Type() == nsAttrValue::eEnum) {
+      attrVal->GetEnumString(aResult, true);
+    } else if (aDefaultInvalid) {
+      AppendASCIItoUTF16(nsDependentCString(aDefaultInvalid), aResult);
+    }
   }
 }
 
 nsHTMLMenuElement*
 nsGenericHTMLElement::GetContextMenu() const
 {
   nsAutoString value;
   GetHTMLAttr(nsGkAtoms::contextmenu, value);
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -916,16 +916,32 @@ protected:
    * @param aDefault  the default value if the attribute is missing or invalid.
    * @param aResult   string corresponding to the value [out].
    */
   NS_HIDDEN_(void) GetEnumAttr(nsIAtom* aAttr,
                                const char* aDefault,
                                nsAString& aResult) const;
 
   /**
+   * Helper method for NS_IMPL_ENUM_ATTR_DEFAULT_MISSING_INVALID_VALUES.
+   * Gets the enum value string of an attribute and using the default missing
+   * value if the attribute is missing or the default invalid value if the
+   * string is an invalid enum value.
+   *
+   * @param aType            the name of the attribute.
+   * @param aDefaultMissing  the default value if the attribute is missing.
+   * @param aDefaultInvalid  the default value if the attribute is invalid.
+   * @param aResult          string corresponding to the value [out].
+   */
+  NS_HIDDEN_(void) GetEnumAttr(nsIAtom* aAttr,
+                               const char* aDefaultMissing,
+                               const char* aDefaultInvalid,
+                               nsAString& aResult) const;
+
+  /**
    * Locates the nsIEditor associated with this node.  In general this is
    * equivalent to GetEditorInternal(), but for designmode or contenteditable,
    * this may need to get an editor that's not actually on this element's
    * associated TextControlFrame.  This is used by the spellchecking routines
    * to get the editor affected by changing the spellcheck attribute on this
    * node.
    */
   virtual already_AddRefed<nsIEditor> GetAssociatedEditor();
@@ -1361,16 +1377,35 @@ protected:
   }                                                                       \
   NS_IMETHODIMP                                                           \
   _class::Set##_method(const nsAString& aValue)                           \
   {                                                                       \
     return SetAttrHelper(nsGkAtoms::_atom, aValue);                       \
   }
 
 /**
+ * A macro to implement the getter and setter for a given content
+ * property that needs to set an enumerated string that has different
+ * default values for missing and invalid values. The method uses a
+ * specific GetEnumAttr and the generic SetAttrHelper methods.
+ */
+#define NS_IMPL_ENUM_ATTR_DEFAULT_MISSING_INVALID_VALUES(_class, _method, _atom, _defaultMissing, _defaultInvalid) \
+  NS_IMETHODIMP                                                                                   \
+  _class::Get##_method(nsAString& aValue)                                                         \
+  {                                                                                               \
+    GetEnumAttr(nsGkAtoms::_atom, _defaultMissing, _defaultInvalid, aValue);                      \
+    return NS_OK;                                                                                 \
+  }                                                                                               \
+  NS_IMETHODIMP                                                                                   \
+  _class::Set##_method(const nsAString& aValue)                                                   \
+  {                                                                                               \
+    return SetAttrHelper(nsGkAtoms::_atom, aValue);                                               \
+  }
+
+/**
  * QueryInterface() implementation helper macros
  */
 
 #define NS_HTML_CONTENT_INTERFACE_TABLE_AMBIGUOUS_BEGIN(_class, _base)        \
   NS_NODE_OFFSET_AND_INTERFACE_TABLE_BEGIN(_class)                            \
     NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsIDOMNode, _base)             \
     NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsIDOMElement, _base)          \
     NS_INTERFACE_TABLE_ENTRY_AMBIGUOUS(_class, nsIDOMHTMLElement, _base)
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -911,20 +911,20 @@ NS_IMPL_STRING_ATTR(nsHTMLInputElement, 
 NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLInputElement, Autocomplete, autocomplete,
                                 kInputDefaultAutocomplete->tag)
 NS_IMPL_BOOL_ATTR(nsHTMLInputElement, Autofocus, autofocus)
 //NS_IMPL_BOOL_ATTR(nsHTMLInputElement, Checked, checked)
 NS_IMPL_BOOL_ATTR(nsHTMLInputElement, Disabled, disabled)
 NS_IMPL_STRING_ATTR(nsHTMLInputElement, Max, max)
 NS_IMPL_STRING_ATTR(nsHTMLInputElement, Min, min)
 NS_IMPL_ACTION_ATTR(nsHTMLInputElement, FormAction, formaction)
-NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLInputElement, FormEnctype, formenctype,
-                                kFormDefaultEnctype->tag)
-NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLInputElement, FormMethod, formmethod,
-                                kFormDefaultMethod->tag)
+NS_IMPL_ENUM_ATTR_DEFAULT_MISSING_INVALID_VALUES(nsHTMLInputElement, FormEnctype, formenctype,
+                                                 "", kFormDefaultEnctype->tag)
+NS_IMPL_ENUM_ATTR_DEFAULT_MISSING_INVALID_VALUES(nsHTMLInputElement, FormMethod, formmethod,
+                                                 "", kFormDefaultMethod->tag)
 NS_IMPL_BOOL_ATTR(nsHTMLInputElement, FormNoValidate, formnovalidate)
 NS_IMPL_STRING_ATTR(nsHTMLInputElement, FormTarget, formtarget)
 NS_IMPL_ENUM_ATTR_DEFAULT_VALUE(nsHTMLInputElement, Inputmode, inputmode,
                                 kInputDefaultInputmode->tag)
 NS_IMPL_BOOL_ATTR(nsHTMLInputElement, Multiple, multiple)
 NS_IMPL_NON_NEGATIVE_INT_ATTR(nsHTMLInputElement, MaxLength, maxlength)
 NS_IMPL_STRING_ATTR(nsHTMLInputElement, Name, name)
 NS_IMPL_BOOL_ATTR(nsHTMLInputElement, ReadOnly, readonly)
--- a/content/html/content/test/forms/test_input_attributes_reflection.html
+++ b/content/html/content/test/forms/test_input_attributes_reflection.html
@@ -71,26 +71,26 @@ reflectBoolean({
 
 // .formEnctype
 reflectLimitedEnumerated({
   element: document.createElement("input"),
   attribute: "formEnctype",
   validValues: [ "application/x-www-form-urlencoded", "multipart/form-data",
                  "text/plain" ],
   invalidValues: [ "", "foo", "tulip", "multipart/foo" ],
-  defaultValue: "application/x-www-form-urlencoded"
+  defaultValue: { invalid: "application/x-www-form-urlencoded", missing: "" }
 });
 
 // .formMethod
 reflectLimitedEnumerated({
   element: document.createElement("input"),
   attribute: "formMethod",
   validValues: [ "get", "post" ],
   invalidValues: [ "", "foo", "tulip" ],
-  defaultValue: "get"
+  defaultValue: { invalid: "get", missing: "" }
 });
 
 // .formNoValidate
 reflectBoolean({
   element: document.createElement("input"),
   attribute: "formNoValidate",
 });
 
--- a/content/html/content/test/reflect.js
+++ b/content/html/content/test/reflect.js
@@ -238,46 +238,54 @@ function reflectUnsignedInt(aParameters)
     is(element[attr], 0, "." + attr + " should be equals to 0");
   }
 }
 
 /**
  * Checks that a given attribute is correctly reflected as limited to known
  * values enumerated attribute.
  *
- * @param aParameters    Object    object containing the parameters, which are:
- *  - element            Element   node to test on
- *  - attribute          String    name of the attribute
+ * @param aParameters     Object   object containing the parameters, which are:
+ *  - element             Element  node to test on
+ *  - attribute           String   name of the attribute
  *     OR
- *    attribute          Object    object containing two attributes, 'content' and 'idl'
- *  - validValues        Array     valid values we support
- *  - invalidValues      Array     invalid values
- *  - defaultValue       String    [optional] default value when no valid value is set
- *  - unsupportedValues  Array     [optional] valid values we do not support
+ *    attribute           Object   object containing two attributes, 'content' and 'idl'
+ *  - validValues         Array    valid values we support
+ *  - invalidValues       Array    invalid values
+ *  - defaultValue        String   [optional] default value when no valid value is set
+ *     OR
+ *    defaultValue        Object   [optional] object containing two attributes, 'invalid' and 'missing'
+ *  - unsupportedValues   Array    [optional] valid values we do not support
  */
 function reflectLimitedEnumerated(aParameters)
 {
   var element = aParameters.element;
   var contentAttr = typeof aParameters.attribute === "string"
                       ? aParameters.attribute : aParameters.attribute.content;
   var idlAttr = typeof aParameters.attribute === "string"
                   ? aParameters.attribute : aParameters.attribute.idl;
   var validValues = aParameters.validValues;
   var invalidValues = aParameters.invalidValues;
   var defaultValue = aParameters.defaultValue !== undefined
                        ? aParameters.defaultValue : "";
+  var defaultValueInvalid = aParameters.defaultValue === undefined
+                               ? "" : typeof aParameters.defaultValue === "string"
+                                   ? aParameters.defaultValue : aParameters.defaultValue.invalid
+  var defaultValueMissing = aParameters.defaultValue === undefined
+                                ? "" : typeof aParameters.defaultValue === "string"
+                                    ? aParameters.defaultValue : aParameters.defaultValue.missing
   var unsupportedValues = aParameters.unsupportedValues !== undefined
                             ? aParameters.unsupportedValues : [];
 
   ok(idlAttr in element, idlAttr + " should be an IDL attribute of this element");
   is(typeof element[idlAttr], "string", idlAttr + " IDL attribute should be a string");
 
   // Explicitly check the default value.
   element.removeAttribute(contentAttr);
-  is(element[idlAttr], defaultValue,
+  is(element[idlAttr], defaultValueMissing,
      "When no attribute is set, the value should be the default value.");
 
   // Check valid values.
   validValues.forEach(function (v) {
     element.setAttribute(contentAttr, v);
     is(element[idlAttr], v,
        v + " should be accepted as a valid value for " + idlAttr);
     is(element.getAttribute(contentAttr), v,
@@ -304,24 +312,24 @@ function reflectLimitedEnumerated(aParam
     is(element.getAttribute(contentAttr), v.toUpperCase(),
        "Content attribute should not be lower-cased.");
     element.removeAttribute(contentAttr);
   });
 
   // Check invalid values.
   invalidValues.forEach(function (v) {
     element.setAttribute(contentAttr, v);
-    is(element[idlAttr], defaultValue,
+    is(element[idlAttr], defaultValueInvalid,
        "When the content attribute is set to an invalid value, the default value should be returned.");
     is(element.getAttribute(contentAttr), v,
        "Content attribute should not have been changed.");
     element.removeAttribute(contentAttr);
 
     element[idlAttr] = v;
-    is(element[idlAttr], defaultValue,
+    is(element[idlAttr], defaultValueInvalid,
        "When the value is set to an invalid value, the default value should be returned.");
     is(element.getAttribute(contentAttr), v,
        "Content attribute should not have been changed.");
     element.removeAttribute(contentAttr);
   });
 
   // Check valid values we currently do not support.
   // Basically, it's like the checks for the valid values but with some todo's.