Backed out changeset a252f3d0a8c9 (bug 1133213) a=backout
authorWes Kocher <wkocher@mozilla.com>
Mon, 21 Sep 2015 13:12:35 -0700
changeset 296113 3e5c15ad88940912747f2c5387441090113cf28d
parent 296112 701a59dcfa76cf47afe26db441ac92f23e3e7f0b
child 296114 968702bfd84b2c01ecee6591e0ebcb195e7afff1
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbackout
bugs1133213
milestone43.0a2
backs outa252f3d0a8c970231c8db43638d0f68e82b66ac3
Backed out changeset a252f3d0a8c9 (bug 1133213) a=backout
accessible/base/AccEvent.cpp
accessible/base/AccEvent.h
accessible/base/EventQueue.cpp
accessible/base/NotificationController.cpp
accessible/base/NotificationController.h
accessible/base/TreeWalker.cpp
accessible/base/TreeWalker.h
accessible/generic/Accessible.cpp
accessible/generic/Accessible.h
accessible/generic/DocAccessible.cpp
accessible/generic/DocAccessible.h
accessible/tests/mochitest/common.js
accessible/tests/mochitest/tree/test_aria_presentation.html
accessible/tests/mochitest/treeupdate/a11y.ini
accessible/tests/mochitest/treeupdate/test_ariaowns.html
dom/base/ChildIterator.h
--- a/accessible/base/AccEvent.cpp
+++ b/accessible/base/AccEvent.cpp
@@ -99,19 +99,18 @@ AccReorderEvent::IsShowHideEventTarget(c
   return 0;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // AccHideEvent
 ////////////////////////////////////////////////////////////////////////////////
 
 AccHideEvent::
-  AccHideEvent(Accessible* aTarget, nsINode* aTargetNode, bool aNeedsShutdown) :
-  AccMutationEvent(::nsIAccessibleEvent::EVENT_HIDE, aTarget, aTargetNode),
-  mNeedsShutdown(aNeedsShutdown)
+  AccHideEvent(Accessible* aTarget, nsINode* aTargetNode) :
+  AccMutationEvent(::nsIAccessibleEvent::EVENT_HIDE, aTarget, aTargetNode)
 {
   mNextSibling = mAccessible->NextSibling();
   mPrevSibling = mAccessible->PrevSibling();
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // AccShowEvent
--- a/accessible/base/AccEvent.h
+++ b/accessible/base/AccEvent.h
@@ -245,34 +245,31 @@ protected:
 
 
 /**
  * Accessible hide event.
  */
 class AccHideEvent: public AccMutationEvent
 {
 public:
-  AccHideEvent(Accessible* aTarget, nsINode* aTargetNode,
-               bool aNeedsShutdown = true);
+  AccHideEvent(Accessible* aTarget, nsINode* aTargetNode);
 
   // Event
   static const EventGroup kEventGroup = eHideEvent;
   virtual unsigned int GetEventGroups() const override
   {
     return AccMutationEvent::GetEventGroups() | (1U << eHideEvent);
   }
 
   // AccHideEvent
   Accessible* TargetParent() const { return mParent; }
   Accessible* TargetNextSibling() const { return mNextSibling; }
   Accessible* TargetPrevSibling() const { return mPrevSibling; }
-  bool NeedsShutdown() const { return mNeedsShutdown; }
 
 protected:
-  bool mNeedsShutdown;
   nsRefPtr<Accessible> mNextSibling;
   nsRefPtr<Accessible> mPrevSibling;
 
   friend class EventQueue;
 };
 
 
 /**
--- a/accessible/base/EventQueue.cpp
+++ b/accessible/base/EventQueue.cpp
@@ -541,17 +541,15 @@ EventQueue::ProcessEventQueue()
       // Fire text change events.
       AccMutationEvent* mutationEvent = downcast_accEvent(event);
       if (mutationEvent) {
         if (mutationEvent->mTextChangeEvent)
           nsEventShell::FireEvent(mutationEvent->mTextChangeEvent);
       }
     }
 
-    AccHideEvent* hideEvent = downcast_accEvent(event);
-    if (hideEvent && hideEvent->NeedsShutdown()) {
+    if (event->mEventType == nsIAccessibleEvent::EVENT_HIDE)
       mDocument->ShutdownChildrenInSubtree(event->mAccessible);
-    }
 
     if (!mDocument)
       return;
   }
 }
--- a/accessible/base/NotificationController.cpp
+++ b/accessible/base/NotificationController.cpp
@@ -104,30 +104,30 @@ NotificationController::ScheduleContentI
   nsRefPtr<ContentInsertion> insertion = new ContentInsertion(mDocument,
                                                               aContainer);
   if (insertion && insertion->InitChildList(aStartChildNode, aEndChildNode) &&
       mContentInsertions.AppendElement(insertion)) {
     ScheduleProcessing();
   }
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// NotificationCollector: protected
+
 void
 NotificationController::ScheduleProcessing()
 {
   // If notification flush isn't planed yet start notification flush
   // asynchronously (after style and layout).
   if (mObservingState == eNotObservingRefresh) {
     if (mPresShell->AddRefreshObserver(this, Flush_Display))
       mObservingState = eRefreshObserving;
   }
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// NotificationCollector: protected
-
 bool
 NotificationController::IsUpdatePending()
 {
   return mPresShell->IsLayoutFlushObserver() ||
     mObservingState == eRefreshProcessingForUpdate ||
     mContentInsertions.Length() != 0 || mNotifications.Length() != 0 ||
     mTextHash.Count() != 0 ||
     !mDocument->HasLoadState(DocAccessible::eTreeConstructed);
--- a/accessible/base/NotificationController.h
+++ b/accessible/base/NotificationController.h
@@ -3,18 +3,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_a11y_NotificationController_h_
 #define mozilla_a11y_NotificationController_h_
 
 #include "EventQueue.h"
 
-#include "mozilla/IndexSequence.h"
-#include "mozilla/Tuple.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsRefreshDriver.h"
 
 #ifdef A11Y_LOG
 #include "Logging.h"
 #endif
 
 namespace mozilla {
@@ -51,42 +49,42 @@ private:
 
 /**
  * Template class for generic notification.
  *
  * @note  Instance is kept as a weak ref, the caller must guarantee it exists
  *        longer than the document accessible owning the notification controller
  *        that this notification is processed by.
  */
-template<class Class, class ... Args>
+template<class Class, class Arg>
 class TNotification : public Notification
 {
 public:
-  typedef void (Class::*Callback)(Args* ...);
+  typedef void (Class::*Callback)(Arg*);
 
-  TNotification(Class* aInstance, Callback aCallback, Args* ... aArgs) :
-    mInstance(aInstance), mCallback(aCallback), mArgs(aArgs...) { }
+  TNotification(Class* aInstance, Callback aCallback, Arg* aArg) :
+    mInstance(aInstance), mCallback(aCallback), mArg(aArg) { }
   virtual ~TNotification() { mInstance = nullptr; }
 
   virtual void Process() override
-    { ProcessHelper(typename IndexSequenceFor<Args...>::Type()); }
+  {
+    (mInstance->*mCallback)(mArg);
+
+    mInstance = nullptr;
+    mCallback = nullptr;
+    mArg = nullptr;
+  }
 
 private:
   TNotification(const TNotification&);
   TNotification& operator = (const TNotification&);
 
-  template <size_t... Indices>
-    void ProcessHelper(IndexSequence<Indices...>)
-  {
-     (mInstance->*mCallback)(Get<Indices>(mArgs)...);
-  }
-
   Class* mInstance;
   Callback mCallback;
-  Tuple<nsRefPtr<Args> ...> mArgs;
+  nsRefPtr<Arg> mArg;
 };
 
 /**
  * Used to process notifications from core for the document accessible.
  */
 class NotificationController final : public EventQueue,
                                      public nsARefreshObserver
 {
@@ -129,22 +127,16 @@ public:
   /**
    * Pend accessible tree update for content insertion.
    */
   void ScheduleContentInsertion(Accessible* aContainer,
                                 nsIContent* aStartChildNode,
                                 nsIContent* aEndChildNode);
 
   /**
-   * Start to observe refresh to make notifications and events processing after
-   * layout.
-   */
-  void ScheduleProcessing();
-
-  /**
    * Process the generic notification synchronously if there are no pending
    * layout changes and no notifications are pending or being processed right
    * now. Otherwise, queue it up to process asynchronously.
    *
    * @note  The caller must guarantee that the given instance still exists when
    *        the notification is processed.
    */
   template<class Class, class Arg>
@@ -168,38 +160,45 @@ public:
   }
 
   /**
    * Schedule the generic notification to process asynchronously.
    *
    * @note  The caller must guarantee that the given instance still exists when
    *        the notification is processed.
    */
-  template<class Class>
+  template<class Class, class Arg>
   inline void ScheduleNotification(Class* aInstance,
-                                   typename TNotification<Class>::Callback aMethod)
+                                   typename TNotification<Class, Arg>::Callback aMethod,
+                                   Arg* aArg)
   {
     nsRefPtr<Notification> notification =
-      new TNotification<Class>(aInstance, aMethod);
+      new TNotification<Class, Arg>(aInstance, aMethod, aArg);
     if (notification && mNotifications.AppendElement(notification))
       ScheduleProcessing();
   }
 
 #ifdef DEBUG
   bool IsUpdating() const
     { return mObservingState == eRefreshProcessingForUpdate; }
 #endif
 
 protected:
   virtual ~NotificationController();
 
   nsCycleCollectingAutoRefCnt mRefCnt;
   NS_DECL_OWNINGTHREAD
 
   /**
+   * Start to observe refresh to make notifications and events processing after
+   * layout.
+   */
+  void ScheduleProcessing();
+
+  /**
    * Return true if the accessible tree state update is pending.
    */
   bool IsUpdatePending();
 
 private:
   NotificationController(const NotificationController&);
   NotificationController& operator = (const NotificationController&);
 
--- a/accessible/base/TreeWalker.cpp
+++ b/accessible/base/TreeWalker.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "TreeWalker.h"
 
 #include "Accessible.h"
-#include "AccIterator.h"
 #include "nsAccessibilityService.h"
 #include "DocAccessible.h"
 
 #include "mozilla/dom/ChildIterator.h"
 #include "mozilla/dom/Element.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
@@ -46,26 +45,30 @@ TreeWalker::~TreeWalker()
 // TreeWalker: private
 
 Accessible*
 TreeWalker::NextChild()
 {
   if (mStateStack.IsEmpty())
     return nullptr;
 
-  ChildrenIterator* top = &mStateStack[mStateStack.Length() - 1];
+  dom::AllChildrenIterator* top = &mStateStack[mStateStack.Length() - 1];
   while (top) {
-    Accessible* child = nullptr;
-    bool skipSubtree = false;
-    while (nsIContent* childNode = Next(top, &child, &skipSubtree)) {
-      if (child)
-        return child;
+    while (nsIContent* childNode = top->GetNextChild()) {
+      bool isSubtreeHidden = false;
+      Accessible* accessible = mFlags & eWalkCache ?
+        mDoc->GetAccessible(childNode) :
+        GetAccService()->GetOrCreateAccessible(childNode, mContext,
+                                               &isSubtreeHidden);
+
+      if (accessible)
+        return accessible;
 
       // Walk down into subtree to find accessibles.
-      if (!skipSubtree && childNode->IsElement())
+      if (!isSubtreeHidden && childNode->IsElement())
         top = PushState(childNode);
     }
 
     top = PopState();
   }
 
   // If we traversed the whole subtree of the anchor node. Move to next node
   // relative anchor node within the context subtree if possible.
@@ -74,73 +77,34 @@ TreeWalker::NextChild()
 
   nsINode* contextNode = mContext->GetNode();
   while (mAnchorNode != contextNode) {
     nsINode* parentNode = mAnchorNode->GetFlattenedTreeParent();
     if (!parentNode || !parentNode->IsElement())
       return nullptr;
 
     nsIContent* parent = parentNode->AsElement();
-    top = PushState(parent);
-    while (nsIContent* childNode = Next(top)) {
+    top = mStateStack.AppendElement(dom::AllChildrenIterator(parent,
+                                                             mChildFilter));
+    while (nsIContent* childNode = top->GetNextChild()) {
       if (childNode == mAnchorNode) {
         mAnchorNode = parent;
         return NextChild();
       }
     }
 
     // XXX We really should never get here, it means we're trying to find an
     // accessible for a dom node where iterating over its parent's children
     // doesn't return it. However this sometimes happens when we're asked for
     // the nearest accessible to place holder content which we ignore.
     mAnchorNode = parent;
   }
 
   return nullptr;
 }
 
-nsIContent*
-TreeWalker::Next(ChildrenIterator* aIter, Accessible** aAccesible,
-                 bool* aSkipSubtree)
-{
-  nsIContent* childEl = aIter->mDOMIter.GetNextChild();
-  if (!aAccesible)
-    return childEl;
-
-  *aAccesible = nullptr;
-  *aSkipSubtree = false;
-
-  if (childEl) {
-    Accessible* accessible = mFlags & eWalkCache ?
-      mDoc->GetAccessible(childEl) :
-      GetAccService()->GetOrCreateAccessible(childEl, mContext, aSkipSubtree);
-
-    // Ignore the accessible and its subtree if it was repositioned by means of
-    // aria-owns.
-    if (accessible) {
-      if (accessible->IsRepositioned()) {
-        *aSkipSubtree = true;
-      } else {
-        *aAccesible = accessible;
-      }
-    }
-    return childEl;
-  }
-
-  // At last iterate over ARIA owned children.
-  Accessible* parent = mDoc->GetAccessible(aIter->mDOMIter.Parent());
-  if (parent) {
-    Accessible* child = mDoc->ARIAOwnedAt(parent, aIter->mARIAOwnsIdx++);
-    if (child) {
-      *aAccesible = child;
-      return child->GetContent();
-    }
-  }
-  return nullptr;
-}
-
-TreeWalker::ChildrenIterator*
+dom::AllChildrenIterator*
 TreeWalker::PopState()
 {
   size_t length = mStateStack.Length();
   mStateStack.RemoveElementAt(length - 1);
   return mStateStack.IsEmpty() ? nullptr : &mStateStack[mStateStack.Length() - 1];
 }
--- a/accessible/base/TreeWalker.h
+++ b/accessible/base/TreeWalker.h
@@ -52,47 +52,37 @@ public:
    */
   Accessible* NextChild();
 
 private:
   TreeWalker();
   TreeWalker(const TreeWalker&);
   TreeWalker& operator =(const TreeWalker&);
 
-  struct ChildrenIterator {
-    ChildrenIterator(nsIContent* aNode, uint32_t aFilter) :
-      mDOMIter(aNode, aFilter), mARIAOwnsIdx(0) { }
-
-    dom::AllChildrenIterator mDOMIter;
-    uint32_t mARIAOwnsIdx;
-  };
-
-  nsIContent* Next(ChildrenIterator* aIter, Accessible** aAccessible = nullptr,
-                   bool* aSkipSubtree = nullptr);
-
   /**
    * Create new state for the given node and push it on top of stack.
    *
    * @note State stack is used to navigate up/down the DOM subtree during
    *        accessible children search.
    */
-  ChildrenIterator* PushState(nsIContent* aContent)
+  dom::AllChildrenIterator* PushState(nsIContent* aContent)
   {
-    return mStateStack.AppendElement(ChildrenIterator(aContent, mChildFilter));
+    return mStateStack.AppendElement(dom::AllChildrenIterator(aContent,
+                                                              mChildFilter));
   }
 
   /**
    * Pop state from stack.
    */
-  ChildrenIterator* PopState();
+  dom::AllChildrenIterator* PopState();
 
   DocAccessible* mDoc;
   Accessible* mContext;
   nsIContent* mAnchorNode;
-  nsAutoTArray<ChildrenIterator, 20> mStateStack;
+  nsAutoTArray<dom::AllChildrenIterator, 20> mStateStack;
   int32_t mChildFilter;
   uint32_t mFlags;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif // mozilla_a11y_TreeWalker_h_
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -1969,18 +1969,18 @@ Accessible::NativeName(nsString& aName)
 void
 Accessible::BindToParent(Accessible* aParent, uint32_t aIndexInParent)
 {
   NS_PRECONDITION(aParent, "This method isn't used to set null parent!");
 
   if (mParent) {
     if (mParent != aParent) {
       NS_ERROR("Adopting child!");
+      mParent->RemoveChild(this);
       mParent->InvalidateChildrenGroupInfo();
-      mParent->RemoveChild(this);
     } else {
       NS_ERROR("Binding to the same parent!");
       return;
     }
   }
 
   mParent = aParent;
   mIndexInParent = aIndexInParent;
--- a/accessible/generic/Accessible.h
+++ b/accessible/generic/Accessible.h
@@ -155,18 +155,16 @@ public:
    */
   virtual nsINode* GetNode() const;
   inline already_AddRefed<nsIDOMNode> DOMNode() const
   {
     nsCOMPtr<nsIDOMNode> DOMNode = do_QueryInterface(GetNode());
     return DOMNode.forget();
   }
   nsIContent* GetContent() const { return mContent; }
-  mozilla::dom::Element* Elm() const
-    { return mContent && mContent->IsElement() ? mContent->AsElement() : nullptr; }
 
   /**
    * Return node type information of DOM node associated with the accessible.
    */
   bool IsContent() const
     { return GetNode() && GetNode()->IsNodeOfType(nsINode::eCONTENT); }
 
   /**
@@ -897,43 +895,31 @@ public:
   {
     if (aIsSurviving)
       mStateFlags |= eSurvivingInUpdate;
     else
       mStateFlags &= ~eSurvivingInUpdate;
   }
 
   /**
-   * Get/set repositioned bit indicating that the accessible was moved in
-   * the accessible tree, i.e. the accessible tree structure differs from DOM.
-   */
-  bool IsRepositioned() const { return mStateFlags & eRepositioned; }
-  void SetRepositioned(bool aRepositioned)
-  {
-    if (aRepositioned)
-      mStateFlags |= eRepositioned;
-    else
-      mStateFlags &= ~eRepositioned;
-  }
-
-  /**
    * Return true if this accessible has a parent whose name depends on this
    * accessible.
    */
   bool HasNameDependentParent() const
     { return mContextFlags & eHasNameDependentParent; }
 
   /**
    * Return true if aria-hidden="true" is applied to the accessible or inherited
    * from the parent.
    */
   bool IsARIAHidden() const { return mContextFlags & eARIAHidden; }
   void SetARIAHidden(bool aIsDefined);
 
 protected:
+
   virtual ~Accessible();
 
   /**
    * Return the accessible name provided by native markup. It doesn't take
    * into account ARIA markup used to specify the name.
    */
   virtual mozilla::a11y::ENameValueFlag NativeName(nsString& aName);
 
@@ -999,19 +985,18 @@ protected:
     eIsNotInDocument = 1 << 1, // accessible is not in document
     eSharedNode = 1 << 2, // accessible shares DOM node from another accessible
     eNotNodeMapEntry = 1 << 3, // accessible shouldn't be in document node map
     eHasNumericValue = 1 << 4, // accessible has a numeric value
     eGroupInfoDirty = 1 << 5, // accessible needs to update group info
     eSubtreeMutating = 1 << 6, // subtree is being mutated
     eIgnoreDOMUIEvent = 1 << 7, // don't process DOM UI events for a11y events
     eSurvivingInUpdate = 1 << 8, // parent drops children to recollect them
-    eRepositioned = 1 << 9, // accessible was moved in tree
 
-    eLastStateFlag = eRepositioned
+    eLastStateFlag = eSurvivingInUpdate
   };
 
   /**
    * Flags used for contextual information about the accessible.
    */
   enum ContextFlags {
     eHasNameDependentParent = 1 << 0, // Parent's name depends on this accessible.
     eARIAHidden = 1 << 1,
@@ -1116,17 +1101,17 @@ protected:
   nsCOMPtr<nsIContent> mContent;
   DocAccessible* mDoc;
 
   nsRefPtr<Accessible> mParent;
   nsTArray<nsRefPtr<Accessible> > mChildren;
   int32_t mIndexInParent;
 
   static const uint8_t kChildrenFlagsBits = 2;
-  static const uint8_t kStateFlagsBits = 10;
+  static const uint8_t kStateFlagsBits = 9;
   static const uint8_t kContextFlagsBits = 2;
   static const uint8_t kTypeBits = 6;
   static const uint8_t kGenericTypesBits = 14;
 
   /**
    * Keep in sync with ChildrenFlags, StateFlags, ContextFlags, and AccTypes.
    */
   uint32_t mChildrenFlags : kChildrenFlagsBits;
--- a/accessible/generic/DocAccessible.cpp
+++ b/accessible/generic/DocAccessible.cpp
@@ -702,17 +702,17 @@ DocAccessible::AttributeWillChange(nsIDo
 
     accessible = this;
   }
 
   // Update dependent IDs cache. Take care of elements that are accessible
   // because dependent IDs cache doesn't contain IDs from non accessible
   // elements.
   if (aModType != nsIDOMMutationEvent::ADDITION)
-    RemoveDependentIDsFor(accessible, aAttribute);
+    RemoveDependentIDsFor(aElement, aAttribute);
 
   // Store the ARIA attribute old value so that it can be used after
   // attribute change. Note, we assume there's no nested ARIA attribute
   // changes. If this happens then we should end up with keeping a stack of
   // old values.
 
   // XXX TODO: bugs 472142, 472143.
   // Here we will want to cache whatever attribute values we are interested
@@ -764,17 +764,17 @@ DocAccessible::AttributeChanged(nsIDocum
 
   // Update dependent IDs cache. Take care of accessible elements because no
   // accessible element means either the element is not accessible at all or
   // its accessible will be created later. It doesn't make sense to keep
   // dependent IDs for non accessible elements. For the second case we'll update
   // dependent IDs cache when its accessible is created.
   if (aModType == nsIDOMMutationEvent::MODIFICATION ||
       aModType == nsIDOMMutationEvent::ADDITION) {
-    AddDependentIDsFor(accessible, aAttribute);
+    AddDependentIDsFor(aElement, aAttribute);
   }
 }
 
 // DocAccessible protected member
 void
 DocAccessible::AttributeChangedImpl(Accessible* aAccessible,
                                     int32_t aNameSpaceID, nsIAtom* aAttribute)
 {
@@ -1236,17 +1236,19 @@ DocAccessible::BindToDocument(Accessible
   if (aAccessible->IsNodeMapEntry())
     mNodeToAccessibleMap.Put(aAccessible->GetNode(), aAccessible);
 
   // Put into unique ID cache.
   mAccessibleCache.Put(aAccessible->UniqueID(), aAccessible);
 
   aAccessible->SetRoleMapEntry(aRoleMapEntry);
 
-  AddDependentIDsFor(aAccessible);
+  nsIContent* content = aAccessible->GetContent();
+  if (content && content->IsElement())
+    AddDependentIDsFor(content->AsElement());
 }
 
 void
 DocAccessible::UnbindFromDocument(Accessible* aAccessible)
 {
   NS_ASSERTION(mAccessibleCache.GetWeak(aAccessible->UniqueID()),
                "Unbinding the unbound accessible!");
 
@@ -1331,59 +1333,16 @@ DocAccessible::ProcessInvalidationList()
     if (!HasAccessible(content)) {
       Accessible* container = GetContainerAccessible(content);
       if (container)
         UpdateTreeOnInsertion(container);
     }
   }
 
   mInvalidationList.Clear();
-
-  // Alter the tree according to aria-owns (seize the trees).
-  for (uint32_t idx = 0; idx < mARIAOwnsInvalidationList.Length(); idx++) {
-    Accessible* owner = mARIAOwnsInvalidationList[idx].mOwner;
-    Accessible* child = GetAccessible(mARIAOwnsInvalidationList[idx].mChild);
-    if (!child) {
-      continue;
-    }
-
-    // XXX: update context flags
-    {
-      Accessible* oldParent = child->Parent();
-      nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(oldParent);
-      nsRefPtr<AccMutationEvent> hideEvent =
-        new AccHideEvent(child, child->GetContent(), false);
-      FireDelayedEvent(hideEvent);
-      reorderEvent->AddSubMutationEvent(hideEvent);
-
-      AutoTreeMutation mut(oldParent);
-      oldParent->RemoveChild(child);
-
-      MaybeNotifyOfValueChange(oldParent);
-      FireDelayedEvent(reorderEvent);
-    }
-
-    {
-      nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(owner);
-      nsRefPtr<AccMutationEvent> showEvent =
-        new AccShowEvent(child, child->GetContent());
-      FireDelayedEvent(showEvent);
-      reorderEvent->AddSubMutationEvent(showEvent);
-
-      AutoTreeMutation mut(owner);
-      owner->AppendChild(child);
-
-      MaybeNotifyOfValueChange(owner);
-      FireDelayedEvent(reorderEvent);
-    }
-
-    child->SetRepositioned(true);
-  }
-
-  mARIAOwnsInvalidationList.Clear();
 }
 
 Accessible*
 DocAccessible::GetAccessibleEvenIfNotInMap(nsINode* aNode) const
 {
 if (!aNode->IsContent() || !aNode->AsContent()->IsHTMLElement(nsGkAtoms::area))
     return GetAccessible(aNode);
 
@@ -1532,207 +1491,104 @@ DocAccessible::ProcessLoad()
 
   // Fire busy state change event.
   nsRefPtr<AccEvent> stateEvent =
     new AccStateChangeEvent(this, states::BUSY, false);
   FireDelayedEvent(stateEvent);
 }
 
 void
-DocAccessible::AddDependentIDsFor(Accessible* aRelProvider, nsIAtom* aRelAttr)
+DocAccessible::AddDependentIDsFor(dom::Element* aRelProviderElm,
+                                  nsIAtom* aRelAttr)
 {
-  dom::Element* relProviderEl = aRelProvider->Elm();
-  if (!relProviderEl)
-    return;
-
   for (uint32_t idx = 0; idx < kRelationAttrsLen; idx++) {
     nsIAtom* relAttr = *kRelationAttrs[idx];
     if (aRelAttr && aRelAttr != relAttr)
       continue;
 
     if (relAttr == nsGkAtoms::_for) {
-      if (!relProviderEl->IsAnyOfHTMLElements(nsGkAtoms::label,
-                                               nsGkAtoms::output))
+      if (!aRelProviderElm->IsAnyOfHTMLElements(nsGkAtoms::label,
+                                                nsGkAtoms::output))
         continue;
 
     } else if (relAttr == nsGkAtoms::control) {
-      if (!relProviderEl->IsAnyOfXULElements(nsGkAtoms::label,
-                                              nsGkAtoms::description))
+      if (!aRelProviderElm->IsAnyOfXULElements(nsGkAtoms::label,
+                                               nsGkAtoms::description))
         continue;
     }
 
-    IDRefsIterator iter(this, relProviderEl, relAttr);
+    IDRefsIterator iter(this, aRelProviderElm, relAttr);
     while (true) {
       const nsDependentSubstring id = iter.NextID();
       if (id.IsEmpty())
         break;
 
       AttrRelProviderArray* providers = mDependentIDsHash.Get(id);
       if (!providers) {
         providers = new AttrRelProviderArray();
         if (providers) {
           mDependentIDsHash.Put(id, providers);
         }
       }
 
       if (providers) {
         AttrRelProvider* provider =
-          new AttrRelProvider(relAttr, relProviderEl);
+          new AttrRelProvider(relAttr, aRelProviderElm);
         if (provider) {
           providers->AppendElement(provider);
 
           // We've got here during the children caching. If the referenced
           // content is not accessible then store it to pend its container
           // children invalidation (this happens immediately after the caching
           // is finished).
           nsIContent* dependentContent = iter.GetElem(id);
-          if (dependentContent) {
-            if (!HasAccessible(dependentContent)) {
-              mInvalidationList.AppendElement(dependentContent);
-            }
-
-            if (relAttr == nsGkAtoms::aria_owns) {
-              // Dependent content cannot point to other aria-owns content or
-              // their parents. Ignore it if so.
-              // XXX: note, this alg may make invalid the scenario when X owns Y
-              // and Y owns Z, we should have something smarter to handle that.
-              bool isvalid = true;
-              for (auto it = mARIAOwnsHash.Iter(); !it.Done(); it.Next()) {
-                Accessible* owner = it.Key();
-                nsIContent* parentEl = owner->GetContent();
-                while (parentEl && parentEl != dependentContent) {
-                  parentEl = parentEl->GetParent();
-                }
-                if (parentEl) {
-                  isvalid = false;
-                  break;
-                }
-              }
-              if (isvalid) {
-                // ARIA owns also cannot refer to itself or a parent.
-                nsIContent* parentEl = relProviderEl;
-                while (parentEl && parentEl != dependentContent) {
-                  parentEl = parentEl->GetParent();
-                }
-                if (parentEl) {
-                  isvalid = false;
-                }
-
-                if (isvalid) {
-                  nsTArray<nsIContent*>* list =
-                    mARIAOwnsHash.LookupOrAdd(aRelProvider);
-                  list->AppendElement(dependentContent);
-
-                  mARIAOwnsInvalidationList.AppendElement(
-                    ARIAOwnsPair(aRelProvider, dependentContent));
-                }
-              }
-            }
+          if (dependentContent && !HasAccessible(dependentContent)) {
+            mInvalidationList.AppendElement(dependentContent);
           }
         }
       }
     }
 
     // If the relation attribute is given then we don't have anything else to
     // check.
     if (aRelAttr)
       break;
   }
-
-  // Make sure to schedule the tree update if needed.
-  mNotificationController->ScheduleProcessing();
 }
 
 void
-DocAccessible::RemoveDependentIDsFor(Accessible* aRelProvider,
+DocAccessible::RemoveDependentIDsFor(dom::Element* aRelProviderElm,
                                      nsIAtom* aRelAttr)
 {
-  dom::Element* relProviderElm = aRelProvider->Elm();
-  if (!relProviderElm)
-    return;
-
   for (uint32_t idx = 0; idx < kRelationAttrsLen; idx++) {
     nsIAtom* relAttr = *kRelationAttrs[idx];
     if (aRelAttr && aRelAttr != *kRelationAttrs[idx])
       continue;
 
-    IDRefsIterator iter(this, relProviderElm, relAttr);
+    IDRefsIterator iter(this, aRelProviderElm, relAttr);
     while (true) {
       const nsDependentSubstring id = iter.NextID();
       if (id.IsEmpty())
         break;
 
       AttrRelProviderArray* providers = mDependentIDsHash.Get(id);
       if (providers) {
         for (uint32_t jdx = 0; jdx < providers->Length(); ) {
           AttrRelProvider* provider = (*providers)[jdx];
           if (provider->mRelAttr == relAttr &&
-              provider->mContent == relProviderElm)
+              provider->mContent == aRelProviderElm)
             providers->RemoveElement(provider);
           else
             jdx++;
         }
         if (providers->Length() == 0)
           mDependentIDsHash.Remove(id);
       }
     }
 
-    // aria-owns has gone, put the children back.
-    if (relAttr == nsGkAtoms::aria_owns) {
-      nsTArray<nsIContent*>* children = mARIAOwnsHash.Get(aRelProvider);
-      if (children) {
-        nsTArray<Accessible*> containers;
-
-        // Remove ARIA owned elements from where they belonged.
-        nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(aRelProvider);
-        {
-          AutoTreeMutation mut(aRelProvider);
-          for (uint32_t idx = 0; idx < children->Length(); idx++) {
-            nsIContent* childEl = children->ElementAt(idx);
-            Accessible* child = GetAccessible(childEl);
-            if (child && child->IsRepositioned()) {
-              {
-                nsRefPtr<AccMutationEvent> hideEvent =
-                  new AccHideEvent(child, childEl, false);
-                FireDelayedEvent(hideEvent);
-                reorderEvent->AddSubMutationEvent(hideEvent);
-
-                aRelProvider->RemoveChild(child);
-              }
-
-              // Collect DOM-order containers to update their trees.
-              child->SetRepositioned(false);
-              Accessible* container = GetContainerAccessible(childEl);
-              if (!containers.Contains(container)) {
-                containers.AppendElement(container);
-              }
-            }
-          }
-        }
-
-        mARIAOwnsHash.Remove(aRelProvider);
-        for (uint32_t idx = 0; idx < mARIAOwnsInvalidationList.Length();) {
-          if (mARIAOwnsInvalidationList[idx].mOwner == aRelProvider) {
-            mARIAOwnsInvalidationList.RemoveElementAt(idx);
-            continue;
-          }
-          idx++;
-        }
-
-        MaybeNotifyOfValueChange(aRelProvider);
-        FireDelayedEvent(reorderEvent);
-
-        // Reinserted previously ARIA owned elements into the tree
-        // (restore a DOM-like order).
-        for (uint32_t idx = 0; idx < containers.Length(); idx++) {
-          UpdateTreeOnInsertion(containers[idx]);
-        }
-      }
-    }
-
     // If the relation attribute is given then we don't have anything else to
     // check.
     if (aRelAttr)
       break;
   }
 }
 
 bool
@@ -1945,21 +1801,16 @@ DocAccessible::UpdateTreeOnRemoval(Acces
       if (childNode != containerNode) {
         updateFlags |= UpdateTreeInternal(child, false, reorderEvent);
       } else {
         idx++;
       }
     }
   }
 
-  // We may not have an integral DOM tree to remove all aria-owns relations
-  // from the tree. Validate all relations after timeout to workaround that.
-  mNotificationController->ScheduleNotification<DocAccessible>
-    (this, &DocAccessible::ValidateARIAOwned);
-
   // Content insertion/removal is not cause of accessible tree change.
   if (updateFlags == eNoAccessible)
     return;
 
   MaybeNotifyOfValueChange(aContainer);
   FireDelayedEvent(reorderEvent);
 }
 
@@ -2034,31 +1885,16 @@ DocAccessible::UpdateTreeInternal(Access
     FocusMgr()->DispatchFocusEvent(this, focusedAcc);
     SelectionMgr()->SetControlSelectionListener(focusedAcc->GetNode()->AsElement());
   }
 
   return updateFlags;
 }
 
 void
-DocAccessible::ValidateARIAOwned()
-{
-  for (auto it = mARIAOwnsHash.Iter(); !it.Done(); it.Next()) {
-    nsTArray<nsIContent*>* childEls = it.UserData();
-    for (uint32_t idx = 0; idx < childEls->Length(); idx++) {
-      nsIContent* childEl = childEls->ElementAt(idx);
-      Accessible* child = GetAccessible(childEl);
-      if (child && !child->GetFrame()) {
-        UpdateTreeOnRemoval(child->Parent(), childEl);
-      }
-    }
-  }
-}
-
-void
 DocAccessible::CacheChildrenInSubtree(Accessible* aRoot,
                                       Accessible** aFocusedAcc)
 {
   // If the accessible is focused then report a focus event after all related
   // mutation events.
   if (aFocusedAcc && !*aFocusedAcc &&
       FocusMgr()->HasDOMFocus(aRoot->GetContent()))
     *aFocusedAcc = aRoot;
@@ -2085,17 +1921,20 @@ DocAccessible::CacheChildrenInSubtree(Ac
       FireDelayedEvent(nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE, aRoot);
   }
 }
 
 void
 DocAccessible::UncacheChildrenInSubtree(Accessible* aRoot)
 {
   aRoot->mStateFlags |= eIsNotInDocument;
-  RemoveDependentIDsFor(aRoot);
+
+  nsIContent* rootContent = aRoot->GetContent();
+  if (rootContent && rootContent->IsElement())
+    RemoveDependentIDsFor(rootContent->AsElement());
 
   uint32_t count = aRoot->ContentChildCount();
   for (uint32_t idx = 0; idx < count; idx++)
     UncacheChildrenInSubtree(aRoot->ContentChildAt(idx));
 
   if (aRoot->IsNodeMapEntry() &&
       mNodeToAccessibleMap.Get(aRoot->GetNode()) == aRoot)
     mNodeToAccessibleMap.Remove(aRoot->GetNode());
--- a/accessible/generic/DocAccessible.h
+++ b/accessible/generic/DocAccessible.h
@@ -27,17 +27,17 @@ const uint32_t kDefaultCacheLength = 128
 
 namespace mozilla {
 namespace a11y {
 
 class DocManager;
 class NotificationController;
 class DocAccessibleChild;
 class RelatedAccIterator;
-template<class Class, class ... Args>
+template<class Class, class Arg>
 class TNotification;
 
 class DocAccessible : public HyperTextAccessibleWrap,
                       public nsIDocumentObserver,
                       public nsIObserver,
                       public nsIScrollPositionListener,
                       public nsSupportsWeakReference,
                       public nsIAccessiblePivotObserver
@@ -277,32 +277,16 @@ public:
   }
 
   /**
    * Return an accessible for the given node or its first accessible descendant.
    */
   Accessible* GetAccessibleOrDescendant(nsINode* aNode) const;
 
   /**
-   * Returns aria-owns seized child at the given index.
-   */
-  Accessible* ARIAOwnedAt(Accessible* aParent, uint32_t aIndex) const
-  {
-    nsTArray<nsIContent*>* childrenEl = mARIAOwnsHash.Get(aParent);
-    if (childrenEl) {
-      nsIContent* childEl = childrenEl->SafeElementAt(aIndex);
-      Accessible* child = GetAccessible(childEl);
-      if (child && child->IsRepositioned()) {
-        return child;
-      }
-    }
-    return nullptr;
-  }
-
-  /**
    * Return true if the given ID is referred by relation attribute.
    *
    * @note Different elements may share the same ID if they are hosted inside
    *       XBL bindings. Be careful the result of this method may be  senseless
    *       while it's called for XUL elements (where XBL is used widely).
    */
   bool IsDependentID(const nsAString& aID) const
     { return mDependentIDsHash.Get(aID, nullptr); }
@@ -417,28 +401,28 @@ protected:
   /**
    * Add dependent IDs pointed by accessible element by relation attribute to
    * cache. If the relation attribute is missed then all relation attributes
    * are checked.
    *
    * @param aRelProvider [in] accessible that element has relation attribute
    * @param aRelAttr     [in, optional] relation attribute
    */
-  void AddDependentIDsFor(Accessible* aRelProvider,
+  void AddDependentIDsFor(dom::Element* aRelProviderElm,
                           nsIAtom* aRelAttr = nullptr);
 
   /**
    * Remove dependent IDs pointed by accessible element by relation attribute
    * from cache. If the relation attribute is absent then all relation
    * attributes are checked.
    *
    * @param aRelProvider [in] accessible that element has relation attribute
    * @param aRelAttr     [in, optional] relation attribute
    */
-  void RemoveDependentIDsFor(Accessible* aRelProvider,
+  void RemoveDependentIDsFor(dom::Element* aRelProviderElm,
                              nsIAtom* aRelAttr = nullptr);
 
   /**
    * Update or recreate an accessible depending on a changed attribute.
    *
    * @param aElement   [in] the element the attribute was changed on
    * @param aAttribute [in] the changed attribute
    * @return            true if an action was taken on the attribute change
@@ -503,21 +487,16 @@ protected:
     eAccessible = 1,
     eAlertAccessible = 2
   };
 
   uint32_t UpdateTreeInternal(Accessible* aChild, bool aIsInsert,
                               AccReorderEvent* aReorderEvent);
 
   /**
-   * Validates all aria-owns connections and updates the tree accordingly.
-   */
-  void ValidateARIAOwned();
-
-  /**
    * Create accessible tree.
    *
    * @param aRoot       [in] a root of subtree to create
    * @param aFocusedAcc [in, optional] a focused accessible under created
    *                      subtree if any
    */
   void CacheChildrenInSubtree(Accessible* aRoot,
                               Accessible** aFocusedAcc = nullptr);
@@ -663,35 +642,16 @@ protected:
    * Used for our caching algorithm. We store the list of nodes that should be
    * invalidated.
    *
    * @see ProcessInvalidationList
    */
   nsTArray<nsIContent*> mInvalidationList;
 
   /**
-   * Holds a list of aria-owns relations.
-   */
-  nsClassHashtable<nsPtrHashKey<Accessible>, nsTArray<nsIContent*> >
-    mARIAOwnsHash;
-
-  struct ARIAOwnsPair {
-    ARIAOwnsPair(Accessible* aOwner, nsIContent* aChild) :
-      mOwner(aOwner), mChild(aChild) { }
-    ARIAOwnsPair(const ARIAOwnsPair& aPair) :
-      mOwner(aPair.mOwner), mChild(aPair.mChild) { }
-    ARIAOwnsPair& operator =(const ARIAOwnsPair& aPair)
-      { mOwner = aPair.mOwner; mChild = aPair.mChild; return *this; }
-
-    Accessible* mOwner;
-    nsIContent* mChild;
-  };
-  nsTArray<ARIAOwnsPair> mARIAOwnsInvalidationList;
-
-  /**
    * Used to process notification from core and accessible events.
    */
   nsRefPtr<NotificationController> mNotificationController;
   friend class EventQueue;
   friend class NotificationController;
 
 private:
 
--- a/accessible/tests/mochitest/common.js
+++ b/accessible/tests/mochitest/common.js
@@ -447,49 +447,36 @@ function testAccessibleTree(aAccOrElmOrI
     }
   }
 
   // Test children.
   if ("children" in accTree && accTree["children"] instanceof Array) {
     var children = acc.children;
     var childCount = children.length;
 
+
     if (accTree.children.length != childCount) {
       for (var i = 0; i < Math.max(accTree.children.length, childCount); i++) {
         var accChild;
         try {
           accChild = children.queryElementAt(i, nsIAccessible);
-
-          testChild = accTree.children[i];
-          if (!testChild) {
+          if (!accTree.children[i]) {
             ok(false, prettyName(acc) + " has an extra child at index " + i +
               " : " + prettyName(accChild));
-            continue;
           }
-
-          var key = Object.keys(testChild)[0];
-          var roleName = "ROLE_" + key;
-          if (roleName in nsIAccessibleRole) {
-            testChild = {
-              role: nsIAccessibleRole[roleName],
-              children: testChild[key]
-            };
-          }
-
-          if (accChild.role !== testChild.role) {
+          if (accChild.role !== accTree.children[i].role) {
             ok(false, prettyName(accTree) + " and " + prettyName(acc) +
               " have different children at index " + i + " : " +
-              prettyName(testChild) + ", " + prettyName(accChild));
+              prettyName(accTree.children[i]) + ", " + prettyName(accChild));
           }
           info("Matching " + prettyName(accTree) + " and " + prettyName(acc) +
                " child at index " + i + " : " + prettyName(accChild));
         } catch (e) {
           ok(false, prettyName(accTree) + " has an extra child at index " + i +
-             " : " + prettyName(testChild) + ", " + e);
-          throw e;
+             " : " + prettyName(accTree.children[i]));
         }
       }
     } else {
       if (aFlags & kSkipTreeFullCheck) {
         for (var i = 0; i < childCount; i++) {
           var child = children.queryElementAt(i, nsIAccessible);
           testAccessibleTree(child, accTree.children[i], aFlags);
         }
--- a/accessible/tests/mochitest/tree/test_aria_presentation.html
+++ b/accessible/tests/mochitest/tree/test_aria_presentation.html
@@ -82,26 +82,29 @@
       ] };
     testAccessibleTree("list_cnt", tree);
 
     // Has ARIA globals or referred by ARIA relationship, role='presentation'
     // and role='none' are ignored.
     tree =
       { SECTION: [ // container
         { LABEL: [ // label, has aria-owns
-          { TEXT_LEAF: [ ] },
-          { LABEL: [ // label, referenced by aria-owns
-            { TEXT_LEAF: [ ] }
-          ] },
+          { TEXT_LEAF: [ ] }
+        ] },
+        { TEXT_LEAF: [ ] },
+        { LABEL: [ // label, referenced by aria-owns
+          { TEXT_LEAF: [ ] }
         ] },
+        { TEXT_LEAF: [ ] },
         { LABEL: [ // label, has aria-owns
-          { TEXT_LEAF: [ ] },
-          { LABEL: [ // label, referenced by aria-owns
-            { TEXT_LEAF: [ ] }
-          ] }
+          { TEXT_LEAF: [ ] }
+        ] },
+        { TEXT_LEAF: [ ] },
+        { LABEL: [ // label, referenced by aria-owns
+          { TEXT_LEAF: [ ] }
         ] }
       ] };
     testAccessibleTree("airaglobalprop_cnt", tree);
 
     SimpleTest.finish();
   }
 
   SimpleTest.waitForExplicitFinish();
@@ -164,16 +167,17 @@
     <ul role="presentation">
       <li>item</li>
     </ul>
     <ul role="none">
       <li>item</li>
     </ul>
   </div>
 
-  <div id="airaglobalprop_cnt"><label
-    role="presentation" aria-owns="ariaowned">has aria-owns</label><label
-    role="presentation" id="ariaowned">referred by aria-owns</label><label
-    role="none" aria-owns="ariaowned2">has aria-owns</label><label
-    role="none" id="ariaowned2">referred by aria-owns</label></div>
+  <div id="airaglobalprop_cnt">
+    <label role="presentation" aria-owns="ariaowned">has aria-owns</label>
+    <label role="presentation" id="ariaowned">referred by aria-owns</label>
+    <label role="none" aria-owns="ariaowned2">has aria-owns</label>
+    <label role="none" id="ariaowned2">referred by aria-owns</label>
+  </div>
 
 </body>
 </html>
--- a/accessible/tests/mochitest/treeupdate/a11y.ini
+++ b/accessible/tests/mochitest/treeupdate/a11y.ini
@@ -1,12 +1,11 @@
 [DEFAULT]
 
 [test_ariadialog.html]
-[test_ariaowns.html]
 [test_bug852150.xhtml]
 [test_bug883708.xhtml]
 [test_bug884251.xhtml]
 [test_bug895082.html]
 [test_bug1040735.html]
 [test_bug1100602.html]
 [test_bug1175913.html]
 [test_bug1189277.html]
deleted file mode 100644
--- a/accessible/tests/mochitest/treeupdate/test_ariaowns.html
+++ /dev/null
@@ -1,234 +0,0 @@
-<!DOCTYPE html>
-<html>
-
-<head>
-  <title>@aria-owns attribute testing</title>
-
-  <link rel="stylesheet" type="text/css"
-        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
-
-  <script type="application/javascript"
-          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-
-  <script type="application/javascript"
-          src="../common.js"></script>
-  <script type="application/javascript"
-          src="../role.js"></script>
-  <script type="application/javascript"
-          src="../events.js"></script>
-
-  <script type="application/javascript">
-
-    ////////////////////////////////////////////////////////////////////////////
-    // Invokers
-    ////////////////////////////////////////////////////////////////////////////
-
-    function removeARIAOwns()
-    {
-      this.eventSeq = [
-        new invokerChecker(EVENT_HIDE, getNode("t2_checkbox")),
-        new invokerChecker(EVENT_HIDE, getNode("t2_button")),
-        new invokerChecker(EVENT_SHOW, getNode("t2_button")),
-        new invokerChecker(EVENT_SHOW, getNode("t2_checkbox")),
-        new invokerChecker(EVENT_REORDER, getNode("container2"))
-      ];
-
-      this.invoke = function removeARIAOwns_invoke()
-      {
-        // children are swapped
-        var tree =
-          { SECTION: [
-              { CHECKBUTTON: [
-                { SECTION: [] }
-              ] },
-              { PUSHBUTTON: [ ] }
-          ] };
-        testAccessibleTree("container2", tree);
-
-        getNode("container2").removeAttribute("aria-owns");
-      }
-
-      this.finalCheck = function removeARIAOwns_finalCheck()
-      {
-        // children follow the DOM order
-        var tree =
-          { SECTION: [
-              { PUSHBUTTON: [ ] },
-              { CHECKBUTTON: [
-                  { SECTION: [] }
-              ] }
-          ] };
-        testAccessibleTree("container2", tree);
-      }
-
-      this.getID = function removeARIAOwns_getID()
-      {
-        return "Remove @aria-owns attribute";
-      }
-    }
-
-    function setARIAOwns()
-    {
-      this.eventSeq = [
-        new invokerChecker(EVENT_HIDE, getNode("t2_button")),
-        new invokerChecker(EVENT_SHOW, getNode("t2_button")),
-        new invokerChecker(EVENT_HIDE, getNode("t2_subdiv")),
-        new invokerChecker(EVENT_SHOW, getNode("t2_subdiv")),
-        new invokerChecker(EVENT_REORDER, getNode("container2"))
-      ];
-
-      this.invoke = function setARIAOwns_invoke()
-      {
-        getNode("container2").setAttribute("aria-owns", "t2_button t2_subdiv");
-      }
-
-      this.finalCheck = function setARIAOwns_finalCheck()
-      {
-        // children are swapped again, button and subdiv are appended to
-        // the children.
-        var tree =
-          { SECTION: [
-              { CHECKBUTTON: [ ] }, // div
-              { PUSHBUTTON: [ ] }, // button
-              { SECTION: [ ] } // subdiv
-          ] };
-        testAccessibleTree("container2", tree);
-      }
-
-      this.getID = function setARIAOwns_getID()
-      {
-        return "Set @aria-owns attribute";
-      }
-    }
-
-    function appendEl()
-    {
-      this.eventSeq = [
-        new invokerChecker(EVENT_SHOW, getNode, "child3"),
-        new invokerChecker(EVENT_REORDER, getNode("container2"))
-      ];
-
-      this.invoke = function appendEl_invoke()
-      {
-        var div = document.createElement("div");
-        div.setAttribute("id", "child3");
-        div.setAttribute("role", "radio")
-        getNode("container2").appendChild(div);
-      }
-
-      this.finalCheck = function appendEl_finalCheck()
-      {
-        // children are invalidated, they includes aria-owns swapped kids and
-        // newly inserted child.
-        var tree =
-          { SECTION: [
-              { CHECKBUTTON: [ ] },
-              { RADIOBUTTON: [ ] },
-              { PUSHBUTTON: [ ] }, // ARIA owned
-              { SECTION: [ ] } // ARIA owned
-          ] };
-        testAccessibleTree("container2", tree);
-      }
-
-      this.getID = function appendEl_getID()
-      {
-        return "Append child under @aria-owns element";
-      }
-    }
-
-    function removeEl()
-    {
-      this.eventSeq = [
-        new invokerChecker(EVENT_HIDE, getNode, "t2_checkbox"),
-        new invokerChecker(EVENT_SHOW, getNode, "t2_checkbox"),
-        new invokerChecker(EVENT_REORDER, getNode("container2"))
-      ];
-
-      this.invoke = function removeEl_invoke()
-      {
-        // remove a container of t2_subdiv
-        getNode("t2_span").parentNode.removeChild(getNode("t2_span"));
-      }
-
-      this.finalCheck = function removeEl_finalCheck()
-      {
-        // subdiv should go away
-        var tree =
-          { SECTION: [
-              { CHECKBUTTON: [ ] },
-              { RADIOBUTTON: [ ] },
-              { PUSHBUTTON: [ ] } // ARIA owned
-          ] };
-        testAccessibleTree("container2", tree);
-      }
-
-      this.getID = function removeEl_getID()
-      {
-        return "Remove a container of ARIA ownded element";
-      }
-    }
-
-    ////////////////////////////////////////////////////////////////////////////
-    // Test
-    ////////////////////////////////////////////////////////////////////////////
-
-    gA11yEventDumpToConsole = true;
-    enableLogging("tree"); // debug stuff
-
-    var gQueue = null;
-
-    function doTest()
-    {
-      // nested and recursive aria-owns
-      var tree =
-        { SECTION: [ // container
-          { SECTION: [ // child
-            { SECTION: [ // mid div
-              { SECTION: [] } // grandchild
-            ] }
-          ] }
-        ] };
-      testAccessibleTree("container", tree);
-
-      // dynamic tests
-      gQueue = new eventQueue();
-
-      gQueue.push(new removeARIAOwns());
-      gQueue.push(new setARIAOwns());
-      gQueue.push(new appendEl());
-      gQueue.push(new removeEl());
-
-      gQueue.invoke(); // SimpleTest.finish() will be called in the end
-    }
-
-    SimpleTest.waitForExplicitFinish();
-    addA11yLoadEvent(doTest);
-
-  </script>
-</head>
-
-<body>
-
-  <p id="display"></p>
-  <div id="content" style="display: none"></div>
-  <pre id="test">
-  </pre>
-
-  <div id="container" aria-owns="child" aria-label="container"></div>
-  <div id="child" aria-label="child">
-    <div aria-owns="grandchild" aria-label="midchild"></div>
-  </div>
-  <div id="grandchild" aria-owns="container" aria-label="grandchild"></div>
-
-  <div id="container2" aria-owns="t2_checkbox t2_button">
-    <div role="button" id="t2_button"></div>
-    <div role="checkbox" id="t2_checkbox">
-      <span id="t2_span">
-        <div id="t2_subdiv"></div>
-      </span>
-    </div>
-  </div>
-
-</body>
-
-</html>
--- a/dom/base/ChildIterator.h
+++ b/dom/base/ChildIterator.h
@@ -195,17 +195,16 @@ public:
 #endif
       {}
 
 #ifdef DEBUG
   ~AllChildrenIterator() { MOZ_ASSERT(!mMutationGuard.Mutated(0)); }
 #endif
 
   nsIContent* GetNextChild();
-  nsIContent* Parent() const { return mOriginalContent; }
 
 private:
   enum IteratorPhase
   {
     eNeedBeforeKid,
     eNeedExplicitKids,
     eNeedAnonKids,
     eNeedAfterKid,