Backed out 1 changesets (bug 1162765)
authorWes Kocher <wkocher@mozilla.com>
Fri, 08 May 2015 18:18:03 -0700
changeset 274445 e6d93b374a9bc80e87553c36d6555dfa97a669b7
parent 274444 24378757d86c7a85d6f1195416f47d391a8d6d5a
child 274446 673edf1e9272a9c8c92987e26f4b27fae1ca5b74
push id863
push userraliiev@mozilla.com
push dateMon, 03 Aug 2015 13:22:43 +0000
treeherdermozilla-release@f6321b14228d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1162765
milestone40.0a1
backs out18886e5d06dfd2aa0d869d5aadc9bc733d77847d
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
Backed out 1 changesets (bug 1162765) Backed out changeset 18886e5d06df (bug 1162765)
dom/html/HTMLFieldSetElement.cpp
dom/html/nsGenericHTMLElement.cpp
dom/html/nsGenericHTMLElement.h
--- a/dom/html/HTMLFieldSetElement.cpp
+++ b/dom/html/HTMLFieldSetElement.cpp
@@ -27,16 +27,20 @@ HTMLFieldSetElement::HTMLFieldSetElement
   SetBarredFromConstraintValidation(true);
 
   // We start out enabled and valid.
   AddStatesSilently(NS_EVENT_STATE_ENABLED | NS_EVENT_STATE_VALID);
 }
 
 HTMLFieldSetElement::~HTMLFieldSetElement()
 {
+  uint32_t length = mDependentElements.Length();
+  for (uint32_t i = 0; i < length; ++i) {
+    mDependentElements[i]->ForgetFieldSet(this);
+  }
 }
 
 // nsISupports
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(HTMLFieldSetElement, nsGenericHTMLFormElement,
                                    mValidity, mElements)
 
 NS_IMPL_ADDREF_INHERITED(HTMLFieldSetElement, Element)
--- a/dom/html/nsGenericHTMLElement.cpp
+++ b/dom/html/nsGenericHTMLElement.cpp
@@ -1890,49 +1890,41 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION
   NS_INTERFACE_TABLE_INHERITED(nsGenericHTMLFormElement,
                                nsIFormControl)
 NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsGenericHTMLFormElement)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsGenericHTMLFormElement,
                                                   nsGenericHTMLElement)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mForm)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFieldSet)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsGenericHTMLFormElement,
                                                 nsGenericHTMLElement)
   tmp->ClearForm(true);
-  tmp->ClearFieldSet();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 nsGenericHTMLFormElement::nsGenericHTMLFormElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo)
+  , mFieldSet(nullptr)
 {
   // We should add the NS_EVENT_STATE_ENABLED bit here as needed, but
   // that depends on our type, which is not initialized yet.  So we
   // have to do this in subclasses.
 }
 
 nsGenericHTMLFormElement::~nsGenericHTMLFormElement()
 {
-  ClearFieldSet();
+  if (mFieldSet) {
+    mFieldSet->RemoveElement(this);
+  }
 
   // Check that this element doesn't know anything about its form at this point.
   NS_ASSERTION(!mForm, "mForm should be null at this point!");
 }
 
-void
-nsGenericHTMLFormElement::ClearFieldSet()
-{
-  if (mFieldSet) {
-    mFieldSet->RemoveElement(this);
-    mFieldSet = nullptr;
-  }
-}
-
 nsINode*
 nsGenericHTMLFormElement::GetScopeChainParent() const
 {
   return mForm ? mForm : nsGenericHTMLElement::GetScopeChainParent();
 }
 
 bool
 nsGenericHTMLFormElement::IsNodeOfType(uint32_t aFlags) const
@@ -2259,16 +2251,24 @@ nsGenericHTMLFormElement::PreHandleEvent
 /* virtual */
 bool
 nsGenericHTMLFormElement::IsDisabled() const
 {
   return HasAttr(kNameSpaceID_None, nsGkAtoms::disabled) ||
          (mFieldSet && mFieldSet->IsDisabled());
 }
 
+void
+nsGenericHTMLFormElement::ForgetFieldSet(nsIContent* aFieldset)
+{
+  if (mFieldSet == aFieldset) {
+    mFieldSet = nullptr;
+  }
+}
+
 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 &&
--- a/dom/html/nsGenericHTMLElement.h
+++ b/dom/html/nsGenericHTMLElement.h
@@ -1327,28 +1327,34 @@ public:
    */
   virtual void FieldSetDisabledChanged(bool aNotify);
 
   void FieldSetFirstLegendChanged(bool aNotify) {
     UpdateFieldSet(aNotify);
   }
 
   /**
+   * This callback is called by a fieldset on all it's elements when it's being
+   * destroyed. When called, the elements should check that aFieldset is there
+   * first parent fieldset and null mFieldset in that case only.
+   *
+   * @param aFieldSet The fieldset being removed.
+   */
+  void ForgetFieldSet(nsIContent* aFieldset);
+
+  /**
    * Returns if the control can be disabled.
    */
   bool CanBeDisabled() const;
 
   virtual bool IsHTMLFocusable(bool aWithMouse, bool* aIsFocusable,
                                  int32_t* aTabIndex) override;
 
   virtual bool IsLabelable() const override;
 
-private:
-  void ClearFieldSet();
-
 protected:
   virtual ~nsGenericHTMLFormElement();
 
   virtual nsresult BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                                  const nsAttrValueOrString* aValue,
                                  bool aNotify) override;
 
   virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
@@ -1408,17 +1414,17 @@ protected:
   // Get our focus state.  If this returns eInactiveWindow, it will set this
   // element as the focused element for that window.
   FocusTristate FocusState();
 
   /** The form that contains this control */
   nsRefPtr<mozilla::dom::HTMLFormElement> mForm;
 
   /* This is a pointer to our closest fieldset parent if any */
-  nsRefPtr<mozilla::dom::HTMLFieldSetElement> mFieldSet;
+  mozilla::dom::HTMLFieldSetElement* mFieldSet;
 };
 
 class nsGenericHTMLFormElementWithState : public nsGenericHTMLFormElement
 {
 public:
   explicit nsGenericHTMLFormElementWithState(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
 
   /**