Bug 1268852. Change <label> elements to not be form-associated anymore. r=bkelly,hsivonen,surkov
authorBoris Zbarsky <bzbarsky@mit.edu>
Thu, 26 May 2016 19:39:03 -0400
changeset 338230 c4bde82ab5934ff314072d653abd983579ea0d23
parent 338229 a0365d37a510dca7411c6043da29992d26490ff9
child 338231 6fc284339ae3a17d4ab750089614e2c8c8fe4c90
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbkelly, hsivonen, surkov
bugs1268852
milestone49.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1268852. Change <label> elements to not be form-associated anymore. r=bkelly,hsivonen,surkov The web platform tests changes are just a cherrypick of https://github.com/w3c/web-platform-tests/pull/2926 so I don't have to add failure annotations until the next test uplift. I've audited our uses of nsIFormControl, and this patch looks to me like it preserves existing behavior in all but the following cases: 1) nsXBLPrototypeHandler::DispatchXBLCommand, the case of scrolling when space is pressed while something inside a <label> is focused. We used to not scroll in this situation; I think this is a bug, so I'm changing that behavior to scroll instead. 2) In Accessible::RelationByType for the RelationType::DEFAULT_BUTTON case, when mContent is a <label> we used to return its form's default submit element. Now we will just return Relation().
dom/events/EventStateManager.cpp
dom/html/HTMLFieldSetElement.cpp
dom/html/HTMLFormControlsCollection.cpp
dom/html/HTMLLabelElement.cpp
dom/html/HTMLLabelElement.h
dom/html/nsGenericHTMLElement.cpp
dom/html/nsIFormControl.h
dom/html/test/forms/test_form_attribute-1.html
dom/html/test/test_bug841466.html
parser/html/javasrc/ElementName.java
parser/html/javasrc/TreeBuilder.java
parser/html/nsHtml5ElementName.cpp
parser/html/nsHtml5TreeBuilder.cpp
parser/html/nsHtml5TreeBuilder.h
testing/web-platform/meta/html/semantics/forms/form-control-infrastructure/form.html.ini
testing/web-platform/meta/html/semantics/forms/the-label-element/label-attributes.html.ini
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -1532,17 +1532,18 @@ EventStateManager::FireContextClick()
       nsCOMPtr<nsIFormControl> formCtrl(do_QueryInterface(mGestureDownContent));
 
       if (formCtrl) {
         allowedToDispatch = formCtrl->IsTextOrNumberControl(/*aExcludePassword*/ false) ||
                             formCtrl->GetType() == NS_FORM_INPUT_FILE;
       }
       else if (mGestureDownContent->IsAnyOfHTMLElements(nsGkAtoms::applet,
                                                         nsGkAtoms::embed,
-                                                        nsGkAtoms::object)) {
+                                                        nsGkAtoms::object,
+                                                        nsGkAtoms::label)) {
         allowedToDispatch = false;
       }
     }
 
     if (allowedToDispatch) {
       // init the event while mCurrentTarget is still good
       WidgetMouseEvent event(true, eContextMenu, targetWidget,
                              WidgetMouseEvent::eReal);
--- a/dom/html/HTMLFieldSetElement.cpp
+++ b/dom/html/HTMLFieldSetElement.cpp
@@ -119,17 +119,17 @@ HTMLFieldSetElement::GetType(nsAString& 
 }
 
 /* static */
 bool
 HTMLFieldSetElement::MatchListedElements(nsIContent* aContent, int32_t aNamespaceID,
                                          nsIAtom* aAtom, void* aData)
 {
   nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(aContent);
-  return formControl && formControl->GetType() != NS_FORM_LABEL;
+  return formControl;
 }
 
 NS_IMETHODIMP
 HTMLFieldSetElement::GetElements(nsIDOMHTMLCollection** aElements)
 {
   NS_ADDREF(*aElements = Elements());
   return NS_OK;
 }
--- a/dom/html/HTMLFormControlsCollection.cpp
+++ b/dom/html/HTMLFormControlsCollection.cpp
@@ -58,17 +58,19 @@ HTMLFormControlsCollection::ShouldBeInEl
   case NS_FORM_OUTPUT :
     return true;
   }
 
   // These form control types are not supposed to end up in the
   // form.elements array
   //
   // NS_FORM_INPUT_IMAGE
-  // NS_FORM_LABEL
+  //
+  // XXXbz maybe we should just check for that type here instead of the big
+  // switch?
 
   return false;
 }
 
 HTMLFormControlsCollection::HTMLFormControlsCollection(HTMLFormElement* aForm)
   : mForm(aForm)
   // Initialize the elements list to have an initial capacity
   // of 8 to reduce allocations on small forms.
--- a/dom/html/HTMLLabelElement.cpp
+++ b/dom/html/HTMLLabelElement.cpp
@@ -29,27 +29,29 @@ HTMLLabelElement::~HTMLLabelElement()
 JSObject*
 HTMLLabelElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return HTMLLabelElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
 // nsISupports
 
-NS_IMPL_ISUPPORTS_INHERITED(HTMLLabelElement, nsGenericHTMLFormElement,
+NS_IMPL_ISUPPORTS_INHERITED(HTMLLabelElement, nsGenericHTMLElement,
                             nsIDOMHTMLLabelElement)
 
 // nsIDOMHTMLLabelElement
 
 NS_IMPL_ELEMENT_CLONE(HTMLLabelElement)
 
 NS_IMETHODIMP
 HTMLLabelElement::GetForm(nsIDOMHTMLFormElement** aForm)
 {
-  return nsGenericHTMLFormElement::GetForm(aForm);
+  RefPtr<nsIDOMHTMLFormElement> form = GetForm();
+  form.forget(aForm);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLLabelElement::GetControl(nsIDOMHTMLElement** aElement)
 {
   nsCOMPtr<nsIDOMHTMLElement> element = do_QueryObject(GetLabeledElement());
   element.forget(aElement);
   return NS_OK;
@@ -67,16 +69,33 @@ NS_IMETHODIMP
 HTMLLabelElement::GetHtmlFor(nsAString& aHtmlFor)
 {
   nsString htmlFor;
   GetHtmlFor(htmlFor);
   aHtmlFor = htmlFor;
   return NS_OK;
 }
 
+HTMLFormElement*
+HTMLLabelElement::GetForm() const
+{
+  nsGenericHTMLElement* control = GetControl();
+  if (!control) {
+    return nullptr;
+  }
+
+  // Not all labeled things have a form association.  Stick to the ones that do.
+  nsCOMPtr<nsIFormControl> formControl = do_QueryObject(control);
+  if (!formControl) {
+    return nullptr;
+  }
+
+  return static_cast<HTMLFormElement*>(formControl->GetFormElement());
+}
+
 void
 HTMLLabelElement::Focus(ErrorResult& aError)
 {
   // retarget the focus method at the for content
   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
   if (fm) {
     nsCOMPtr<nsIDOMElement> elem = do_QueryObject(GetLabeledElement());
     if (elem)
@@ -203,28 +222,16 @@ HTMLLabelElement::PostHandleEvent(EventC
       default:
         break;
     }
     mHandlingEvent = false;
   }
   return NS_OK;
 }
 
-nsresult
-HTMLLabelElement::Reset()
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-HTMLLabelElement::SubmitNamesValues(nsFormSubmission* aFormSubmission)
-{
-  return NS_OK;
-}
-
 bool
 HTMLLabelElement::PerformAccesskey(bool aKeyCausesActivation,
                                    bool aIsTrustedEvent)
 {
   if (!aKeyCausesActivation) {
     RefPtr<Element> element = GetLabeledElement();
     if (element) {
       return element->PerformAccesskey(aKeyCausesActivation, aIsTrustedEvent);
--- a/dom/html/HTMLLabelElement.h
+++ b/dom/html/HTMLLabelElement.h
@@ -13,22 +13,22 @@
 #include "mozilla/Attributes.h"
 #include "nsGenericHTMLElement.h"
 #include "nsIDOMHTMLLabelElement.h"
 
 namespace mozilla {
 class EventChainPostVisitor;
 namespace dom {
 
-class HTMLLabelElement final : public nsGenericHTMLFormElement,
+class HTMLLabelElement final : public nsGenericHTMLElement,
                                public nsIDOMHTMLLabelElement
 {
 public:
   explicit HTMLLabelElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
-    : nsGenericHTMLFormElement(aNodeInfo),
+    : nsGenericHTMLElement(aNodeInfo),
       mHandlingEvent(false)
   {
   }
 
   NS_IMPL_FROMCONTENT_HTML_WITH_TAG(HTMLLabelElement, label)
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
@@ -37,38 +37,33 @@ public:
   virtual bool IsInteractiveHTMLContent(bool aIgnoreTabindex) const override
   {
     return true;
   }
 
   // nsIDOMHTMLLabelElement
   NS_DECL_NSIDOMHTMLLABELELEMENT
 
-  using nsGenericHTMLFormElement::GetForm;
+  HTMLFormElement* GetForm() const;
   void GetHtmlFor(nsString& aHtmlFor)
   {
     GetHTMLAttr(nsGkAtoms::_for, aHtmlFor);
   }
   void SetHtmlFor(const nsAString& aHtmlFor, ErrorResult& aError)
   {
     SetHTMLAttr(nsGkAtoms::_for, aHtmlFor, aError);
   }
   nsGenericHTMLElement* GetControl() const
   {
     return GetLabeledElement();
   }
 
   using nsGenericHTMLElement::Focus;
   virtual void Focus(mozilla::ErrorResult& aError) override;
 
-  // nsIFormControl
-  NS_IMETHOD_(uint32_t) GetType() const override { return NS_FORM_LABEL; }
-  NS_IMETHOD Reset() override;
-  NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission) override;
-
   virtual bool IsDisabled() const override { return false; }
 
   // nsIContent
   virtual nsresult PostHandleEvent(
                      EventChainPostVisitor& aVisitor) override;
   virtual bool PerformAccesskey(bool aKeyCausesActivation,
                                 bool aIsTrustedEvent) override;
   virtual nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult) const override;
--- a/dom/html/nsGenericHTMLElement.cpp
+++ b/dom/html/nsGenericHTMLElement.cpp
@@ -2296,17 +2296,16 @@ nsGenericHTMLFormElement::ForgetFieldSet
 }
 
 bool
 nsGenericHTMLFormElement::CanBeDisabled() const
 {
   int32_t type = GetType();
   // It's easier to test the types that _cannot_ be disabled
   return
-    type != NS_FORM_LABEL &&
     type != NS_FORM_OBJECT &&
     type != NS_FORM_OUTPUT;
 }
 
 bool
 nsGenericHTMLFormElement::IsHTMLFocusable(bool aWithMouse,
                                           bool* aIsFocusable,
                                           int32_t* aTabIndex)
--- a/dom/html/nsIFormControl.h
+++ b/dom/html/nsIFormControl.h
@@ -17,17 +17,16 @@ namespace mozilla {
 namespace dom {
 class Element;
 class HTMLFieldSetElement;
 } // namespace dom
 } // namespace mozilla
 
 enum FormControlsTypes {
   NS_FORM_FIELDSET = 1,
-  NS_FORM_LABEL,
   NS_FORM_OUTPUT,
   NS_FORM_SELECT,
   NS_FORM_TEXTAREA,
   NS_FORM_OBJECT,
   eFormControlsWithoutSubTypesMax,
   // After this, all types will have sub-types which introduce new enum lists.
   // eFormControlsWithoutSubTypesMax let us know if the previous types values
   // are not overlapping with sub-types/masks.
@@ -282,17 +281,16 @@ nsIFormControl::IsSubmittableControl() c
          type & NS_FORM_INPUT_ELEMENT;
 }
 
 bool
 nsIFormControl::AllowDraggableChildren() const
 {
   uint32_t type = GetType();
   return type == NS_FORM_OBJECT ||
-         type == NS_FORM_LABEL ||
          type == NS_FORM_FIELDSET ||
          type == NS_FORM_OUTPUT;
 }
 
 bool
 nsIFormControl::IsAutofocusable() const
 {
   uint32_t type = GetType();
--- a/dom/html/test/forms/test_form_attribute-1.html
+++ b/dom/html/test/forms/test_form_attribute-1.html
@@ -447,18 +447,20 @@ for (var name of elementNames) {
         is(formsList[i].elements.length, elementsList.length,
            "The form should contain " + elementsList.length + " elements");
       }
       for (var j=0; j<elementsList.length; ++j) {
         if (name != 'label' && name != 'meter' && name != 'progress') {
           is(formsList[i].elements[j], elementsList[j],
              "The form should contain " + elementsList[j]);
         }
-        is(elementsList[j].form, formsList[i],
-           "The form owner should be the form associated to the list");
+        if (name != 'label') {
+          is(elementsList[j].form, formsList[i],
+             "The form owner should be the form associated to the list");
+        }
       }
     }
   }
 
   // Cleaning-up.
   for (e of elements) {
     e.parentNode.removeChild(e);
     e = null;
--- a/dom/html/test/test_bug841466.html
+++ b/dom/html/test/test_bug841466.html
@@ -5,17 +5,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 -->
 <head>
   <meta charset="utf-8">
   <title>Test for Bug 841466</title>
   <script src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" href="/tests/SimpleTest/test.css">
   <script>
   /** Test for Bug 841466 **/
-var els = ['button', 'fieldset', 'input', 'keygen', 'label', 'object', 'output', 'select', 'textarea'];
+var els = ['button', 'fieldset', 'input', 'keygen', 'object', 'output', 'select', 'textarea'];
 var code = "try { is(foo, 'bar', 'expected value bar from expando on element ' + localName); } catch (e) { ok(false, String(e)); }";
 els.forEach(function(el) {
   var f = document.createElement("form");
   f.foo = "bar";
   f.innerHTML = '<' + el + ' onclick="' + code + '">';
   var e = f.firstChild
   if (el === "keygen") {
     todo_is(e.localName, "keygen", "Bug 101019");
--- a/parser/html/javasrc/ElementName.java
+++ b/parser/html/javasrc/ElementName.java
@@ -323,18 +323,18 @@ public final class ElementName
 //            case TreeBuilder.TD_OR_TH:
 //                return "TD_OR_TH";
 //            case TreeBuilder.DD_OR_DT:
 //                return "DD_OR_DT";
 //            case TreeBuilder.H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6:
 //                return "H1_OR_H2_OR_H3_OR_H4_OR_H5_OR_H6";
 //            case TreeBuilder.OBJECT:
 //                return "OBJECT";
-//            case TreeBuilder.OUTPUT_OR_LABEL:
-//                return "OUTPUT_OR_LABEL";
+//            case TreeBuilder.OUTPUT:
+//                return "OUTPUT";
 //            case TreeBuilder.MARQUEE_OR_APPLET:
 //                return "MARQUEE_OR_APPLET";
 //            case TreeBuilder.PRE_OR_LISTING:
 //                return "PRE_OR_LISTING";
 //            case TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U:
 //                return "B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U";
 //            case TreeBuilder.UL_OR_OL_OR_DL:
 //                return "UL_OR_OL_OR_DL";
@@ -567,17 +567,17 @@ public final class ElementName
     public static final ElementName FRAME = new ElementName("frame", "frame", TreeBuilder.FRAME | SPECIAL);
     public static final ElementName FALSE = new ElementName("false", "false", TreeBuilder.OTHER);
     public static final ElementName FLOOR = new ElementName("floor", "floor", TreeBuilder.OTHER);
     public static final ElementName GLYPH = new ElementName("glyph", "glyph", TreeBuilder.OTHER);
     public static final ElementName HKERN = new ElementName("hkern", "hkern", TreeBuilder.OTHER);
     public static final ElementName IMAGE = new ElementName("image", "image", TreeBuilder.IMAGE);
     public static final ElementName IDENT = new ElementName("ident", "ident", TreeBuilder.OTHER);
     public static final ElementName INPUT = new ElementName("input", "input", TreeBuilder.INPUT | SPECIAL);
-    public static final ElementName LABEL = new ElementName("label", "label", TreeBuilder.OUTPUT_OR_LABEL);
+    public static final ElementName LABEL = new ElementName("label", "label", TreeBuilder.OTHER);
     public static final ElementName LIMIT = new ElementName("limit", "limit", TreeBuilder.OTHER);
     public static final ElementName MFRAC = new ElementName("mfrac", "mfrac", TreeBuilder.OTHER);
     public static final ElementName MPATH = new ElementName("mpath", "mpath", TreeBuilder.OTHER);
     public static final ElementName METER = new ElementName("meter", "meter", TreeBuilder.OTHER);
     public static final ElementName MOVER = new ElementName("mover", "mover", TreeBuilder.OTHER);
     public static final ElementName MINUS = new ElementName("minus", "minus", TreeBuilder.OTHER);
     public static final ElementName MROOT = new ElementName("mroot", "mroot", TreeBuilder.OTHER);
     public static final ElementName MSQRT = new ElementName("msqrt", "msqrt", TreeBuilder.OTHER);
@@ -635,17 +635,17 @@ public final class ElementName
     public static final ElementName MEDIAN = new ElementName("median", "median", TreeBuilder.OTHER);
     public static final ElementName MUNDER = new ElementName("munder", "munder", TreeBuilder.OTHER);
     public static final ElementName MARKER = new ElementName("marker", "marker", TreeBuilder.OTHER);
     public static final ElementName MERROR = new ElementName("merror", "merror", TreeBuilder.OTHER);
     public static final ElementName MOMENT = new ElementName("moment", "moment", TreeBuilder.OTHER);
     public static final ElementName MATRIX = new ElementName("matrix", "matrix", TreeBuilder.OTHER);
     public static final ElementName OPTION = new ElementName("option", "option", TreeBuilder.OPTION | OPTIONAL_END_TAG);
     public static final ElementName OBJECT = new ElementName("object", "object", TreeBuilder.OBJECT | SPECIAL | SCOPING);
-    public static final ElementName OUTPUT = new ElementName("output", "output", TreeBuilder.OUTPUT_OR_LABEL);
+    public static final ElementName OUTPUT = new ElementName("output", "output", TreeBuilder.OUTPUT);
     public static final ElementName PRIMES = new ElementName("primes", "primes", TreeBuilder.OTHER);
     public static final ElementName SOURCE = new ElementName("source", "source", TreeBuilder.PARAM_OR_SOURCE_OR_TRACK);
     public static final ElementName STRIKE = new ElementName("strike", "strike", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
     public static final ElementName STRONG = new ElementName("strong", "strong", TreeBuilder.B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
     public static final ElementName SWITCH = new ElementName("switch", "switch", TreeBuilder.OTHER);
     public static final ElementName SYMBOL = new ElementName("symbol", "symbol", TreeBuilder.OTHER);
     public static final ElementName SELECT = new ElementName("select", "select", TreeBuilder.SELECT | SPECIAL);
     public static final ElementName SUBSET = new ElementName("subset", "subset", TreeBuilder.OTHER);
--- a/parser/html/javasrc/TreeBuilder.java
+++ b/parser/html/javasrc/TreeBuilder.java
@@ -184,17 +184,17 @@ public abstract class TreeBuilder<T> imp
     final static int ANNOTATION_XML = 58;
 
     final static int FOREIGNOBJECT_OR_DESC = 59;
 
     final static int NOEMBED = 60;
 
     final static int FIELDSET = 61;
 
-    final static int OUTPUT_OR_LABEL = 62;
+    final static int OUTPUT = 62;
 
     final static int OBJECT = 63;
 
     final static int FONT = 64;
 
     final static int KEYGEN = 65;
 
     final static int MENUITEM = 66;
@@ -2548,17 +2548,17 @@ public abstract class TreeBuilder<T> imp
                             case TBODY_OR_THEAD_OR_TFOOT:
                             case TR:
                             case TD_OR_TH:
                             case FRAME:
                             case FRAMESET:
                             case HEAD:
                                 errStrayStartTag(name);
                                 break starttagloop;
-                            case OUTPUT_OR_LABEL:
+                            case OUTPUT:
                                 reconstructTheActiveFormattingElements();
                                 appendToCurrentNodeAndPushElementMayFoster(
                                         elementName,
                                         attributes, formPointer);
                                 attributes = null; // CPP
                                 break starttagloop;
                             default:
                                 reconstructTheActiveFormattingElements();
--- a/parser/html/nsHtml5ElementName.cpp
+++ b/parser/html/nsHtml5ElementName.cpp
@@ -695,17 +695,17 @@ nsHtml5ElementName::initializeStatics()
   ELT_FRAME = new nsHtml5ElementName(nsHtml5Atoms::frame, nsHtml5Atoms::frame, NS_HTML5TREE_BUILDER_FRAME | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_FALSE = new nsHtml5ElementName(nsHtml5Atoms::false_, nsHtml5Atoms::false_, NS_HTML5TREE_BUILDER_OTHER);
   ELT_FLOOR = new nsHtml5ElementName(nsHtml5Atoms::floor, nsHtml5Atoms::floor, NS_HTML5TREE_BUILDER_OTHER);
   ELT_GLYPH = new nsHtml5ElementName(nsHtml5Atoms::glyph, nsHtml5Atoms::glyph, NS_HTML5TREE_BUILDER_OTHER);
   ELT_HKERN = new nsHtml5ElementName(nsHtml5Atoms::hkern, nsHtml5Atoms::hkern, NS_HTML5TREE_BUILDER_OTHER);
   ELT_IMAGE = new nsHtml5ElementName(nsHtml5Atoms::image, nsHtml5Atoms::image, NS_HTML5TREE_BUILDER_IMAGE);
   ELT_IDENT = new nsHtml5ElementName(nsHtml5Atoms::ident, nsHtml5Atoms::ident, NS_HTML5TREE_BUILDER_OTHER);
   ELT_INPUT = new nsHtml5ElementName(nsHtml5Atoms::input, nsHtml5Atoms::input, NS_HTML5TREE_BUILDER_INPUT | NS_HTML5ELEMENT_NAME_SPECIAL);
-  ELT_LABEL = new nsHtml5ElementName(nsHtml5Atoms::label, nsHtml5Atoms::label, NS_HTML5TREE_BUILDER_OUTPUT_OR_LABEL);
+  ELT_LABEL = new nsHtml5ElementName(nsHtml5Atoms::label, nsHtml5Atoms::label, NS_HTML5TREE_BUILDER_OTHER);
   ELT_LIMIT = new nsHtml5ElementName(nsHtml5Atoms::limit, nsHtml5Atoms::limit, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MFRAC = new nsHtml5ElementName(nsHtml5Atoms::mfrac, nsHtml5Atoms::mfrac, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MPATH = new nsHtml5ElementName(nsHtml5Atoms::mpath, nsHtml5Atoms::mpath, NS_HTML5TREE_BUILDER_OTHER);
   ELT_METER = new nsHtml5ElementName(nsHtml5Atoms::meter, nsHtml5Atoms::meter, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MOVER = new nsHtml5ElementName(nsHtml5Atoms::mover, nsHtml5Atoms::mover, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MINUS = new nsHtml5ElementName(nsHtml5Atoms::minus, nsHtml5Atoms::minus, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MROOT = new nsHtml5ElementName(nsHtml5Atoms::mroot, nsHtml5Atoms::mroot, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MSQRT = new nsHtml5ElementName(nsHtml5Atoms::msqrt, nsHtml5Atoms::msqrt, NS_HTML5TREE_BUILDER_OTHER);
@@ -763,17 +763,17 @@ nsHtml5ElementName::initializeStatics()
   ELT_MEDIAN = new nsHtml5ElementName(nsHtml5Atoms::median, nsHtml5Atoms::median, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MUNDER = new nsHtml5ElementName(nsHtml5Atoms::munder, nsHtml5Atoms::munder, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MARKER = new nsHtml5ElementName(nsHtml5Atoms::marker, nsHtml5Atoms::marker, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MERROR = new nsHtml5ElementName(nsHtml5Atoms::merror, nsHtml5Atoms::merror, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MOMENT = new nsHtml5ElementName(nsHtml5Atoms::moment, nsHtml5Atoms::moment, NS_HTML5TREE_BUILDER_OTHER);
   ELT_MATRIX = new nsHtml5ElementName(nsHtml5Atoms::matrix, nsHtml5Atoms::matrix, NS_HTML5TREE_BUILDER_OTHER);
   ELT_OPTION = new nsHtml5ElementName(nsHtml5Atoms::option, nsHtml5Atoms::option, NS_HTML5TREE_BUILDER_OPTION | NS_HTML5ELEMENT_NAME_OPTIONAL_END_TAG);
   ELT_OBJECT = new nsHtml5ElementName(nsHtml5Atoms::object, nsHtml5Atoms::object, NS_HTML5TREE_BUILDER_OBJECT | NS_HTML5ELEMENT_NAME_SPECIAL | NS_HTML5ELEMENT_NAME_SCOPING);
-  ELT_OUTPUT = new nsHtml5ElementName(nsHtml5Atoms::output, nsHtml5Atoms::output, NS_HTML5TREE_BUILDER_OUTPUT_OR_LABEL);
+  ELT_OUTPUT = new nsHtml5ElementName(nsHtml5Atoms::output, nsHtml5Atoms::output, NS_HTML5TREE_BUILDER_OUTPUT);
   ELT_PRIMES = new nsHtml5ElementName(nsHtml5Atoms::primes, nsHtml5Atoms::primes, NS_HTML5TREE_BUILDER_OTHER);
   ELT_SOURCE = new nsHtml5ElementName(nsHtml5Atoms::source, nsHtml5Atoms::source, NS_HTML5TREE_BUILDER_PARAM_OR_SOURCE_OR_TRACK);
   ELT_STRIKE = new nsHtml5ElementName(nsHtml5Atoms::strike, nsHtml5Atoms::strike, NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
   ELT_STRONG = new nsHtml5ElementName(nsHtml5Atoms::strong, nsHtml5Atoms::strong, NS_HTML5TREE_BUILDER_B_OR_BIG_OR_CODE_OR_EM_OR_I_OR_S_OR_SMALL_OR_STRIKE_OR_STRONG_OR_TT_OR_U);
   ELT_SWITCH = new nsHtml5ElementName(nsHtml5Atoms::switch_, nsHtml5Atoms::switch_, NS_HTML5TREE_BUILDER_OTHER);
   ELT_SYMBOL = new nsHtml5ElementName(nsHtml5Atoms::symbol, nsHtml5Atoms::symbol, NS_HTML5TREE_BUILDER_OTHER);
   ELT_SELECT = new nsHtml5ElementName(nsHtml5Atoms::select, nsHtml5Atoms::select, NS_HTML5TREE_BUILDER_SELECT | NS_HTML5ELEMENT_NAME_SPECIAL);
   ELT_SUBSET = new nsHtml5ElementName(nsHtml5Atoms::subset, nsHtml5Atoms::subset, NS_HTML5TREE_BUILDER_OTHER);
--- a/parser/html/nsHtml5TreeBuilder.cpp
+++ b/parser/html/nsHtml5TreeBuilder.cpp
@@ -1407,17 +1407,17 @@ nsHtml5TreeBuilder::startTag(nsHtml5Elem
             case NS_HTML5TREE_BUILDER_TR:
             case NS_HTML5TREE_BUILDER_TD_OR_TH:
             case NS_HTML5TREE_BUILDER_FRAME:
             case NS_HTML5TREE_BUILDER_FRAMESET:
             case NS_HTML5TREE_BUILDER_HEAD: {
               errStrayStartTag(name);
               NS_HTML5_BREAK(starttagloop);
             }
-            case NS_HTML5TREE_BUILDER_OUTPUT_OR_LABEL: {
+            case NS_HTML5TREE_BUILDER_OUTPUT: {
               reconstructTheActiveFormattingElements();
               appendToCurrentNodeAndPushElementMayFoster(elementName, attributes, formPointer);
               attributes = nullptr;
               NS_HTML5_BREAK(starttagloop);
             }
             default: {
               reconstructTheActiveFormattingElements();
               appendToCurrentNodeAndPushElementMayFoster(elementName, attributes);
--- a/parser/html/nsHtml5TreeBuilder.h
+++ b/parser/html/nsHtml5TreeBuilder.h
@@ -329,17 +329,17 @@ class nsHtml5TreeBuilder : public nsAHtm
 #define NS_HTML5TREE_BUILDER_RB_OR_RTC 53
 #define NS_HTML5TREE_BUILDER_PARAM_OR_SOURCE_OR_TRACK 55
 #define NS_HTML5TREE_BUILDER_MGLYPH_OR_MALIGNMARK 56
 #define NS_HTML5TREE_BUILDER_MI_MO_MN_MS_MTEXT 57
 #define NS_HTML5TREE_BUILDER_ANNOTATION_XML 58
 #define NS_HTML5TREE_BUILDER_FOREIGNOBJECT_OR_DESC 59
 #define NS_HTML5TREE_BUILDER_NOEMBED 60
 #define NS_HTML5TREE_BUILDER_FIELDSET 61
-#define NS_HTML5TREE_BUILDER_OUTPUT_OR_LABEL 62
+#define NS_HTML5TREE_BUILDER_OUTPUT 62
 #define NS_HTML5TREE_BUILDER_OBJECT 63
 #define NS_HTML5TREE_BUILDER_FONT 64
 #define NS_HTML5TREE_BUILDER_KEYGEN 65
 #define NS_HTML5TREE_BUILDER_MENUITEM 66
 #define NS_HTML5TREE_BUILDER_TEMPLATE 67
 #define NS_HTML5TREE_BUILDER_IMG 68
 #define NS_HTML5TREE_BUILDER_RT_OR_RP 69
 #define NS_HTML5TREE_BUILDER_IN_ROW 0
deleted file mode 100644
--- a/testing/web-platform/meta/html/semantics/forms/form-control-infrastructure/form.html.ini
+++ /dev/null
@@ -1,20 +0,0 @@
-[form.html]
-  type: testharness
-  [label.form]
-    expected: FAIL
-
-  [label-form.form]
-    expected: FAIL
-
-  [label-form-form2.form]
-    expected: FAIL
-
-  [label-for-control-form-in-form.form]
-    expected: FAIL
-
-  [label-for-control-form.form]
-    expected: FAIL
-
-  [label-in-table.form]
-    expected: FAIL
-
--- a/testing/web-platform/meta/html/semantics/forms/the-label-element/label-attributes.html.ini
+++ b/testing/web-platform/meta/html/semantics/forms/the-label-element/label-attributes.html.ini
@@ -10,14 +10,8 @@
     expected: FAIL
 
   [A form control has no label 2.]
     expected: FAIL
 
   [A form control has an implicit label.]
     expected: FAIL
 
-  [A label in a form without a control]
-    expected: FAIL
-
-  [A label outside a form with a control inside the form]
-    expected: FAIL
-