Bug 557087 (6/6) - Elements in the first legend should not be disabled if the fieldset is disabled but not it's fieldset parent. r+a=sicking
authorMounir Lamouri <mounir.lamouri@gmail.com>
Sun, 19 Sep 2010 03:47:15 +0200
changeset 54346 8b47f3cabf9f
parent 54345 f3f0428af281
child 54347 6d01d25a93bf
push id15858
push usermlamouri@mozilla.com
push dateMon, 20 Sep 2010 03:35:23 +0000
treeherdermozilla-central@8b47f3cabf9f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs557087
milestone2.0b7pre
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 557087 (6/6) - Elements in the first legend should not be disabled if the fieldset is disabled but not it's fieldset parent. r+a=sicking
content/html/content/src/nsGenericHTMLElement.cpp
content/html/content/src/nsGenericHTMLElement.h
content/html/content/src/nsHTMLButtonElement.cpp
content/html/content/src/nsHTMLFieldSetElement.cpp
content/html/content/src/nsHTMLFieldSetElement.h
content/html/content/src/nsHTMLInputElement.cpp
content/html/content/src/nsHTMLInputElement.h
content/html/content/src/nsHTMLSelectElement.cpp
content/html/content/src/nsHTMLSelectElement.h
content/html/content/src/nsHTMLTextAreaElement.cpp
content/html/content/test/test_bug557087-2.html
content/html/content/test/test_bug557087-3.html
content/html/content/test/test_bug557087-4.html
content/html/content/test/test_bug557087-5.html
layout/reftests/css-disabled/button/button-fieldset-legend-1.html
layout/reftests/css-disabled/button/button-fieldset-legend-2.html
layout/reftests/css-disabled/button/button-fieldset-legend-3.html
layout/reftests/css-disabled/button/button-fieldset-legend-4.html
layout/reftests/css-disabled/button/button-fieldset-legend-5.html
layout/reftests/css-disabled/button/button-fieldset-legend-ref-1.html
layout/reftests/css-disabled/button/button-fieldset-legend-ref-2.html
layout/reftests/css-disabled/button/button-fieldset-legend-ref-3.html
layout/reftests/css-disabled/button/button-fieldset-legend-ref-4.html
layout/reftests/css-disabled/button/button-fieldset-legend-ref-5.html
layout/reftests/css-disabled/button/reftest.list
layout/reftests/css-disabled/fieldset/fieldset-legend-1.html
layout/reftests/css-disabled/fieldset/fieldset-legend-2.html
layout/reftests/css-disabled/fieldset/fieldset-legend-3.html
layout/reftests/css-disabled/fieldset/fieldset-legend-4.html
layout/reftests/css-disabled/fieldset/fieldset-legend-5.html
layout/reftests/css-disabled/fieldset/fieldset-legend-ref-1.html
layout/reftests/css-disabled/fieldset/fieldset-legend-ref-2.html
layout/reftests/css-disabled/fieldset/fieldset-legend-ref-3.html
layout/reftests/css-disabled/fieldset/fieldset-legend-ref-4.html
layout/reftests/css-disabled/fieldset/fieldset-legend-ref-5.html
layout/reftests/css-disabled/fieldset/reftest.list
layout/reftests/css-disabled/input/input-fieldset-legend-1.html
layout/reftests/css-disabled/input/input-fieldset-legend-2.html
layout/reftests/css-disabled/input/input-fieldset-legend-3.html
layout/reftests/css-disabled/input/input-fieldset-legend-4.html
layout/reftests/css-disabled/input/input-fieldset-legend-5.html
layout/reftests/css-disabled/input/input-fieldset-legend-ref-1.html
layout/reftests/css-disabled/input/input-fieldset-legend-ref-2.html
layout/reftests/css-disabled/input/input-fieldset-legend-ref-3.html
layout/reftests/css-disabled/input/input-fieldset-legend-ref-4.html
layout/reftests/css-disabled/input/input-fieldset-legend-ref-5.html
layout/reftests/css-disabled/input/reftest.list
layout/reftests/css-disabled/select/reftest.list
layout/reftests/css-disabled/select/select-fieldset-legend-1.html
layout/reftests/css-disabled/select/select-fieldset-legend-2.html
layout/reftests/css-disabled/select/select-fieldset-legend-3.html
layout/reftests/css-disabled/select/select-fieldset-legend-4.html
layout/reftests/css-disabled/select/select-fieldset-legend-5.html
layout/reftests/css-disabled/select/select-fieldset-legend-ref-1.html
layout/reftests/css-disabled/select/select-fieldset-legend-ref-2.html
layout/reftests/css-disabled/select/select-fieldset-legend-ref-3.html
layout/reftests/css-disabled/select/select-fieldset-legend-ref-4.html
layout/reftests/css-disabled/select/select-fieldset-legend-ref-5.html
layout/reftests/css-disabled/textarea/reftest.list
layout/reftests/css-disabled/textarea/textarea-fieldset-legend-1.html
layout/reftests/css-disabled/textarea/textarea-fieldset-legend-2.html
layout/reftests/css-disabled/textarea/textarea-fieldset-legend-3.html
layout/reftests/css-disabled/textarea/textarea-fieldset-legend-4.html
layout/reftests/css-disabled/textarea/textarea-fieldset-legend-5.html
layout/reftests/css-disabled/textarea/textarea-fieldset-legend-ref-1.html
layout/reftests/css-disabled/textarea/textarea-fieldset-legend-ref-2.html
layout/reftests/css-disabled/textarea/textarea-fieldset-legend-ref-3.html
layout/reftests/css-disabled/textarea/textarea-fieldset-legend-ref-4.html
layout/reftests/css-disabled/textarea/textarea-fieldset-legend-ref-5.html
layout/reftests/css-enabled/button/button-fieldset-legend-1.html
layout/reftests/css-enabled/button/button-fieldset-legend-2.html
layout/reftests/css-enabled/button/button-fieldset-legend-3.html
layout/reftests/css-enabled/button/button-fieldset-legend-4.html
layout/reftests/css-enabled/button/button-fieldset-legend-5.html
layout/reftests/css-enabled/button/button-fieldset-legend-ref-1.html
layout/reftests/css-enabled/button/button-fieldset-legend-ref-2.html
layout/reftests/css-enabled/button/button-fieldset-legend-ref-3.html
layout/reftests/css-enabled/button/button-fieldset-legend-ref-4.html
layout/reftests/css-enabled/button/button-fieldset-legend-ref-5.html
layout/reftests/css-enabled/button/reftest.list
layout/reftests/css-enabled/fieldset/fieldset-legend-1.html
layout/reftests/css-enabled/fieldset/fieldset-legend-2.html
layout/reftests/css-enabled/fieldset/fieldset-legend-3.html
layout/reftests/css-enabled/fieldset/fieldset-legend-4.html
layout/reftests/css-enabled/fieldset/fieldset-legend-5.html
layout/reftests/css-enabled/fieldset/fieldset-legend-ref-1.html
layout/reftests/css-enabled/fieldset/fieldset-legend-ref-2.html
layout/reftests/css-enabled/fieldset/fieldset-legend-ref-3.html
layout/reftests/css-enabled/fieldset/fieldset-legend-ref-4.html
layout/reftests/css-enabled/fieldset/fieldset-legend-ref-5.html
layout/reftests/css-enabled/fieldset/reftest.list
layout/reftests/css-enabled/input/input-fieldset-legend-1.html
layout/reftests/css-enabled/input/input-fieldset-legend-2.html
layout/reftests/css-enabled/input/input-fieldset-legend-3.html
layout/reftests/css-enabled/input/input-fieldset-legend-4.html
layout/reftests/css-enabled/input/input-fieldset-legend-5.html
layout/reftests/css-enabled/input/input-fieldset-legend-ref-1.html
layout/reftests/css-enabled/input/input-fieldset-legend-ref-2.html
layout/reftests/css-enabled/input/input-fieldset-legend-ref-3.html
layout/reftests/css-enabled/input/input-fieldset-legend-ref-4.html
layout/reftests/css-enabled/input/input-fieldset-legend-ref-5.html
layout/reftests/css-enabled/input/reftest.list
layout/reftests/css-enabled/select/reftest.list
layout/reftests/css-enabled/select/select-fieldset-legend-1.html
layout/reftests/css-enabled/select/select-fieldset-legend-2.html
layout/reftests/css-enabled/select/select-fieldset-legend-3.html
layout/reftests/css-enabled/select/select-fieldset-legend-4.html
layout/reftests/css-enabled/select/select-fieldset-legend-5.html
layout/reftests/css-enabled/select/select-fieldset-legend-ref-1.html
layout/reftests/css-enabled/select/select-fieldset-legend-ref-2.html
layout/reftests/css-enabled/select/select-fieldset-legend-ref-3.html
layout/reftests/css-enabled/select/select-fieldset-legend-ref-4.html
layout/reftests/css-enabled/select/select-fieldset-legend-ref-5.html
layout/reftests/css-enabled/textarea/reftest.list
layout/reftests/css-enabled/textarea/textarea-fieldset-legend-1.html
layout/reftests/css-enabled/textarea/textarea-fieldset-legend-2.html
layout/reftests/css-enabled/textarea/textarea-fieldset-legend-3.html
layout/reftests/css-enabled/textarea/textarea-fieldset-legend-4.html
layout/reftests/css-enabled/textarea/textarea-fieldset-legend-5.html
layout/reftests/css-enabled/textarea/textarea-fieldset-legend-ref-1.html
layout/reftests/css-enabled/textarea/textarea-fieldset-legend-ref-2.html
layout/reftests/css-enabled/textarea/textarea-fieldset-legend-ref-3.html
layout/reftests/css-enabled/textarea/textarea-fieldset-legend-ref-4.html
layout/reftests/css-enabled/textarea/textarea-fieldset-legend-ref-5.html
layout/reftests/css-invalid/button/button-fieldset-legend-ref.html
layout/reftests/css-invalid/button/button-fieldset-legend.html
layout/reftests/css-invalid/button/reftest.list
layout/reftests/css-invalid/input/input-disabled-fieldset-1.html
layout/reftests/css-invalid/input/input-fieldset-legend-ref.html
layout/reftests/css-invalid/input/input-fieldset-legend.html
layout/reftests/css-invalid/input/reftest.list
layout/reftests/css-invalid/select/reftest.list
layout/reftests/css-invalid/select/select-fieldset-legend-ref.html
layout/reftests/css-invalid/select/select-fieldset-legend.html
layout/reftests/css-invalid/textarea/reftest.list
layout/reftests/css-invalid/textarea/textarea-disabled-fieldset-1.html
layout/reftests/css-invalid/textarea/textarea-fieldset-legend-ref.html
layout/reftests/css-invalid/textarea/textarea-fieldset-legend.html
layout/reftests/css-valid/button/button-fieldset-legend-ref.html
layout/reftests/css-valid/button/button-fieldset-legend.html
layout/reftests/css-valid/button/reftest.list
layout/reftests/css-valid/input/input-fieldset-legend-ref.html
layout/reftests/css-valid/input/input-fieldset-legend.html
layout/reftests/css-valid/input/reftest.list
layout/reftests/css-valid/select/reftest.list
layout/reftests/css-valid/select/select-fieldset-legend-ref.html
layout/reftests/css-valid/select/select-fieldset-legend.html
layout/reftests/css-valid/textarea/reftest.list
layout/reftests/css-valid/textarea/textarea-fieldset-legend-ref.html
layout/reftests/css-valid/textarea/textarea-fieldset-legend.html
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -107,16 +107,17 @@
 #include "nsIEditorIMESupport.h"
 #include "nsEventDispatcher.h"
 #include "nsLayoutUtils.h"
 #include "nsContentCreatorFunctions.h"
 #include "mozAutoDocUpdate.h"
 #include "nsHtml5Module.h"
 #include "nsITextControlElement.h"
 #include "mozilla/dom/Element.h"
+#include "nsHTMLFieldSetElement.h"
 
 using namespace mozilla::dom;
 
 #include "nsThreadUtils.h"
 
 class nsINodeInfo;
 class nsIDOMNodeList;
 class nsRuleWalker;
@@ -2949,29 +2950,38 @@ nsGenericHTMLFormElement::UpdateFormOwne
       mForm->AddElementToTable(this, idVal);
     }
   }
 }
 
 void
 nsGenericHTMLFormElement::UpdateFieldSet()
 {
-  for (nsIContent* parent = GetParent(); parent; parent = parent->GetParent()) {
+  nsIContent* parent = nsnull;
+  nsIContent* prev = nsnull;
+
+  for (parent = GetParent(); parent;
+       prev = parent, parent = parent->GetParent()) {
     if (parent->IsHTML(nsGkAtoms::fieldset)) {
-      mFieldSet = static_cast<nsGenericHTMLFormElement*>(parent);
-      return;
+      nsHTMLFieldSetElement* fieldset =
+        static_cast<nsHTMLFieldSetElement*>(parent);
+
+      if (!prev || fieldset->GetFirstLegend() != prev) {
+        mFieldSet = fieldset;
+        return;
+      }
     }
   }
 
   // No fieldset found.
   mFieldSet = nsnull;
 }
 
 void
-nsGenericHTMLFormElement::OnFieldSetDisabledChanged(PRInt32 aStates)
+nsGenericHTMLFormElement::FieldSetDisabledChanged(PRInt32 aStates)
 {
   aStates |= NS_EVENT_STATE_DISABLED | NS_EVENT_STATE_ENABLED;
 
   nsIDocument* doc = GetCurrentDoc();
   // TODO: should we use aNotify ?!
   if (doc) {
     MOZ_AUTO_DOC_UPDATE(doc, UPDATE_CONTENT_STATE, PR_TRUE);
     doc->ContentStatesChanged(this, nsnull, aStates);
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -859,17 +859,25 @@ public:
    * This callback is called by a fieldest on all it's elements whenever it's
    * disabled attribute is changed so the element knows it's disabled state
    * might have changed.
    *
    * @param aStates States for which a change should be notified.
    * @note Classes redefining this method should not call ContentStatesChanged
    * but they should pass aStates instead.
    */
-  virtual void OnFieldSetDisabledChanged(PRInt32 aStates);
+  virtual void FieldSetDisabledChanged(PRInt32 aStates);
+
+  void FieldSetFirstLegendChanged() {
+    UpdateFieldSet();
+
+    // The disabled state may have change because the element might not be in
+    // the first legend anymore.
+    FieldSetDisabledChanged(0);
+  }
 
   /**
    * Returns if the control can be disabled.
    */
   PRBool CanBeDisabled() const;
 
 protected:
   virtual nsresult BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
--- a/content/html/content/src/nsHTMLButtonElement.cpp
+++ b/content/html/content/src/nsHTMLButtonElement.cpp
@@ -105,17 +105,17 @@ public:
 
   // overriden nsIFormControl methods
   NS_IMETHOD_(PRUint32) GetType() const { return mType; }
   NS_IMETHOD Reset();
   NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission);
   NS_IMETHOD SaveState();
   PRBool RestoreState(nsPresState* aState);
 
-  virtual void OnFieldSetDisabledChanged(PRInt32 aStates);
+  virtual void FieldSetDisabledChanged(PRInt32 aStates);
 
   PRInt32 IntrinsicState() const;
 
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                                nsIContent* aBindingParent,
                                PRBool aCompileEventHandlers);
   /**
    * Called when an attribute is about to be changed
@@ -733,16 +733,16 @@ void
 nsHTMLButtonElement::UpdateBarredFromConstraintValidation()
 {
   SetBarredFromConstraintValidation(mType == NS_FORM_BUTTON_BUTTON ||
                                     mType == NS_FORM_BUTTON_RESET ||
                                     IsDisabled());
 }
 
 void
-nsHTMLButtonElement::OnFieldSetDisabledChanged(PRInt32 aStates)
+nsHTMLButtonElement::FieldSetDisabledChanged(PRInt32 aStates)
 {
   UpdateBarredFromConstraintValidation();
 
   aStates |= NS_EVENT_STATE_VALID | NS_EVENT_STATE_INVALID;
-  nsGenericHTMLFormElement::OnFieldSetDisabledChanged(aStates);
+  nsGenericHTMLFormElement::FieldSetDisabledChanged(aStates);
 }
 
--- a/content/html/content/src/nsHTMLFieldSetElement.cpp
+++ b/content/html/content/src/nsHTMLFieldSetElement.cpp
@@ -29,85 +29,33 @@
  * 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 "nsIDOMHTMLFieldSetElement.h"
+
+#include "nsHTMLFieldSetElement.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIDOMEventTarget.h"
-#include "nsGenericHTMLElement.h"
 #include "nsStyleConsts.h"
 #include "nsIForm.h"
 #include "nsIFormControl.h"
-#include "nsIConstraintValidation.h"
 #include "nsEventDispatcher.h"
 
 
-class nsHTMLFieldSetElement : public nsGenericHTMLFormElement,
-                              public nsIDOMHTMLFieldSetElement,
-                              public nsIConstraintValidation
-{
-public:
-  using nsIConstraintValidation::GetValidationMessage;
-
-  nsHTMLFieldSetElement(already_AddRefed<nsINodeInfo> aNodeInfo);
-  virtual ~nsHTMLFieldSetElement();
-
-  // nsISupports
-  NS_DECL_ISUPPORTS_INHERITED
-
-  // nsIDOMNode
-  NS_FORWARD_NSIDOMNODE(nsGenericHTMLFormElement::)
-
-  // nsIDOMElement
-  NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLFormElement::)
-
-  // nsIDOMHTMLElement
-  NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLFormElement::)
-
-  // nsIDOMHTMLFieldSetElement
-  NS_DECL_NSIDOMHTMLFIELDSETELEMENT
-
-  // nsIContent
-  virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
-  virtual nsresult AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
-                                const nsAString* aValue, PRBool aNotify);
-
-  // nsIFormControl
-  NS_IMETHOD_(PRUint32) GetType() const { return NS_FORM_FIELDSET; }
-  NS_IMETHOD Reset();
-  NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission);
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-  virtual nsXPCClassInfo* GetClassInfo();
-
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHTMLFieldSetElement,
-                                           nsGenericHTMLFormElement)
-private:
-
-  // This function is used to generate the nsContentList (listed form elements).
-  static PRBool MatchListedElements(nsIContent* aContent, PRInt32 aNamespaceID,
-                                    nsIAtom* aAtom, void* aData);
-
-  // listed form controls elements.
-  nsRefPtr<nsContentList> mElements;
-};
-
-// construction, destruction
-
-
 NS_IMPL_NS_NEW_HTML_ELEMENT(FieldSet)
 
 
 nsHTMLFieldSetElement::nsHTMLFieldSetElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericHTMLFormElement(aNodeInfo)
   , mElements(nsnull)
+  , mFirstLegend(nsnull)
 {
   // <fieldset> is always barred from constraint validation.
   SetBarredFromConstraintValidation(PR_TRUE);
 }
 
 nsHTMLFieldSetElement::~nsHTMLFieldSetElement()
 {
 }
@@ -169,17 +117,17 @@ nsHTMLFieldSetElement::AfterSetAttr(PRIn
     if (!mElements) {
       mElements = new nsContentList(this, MatchListedElements, nsnull, nsnull,
                                     PR_TRUE);
     }
 
     PRUint32 length = mElements->Length(PR_TRUE);
     for (PRUint32 i=0; i<length; ++i) {
       static_cast<nsGenericHTMLFormElement*>(mElements->GetNodeAt(i))
-        ->OnFieldSetDisabledChanged(0);
+        ->FieldSetDisabledChanged(0);
     }
   }
 
   return nsGenericHTMLFormElement::AfterSetAttr(aNameSpaceID, aName,
                                                 aValue, aNotify);
 }
 
 // nsIDOMHTMLFieldSetElement
@@ -226,8 +174,88 @@ nsHTMLFieldSetElement::Reset()
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHTMLFieldSetElement::SubmitNamesValues(nsFormSubmission* aFormSubmission)
 {
   return NS_OK;
 }
+
+nsresult
+nsHTMLFieldSetElement::InsertChildAt(nsIContent* aChild, PRUint32 aIndex,
+                                     PRBool aNotify)
+{
+  bool firstLegendHasChanged = false;
+
+  if (aChild->IsHTML(nsGkAtoms::legend)) {
+    if (!mFirstLegend) {
+      mFirstLegend = aChild;
+      // We do not want to notify the first time mFirstElement is set.
+    } else {
+      // If mFirstLegend is before aIndex, we do not change it.
+      // Otherwise, mFirstLegend is now aChild.
+      if (aIndex <= IndexOf(mFirstLegend)) {
+        mFirstLegend = aChild;
+        firstLegendHasChanged = true;
+      }
+    }
+  }
+
+  nsresult rv = nsGenericHTMLFormElement::InsertChildAt(aChild, aIndex, aNotify);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (firstLegendHasChanged) {
+    NotifyElementsForFirstLegendChange();
+  }
+
+  return rv;
+}
+
+nsresult
+nsHTMLFieldSetElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify,
+                                     PRBool aMutationEvent /* = PR_TRUE */)
+{
+  bool firstLegendHasChanged = false;
+
+  if (GetChildAt(aIndex) == mFirstLegend) {
+    // If we are removing the first legend we have to found another one.
+    for (nsIContent* child = mFirstLegend; child;
+         child = child->GetNextSibling()) {
+      if (child->IsHTML(nsGkAtoms::legend)) {
+        mFirstLegend = child;
+        firstLegendHasChanged = true;
+        break;
+      }
+    }
+  }
+
+  nsresult rv = nsGenericHTMLFormElement::RemoveChildAt(aIndex, aNotify, aMutationEvent);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (firstLegendHasChanged) {
+    NotifyElementsForFirstLegendChange();
+  }
+
+  return rv;
+}
+
+void
+nsHTMLFieldSetElement::NotifyElementsForFirstLegendChange()
+{
+  /**
+   * NOTE: this could be optimized if only call when the fieldset is currently
+   * disabled.
+   * This should also make sure that mElements is set when we happen to be here.
+   * However, this method shouldn't be called very often in normal use cases.
+   */
+  if (!mElements) {
+    mElements = new nsContentList(this, MatchListedElements, nsnull, nsnull,
+                                  PR_TRUE);
+  }
+
+  PRUint32 length = mElements->Length(PR_TRUE);
+  for (PRUint32 i=0; i<length; ++i) {
+    static_cast<nsGenericHTMLFormElement*>(mElements->GetNodeAt(i))
+      ->FieldSetFirstLegendChanged();
+  }
+}
+
new file mode 100644
--- /dev/null
+++ b/content/html/content/src/nsHTMLFieldSetElement.h
@@ -0,0 +1,111 @@
+/* -*- 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 Communicator client code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 ***** */
+
+#ifndef nsHTMLFieldSetElement_h___
+#define nsHTMLFieldSetElement_h___
+
+#include "nsGenericHTMLElement.h"
+#include "nsIDOMHTMLFieldSetElement.h"
+#include "nsIConstraintValidation.h"
+
+
+class nsHTMLFieldSetElement : public nsGenericHTMLFormElement,
+                              public nsIDOMHTMLFieldSetElement,
+                              public nsIConstraintValidation
+{
+public:
+  using nsIConstraintValidation::GetValidationMessage;
+
+  nsHTMLFieldSetElement(already_AddRefed<nsINodeInfo> aNodeInfo);
+  virtual ~nsHTMLFieldSetElement();
+
+  // nsISupports
+  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+
+  // nsIDOMNode
+  NS_FORWARD_NSIDOMNODE(nsGenericHTMLFormElement::)
+
+  // nsIDOMElement
+  NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLFormElement::)
+
+  // nsIDOMHTMLElement
+  NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLFormElement::)
+
+  // nsIDOMHTMLFieldSetElement
+  NS_DECL_NSIDOMHTMLFIELDSETELEMENT
+
+  // nsIContent
+  virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
+  virtual nsresult AfterSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
+                                const nsAString* aValue, PRBool aNotify);
+
+  virtual nsresult InsertChildAt(nsIContent* aChild, PRUint32 aIndex,
+                                     PRBool aNotify);
+  virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify,
+                                 PRBool aMutationEvent = PR_TRUE);
+
+  // nsIFormControl
+  NS_IMETHOD_(PRUint32) GetType() const { return NS_FORM_FIELDSET; }
+  NS_IMETHOD Reset();
+  NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission);
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsXPCClassInfo* GetClassInfo();
+
+  const nsIContent* GetFirstLegend() const { return mFirstLegend; }
+
+  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHTMLFieldSetElement,
+                                           nsGenericHTMLFormElement)
+private:
+
+  /**
+   * Notify all elements (in mElements) that the first legend of the fieldset
+   * has now changed.
+   */
+  void NotifyElementsForFirstLegendChange();
+
+  // This function is used to generate the nsContentList (listed form elements).
+  static PRBool MatchListedElements(nsIContent* aContent, PRInt32 aNamespaceID,
+                                    nsIAtom* aAtom, void* aData);
+
+  // listed form controls elements.
+  nsRefPtr<nsContentList> mElements;
+
+  nsIContent* mFirstLegend;
+};
+
+#endif /* nsHTMLFieldSetElement_h___ */
+
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -4373,17 +4373,17 @@ nsHTMLInputElement::OnValueChanged(PRBoo
     if (doc) {
       MOZ_AUTO_DOC_UPDATE(doc, UPDATE_CONTENT_STATE, PR_TRUE);
       doc->ContentStatesChanged(this, nsnull, NS_EVENT_STATE_MOZ_PLACEHOLDER);
     }
   }
 }
 
 void
-nsHTMLInputElement::OnFieldSetDisabledChanged(PRInt32 aStates)
+nsHTMLInputElement::FieldSetDisabledChanged(PRInt32 aStates)
 {
   UpdateValueMissingValidityState();
   UpdateBarredFromConstraintValidation();
 
   aStates |= NS_EVENT_STATE_VALID | NS_EVENT_STATE_INVALID;
-  nsGenericHTMLFormElement::OnFieldSetDisabledChanged(aStates);
+  nsGenericHTMLFormElement::FieldSetDisabledChanged(aStates);
 }
 
--- a/content/html/content/src/nsHTMLInputElement.h
+++ b/content/html/content/src/nsHTMLInputElement.h
@@ -154,17 +154,17 @@ public:
   // Overriden nsIFormControl methods
   NS_IMETHOD_(PRUint32) GetType() const { return mType; }
   NS_IMETHOD Reset();
   NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission);
   NS_IMETHOD SaveState();
   virtual PRBool RestoreState(nsPresState* aState);
   virtual PRBool AllowDrop();
 
-  virtual void OnFieldSetDisabledChanged(PRInt32 aStates);
+  virtual void FieldSetDisabledChanged(PRInt32 aStates);
 
   // nsIContent
   virtual PRBool IsHTMLFocusable(PRBool aWithMouse, PRBool *aIsFocusable, PRInt32 *aTabIndex);
 
   virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
                                 nsAttrValue& aResult);
--- a/content/html/content/src/nsHTMLSelectElement.cpp
+++ b/content/html/content/src/nsHTMLSelectElement.cpp
@@ -2103,16 +2103,16 @@ nsHTMLOptionCollection::Remove(PRInt32 a
 
 void
 nsHTMLSelectElement::UpdateBarredFromConstraintValidation()
 {
   SetBarredFromConstraintValidation(IsDisabled());
 }
 
 void
-nsHTMLSelectElement::OnFieldSetDisabledChanged(PRInt32 aStates)
+nsHTMLSelectElement::FieldSetDisabledChanged(PRInt32 aStates)
 {
   UpdateBarredFromConstraintValidation();
 
   aStates |= NS_EVENT_STATE_VALID | NS_EVENT_STATE_INVALID;
-  nsGenericHTMLFormElement::OnFieldSetDisabledChanged(aStates);
+  nsGenericHTMLFormElement::FieldSetDisabledChanged(aStates);
 }
 
--- a/content/html/content/src/nsHTMLSelectElement.h
+++ b/content/html/content/src/nsHTMLSelectElement.h
@@ -272,17 +272,17 @@ public:
 
   // Overriden nsIFormControl methods
   NS_IMETHOD_(PRUint32) GetType() const { return NS_FORM_SELECT; }
   NS_IMETHOD Reset();
   NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission);
   NS_IMETHOD SaveState();
   virtual PRBool RestoreState(nsPresState* aState);
 
-  virtual void OnFieldSetDisabledChanged(PRInt32 aStates);
+  virtual void FieldSetDisabledChanged(PRInt32 aStates);
 
   PRInt32 IntrinsicState() const;
 
   // nsISelectElement
   NS_DECL_NSISELECTELEMENT
 
   /**
    * Called when an attribute is about to be changed
--- a/content/html/content/src/nsHTMLTextAreaElement.cpp
+++ b/content/html/content/src/nsHTMLTextAreaElement.cpp
@@ -126,17 +126,17 @@ public:
 
   // nsIFormControl
   NS_IMETHOD_(PRUint32) GetType() const { return NS_FORM_TEXTAREA; }
   NS_IMETHOD Reset();
   NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission);
   NS_IMETHOD SaveState();
   virtual PRBool RestoreState(nsPresState* aState);
 
-  virtual void OnFieldSetDisabledChanged(PRInt32 aStates);
+  virtual void FieldSetDisabledChanged(PRInt32 aStates);
 
   virtual PRInt32 IntrinsicState() const;
 
   // nsITextControlElemet
   NS_IMETHOD SetValueChanged(PRBool aValueChanged);
   NS_IMETHOD_(PRBool) IsSingleLineTextControl() const;
   NS_IMETHOD_(PRBool) IsTextArea() const;
   NS_IMETHOD_(PRBool) IsPlainTextControl() const;
@@ -1385,17 +1385,17 @@ nsHTMLTextAreaElement::OnValueChanged(PR
                                               // we are already updating the
                                               // state for valid/invalid...
                                               NS_EVENT_STATE_MOZ_PLACEHOLDER);
     }
   }
 }
 
 void
-nsHTMLTextAreaElement::OnFieldSetDisabledChanged(PRInt32 aStates)
+nsHTMLTextAreaElement::FieldSetDisabledChanged(PRInt32 aStates)
 {
   UpdateValueMissingValidityState();
   UpdateBarredFromConstraintValidation();
 
   aStates |= NS_EVENT_STATE_VALID | NS_EVENT_STATE_INVALID;
-  nsGenericHTMLFormElement::OnFieldSetDisabledChanged(aStates);
+  nsGenericHTMLFormElement::FieldSetDisabledChanged(aStates);
 }
 
--- a/content/html/content/test/test_bug557087-2.html
+++ b/content/html/content/test/test_bug557087-2.html
@@ -33,22 +33,40 @@ function clickShouldNotHappenHandler(aEv
   if (++gHandled >= elementsWithClick.length) {
     test2();
   }
 }
 
 function clickShouldNotHappenHandler2(aEvent)
 {
   aEvent.target.removeEventListener("click", clickShouldNotHappenHandler3, false);
-  ok(false, "click event should be prevented! (test3)");
+  ok(false, "click event should be prevented! (test2)");
   if (++gHandled >= elementsWithClick.length) {
     test3();
   }
 }
 
+function clickShouldNotHappenHandler5(aEvent)
+{
+  aEvent.target.removeEventListener("click", clickShouldNotHappenHandler5, false);
+  ok(false, "click event should be prevented! (test5)");
+  if (++gHandled >= elementsWithClick.length) {
+    test6();
+  }
+}
+
+function clickShouldNotHappenHandler7(aEvent)
+{
+  aEvent.target.removeEventListener("click", clickShouldNotHappenHandler7, false);
+  ok(false, "click event should be prevented! (test7)");
+  if (++gHandled >= elementsWithClick.length) {
+    test8();
+  }
+}
+
 function clickShouldHappenHandler(aEvent)
 {
   aEvent.target.removeEventListener("click", clickShouldHappenHandler, false);
   ok(true, "click event has been correctly received (test1)");
   if (++gHandled >= elementsWithClick.length) {
     test2();
   }
 }
@@ -63,43 +81,103 @@ function clickShouldHappenHandler2(aEven
 }
 
 function clickShouldHappenHandler3(aEvent)
 {
   aEvent.target.removeEventListener("click", clickShouldHappenHandler3, false);
   ok(true, "click event has been correctly received (test3)");
   if (++gHandled >= (elementsWithClick.length +
                      elementsPreventingClick.length)) {
+    test4();
+  }
+}
+
+function clickShouldHappenHandler4(aEvent)
+{
+  aEvent.target.removeEventListener("click", clickShouldHappenHandler4, false);
+  ok(true, "click event has been correctly received (test4)");
+  if (++gHandled >= (elementsWithClick.length +
+                     elementsPreventingClick.length)) {
+    test5();
+  }
+}
+
+function clickShouldHappenHandler5(aEvent)
+{
+  aEvent.target.removeEventListener("click", clickShouldHappenHandler5, false);
+  ok(true, "click event has been correctly received (test5)");
+  if (++gHandled >= elementsWithClick.length) {
+    test6();
+  }
+}
+
+function clickShouldHappenHandler6(aEvent)
+{
+  aEvent.target.removeEventListener("click", clickShouldHappenHandler6, false);
+  ok(true, "click event has been correctly received (test6)");
+  if (++gHandled >= (elementsWithClick.length +
+                     elementsPreventingClick.length)) {
+    test7();
+  }
+}
+
+function clickShouldHappenHandler7(aEvent)
+{
+  aEvent.target.removeEventListener("click", clickShouldHappenHandler7, false);
+  ok(true, "click event has been correctly received (test5)");
+  if (++gHandled >= elementsWithClick.length) {
+    test8();
+  }
+}
+
+function clickShouldHappenHandler8(aEvent)
+{
+  aEvent.target.removeEventListener("click", clickShouldHappenHandler8, false);
+  ok(true, "click event has been correctly received (test8)");
+  if (++gHandled >= (elementsWithClick.length +
+                     elementsPreventingClick.length)) {
     SimpleTest.finish();
   }
 }
 
 var fieldset1 = document.createElement("fieldset");
 var fieldset2 = document.createElement("fieldset");
+var legendA = document.createElement("legend");
+var legendB = document.createElement("legend");
 var content  = document.getElementById('content');
 fieldset1.disabled = true;
 content.appendChild(fieldset1);
 fieldset1.appendChild(fieldset2);
 
+function clean()
+{
+  var count = fieldset2.children.length;
+  for (var i=0; i<count; ++i) {
+    if (fieldset2.children[i] != legendA &&
+        fieldset2.children[i] != legendB) {
+      fieldset2.removeChild(fieldset2.children[i]);
+    }
+  }
+}
+
 function test1()
 {
   gHandled = 0;
 
   // Initialize children without click expected.
   for each(var name in elementsPreventingClick) {
     var element = document.createElement(name);
     fieldset2.appendChild(element);
     element.addEventListener("click", clickShouldNotHappenHandler, false);
     sendMouseEvent({type:'click'}, element);
   }
 
   // Initialize children with click expected.
   for each(var name in elementsWithClick) {
     var element = document.createElement(name);
-    element.innerHTML = "foo";
     fieldset2.appendChild(element);
     element.addEventListener("click", clickShouldHappenHandler, false);
     sendMouseEvent({type:'click'}, element);
   }
 }
 
 function test2()
 {
@@ -113,17 +191,16 @@ function test2()
     fieldset2.appendChild(element);
     element.addEventListener("click", clickShouldNotHappenHandler2, false);
     sendMouseEvent({type:'click'}, element);
   }
 
   // Initialize children with click expected.
   for each(var name in elementsWithClick) {
     var element = document.createElement(name);
-    element.innerHTML = "foo";
     fieldset2.appendChild(element);
     element.addEventListener("click", clickShouldHappenHandler2, false);
     sendMouseEvent({type:'click'}, element);
   }
 }
 
 function test3()
 {
@@ -137,21 +214,147 @@ function test3()
     fieldset2.appendChild(element);
     element.addEventListener("click", clickShouldHappenHandler3, false);
     sendMouseEvent({type:'click'}, element);
   }
 
   // Initialize children with click expected.
   for each(var name in elementsWithClick) {
     var element = document.createElement(name);
-    element.innerHTML = "foo";
     fieldset2.appendChild(element);
     element.addEventListener("click", clickShouldHappenHandler3, false);
     sendMouseEvent({type:'click'}, element);
   }
 }
 
+function test4()
+{
+  gHandled = 0;
+  fieldset1.disabled = false;
+  fieldset2.disabled = true;
+
+  fieldset2.appendChild(legendA);
+
+  // All elements should accept the click.
+  for each(var name in elementsPreventingClick) {
+    var element = document.createElement(name);
+    legendA.appendChild(element);
+    element.addEventListener("click", clickShouldHappenHandler4, false);
+    sendMouseEvent({type:'click'}, element);
+  }
+
+  // Initialize children with click expected.
+  for each(var name in elementsWithClick) {
+    var element = document.createElement(name);
+    legendA.appendChild(element);
+    element.addEventListener("click", clickShouldHappenHandler4, false);
+    sendMouseEvent({type:'click'}, element);
+  }
+}
+
+function test5()
+{
+  gHandled = 0;
+  fieldset2.insertBefore(legendB, legendA);
+
+  // Initialize children without click expected.
+  for each(var name in elementsPreventingClick) {
+    var element = document.createElement(name);
+    legendA.appendChild(element);
+    element.addEventListener("click", clickShouldNotHappenHandler5, false);
+    sendMouseEvent({type:'click'}, element);
+  }
+
+  // Initialize children with click expected.
+  for each(var name in elementsWithClick) {
+    var element = document.createElement(name);
+    legendA.appendChild(element);
+    element.addEventListener("click", clickShouldHappenHandler5, false);
+    sendMouseEvent({type:'click'}, element);
+  }
+}
+
+function test6()
+{
+  gHandled = 0;
+  fieldset2.removeChild(legendB);
+  fieldset1.disabled = true;
+  fieldset2.disabled = false;
+
+  fieldset1.appendChild(legendA);
+  legendA.appendChild(fieldset2);
+
+  // All elements should accept the click.
+  for each(var name in elementsPreventingClick) {
+    var element = document.createElement(name);
+    fieldset2.appendChild(element);
+    element.addEventListener("click", clickShouldHappenHandler6, false);
+    sendMouseEvent({type:'click'}, element);
+  }
+
+  // Initialize children with click expected.
+  for each(var name in elementsWithClick) {
+    var element = document.createElement(name);
+    fieldset2.appendChild(element);
+    element.addEventListener("click", clickShouldHappenHandler6, false);
+    sendMouseEvent({type:'click'}, element);
+  }
+}
+
+function test7()
+{
+  gHandled = 0;
+  fieldset1.disabled = true;
+  fieldset2.disabled = false;
+
+  fieldset1.appendChild(fieldset2);
+  fieldset2.appendChild(legendA);
+
+  // All elements should accept the click.
+  for each(var name in elementsPreventingClick) {
+    var element = document.createElement(name);
+    legendA.appendChild(element);
+    element.addEventListener("click", clickShouldNotHappenHandler7, false);
+    sendMouseEvent({type:'click'}, element);
+  }
+
+  // Initialize children with click expected.
+  for each(var name in elementsWithClick) {
+    var element = document.createElement(name);
+    legendA.appendChild(element);
+    element.addEventListener("click", clickShouldHappenHandler7, false);
+    sendMouseEvent({type:'click'}, element);
+  }
+}
+
+function test8()
+{
+  gHandled = 0;
+  fieldset1.disabled = true;
+  fieldset2.disabled = true;
+
+  fieldset1.appendChild(legendA);
+  legendA.appendChild(fieldset2);
+  fieldset2.appendChild(legendB);
+
+  // All elements should accept the click.
+  for each(var name in elementsPreventingClick) {
+    var element = document.createElement(name);
+    legendB.appendChild(element);
+    element.addEventListener("click", clickShouldHappenHandler8, false);
+    sendMouseEvent({type:'click'}, element);
+  }
+
+  // Initialize children with click expected.
+  for each(var name in elementsWithClick) {
+    var element = document.createElement(name);
+    legendB.appendChild(element);
+    element.addEventListener("click", clickShouldHappenHandler8, false);
+    sendMouseEvent({type:'click'}, element);
+  }
+}
+
 test1();
 
 </script>
 </pre>
 </body>
 </html>
--- a/content/html/content/test/test_bug557087-3.html
+++ b/content/html/content/test/test_bug557087-3.html
@@ -130,28 +130,31 @@ function checkElement(aElement, aDisable
 
   if (data[4]) {
     checkValueMissing(aElement, expected);
   }
 }
 
 var fieldset1 = document.createElement("fieldset");
 var fieldset2 = document.createElement("fieldset");
+var legendA = document.createElement("legend");
+var legendB = document.createElement("legend");
 var content  = document.getElementById('content');
 content.appendChild(fieldset1);
 fieldset1.appendChild(fieldset2);
 fieldset2.disabled = true;
 
 for each(var data in elements) {
   var element = document.createElement(data);
 
   if (data[4]) {
     element.required = true;
   }
 
+  fieldset1.disabled = false;
   fieldset2.appendChild(element);
 
   checkElement(element, fieldset2.disabled);
 
   // Make sure changes are correctly managed.
   fieldset2.disabled = false;
   checkElement(element, fieldset2.disabled);
   fieldset2.disabled = true;
@@ -163,17 +166,52 @@ for each(var data in elements) {
   fieldset1.disabled = true;
   checkElement(element, fieldset1.disabled);
 
   // Make sure the state change of the inner fieldset will not confuse.
   fieldset2.disabled = true;
   fieldset2.disabled = false;
   checkElement(element, fieldset1.disabled);
 
+
+  /* legend tests */
+
+  // elements in the first legend of a disabled fieldset should not be disabled.
   fieldset2.disabled = true;
   fieldset1.disabled = false;
-  fieldset2.removeChild(element);
+  legendA.appendChild(element);
+  fieldset2.appendChild(legendA);
+  checkElement(element, false);
+
+  // elements in the second legend should be disabled
+  fieldset2.insertBefore(legendB, legendA);
+  checkElement(element, fieldset2.disabled);
+  fieldset2.removeChild(legendB);
+
+  // Elements in the first legend of a fieldset disabled by another fieldset
+  // should be disabled.
+  fieldset1.disabled = true;
+  checkElement(element, fieldset1.disabled);
+
+  // Elements inside a fieldset inside the first legend of a disabled fieldset
+  // should not be diasbled.
+  fieldset2.disabled = false;
+  fieldset1.appendChild(legendA);
+  legendA.appendChild(fieldset2);
+  fieldset2.appendChild(element);
+  checkElement(element, false);
+
+  // Elements inside the first legend of a disabled fieldset inside the first
+  // legend of a disabled fieldset should not be disabled.
+  fieldset2.disabled = false;
+  fieldset2.appendChild(legendB);
+  legendB.appendChild(element);
+  checkElement(element, false);
+  fieldset2.removeChild(legendB);
+  fieldset1.appendChild(fieldset2);
+
+  element.parentNode.removeChild(element);
 }
 
 </script>
 </pre>
 </body>
 </html>
--- a/content/html/content/test/test_bug557087-4.html
+++ b/content/html/content/test/test_bug557087-4.html
@@ -16,29 +16,29 @@ https://bugzilla.mozilla.org/show_bug.cg
 <div id="content">
   <iframe name='f'></iframe>
   <form target='f' action="data:text/html">
     <input type='text' id='a'>
     <input type='checkbox' id='b'>
     <input type='radio' id='c'>
     <fieldset disabled>
       <fieldset>
-        <input type='submit'>
+        <input type='submit' id='s'>
       </fieldset>
     </fieldset>
   </form>
 </div>
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 557087 **/
 
 SimpleTest.waitForExplicitFinish();
 
-var gExpectedSubmits = 3;
+var gExpectedSubmits = 6;
 var gSubmitReceived = 0;
 var gEnd = false;
 
 var fieldsets = document.getElementsByTagName("fieldset");
 var form = document.forms[0];
 
 form.addEventListener("submit", function() {
   ok(gEnd, gEnd ? "expected submit" : "non expected submit");
@@ -69,14 +69,23 @@ SimpleTest.waitForFocus(function() {
   fieldsets[0].disabled = false;
   doSubmit();
 
   fieldsets[0].disabled = false;
   fieldsets[1].disabled = false;
 
   gEnd = true;
   doSubmit();
+
+  // Simple check that we can submit from inside a legend even if the fieldset
+  // is disabled.
+  var legend = document.createElement("legend");
+  fieldsets[0].appendChild(legend);
+  fieldsets[0].disabled = true;
+  legend.appendChild(document.getElementById('s'));
+
+  doSubmit();
 });
 
 </script>
 </pre>
 </body>
 </html>
--- a/content/html/content/test/test_bug557087-5.html
+++ b/content/html/content/test/test_bug557087-5.html
@@ -30,16 +30,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 /** Test for Bug 557087 **/
 
 SimpleTest.waitForExplicitFinish();
 
 var testResults = [
   "data:text/html,?",
   "data:text/html,?",
   "data:text/html,?i=i&t=t&s=s",
+  "data:text/html,?i=i&t=t&s=s",
 ];
 var gTestCount = 0;
 
 var form = document.forms[0];
 var iframe = document.getElementsByTagName('iframe')[0];
 var fieldsets = document.getElementsByTagName('fieldset');
 
 function runTest()
@@ -59,16 +60,29 @@ function runTest()
         break;
       case 2:
         fieldsets[0].disabled = false;
         fieldsets[1].disabled = false;
         SimpleTest.executeSoon(function() {
           form.submit()
         });
         break;
+      case 3:
+        // Elements inside the first legend of a disabled fieldset are submittable.
+        fieldsets[0].disabled = true;
+        fieldsets[1].disabled = true;
+        var legend = document.createElement("legend");
+        fieldsets[0].appendChild(legend);
+        while (fieldsets[1].firstChild) {
+          legend.appendChild(fieldsets[1].firstChild);
+        }
+        SimpleTest.executeSoon(function() {
+          form.submit()
+        });
+        break;
       default:
         iframe.removeEventListener("load", arguments.callee, false);
         SimpleTest.executeSoon(SimpleTest.finish);
     }
   }, false);
 
   form.submit();
 }
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/button/button-fieldset-legend-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend id='i'>
+        <button class="enabled"></button>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/button/button-fieldset-legend-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+      </legend>
+      <legend>
+        <button class="disabled"></button>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/button/button-fieldset-legend-3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <fieldset class="disabled">
+        <legend>
+          <button class="disabled"></button>
+        </legend>
+      </fieldset>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/button/button-fieldset-legend-4.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+        <fieldset class="enabled">
+          <button class="enabled"></button>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/button/button-fieldset-legend-5.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+        <fieldset class="disabled" disabled>
+          <legend>
+            <button class="enabled"></button>
+          </legend>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/button/button-fieldset-legend-ref-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <button class="ref"></button>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/button/button-fieldset-legend-ref-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+      </legend>
+      <legend>
+        <button class="ref"></button>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/button/button-fieldset-legend-ref-3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <fieldset class="ref">
+        <legend>
+          <button class="ref"></button>
+        </legend>
+      </fieldset>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/button/button-fieldset-legend-ref-4.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref">
+          <button class="ref"></button>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/button/button-fieldset-legend-ref-5.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref">
+          <legend>
+            <button class="ref"></button>
+          </legend>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
--- a/layout/reftests/css-disabled/button/reftest.list
+++ b/layout/reftests/css-disabled/button/reftest.list
@@ -1,4 +1,9 @@
 == button-fieldset-1.html button-fieldset-ref.html
 == button-fieldset-2.html button-fieldset-ref.html
 == button-fieldset-3.html button-fieldset-ref.html
 == button-fieldset-4.html button-fieldset-ref.html
+== button-fieldset-legend-1.html button-fieldset-legend-ref-1.html
+== button-fieldset-legend-2.html button-fieldset-legend-ref-2.html
+== button-fieldset-legend-3.html button-fieldset-legend-ref-3.html
+== button-fieldset-legend-4.html button-fieldset-legend-ref-4.html
+== button-fieldset-legend-5.html button-fieldset-legend-ref-5.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/fieldset/fieldset-legend-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend id='i'>
+        <fieldset class="enabled"></fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/fieldset/fieldset-legend-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+      </legend>
+      <legend>
+        <fieldset class="disabled"></fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/fieldset/fieldset-legend-3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <fieldset class="disabled">
+        <legend>
+          <fieldset class="disabled"></fieldset>
+        </legend>
+      </fieldset>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/fieldset/fieldset-legend-4.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+        <fieldset class="enabled">
+          <fieldset class="enabled"></fieldset>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/fieldset/fieldset-legend-5.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+        <fieldset class="disabled" disabled>
+          <legend>
+            <fieldset class="enabled"></fieldset>
+          </legend>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/fieldset/fieldset-legend-ref-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref"></fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/fieldset/fieldset-legend-ref-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+      </legend>
+      <legend>
+        <fieldset class="ref"></fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/fieldset/fieldset-legend-ref-3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <fieldset class="ref">
+        <legend>
+          <fieldset class="ref"></fieldset>
+        </legend>
+      </fieldset>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/fieldset/fieldset-legend-ref-4.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref">
+          <fieldset class="ref"></fieldset>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/fieldset/fieldset-legend-ref-5.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref">
+          <legend>
+            <fieldset class="ref"></fieldset>
+          </legend>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
--- a/layout/reftests/css-disabled/fieldset/reftest.list
+++ b/layout/reftests/css-disabled/fieldset/reftest.list
@@ -1,6 +1,11 @@
 == fieldset-enabled.html fieldset-ref.html
 == fieldset-disabled.html fieldset-ref.html
 == fieldset-fieldset-1.html fieldset-fieldset-ref.html
 == fieldset-fieldset-2.html fieldset-fieldset-ref.html
 == fieldset-fieldset-3.html fieldset-fieldset-ref.html
 == fieldset-fieldset-4.html fieldset-fieldset-ref.html
+== fieldset-legend-1.html fieldset-legend-ref-1.html
+== fieldset-legend-2.html fieldset-legend-ref-2.html
+== fieldset-legend-3.html fieldset-legend-ref-3.html
+== fieldset-legend-4.html fieldset-legend-ref-4.html
+== fieldset-legend-5.html fieldset-legend-ref-5.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/input/input-fieldset-legend-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend id='i'>
+        <input class="enabled">
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/input/input-fieldset-legend-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+      </legend>
+      <legend>
+        <input class="disabled">
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/input/input-fieldset-legend-3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <fieldset class="disabled">
+        <legend>
+          <input class="disabled">
+        </legend>
+      </fieldset>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/input/input-fieldset-legend-4.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+        <fieldset class="enabled">
+          <input class="enabled">
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/input/input-fieldset-legend-5.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+        <fieldset class="disabled" disabled>
+          <legend>
+            <input class="enabled">
+          </legend>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/input/input-fieldset-legend-ref-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <input class="ref">
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/input/input-fieldset-legend-ref-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+      </legend>
+      <legend>
+        <input class="ref">
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/input/input-fieldset-legend-ref-3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <fieldset class="ref">
+        <legend>
+          <input class="ref">
+        </legend>
+      </fieldset>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/input/input-fieldset-legend-ref-4.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref">
+          <input class="ref">
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/input/input-fieldset-legend-ref-5.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref">
+          <legend>
+            <input class="ref">
+          </legend>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
--- a/layout/reftests/css-disabled/input/reftest.list
+++ b/layout/reftests/css-disabled/input/reftest.list
@@ -1,4 +1,9 @@
 == input-fieldset-1.html input-fieldset-ref.html
 == input-fieldset-2.html input-fieldset-ref.html
 == input-fieldset-3.html input-fieldset-ref.html
 == input-fieldset-4.html input-fieldset-ref.html
+== input-fieldset-legend-1.html input-fieldset-legend-ref-1.html
+== input-fieldset-legend-2.html input-fieldset-legend-ref-2.html
+== input-fieldset-legend-3.html input-fieldset-legend-ref-3.html
+== input-fieldset-legend-4.html input-fieldset-legend-ref-4.html
+== input-fieldset-legend-5.html input-fieldset-legend-ref-5.html
--- a/layout/reftests/css-disabled/select/reftest.list
+++ b/layout/reftests/css-disabled/select/reftest.list
@@ -1,4 +1,9 @@
 == select-fieldset-1.html select-fieldset-ref.html
 == select-fieldset-2.html select-fieldset-ref-disabled.html
 == select-fieldset-3.html select-fieldset-ref-disabled.html
 == select-fieldset-4.html select-fieldset-ref.html
+== select-fieldset-legend-1.html select-fieldset-legend-ref-1.html
+== select-fieldset-legend-2.html select-fieldset-legend-ref-2.html
+== select-fieldset-legend-3.html select-fieldset-legend-ref-3.html
+== select-fieldset-legend-4.html select-fieldset-legend-ref-4.html
+== select-fieldset-legend-5.html select-fieldset-legend-ref-5.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/select/select-fieldset-legend-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend id='i'>
+        <select class="enabled"></select>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/select/select-fieldset-legend-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+      </legend>
+      <legend>
+        <select class="disabled"></select>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/select/select-fieldset-legend-3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <fieldset class="disabled">
+        <legend>
+          <select class="disabled"></select>
+        </legend>
+      </fieldset>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/select/select-fieldset-legend-4.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+        <fieldset class="enabled">
+          <select class="enabled"></select>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/select/select-fieldset-legend-5.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+        <fieldset class="disabled" disabled>
+          <legend>
+            <select class="enabled"></select>
+          </legend>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/select/select-fieldset-legend-ref-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <select class="ref"></select>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/select/select-fieldset-legend-ref-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+      </legend>
+      <legend>
+        <select disabled class="ref"></select>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/select/select-fieldset-legend-ref-3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <fieldset class="ref">
+        <legend>
+          <select disabled class="ref"></select>
+        </legend>
+      </fieldset>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/select/select-fieldset-legend-ref-4.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref">
+          <select class="ref"></select>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/select/select-fieldset-legend-ref-5.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref">
+          <legend>
+            <select class="ref"></select>
+          </legend>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
--- a/layout/reftests/css-disabled/textarea/reftest.list
+++ b/layout/reftests/css-disabled/textarea/reftest.list
@@ -1,4 +1,9 @@
 == textarea-fieldset-1.html textarea-fieldset-ref.html
 == textarea-fieldset-2.html textarea-fieldset-ref.html
 == textarea-fieldset-3.html textarea-fieldset-ref.html
 == textarea-fieldset-4.html textarea-fieldset-ref.html
+== textarea-fieldset-legend-1.html textarea-fieldset-legend-ref-1.html
+== textarea-fieldset-legend-2.html textarea-fieldset-legend-ref-2.html
+== textarea-fieldset-legend-3.html textarea-fieldset-legend-ref-3.html
+== textarea-fieldset-legend-4.html textarea-fieldset-legend-ref-4.html
+== textarea-fieldset-legend-5.html textarea-fieldset-legend-ref-5.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/textarea/textarea-fieldset-legend-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend id='i'>
+        <textarea class="enabled"></textarea>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/textarea/textarea-fieldset-legend-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+      </legend>
+      <legend>
+        <textarea class="disabled"></textarea>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/textarea/textarea-fieldset-legend-3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <fieldset class="disabled">
+        <legend>
+          <textarea class="disabled"></textarea>
+        </legend>
+      </fieldset>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/textarea/textarea-fieldset-legend-4.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+        <fieldset class="enabled">
+          <textarea class="enabled"></textarea>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/textarea/textarea-fieldset-legend-5.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+        <fieldset class="disabled" disabled>
+          <legend>
+            <textarea class="enabled"></textarea>
+          </legend>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/textarea/textarea-fieldset-legend-ref-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <textarea class="ref"></textarea>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/textarea/textarea-fieldset-legend-ref-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+      </legend>
+      <legend>
+        <textarea class="ref"></textarea>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/textarea/textarea-fieldset-legend-ref-3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <fieldset class="ref">
+        <legend>
+          <textarea class="ref"></textarea>
+        </legend>
+      </fieldset>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/textarea/textarea-fieldset-legend-ref-4.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref">
+          <textarea class="ref"></textarea>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-disabled/textarea/textarea-fieldset-legend-ref-5.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref">
+          <legend>
+            <textarea class="ref"></textarea>
+          </legend>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/button/button-fieldset-legend-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend id='i'>
+        <button class="enabled"></button>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/button/button-fieldset-legend-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+      </legend>
+      <legend>
+        <button class="disabled"></button>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/button/button-fieldset-legend-3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <fieldset class="disabled">
+        <legend>
+          <button class="disabled"></button>
+        </legend>
+      </fieldset>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/button/button-fieldset-legend-4.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+        <fieldset class="enabled">
+          <button class="enabled"></button>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/button/button-fieldset-legend-5.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+        <fieldset class="disabled" disabled>
+          <legend>
+            <button class="enabled"></button>
+          </legend>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/button/button-fieldset-legend-ref-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <button class="ref"></button>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/button/button-fieldset-legend-ref-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+      </legend>
+      <legend>
+        <button class="ref"></button>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/button/button-fieldset-legend-ref-3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <fieldset class="ref">
+        <legend>
+          <button class="ref"></button>
+        </legend>
+      </fieldset>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/button/button-fieldset-legend-ref-4.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref">
+          <button class="ref"></button>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/button/button-fieldset-legend-ref-5.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref">
+          <legend>
+            <button class="ref"></button>
+          </legend>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
--- a/layout/reftests/css-enabled/button/reftest.list
+++ b/layout/reftests/css-enabled/button/reftest.list
@@ -1,4 +1,9 @@
 == button-fieldset-1.html button-fieldset-ref.html
 == button-fieldset-2.html button-fieldset-ref.html
 == button-fieldset-3.html button-fieldset-ref.html
 == button-fieldset-4.html button-fieldset-ref.html
+== button-fieldset-legend-1.html button-fieldset-legend-ref-1.html
+== button-fieldset-legend-2.html button-fieldset-legend-ref-2.html
+== button-fieldset-legend-3.html button-fieldset-legend-ref-3.html
+== button-fieldset-legend-4.html button-fieldset-legend-ref-4.html
+== button-fieldset-legend-5.html button-fieldset-legend-ref-5.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/fieldset/fieldset-legend-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend id='i'>
+        <fieldset class="enabled"></fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/fieldset/fieldset-legend-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+      </legend>
+      <legend>
+        <fieldset class="disabled"></fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/fieldset/fieldset-legend-3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <fieldset class="disabled">
+        <legend>
+          <fieldset class="disabled"></fieldset>
+        </legend>
+      </fieldset>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/fieldset/fieldset-legend-4.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+        <fieldset class="enabled">
+          <fieldset class="enabled"></fieldset>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/fieldset/fieldset-legend-5.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+        <fieldset class="disabled" disabled>
+          <legend>
+            <fieldset class="enabled"></fieldset>
+          </legend>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/fieldset/fieldset-legend-ref-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref"></fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/fieldset/fieldset-legend-ref-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+      </legend>
+      <legend>
+        <fieldset class="ref"></fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/fieldset/fieldset-legend-ref-3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <fieldset class="ref">
+        <legend>
+          <fieldset class="ref"></fieldset>
+        </legend>
+      </fieldset>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/fieldset/fieldset-legend-ref-4.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref">
+          <fieldset class="ref"></fieldset>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/fieldset/fieldset-legend-ref-5.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref">
+          <legend>
+            <fieldset class="ref"></fieldset>
+          </legend>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
--- a/layout/reftests/css-enabled/fieldset/reftest.list
+++ b/layout/reftests/css-enabled/fieldset/reftest.list
@@ -1,6 +1,11 @@
 == fieldset-enabled.html fieldset-ref.html
 == fieldset-disabled.html fieldset-ref.html
 == fieldset-fieldset-1.html fieldset-fieldset-ref.html
 == fieldset-fieldset-2.html fieldset-fieldset-ref.html
 == fieldset-fieldset-3.html fieldset-fieldset-ref.html
 == fieldset-fieldset-4.html fieldset-fieldset-ref.html
+== fieldset-legend-1.html fieldset-legend-ref-1.html
+== fieldset-legend-2.html fieldset-legend-ref-2.html
+== fieldset-legend-3.html fieldset-legend-ref-3.html
+== fieldset-legend-4.html fieldset-legend-ref-4.html
+== fieldset-legend-5.html fieldset-legend-ref-5.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/input/input-fieldset-legend-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend id='i'>
+        <input class="enabled">
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/input/input-fieldset-legend-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+      </legend>
+      <legend>
+        <input class="disabled">
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/input/input-fieldset-legend-3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <fieldset class="disabled">
+        <legend>
+          <input class="disabled">
+        </legend>
+      </fieldset>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/input/input-fieldset-legend-4.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+        <fieldset class="enabled">
+          <input class="enabled">
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/input/input-fieldset-legend-5.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+        <fieldset class="disabled" disabled>
+          <legend>
+            <input class="enabled">
+          </legend>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/input/input-fieldset-legend-ref-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <input class="ref">
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/input/input-fieldset-legend-ref-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+      </legend>
+      <legend>
+        <input class="ref">
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/input/input-fieldset-legend-ref-3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <fieldset class="ref">
+        <legend>
+          <input class="ref">
+        </legend>
+      </fieldset>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/input/input-fieldset-legend-ref-4.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref">
+          <input class="ref">
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/input/input-fieldset-legend-ref-5.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref">
+          <legend>
+            <input class="ref">
+          </legend>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
--- a/layout/reftests/css-enabled/input/reftest.list
+++ b/layout/reftests/css-enabled/input/reftest.list
@@ -1,4 +1,9 @@
 == input-fieldset-1.html input-fieldset-ref.html
 == input-fieldset-2.html input-fieldset-ref.html
 == input-fieldset-3.html input-fieldset-ref.html
 == input-fieldset-4.html input-fieldset-ref.html
+== input-fieldset-legend-1.html input-fieldset-legend-ref-1.html
+== input-fieldset-legend-2.html input-fieldset-legend-ref-2.html
+== input-fieldset-legend-3.html input-fieldset-legend-ref-3.html
+== input-fieldset-legend-4.html input-fieldset-legend-ref-4.html
+== input-fieldset-legend-5.html input-fieldset-legend-ref-5.html
--- a/layout/reftests/css-enabled/select/reftest.list
+++ b/layout/reftests/css-enabled/select/reftest.list
@@ -1,4 +1,9 @@
 == select-fieldset-1.html select-fieldset-ref.html
 == select-fieldset-2.html select-fieldset-ref-disabled.html
 == select-fieldset-3.html select-fieldset-ref-disabled.html
 == select-fieldset-4.html select-fieldset-ref.html
+== select-fieldset-legend-1.html select-fieldset-legend-ref-1.html
+== select-fieldset-legend-2.html select-fieldset-legend-ref-2.html
+== select-fieldset-legend-3.html select-fieldset-legend-ref-3.html
+== select-fieldset-legend-4.html select-fieldset-legend-ref-4.html
+== select-fieldset-legend-5.html select-fieldset-legend-ref-5.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/select/select-fieldset-legend-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend id='i'>
+        <select class="enabled"></select>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/select/select-fieldset-legend-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+      </legend>
+      <legend>
+        <select class="disabled"></select>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/select/select-fieldset-legend-3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <fieldset class="disabled">
+        <legend>
+          <select class="disabled"></select>
+        </legend>
+      </fieldset>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/select/select-fieldset-legend-4.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+        <fieldset class="enabled">
+          <select class="enabled"></select>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/select/select-fieldset-legend-5.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+        <fieldset class="disabled" disabled>
+          <legend>
+            <select class="enabled"></select>
+          </legend>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/select/select-fieldset-legend-ref-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <select class="ref"></select>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/select/select-fieldset-legend-ref-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+      </legend>
+      <legend>
+        <select disabled class="ref"></select>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/select/select-fieldset-legend-ref-3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <fieldset class="ref">
+        <legend>
+          <select disabled class="ref"></select>
+        </legend>
+      </fieldset>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/select/select-fieldset-legend-ref-4.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref">
+          <select class="ref"></select>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/select/select-fieldset-legend-ref-5.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref">
+          <legend>
+            <select class="ref"></select>
+          </legend>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
--- a/layout/reftests/css-enabled/textarea/reftest.list
+++ b/layout/reftests/css-enabled/textarea/reftest.list
@@ -1,4 +1,9 @@
 == textarea-fieldset-1.html textarea-fieldset-ref.html
 == textarea-fieldset-2.html textarea-fieldset-ref.html
 == textarea-fieldset-3.html textarea-fieldset-ref.html
 == textarea-fieldset-4.html textarea-fieldset-ref.html
+== textarea-fieldset-legend-1.html textarea-fieldset-legend-ref-1.html
+== textarea-fieldset-legend-2.html textarea-fieldset-legend-ref-2.html
+== textarea-fieldset-legend-3.html textarea-fieldset-legend-ref-3.html
+== textarea-fieldset-legend-4.html textarea-fieldset-legend-ref-4.html
+== textarea-fieldset-legend-5.html textarea-fieldset-legend-ref-5.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/textarea/textarea-fieldset-legend-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend id='i'>
+        <textarea class="enabled"></textarea>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/textarea/textarea-fieldset-legend-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+      </legend>
+      <legend>
+        <textarea class="disabled"></textarea>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/textarea/textarea-fieldset-legend-3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <fieldset class="disabled">
+        <legend>
+          <textarea class="disabled"></textarea>
+        </legend>
+      </fieldset>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/textarea/textarea-fieldset-legend-4.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+        <fieldset class="enabled">
+          <textarea class="enabled"></textarea>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/textarea/textarea-fieldset-legend-5.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="disabled" disabled>
+      <legend>
+        <fieldset class="disabled" disabled>
+          <legend>
+            <textarea class="enabled"></textarea>
+          </legend>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/textarea/textarea-fieldset-legend-ref-1.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <textarea class="ref"></textarea>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/textarea/textarea-fieldset-legend-ref-2.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+      </legend>
+      <legend>
+        <textarea class="ref"></textarea>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/textarea/textarea-fieldset-legend-ref-3.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <fieldset class="ref">
+        <legend>
+          <textarea class="ref"></textarea>
+        </legend>
+      </fieldset>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/textarea/textarea-fieldset-legend-ref-4.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref">
+          <textarea class="ref"></textarea>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-enabled/textarea/textarea-fieldset-legend-ref-5.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset class="ref">
+      <legend>
+        <fieldset class="ref">
+          <legend>
+            <textarea class="ref"></textarea>
+          </legend>
+        </fieldset>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-invalid/button/button-fieldset-legend-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <fieldset>
+      <legend>
+        <button style="background-color: green;"></button>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-invalid/button/button-fieldset-legend.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <!-- Test: if button has a disabled fieldset ancestor, but is in the first
+             legend, it is not barred from constraint validation and should be
+             affected by :invalid pseudo-class. -->
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <script>
+    function onLoadHandler()
+    {
+      var e = document.getElementById('b');
+      e.setCustomValidity('foo');
+      document.documentElement.className='';
+    }
+  </script>
+  <body onload="onLoadHandler();">
+    <fieldset disabled>
+      <legend>
+        <button class='invalid' id='b'></button>
+      </legend>
+    </fieldset>
+  </body>
+</html>
--- a/layout/reftests/css-invalid/button/reftest.list
+++ b/layout/reftests/css-invalid/button/reftest.list
@@ -4,8 +4,9 @@
 == button-dyn-disabled.html button-ref.html
 == button-dyn-not-disabled.html button-ref.html
 == button-button.html button-ref.html
 == button-reset.html button-ref.html
 == button-type-invalid.html button-ref.html
 == button-type-barred.html button-ref.html
 == button-disabled-fieldset-1.html button-fieldset-ref.html
 == button-disabled-fieldset-2.html button-fieldset-ref.html
+== button-fieldset-legend.html button-fieldset-legend-ref.html
--- a/layout/reftests/css-invalid/input/input-disabled-fieldset-1.html
+++ b/layout/reftests/css-invalid/input/input-disabled-fieldset-1.html
@@ -1,14 +1,14 @@
 <!DOCTYPE html>
 <html>
   <!-- Test: if input has a disabled fieldset ancestor, it is barred from
              constraint validation and should not be affected by :invalid
              pseudo-class. -->
   <link rel='stylesheet' type='text/css' href='style.css'>
-  <body onload="onLoadHandler();">
+  <body>
     <fieldset disabled>
       <fieldset>
         <input class='notinvalid' required>
       </fieldset>
     </fieldset>
   </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-invalid/input/input-fieldset-legend-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <fieldset>
+      <legend>
+        <input style="background-color: green;">
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-invalid/input/input-fieldset-legend.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+  <!-- Test: if input has a disabled fieldset ancestor, but is in the first
+             legend, it is not barred from constraint validation and should be
+             affected by :invalid pseudo-class. -->
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset disabled>
+      <legend>
+        <input class='invalid' required>
+      </legend>
+    </fieldset>
+  </body>
+</html>
--- a/layout/reftests/css-invalid/input/reftest.list
+++ b/layout/reftests/css-invalid/input/reftest.list
@@ -17,9 +17,10 @@
 == input-url-invalid.html input-withtext-ref.html
 == input-url-valid.html input-url-ref.html
 == input-pattern-valid.html input-withtext-ref.html
 == input-pattern-invalid.html input-withtext-ref.html
 == input-type-barred.html input-button-ref.html
 == input-type-invalid.html input-ref.html
 == input-disabled-fieldset-1.html input-fieldset-ref.html
 == input-disabled-fieldset-2.html input-fieldset-ref.html
+== input-fieldset-legend.html input-fieldset-legend-ref.html
 # input type='hidden' shouldn't show
--- a/layout/reftests/css-invalid/select/reftest.list
+++ b/layout/reftests/css-invalid/select/reftest.list
@@ -1,7 +1,8 @@
 == select-valid.html select-ref.html
 == select-invalid.html select-ref.html
 == select-disabled.html select-disabled-ref.html
 == select-dyn-disabled.html select-disabled-ref.html
 == select-dyn-not-disabled.html select-ref.html
 == select-disabled-fieldset-1.html select-fieldset-ref.html
 == select-disabled-fieldset-2.html select-fieldset-ref.html
+== select-fieldset-legend.html select-fieldset-legend-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-invalid/select/select-fieldset-legend-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <fieldset>
+      <legend>
+        <select style="background-color: green;"></select>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-invalid/select/select-fieldset-legend.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <!-- Test: if select has a disabled fieldset ancestor, but is in the first
+             legend, it is not barred from constraint validation and should be
+             affected by :invalid pseudo-class. -->
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <script>
+    function onLoadHandler()
+    {
+      var e = document.getElementById('b');
+      e.setCustomValidity('foo');
+      document.documentElement.className='';
+    }
+  </script>
+  <body onload="onLoadHandler();">
+    <fieldset disabled>
+      <legend>
+        <select class='invalid' id='b'></select>
+      </legend>
+    </fieldset>
+  </body>
+</html>
--- a/layout/reftests/css-invalid/textarea/reftest.list
+++ b/layout/reftests/css-invalid/textarea/reftest.list
@@ -7,8 +7,9 @@
 == textarea-dyn-readonly.html textarea-ref.html
 == textarea-dyn-not-readonly.html textarea-ref.html
 == textarea-maxlength-valid.html textarea-ref.html
 == textarea-maxlength-invalid.html textarea-withtext-ref.html
 == textarea-required-valid.html textarea-withtext-ref.html
 == textarea-required-invalid.html textarea-ref.html
 == textarea-disabled-fieldset-1.html textarea-fieldset-ref.html
 == textarea-disabled-fieldset-2.html textarea-fieldset-ref.html
+== textarea-fieldset-legend.html textarea-fieldset-legend-ref.html
--- a/layout/reftests/css-invalid/textarea/textarea-disabled-fieldset-1.html
+++ b/layout/reftests/css-invalid/textarea/textarea-disabled-fieldset-1.html
@@ -1,14 +1,14 @@
 <!DOCTYPE html>
 <html>
   <!-- Test: if textarea has a disabled fieldset ancestor, it is barred from
              constraint validation and should not be affected by :invalid
              pseudo-class. -->
   <link rel='stylesheet' type='text/css' href='style.css'>
-  <body onload="onLoadHandler();">
+  <body>
     <fieldset disabled>
       <fieldset>
         <textarea class='notinvalid' required></textarea>
       </fieldset>
     </fieldset>
   </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-invalid/textarea/textarea-fieldset-legend-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <fieldset>
+      <legend>
+        <textarea style="background-color: green;"></textarea>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-invalid/textarea/textarea-fieldset-legend.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+  <!-- Test: if textarea has a disabled fieldset ancestor, but is in the first
+             legend, it is not barred from constraint validation and should be
+             affected by :invalid pseudo-class. -->
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset disabled>
+      <legend>
+        <textarea class='invalid' required></textarea>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-valid/button/button-fieldset-legend-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <fieldset>
+      <legend>
+        <button style="background-color: green;"></button>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-valid/button/button-fieldset-legend.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+  <!-- Test: if button has a disabled fieldset ancestor, but is in the first
+             legend, it is not barred from constraint validation and should be
+             affected by :valid pseudo-class. -->
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset disabled>
+      <legend>
+        <button class='valid'></button>
+      </legend>
+    </fieldset>
+  </body>
+</html>
--- a/layout/reftests/css-valid/button/reftest.list
+++ b/layout/reftests/css-valid/button/reftest.list
@@ -4,8 +4,9 @@
 == button-dyn-disabled.html button-ref.html
 == button-dyn-not-disabled.html button-ref.html
 == button-button.html button-ref.html
 == button-reset.html button-ref.html
 == button-type-invalid.html button-ref.html
 == button-type-barred.html button-ref.html
 == button-disabled-fieldset-1.html button-fieldset-ref.html
 == button-disabled-fieldset-2.html button-fieldset-ref.html
+== button-fieldset-legend.html button-fieldset-legend-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-valid/input/input-fieldset-legend-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <fieldset>
+      <legend>
+        <input style="background-color: green;"></input>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-valid/input/input-fieldset-legend.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+  <!-- Test: if input has a disabled fieldset ancestor, but is in the first
+             legend, it is not barred from constraint validation and should be
+             affected by :valid pseudo-class. -->
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset disabled>
+      <legend>
+        <input class='valid'></input>
+      </legend>
+    </fieldset>
+  </body>
+</html>
--- a/layout/reftests/css-valid/input/reftest.list
+++ b/layout/reftests/css-valid/input/reftest.list
@@ -17,9 +17,10 @@
 == input-url-invalid.html input-withtext-ref.html
 == input-url-valid.html input-url-ref.html
 == input-pattern-valid.html input-withtext-ref.html
 == input-pattern-invalid.html input-withtext-ref.html
 == input-type-barred.html input-button-ref.html
 == input-type-invalid.html input-ref.html
 == input-disabled-fieldset-1.html input-fieldset-ref.html
 == input-disabled-fieldset-2.html input-fieldset-ref.html
+== input-fieldset-legend.html input-fieldset-legend-ref.html
 # input type='hidden' shouldn't show
--- a/layout/reftests/css-valid/select/reftest.list
+++ b/layout/reftests/css-valid/select/reftest.list
@@ -1,7 +1,8 @@
 == select-valid.html select-ref.html
 == select-invalid.html select-ref.html
 == select-disabled.html select-disabled-ref.html
 == select-dyn-disabled.html select-disabled-ref.html
 == select-dyn-not-disabled.html select-ref.html
 == select-disabled-fieldset-1.html select-fieldset-ref.html
 == select-disabled-fieldset-2.html select-fieldset-ref.html
+== select-fieldset-legend.html select-fieldset-legend-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-valid/select/select-fieldset-legend-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <fieldset>
+      <legend>
+        <select style="background-color: green;"></select>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-valid/select/select-fieldset-legend.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+  <!-- Test: if select has a disabled fieldset ancestor, but is in the first
+             legend, it is not barred from constraint validation and should be
+             affected by :valid pseudo-class. -->
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset disabled>
+      <legend>
+        <select class='valid'></select>
+      </legend>
+    </fieldset>
+  </body>
+</html>
--- a/layout/reftests/css-valid/textarea/reftest.list
+++ b/layout/reftests/css-valid/textarea/reftest.list
@@ -7,8 +7,9 @@
 == textarea-dyn-readonly.html textarea-ref.html
 == textarea-dyn-not-readonly.html textarea-ref.html
 == textarea-maxlength-valid.html textarea-ref.html
 == textarea-maxlength-invalid.html textarea-withtext-ref.html
 == textarea-required-valid.html textarea-withtext-ref.html
 == textarea-required-invalid.html textarea-ref.html
 == textarea-disabled-fieldset-1.html textarea-fieldset-ref.html
 == textarea-disabled-fieldset-2.html textarea-fieldset-ref.html
+== textarea-fieldset-legend.html textarea-fieldset-legend-ref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-valid/textarea/textarea-fieldset-legend-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+  <body>
+    <fieldset>
+      <legend>
+        <textarea style="background-color: green;"></textarea>
+      </legend>
+    </fieldset>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-valid/textarea/textarea-fieldset-legend.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+  <!-- Test: if textarea has a disabled fieldset ancestor, but is in the first
+             legend, it is not barred from constraint validation and should be
+             affected by :valid pseudo-class. -->
+  <link rel='stylesheet' type='text/css' href='style.css'>
+  <body>
+    <fieldset disabled>
+      <legend>
+        <textarea class='valid'></textarea>
+      </legend>
+    </fieldset>
+  </body>
+</html>