Bug 657938 (1/2) - Implement the content part of the meter element. f=mounir r=smaug,mrbkap
authorLaurent Dulary <dularylaurent@gmail.com>
Wed, 16 May 2012 13:18:33 +0200
changeset 100738 203c7622721176fbcf5e2fe004344a9d36acedb3
parent 100737 a6c39a15557befac8ce98359ee6c0789c7e80a1d
child 100739 9822d3931e312ccca4c45b75a9c7fd2a9eb00d75
push id1316
push userakeybl@mozilla.com
push dateMon, 27 Aug 2012 22:37:00 +0000
treeherdermozilla-beta@db4b09302ee2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, mrbkap
bugs657938
milestone16.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 657938 (1/2) - Implement the content part of the meter element. f=mounir r=smaug,mrbkap
content/html/content/public/nsIFormControl.h
content/html/content/src/Makefile.in
content/html/content/src/nsGenericHTMLElement.cpp
content/html/content/src/nsGenericHTMLElement.h
content/html/content/src/nsHTMLFieldSetElement.cpp
content/html/content/src/nsHTMLFormElement.cpp
content/html/content/src/nsHTMLMeterElement.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/interfaces/html/Makefile.in
dom/interfaces/html/nsIDOMHTMLMeterElement.idl
editor/libeditor/base/nsEditPropertyAtomList.h
editor/libeditor/html/nsHTMLEditUtils.cpp
js/xpconnect/src/dom_quickstubs.qsconf
parser/htmlparser/public/nsHTMLTagList.h
parser/htmlparser/src/nsElementTable.cpp
parser/htmlparser/src/nsHTMLTags.cpp
--- a/content/html/content/public/nsIFormControl.h
+++ b/content/html/content/public/nsIFormControl.h
@@ -21,16 +21,17 @@ class Element;
 
 enum FormControlsTypes {
   NS_FORM_FIELDSET = 1,
   NS_FORM_LABEL,
   NS_FORM_OUTPUT,
   NS_FORM_SELECT,
   NS_FORM_TEXTAREA,
   NS_FORM_OBJECT,
+  NS_FORM_METER,
   eFormControlsWithoutSubTypesMax,
   // After this, all types will have sub-types which introduce new enum lists.
   // eFormControlsWithoutSubTypesMax let us know if the previous types values
   // are not overlapping with sub-types/masks.
 
   // Elements with different types, the value is used as a mask.
   // Adding '_ELEMENT' because NS_FORM_INPUT is used for 'oninput' event.
   // When changing the order, adding or removing elements, be sure to update
@@ -238,23 +239,22 @@ nsIFormControl::IsSingleLineTextControl(
          aType == NS_FORM_INPUT_URL ||
          (!aExcludePassword && aType == NS_FORM_INPUT_PASSWORD);
 }
 
 bool
 nsIFormControl::IsLabelableControl() const
 {
   // TODO: keygen should be in that list, see bug 101019.
-  // TODO: meter should be added, see bug 555985.
   // TODO: NS_FORM_INPUT_HIDDEN should be removed, see bug 597650.
   PRUint32 type = GetType();
   return type & NS_FORM_INPUT_ELEMENT ||
          type & NS_FORM_BUTTON_ELEMENT ||
          // type == NS_FORM_KEYGEN ||
-         // type == NS_FORM_METER ||
+         type == NS_FORM_METER ||
          type == NS_FORM_OUTPUT ||
          type == NS_FORM_SELECT ||
          type == NS_FORM_TEXTAREA;
 }
 
 bool
 nsIFormControl::IsSubmittableControl() const
 {
--- a/content/html/content/src/Makefile.in
+++ b/content/html/content/src/Makefile.in
@@ -53,16 +53,17 @@ CPPSRCS		= \
 		nsHTMLLIElement.cpp \
 		nsHTMLLabelElement.cpp \
 		nsHTMLLegendElement.cpp \
 		nsHTMLLinkElement.cpp \
 		nsHTMLMapElement.cpp \
 		nsHTMLMenuElement.cpp \
 		nsHTMLMenuItemElement.cpp \
 		nsHTMLMetaElement.cpp \
+		nsHTMLMeterElement.cpp \
 		nsHTMLModElement.cpp \
 		nsHTMLObjectElement.cpp \
 		nsHTMLOListElement.cpp \
 		nsHTMLSharedObjectElement.cpp \
 		nsHTMLOptionElement.cpp \
 		nsHTMLOptGroupElement.cpp \
 		nsHTMLOutputElement.cpp \
 		nsHTMLParagraphElement.cpp \
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -3461,17 +3461,18 @@ nsGenericHTMLFormElement::ForgetFieldSet
 bool
 nsGenericHTMLFormElement::CanBeDisabled() const
 {
   PRInt32 type = GetType();
   // It's easier to test the types that _cannot_ be disabled
   return
     type != NS_FORM_LABEL &&
     type != NS_FORM_OBJECT &&
-    type != NS_FORM_OUTPUT;
+    type != NS_FORM_OUTPUT &&
+    type != NS_FORM_METER;
 }
 
 bool
 nsGenericHTMLFormElement::IsHTMLFocusable(bool aWithMouse,
                                           bool* aIsFocusable,
                                           PRInt32* aTabIndex)
 {
   if (nsGenericHTMLElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex)) {
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -1539,16 +1539,17 @@ NS_DECLARE_NS_NEW_HTML_ELEMENT(Input)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(LI)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Label)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Legend)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Link)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Map)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Menu)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(MenuItem)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Meta)
+NS_DECLARE_NS_NEW_HTML_ELEMENT(Meter)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Object)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(OptGroup)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Option)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Output)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Paragraph)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Pre)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Progress)
 NS_DECLARE_NS_NEW_HTML_ELEMENT(Script)
--- a/content/html/content/src/nsHTMLFieldSetElement.cpp
+++ b/content/html/content/src/nsHTMLFieldSetElement.cpp
@@ -123,17 +123,18 @@ nsHTMLFieldSetElement::GetType(nsAString
 }
 
 /* static */
 bool
 nsHTMLFieldSetElement::MatchListedElements(nsIContent* aContent, PRInt32 aNamespaceID,
                                            nsIAtom* aAtom, void* aData)
 {
   nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(aContent);
-  return formControl && formControl->GetType() != NS_FORM_LABEL;
+  return formControl && formControl->GetType() != NS_FORM_LABEL &&
+                        formControl->GetType() != NS_FORM_METER;
 }
 
 NS_IMETHODIMP
 nsHTMLFieldSetElement::GetElements(nsIDOMHTMLCollection** aElements)
 {
   if (!mElements) {
     mElements = new nsContentList(this, MatchListedElements, nsnull, nsnull,
                                   true);
--- a/content/html/content/src/nsHTMLFormElement.cpp
+++ b/content/html/content/src/nsHTMLFormElement.cpp
@@ -186,16 +186,17 @@ ShouldBeInElements(nsIFormControl* aForm
     return true;
   }
 
   // These form control types are not supposed to end up in the
   // form.elements array
   //
   // NS_FORM_INPUT_IMAGE
   // NS_FORM_LABEL
+  // NS_FORM_METER
 
   return false;
 }
 
 // nsHTMLFormElement implementation
 
 // construction, destruction
 nsGenericHTMLElement*
new file mode 100644
--- /dev/null
+++ b/content/html/content/src/nsHTMLMeterElement.cpp
@@ -0,0 +1,379 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Mounir Lamouri <mounir.lamouri@mozilla.com> (original author)
+ *   Vincent Lamotte <Vincent.Lamotte@ensimag.imag.fr>
+ *   Laurent Dulary <Laurent.Dulary@ensimag.imag.fr>
+ *   Yoan Teboul <Yoan.Teboul@ensimag.imag.fr>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+ 
+#include "nsIDOMHTMLMeterElement.h"
+#include "nsGenericHTMLElement.h"
+#include "nsAttrValue.h"
+#include "nsEventStateManager.h"
+#include "nsAlgorithm.h"
+
+
+class nsHTMLMeterElement : public nsGenericHTMLFormElement,
+                           public nsIDOMHTMLMeterElement
+{
+public:
+  nsHTMLMeterElement(already_AddRefed<nsINodeInfo> aNodeInfo);
+  virtual ~nsHTMLMeterElement();
+
+  /* nsISupports */
+  NS_DECL_ISUPPORTS_INHERITED
+
+  /* nsIDOMNode */
+  NS_FORWARD_NSIDOMNODE(nsGenericHTMLFormElement::)
+
+  /* nsIDOMElement */
+  NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLFormElement::)
+
+  /* nsIDOMHTMLElement */
+  NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLFormElement::)
+
+  /* nsIDOMHTMLMeterElement */
+  NS_DECL_NSIDOMHTMLMETERELEMENT
+
+  /* nsIFormControl */
+  NS_IMETHOD_(PRUint32) GetType() const { return NS_FORM_METER; }
+  NS_IMETHOD Reset();
+  NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission);
+
+  nsresult Clone(nsINodeInfo* aNodeInfo, nsINode** aResult) const;
+
+  bool ParseAttribute(PRInt32 aNamespaceID, nsIAtom* aAttribute,
+                      const nsAString& aValue, nsAttrValue& aResult);
+
+  virtual nsXPCClassInfo* GetClassInfo();
+
+  virtual nsIDOMNode* AsDOMNode() { return this; }
+
+protected:
+
+  static const double kDefaultValue;
+  static const double kDefaultMin;
+  static const double kDefaultMax;
+};
+
+const double nsHTMLMeterElement::kDefaultValue =  0.0;
+const double nsHTMLMeterElement::kDefaultMin   =  0.0;
+const double nsHTMLMeterElement::kDefaultMax   =  1.0;
+
+NS_IMPL_NS_NEW_HTML_ELEMENT(Meter)
+
+
+nsHTMLMeterElement::nsHTMLMeterElement(already_AddRefed<nsINodeInfo> aNodeInfo)
+  : nsGenericHTMLFormElement(aNodeInfo)
+{
+}
+
+nsHTMLMeterElement::~nsHTMLMeterElement()
+{
+}
+
+NS_IMPL_ADDREF_INHERITED(nsHTMLMeterElement, nsGenericElement)
+NS_IMPL_RELEASE_INHERITED(nsHTMLMeterElement, nsGenericElement)
+
+DOMCI_NODE_DATA(HTMLMeterElement, nsHTMLMeterElement)
+
+NS_INTERFACE_TABLE_HEAD(nsHTMLMeterElement)
+  NS_HTML_CONTENT_INTERFACE_TABLE1(nsHTMLMeterElement,
+                                   nsIDOMHTMLMeterElement)
+  NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLMeterElement,
+                                               nsGenericHTMLFormElement)
+NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLMeterElement)
+
+NS_IMPL_ELEMENT_CLONE(nsHTMLMeterElement)
+
+
+NS_IMETHODIMP
+nsHTMLMeterElement::Reset()
+{
+  /* The meter element is not resettable. */
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHTMLMeterElement::SubmitNamesValues(nsFormSubmission* aFormSubmission)
+{
+  /* The meter element is not submittable. */
+  return NS_OK;
+}
+
+bool
+nsHTMLMeterElement::ParseAttribute(PRInt32 aNamespaceID, nsIAtom* aAttribute,
+                                 const nsAString& aValue, nsAttrValue& aResult)
+{
+  if (aNamespaceID == kNameSpaceID_None) {
+    if (aAttribute == nsGkAtoms::value || aAttribute == nsGkAtoms::max ||
+        aAttribute == nsGkAtoms::min   || aAttribute == nsGkAtoms::low ||
+        aAttribute == nsGkAtoms::high  || aAttribute == nsGkAtoms::optimum) {
+      return aResult.ParseDoubleValue(aValue);
+    }
+  }
+
+  return nsGenericHTMLFormElement::ParseAttribute(aNamespaceID, aAttribute,
+                                                  aValue, aResult);
+}
+
+NS_IMETHODIMP
+nsHTMLMeterElement::GetForm(nsIDOMHTMLFormElement** aForm)
+{
+  return nsGenericHTMLFormElement::GetForm(aForm);
+}
+
+NS_IMETHODIMP
+nsHTMLMeterElement::GetMin(double* aValue)
+{
+  /**
+   * If the attribute min is defined, the minimum is this value.
+   * Otherwise, the minimum is the default value.
+   */
+  const nsAttrValue* attrMin = mAttrsAndChildren.GetAttr(nsGkAtoms::min);
+  if (attrMin && attrMin->Type() == nsAttrValue::eDoubleValue) {
+    *aValue = attrMin->GetDoubleValue();
+    return NS_OK;
+  }
+
+  *aValue = kDefaultMin;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHTMLMeterElement::SetMin(double aValue)
+{
+  return SetDoubleAttr(nsGkAtoms::min, aValue);
+}
+
+NS_IMETHODIMP
+nsHTMLMeterElement::GetMax(double* aValue)
+{
+  /**
+   * If the attribute max is defined, the maximum is this value.
+   * Otherwise, the maximum is the default value.
+   * If the maximum value is less than the minimum value,
+   * the maximum value is the same as the minimum value.
+   */
+  const nsAttrValue* attrMax = mAttrsAndChildren.GetAttr(nsGkAtoms::max);
+  if (attrMax && attrMax->Type() == nsAttrValue::eDoubleValue) {
+    *aValue = attrMax->GetDoubleValue();
+  } else {
+    *aValue = kDefaultMax;
+  }
+
+  double min;
+  GetMin(&min);
+
+  *aValue = NS_MAX(*aValue, min);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHTMLMeterElement::SetMax(double aValue)
+{
+  return SetDoubleAttr(nsGkAtoms::max, aValue);
+}
+
+NS_IMETHODIMP
+nsHTMLMeterElement::GetValue(double* aValue)
+{
+  /**
+   * If the attribute value is defined, the actual value is this value.
+   * Otherwise, the actual value is the default value.
+   * If the actual value is less than the minimum value,
+   * the actual value is the same as the minimum value.
+   * If the actual value is greater than the maximum value,
+   * the actual value is the same as the maximum value.
+   */
+  const nsAttrValue* attrValue = mAttrsAndChildren.GetAttr(nsGkAtoms::value);
+  if (attrValue && attrValue->Type() == nsAttrValue::eDoubleValue) {
+    *aValue = attrValue->GetDoubleValue();
+  } else {
+    *aValue = kDefaultValue;
+  }
+
+  double min;
+  GetMin(&min);
+
+  if (*aValue <= min) {
+    *aValue = min;
+    return NS_OK;
+  }
+
+  double max;
+  GetMax(&max);
+
+  *aValue = NS_MIN(*aValue, max);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHTMLMeterElement::SetValue(double aValue)
+{
+  return SetDoubleAttr(nsGkAtoms::value, aValue);
+}
+
+NS_IMETHODIMP
+nsHTMLMeterElement::GetLow(double* aValue)
+{
+  /**
+   * If the low value is defined, the low value is this value.
+   * Otherwise, the low value is the minimum value.
+   * If the low value is less than the minimum value,
+   * the low value is the same as the minimum value.
+   * If the low value is greater than the maximum value,
+   * the low value is the same as the maximum value.
+   */
+
+  double min;
+  GetMin(&min);
+
+  const nsAttrValue* attrLow = mAttrsAndChildren.GetAttr(nsGkAtoms::low);
+  if (!attrLow || attrLow->Type() != nsAttrValue::eDoubleValue) {
+    *aValue = min;
+    return NS_OK;
+  }
+
+  *aValue = attrLow->GetDoubleValue();
+
+  if (*aValue <= min) {
+    *aValue = min;
+    return NS_OK;
+  }
+
+  double max;
+  GetMax(&max);
+
+  *aValue = NS_MIN(*aValue, max);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHTMLMeterElement::SetLow(double aValue)
+{
+  return SetDoubleAttr(nsGkAtoms::low, aValue);
+}
+
+NS_IMETHODIMP
+nsHTMLMeterElement::GetHigh(double* aValue)
+{
+  /**
+   * If the high value is defined, the high value is this value.
+   * Otherwise, the high value is the maximum value.
+   * If the high value is less than the low value,
+   * the high value is the same as the low value.
+   * If the high value is greater than the maximum value,
+   * the high value is the same as the maximum value.
+   */
+
+  double max;
+  GetMax(&max);
+
+  const nsAttrValue* attrHigh = mAttrsAndChildren.GetAttr(nsGkAtoms::high);
+  if (!attrHigh || attrHigh->Type() != nsAttrValue::eDoubleValue) {
+    *aValue = max;
+    return NS_OK;
+  }
+
+  *aValue = attrHigh->GetDoubleValue();
+
+  if (*aValue >= max) {
+    *aValue = max;
+    return NS_OK;
+  }
+
+  double low;
+  GetLow(&low);
+
+  *aValue = NS_MAX(*aValue, low);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHTMLMeterElement::SetHigh(double aValue)
+{
+  return SetDoubleAttr(nsGkAtoms::high, aValue);
+}
+
+NS_IMETHODIMP
+nsHTMLMeterElement::GetOptimum(double* aValue)
+{
+  /**
+   * If the optimum value is defined, the optimum value is this value.
+   * Otherwise, the optimum value is the midpoint between
+   * the minimum value and the maximum value :
+   * min + (max - min)/2 = (min + max)/2
+   * If the optimum value is less than the minimum value,
+   * the optimum value is the same as the minimum value.
+   * If the optimum value is greater than the maximum value,
+   * the optimum value is the same as the maximum value.
+   */
+
+  double max;
+  GetMax(&max);
+
+  double min;
+  GetMin(&min);
+
+  const nsAttrValue* attrOptimum =
+              mAttrsAndChildren.GetAttr(nsGkAtoms::optimum);
+  if (!attrOptimum || attrOptimum->Type() != nsAttrValue::eDoubleValue) {
+    *aValue = (min + max) / 2.0;
+    return NS_OK;
+  }
+
+  *aValue = attrOptimum->GetDoubleValue();
+
+  if (*aValue <= min) {
+    *aValue = min;
+    return NS_OK;
+  }
+
+  *aValue = NS_MIN(*aValue, max);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsHTMLMeterElement::SetOptimum(double aValue)
+{
+  return SetDoubleAttr(nsGkAtoms::optimum, aValue);
+}
+
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -243,16 +243,17 @@
 #include "nsIDOMHTMLLIElement.h"
 #include "nsIDOMHTMLLabelElement.h"
 #include "nsIDOMHTMLLegendElement.h"
 #include "nsIDOMHTMLLinkElement.h"
 #include "nsIDOMHTMLMapElement.h"
 #include "nsIDOMHTMLMenuElement.h"
 #include "nsIDOMHTMLMenuItemElement.h"
 #include "nsIDOMHTMLMetaElement.h"
+#include "nsIDOMHTMLMeterElement.h"
 #include "nsIDOMHTMLModElement.h"
 #include "nsIDOMHTMLOListElement.h"
 #include "nsIDOMHTMLObjectElement.h"
 #include "nsIDOMHTMLOptGroupElement.h"
 #include "nsIDOMHTMLOutputElement.h"
 #include "nsIDOMHTMLParagraphElement.h"
 #include "nsIDOMHTMLParamElement.h"
 #include "nsIDOMHTMLPreElement.h"
@@ -900,16 +901,18 @@ static nsDOMClassInfoData sClassInfoData
   NS_DEFINE_CLASSINFO_DATA(HTMLMapElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLMenuElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLMenuItemElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLMetaElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
+  NS_DEFINE_CLASSINFO_DATA(HTMLMeterElement, nsElementSH,
+                           ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLModElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLOListElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLObjectElement, nsHTMLPluginObjElementSH,
                            EXTERNAL_OBJ_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLOptGroupElement, nsElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
@@ -2913,16 +2916,21 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLMetaElement, nsIDOMHTMLMetaElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLMetaElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
+  DOM_CLASSINFO_MAP_BEGIN(HTMLMeterElement, nsIDOMHTMLMeterElement)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLMeterElement)
+    DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
+  DOM_CLASSINFO_MAP_END
+
   DOM_CLASSINFO_MAP_BEGIN(HTMLModElement, nsIDOMHTMLModElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLModElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(HTMLOListElement, nsIDOMHTMLOListElement)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLOListElement)
     DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -90,16 +90,17 @@ DOMCI_CLASS(HTMLInputElement)
 DOMCI_CLASS(HTMLLIElement)
 DOMCI_CLASS(HTMLLabelElement)
 DOMCI_CLASS(HTMLLegendElement)
 DOMCI_CLASS(HTMLLinkElement)
 DOMCI_CLASS(HTMLMapElement)
 DOMCI_CLASS(HTMLMenuElement)
 DOMCI_CLASS(HTMLMenuItemElement)
 DOMCI_CLASS(HTMLMetaElement)
+DOMCI_CLASS(HTMLMeterElement)
 DOMCI_CLASS(HTMLModElement)
 DOMCI_CLASS(HTMLOListElement)
 DOMCI_CLASS(HTMLObjectElement)
 DOMCI_CLASS(HTMLOptGroupElement)
 DOMCI_CLASS(HTMLOptionElement)
 DOMCI_CLASS(HTMLOutputElement)
 DOMCI_CLASS(HTMLParagraphElement)
 DOMCI_CLASS(HTMLParamElement)
--- a/dom/interfaces/html/Makefile.in
+++ b/dom/interfaces/html/Makefile.in
@@ -46,16 +46,17 @@ SDK_XPIDLSRCS =					\
 	nsIDOMHTMLLIElement.idl			\
 	nsIDOMHTMLLabelElement.idl		\
 	nsIDOMHTMLLegendElement.idl		\
 	nsIDOMHTMLLinkElement.idl		\
 	nsIDOMHTMLMapElement.idl		\
 	nsIDOMHTMLMenuElement.idl		\
 	nsIDOMHTMLMenuItemElement.idl		\
 	nsIDOMHTMLMetaElement.idl		\
+	nsIDOMHTMLMeterElement.idl		\
 	nsIDOMHTMLModElement.idl		\
 	nsIDOMHTMLOListElement.idl		\
 	nsIDOMHTMLObjectElement.idl		\
 	nsIDOMHTMLOptGroupElement.idl		\
 	nsIDOMHTMLOptionElement.idl		\
 	nsIDOMHTMLOptionsCollection.idl		\
 	nsIDOMHTMLOutputElement.idl		\
 	nsIDOMHTMLParagraphElement.idl		\
new file mode 100644
--- /dev/null
+++ b/dom/interfaces/html/nsIDOMHTMLMeterElement.idl
@@ -0,0 +1,64 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Vincent Lamotte <Vincent.Lamotte@ensimag.imag.fr>
+ *   Laurent Dulary <Laurent.Dulary@ensimag.imag.fr>
+ *   Yoan Teboul <Yoan.Teboul@ensimag.imag.fr>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsIDOMHTMLElement.idl"
+
+/**
+ * The nsIDOMHTMLMeterElement interface is the interface to a HTML
+ * <meter> element.
+ *
+ * For more information on this interface, please see
+ * http://www.whatwg.org/specs/web-apps/current-work/multipage/the-button-element.html#the-meter-element
+ */
+
+[scriptable, uuid(d4466510-8143-11e0-b278-0800200c9a66)]
+interface nsIDOMHTMLMeterElement : nsIDOMHTMLElement
+{
+           attribute double value;
+           attribute double min;
+           attribute double max;
+           attribute double low;
+           attribute double high;
+           attribute double optimum;
+  readonly attribute nsIDOMHTMLFormElement form;
+  /**
+   * The labels attribute will be done with bug 556743.
+   */
+  //readonly attribute NodeList labels;
+};
--- a/editor/libeditor/base/nsEditPropertyAtomList.h
+++ b/editor/libeditor/base/nsEditPropertyAtomList.h
@@ -109,16 +109,17 @@ EDITOR_ATOM(img, "img")
 EDITOR_ATOM(input, "input")
 EDITOR_ATOM(kbd, "kbd")
 EDITOR_ATOM(keygen, "keygen")
 EDITOR_ATOM(label, "label")
 EDITOR_ATOM(legend, "legend")
 EDITOR_ATOM(li, "li")
 EDITOR_ATOM(map, "map")
 EDITOR_ATOM(mark, "mark")
+EDITOR_ATOM(meter, "meter")
 EDITOR_ATOM(menuitem, "menuitem")
 EDITOR_ATOM(mozdirty, "_moz_dirty")
 EDITOR_ATOM(mozEditorBogusNode, "_moz_editor_bogus_node")
 EDITOR_ATOM(name, "name")
 EDITOR_ATOM(nav, "nav")
 EDITOR_ATOM(noscript, "noscript")
 EDITOR_ATOM(object, "object")
 EDITOR_ATOM(ol, "ol")
--- a/editor/libeditor/html/nsHTMLEditUtils.cpp
+++ b/editor/libeditor/html/nsHTMLEditUtils.cpp
@@ -461,16 +461,17 @@ nsHTMLEditUtils::IsFormWidget(dom::Eleme
   MOZ_ASSERT(node);
   nsCOMPtr<nsIAtom> nodeAtom = node->Tag();
   return (nodeAtom == nsEditProperty::textarea)
       || (nodeAtom == nsEditProperty::select)
       || (nodeAtom == nsEditProperty::button)
       || (nodeAtom == nsEditProperty::output)
       || (nodeAtom == nsEditProperty::keygen)
       || (nodeAtom == nsEditProperty::progress)
+      || (nodeAtom == nsEditProperty::meter)
       || (nodeAtom == nsEditProperty::input);
 }
 
 bool
 nsHTMLEditUtils::SupportsAlignAttr(nsIDOMNode * aNode)
 {
   NS_PRECONDITION(aNode, "null node passed to nsHTMLEditUtils::SupportsAlignAttr");
   nsCOMPtr<nsIAtom> nodeAtom = nsEditor::GetTag(aNode);
@@ -512,17 +513,17 @@ nsHTMLEditUtils::SupportsAlignAttr(nsIDO
 
 // b, big, i, s, small, strike, tt, u
 #define GROUP_FONTSTYLE        (1 << 3)
 
 // abbr, acronym, cite, code, datalist, del, dfn, em, ins, kbd, mark, samp,
 // strong, var
 #define GROUP_PHRASE           (1 << 4)
 
-// a, applet, basefont, bdo, br, font, iframe, img, map, object, output,
+// a, applet, basefont, bdo, br, font, iframe, img, map, meter, object, output,
 // progress, q, script, span, sub, sup
 #define GROUP_SPECIAL          (1 << 5)
 
 // button, form, input, label, select, textarea
 #define GROUP_FORMCONTROL      (1 << 6)
 
 // address, applet, article, aside, blockquote, button, center, del, dir, div,
 // dl, fieldset, figure, footer, form, h1, h2, h3, h4, h5, h6, header, hgroup,
@@ -690,16 +691,17 @@ static const nsElementInfo kElements[eHT
   ELEM(link, false, false, GROUP_HEAD_CONTENT, GROUP_NONE),
   ELEM(listing, false, false, GROUP_NONE, GROUP_NONE),
   ELEM(map, true, true, GROUP_SPECIAL, GROUP_BLOCK | GROUP_MAP_CONTENT),
   ELEM(mark, true, true, GROUP_PHRASE, GROUP_INLINE_ELEMENT),
   ELEM(marquee, false, false, GROUP_NONE, GROUP_NONE),
   ELEM(menu, true, true, GROUP_BLOCK, GROUP_LI | GROUP_FLOW_ELEMENT),
   ELEM(menuitem, false, false, GROUP_NONE, GROUP_NONE),
   ELEM(meta, false, false, GROUP_HEAD_CONTENT, GROUP_NONE),
+  ELEM(meter, true, false, GROUP_SPECIAL, GROUP_FLOW_ELEMENT),
   ELEM(multicol, false, false, GROUP_NONE, GROUP_NONE),
   ELEM(nav, true, true, GROUP_BLOCK, GROUP_FLOW_ELEMENT),
   ELEM(nobr, false, false, GROUP_NONE, GROUP_NONE),
   ELEM(noembed, false, false, GROUP_NONE, GROUP_NONE),
   ELEM(noframes, true, true, GROUP_BLOCK, GROUP_FLOW_ELEMENT),
   ELEM(noscript, true, true, GROUP_BLOCK, GROUP_FLOW_ELEMENT),
   ELEM(object, true, true, GROUP_SPECIAL | GROUP_BLOCK,
        GROUP_FLOW_ELEMENT | GROUP_OBJECT_CONTENT),
--- a/js/xpconnect/src/dom_quickstubs.qsconf
+++ b/js/xpconnect/src/dom_quickstubs.qsconf
@@ -277,16 +277,17 @@ members = [
     'nsIDOMHTMLInputElement.value',
     'nsIDOMHTMLInputElement.files',
     'nsIDOMHTMLInputElement.textLength',
     'nsIDOMHTMLInputElement.selectionStart',
     'nsIDOMHTMLInputElement.selectionEnd',
     'nsIDOMHTMLInputElement.selectionDirection',
     'nsIDOMHTMLInputElement.setSelectionRange',
     'nsIDOMHTMLLinkElement.disabled',
+    'nsIDOMHTMLMeterElement.*',
     'nsIDOMHTMLMenuElement.*',
     'nsIDOMHTMLMenuItemElement.*',
     'nsIDOMHTMLOptionElement.index',
     'nsIDOMHTMLOptionElement.selected',
     'nsIDOMHTMLOptionElement.form',
     'nsIDOMHTMLOptionElement.text',
     'nsIDOMHTMLOptionElement.defaultSelected',
     'nsIDOMHTMLOptionElement.value',
--- a/parser/htmlparser/public/nsHTMLTagList.h
+++ b/parser/htmlparser/public/nsHTMLTagList.h
@@ -105,16 +105,17 @@ HTML_TAG(li, LI)
 HTML_TAG(link, Link)
 HTML_HTMLELEMENT_TAG(listing)
 HTML_TAG(map, Map)
 HTML_HTMLELEMENT_TAG(mark)
 HTML_TAG(marquee, Div)
 HTML_TAG(menu, Menu)
 HTML_TAG(menuitem, MenuItem)
 HTML_TAG(meta, Meta)
+HTML_TAG(meter, Meter)
 HTML_TAG(multicol, Span)
 HTML_HTMLELEMENT_TAG(nav)
 HTML_HTMLELEMENT_TAG(nobr)
 HTML_HTMLELEMENT_TAG(noembed)
 HTML_HTMLELEMENT_TAG(noframes)
 HTML_HTMLELEMENT_TAG(noscript)
 HTML_TAG(object, Object)
 HTML_TAG(ol, SharedList)
--- a/parser/htmlparser/src/nsElementTable.cpp
+++ b/parser/htmlparser/src/nsElementTable.cpp
@@ -836,16 +836,25 @@ const nsHTMLElement gHTMLElements[] = {
     /*req-parent excl-parent*/          eHTMLTag_unknown,eHTMLTag_unknown,
     /*rootnodes,endrootnodes*/          &gInHead,&gInHead,
     /*autoclose starttags and endtags*/ 0,0,0,0,
     /*parent,incl,exclgroups*/          kHeadContent, kNone, kNone,
     /*special props, prop-range*/       kNoStyleLeaksIn|kNonContainer, kDefaultPropRange,
     /*special parents,kids*/            &gInHead,0,
   },
   {
+    /*tag*/                             eHTMLTag_meter,
+    /*req-parent excl-parent*/          eHTMLTag_unknown,eHTMLTag_unknown,
+    /*rootnodes,endrootnodes*/          &gRootTags,&gRootTags,
+    /*autoclose starttags and endtags*/ 0,0,0,0,
+    /*parent,incl,exclgroups*/          kFormControl, kFlowEntity, kNone,
+    /*special props, prop-range*/       0,kDefaultPropRange,
+    /*special parents,kids*/            0,0,
+  },
+  {
     /*tag*/                             eHTMLTag_multicol,
     /*req-parent excl-parent*/          eHTMLTag_unknown,eHTMLTag_unknown,
     /*rootnodes,endrootnodes*/          &gRootTags,&gRootTags,
     /*autoclose starttags and endtags*/ 0,0,0,0,
     /*parent,incl,exclgroups*/          kBlock, kFlowEntity, kNone,
     /*special props, prop-range*/       0,kDefaultPropRange,
     /*special parents,kids*/            0,0,
   },
--- a/parser/htmlparser/src/nsHTMLTags.cpp
+++ b/parser/htmlparser/src/nsHTMLTags.cpp
@@ -167,16 +167,18 @@ static const PRUnichar sHTMLTagUnicodeNa
 static const PRUnichar sHTMLTagUnicodeName_marquee[] =
   {'m', 'a', 'r', 'q', 'u', 'e', 'e', '\0'};
 static const PRUnichar sHTMLTagUnicodeName_menu[] =
   {'m', 'e', 'n', 'u', '\0'};
 static const PRUnichar sHTMLTagUnicodeName_menuitem[] =
   {'m', 'e', 'n', 'u', 'i', 't', 'e', 'm', '\0'};
 static const PRUnichar sHTMLTagUnicodeName_meta[] =
   {'m', 'e', 't', 'a', '\0'};
+static const PRUnichar sHTMLTagUnicodeName_meter[] =
+  {'m', 'e', 't', 'e', 'r', '\0'};
 static const PRUnichar sHTMLTagUnicodeName_multicol[] =
   {'m', 'u', 'l', 't', 'i', 'c', 'o', 'l', '\0'};
 static const PRUnichar sHTMLTagUnicodeName_nav[] =
   {'n', 'a', 'v', '\0'};
 static const PRUnichar sHTMLTagUnicodeName_nobr[] =
   {'n', 'o', 'b', 'r', '\0'};
 static const PRUnichar sHTMLTagUnicodeName_noembed[] =
   {'n', 'o', 'e', 'm', 'b', 'e', 'd', '\0'};