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 8b47f3cabf9f4c88a0614c5dc9d5938cb58be773
parent 54345 f3f0428af2810c2e8c3cbfd8e6ed8f841c3b1d6c
child 54347 6d01d25a93bf4dc23e8b89cf4e26c3b9556825a2
push idunknown
push userunknown
push dateunknown
bugs557087
milestone2.0b7pre
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>