Bug 748639 - add set of internal accessible relation types, r=tbsaunde
authorAlexander Surkov <surkov.alexander@gmail.com>
Sat, 19 Oct 2013 14:19:50 -0400
changeset 160076 e8f7b915ad46f573d7b744597967d4e2f26aa0a5
parent 160075 5373095214d9b1d0fa695388717161fc28e1a1c8
child 160077 8de556315ae67ab77b7f95284efbb25f48495c1a
push idunknown
push userunknown
push dateunknown
reviewerstbsaunde
bugs748639
milestone27.0a1
Bug 748639 - add set of internal accessible relation types, r=tbsaunde
accessible/src/atk/AccessibleWrap.cpp
accessible/src/base/Relation.h
accessible/src/base/RelationType.h
accessible/src/base/moz.build
accessible/src/generic/Accessible.cpp
accessible/src/generic/Accessible.h
accessible/src/generic/ApplicationAccessible.cpp
accessible/src/generic/ApplicationAccessible.h
accessible/src/generic/RootAccessible.cpp
accessible/src/generic/RootAccessible.h
accessible/src/html/HTMLElementAccessibles.cpp
accessible/src/html/HTMLElementAccessibles.h
accessible/src/html/HTMLFormControlAccessible.cpp
accessible/src/html/HTMLFormControlAccessible.h
accessible/src/html/HTMLTableAccessible.cpp
accessible/src/html/HTMLTableAccessible.h
accessible/src/mac/mozAccessible.mm
accessible/src/windows/ia2/ia2Accessible.cpp
accessible/src/windows/ia2/ia2AccessibleRelation.cpp
accessible/src/windows/ia2/ia2AccessibleRelation.h
accessible/src/windows/msaa/AccessibleWrap.cpp
accessible/src/xul/XULElementAccessibles.cpp
accessible/src/xul/XULElementAccessibles.h
accessible/src/xul/XULFormControlAccessible.cpp
accessible/src/xul/XULFormControlAccessible.h
accessible/src/xul/XULTabAccessible.cpp
accessible/src/xul/XULTabAccessible.h
accessible/src/xul/XULTreeAccessible.cpp
accessible/src/xul/XULTreeAccessible.h
accessible/src/xul/XULTreeGridAccessible.cpp
accessible/src/xul/XULTreeGridAccessible.h
--- a/accessible/src/atk/AccessibleWrap.cpp
+++ b/accessible/src/atk/AccessibleWrap.cpp
@@ -877,33 +877,33 @@ refRelationSetCB(AtkObject *aAtkObj)
   AtkRelationSet* relation_set =
     ATK_OBJECT_CLASS(parent_class)->ref_relation_set(aAtkObj);
 
   AccessibleWrap* accWrap = GetAccessibleWrap(aAtkObj);
   if (!accWrap)
     return relation_set;
 
   // Keep in sync with AtkRelationType enum.
-  static const uint32_t relationTypes[] = {
-    nsIAccessibleRelation::RELATION_CONTROLLED_BY,
-    nsIAccessibleRelation::RELATION_CONTROLLER_FOR,
-    nsIAccessibleRelation::RELATION_LABEL_FOR,
-    nsIAccessibleRelation::RELATION_LABELLED_BY,
-    nsIAccessibleRelation::RELATION_MEMBER_OF,
-    nsIAccessibleRelation::RELATION_NODE_CHILD_OF,
-    nsIAccessibleRelation::RELATION_FLOWS_TO,
-    nsIAccessibleRelation::RELATION_FLOWS_FROM,
-    nsIAccessibleRelation::RELATION_SUBWINDOW_OF,
-    nsIAccessibleRelation::RELATION_EMBEDS,
-    nsIAccessibleRelation::RELATION_EMBEDDED_BY,
-    nsIAccessibleRelation::RELATION_POPUP_FOR,
-    nsIAccessibleRelation::RELATION_PARENT_WINDOW_OF,
-    nsIAccessibleRelation::RELATION_DESCRIBED_BY,
-    nsIAccessibleRelation::RELATION_DESCRIPTION_FOR,
-    nsIAccessibleRelation::RELATION_NODE_PARENT_OF
+  static const RelationType relationTypes[] = {
+    RelationType::CONTROLLED_BY,
+    RelationType::CONTROLLER_FOR,
+    RelationType::LABEL_FOR,
+    RelationType::LABELLED_BY,
+    RelationType::MEMBER_OF,
+    RelationType::NODE_CHILD_OF,
+    RelationType::FLOWS_TO,
+    RelationType::FLOWS_FROM,
+    RelationType::SUBWINDOW_OF,
+    RelationType::EMBEDS,
+    RelationType::EMBEDDED_BY,
+    RelationType::POPUP_FOR,
+    RelationType::PARENT_WINDOW_OF,
+    RelationType::DESCRIBED_BY,
+    RelationType::DESCRIPTION_FOR,
+    RelationType::NODE_PARENT_OF
   };
 
   for (uint32_t i = 0; i < ArrayLength(relationTypes); i++) {
     // Shift to 1 to skip ATK_RELATION_NULL.
     AtkRelationType atkType = static_cast<AtkRelationType>(i + 1);
     AtkRelation* atkRelation =
       atk_relation_set_get_relation_by_type(relation_set, atkType);
     if (atkRelation)
--- a/accessible/src/base/Relation.h
+++ b/accessible/src/base/Relation.h
@@ -1,16 +1,16 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 et sw=2 tw=80: */
 /* 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/. */
 
-#ifndef RELATION_H_
-#define RELATION_H_
+#ifndef mozilla_a11y_relation_h_
+#define mozilla_a11y_relation_h_
 
 #include "AccIterator.h"
 
 namespace mozilla {
 namespace a11y {
 
 /**
  * This class is used to return Relation objects from functions.  A copy
new file mode 100644
--- /dev/null
+++ b/accessible/src/base/RelationType.h
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_a11y_relationtype_h_
+#define mozilla_a11y_relationtype_h_
+
+#include "mozilla/TypedEnum.h"
+
+namespace mozilla {
+namespace a11y {
+
+MOZ_BEGIN_ENUM_CLASS(RelationType)
+
+  /**
+   * This object is labelled by a target object.
+   */
+  LABELLED_BY = 0x00,
+
+  /**
+   * This object is label for a target object.
+   */
+  LABEL_FOR = 0x01,
+
+  /**
+   * This object is described by the target object.
+   */
+  DESCRIBED_BY = 0x02,
+
+  /**
+   * This object is describes the target object.
+   */
+  DESCRIPTION_FOR = 0x3,
+
+  /**
+   * This object is a child of a target object.
+   */
+  NODE_CHILD_OF = 0x4,
+
+  /**
+   * This object is a parent of a target object. A dual relation to
+   * NODE_CHILD_OF.
+   */
+  NODE_PARENT_OF = 0x5,
+
+  /**
+   * Some attribute of this object is affected by a target object.
+   */
+  CONTROLLED_BY = 0x06,
+
+  /**
+   * This object is interactive and controls some attribute of a target object.
+   */
+  CONTROLLER_FOR = 0x07,
+
+  /**
+   * Content flows from this object to a target object, i.e. has content that
+   * flows logically to another object in a sequential way, e.g. text flow.
+   */
+  FLOWS_TO = 0x08,
+
+  /**
+   * Content flows to this object from a target object, i.e. has content that
+   * flows logically from another object in a sequential way, e.g. text flow.
+   */
+  FLOWS_FROM = 0x09,
+
+  /**
+   * This object is a member of a group of one or more objects. When there is
+   * more than one object in the group each member may have one and the same
+   * target, e.g. a grouping object.  It is also possible that each member has
+   * multiple additional targets, e.g. one for every other member in the group.
+   */
+  MEMBER_OF = 0x0a,
+
+  /**
+   * This object is a sub window of a target object.
+   */
+  SUBWINDOW_OF = 0x0b,
+
+  /**
+   * This object embeds a target object. This relation can be used on the
+   * OBJID_CLIENT accessible for a top level window to show where the content
+   * areas are.
+   */
+  EMBEDS = 0x0c,
+
+  /**
+   * This object is embedded by a target object.
+   */
+  EMBEDDED_BY = 0x0d,
+
+  /**
+   * This object is a transient component related to the target object. When
+   * this object is activated the target object doesn't lose focus.
+   */
+  POPUP_FOR = 0x0e,
+
+  /**
+   * This object is a parent window of the target object.
+   */
+  PARENT_WINDOW_OF = 0x0f,
+
+  /**
+   * Part of a form/dialog with a related default button. It is used for
+   * MSAA/XPCOM, it isn't for IA2 or ATK.
+   */
+  DEFAULT_BUTTON = 0x10,
+
+  LAST = DEFAULT_BUTTON
+
+MOZ_END_ENUM_CLASS(RelationType)
+
+} // namespace a11y
+} // namespace mozilla
+
+#endif
--- a/accessible/src/base/moz.build
+++ b/accessible/src/base/moz.build
@@ -14,16 +14,17 @@ EXPORTS += [
     'nsAccessibilityService.h',
 ]
 
 EXPORTS.mozilla.a11y += [
     'AccTypes.h',
     'DocManager.h',
     'FocusManager.h',
     'Platform.h',
+    'RelationType.h',
     'Role.h',
     'SelectionManager.h',
     'States.h',
 ]
 
 if CONFIG['MOZ_DEBUG']:
     EXPORTS.mozilla.a11y += [
         'Logging.h',
--- a/accessible/src/generic/Accessible.cpp
+++ b/accessible/src/generic/Accessible.cpp
@@ -1514,17 +1514,17 @@ Accessible::State()
                              nsGkAtoms::_false, eCaseMatters)) {
     // Special case for tabs: focused tab or focus inside related tab panel
     // implies selected state.
     if (mRoleMapEntry->role == roles::PAGETAB) {
       if (state & states::FOCUSED) {
         state |= states::SELECTED;
       } else {
         // If focus is in a child of the tab panel surely the tab is selected!
-        Relation rel = RelationByType(nsIAccessibleRelation::RELATION_LABEL_FOR);
+        Relation rel = RelationByType(RelationType::LABEL_FOR);
         Accessible* relTarget = nullptr;
         while ((relTarget = rel.Next())) {
           if (relTarget->Role() == roles::PROPERTYPAGE &&
               FocusMgr()->IsFocusWithin(relTarget))
             state |= states::SELECTED;
         }
       }
     } else if (state & states::FOCUSED) {
@@ -1809,17 +1809,17 @@ Accessible::ARIATransformRole(role aRole
     }
 
   } else if (aRole == roles::LISTBOX) {
     // A listbox inside of a combobox needs a special role because of ATK
     // mapping to menu.
     if (mParent && mParent->Role() == roles::COMBOBOX) {
       return roles::COMBOBOX_LIST;
 
-      Relation rel = RelationByType(nsIAccessibleRelation::RELATION_NODE_CHILD_OF);
+      Relation rel = RelationByType(RelationType::NODE_CHILD_OF);
       Accessible* targetAcc = nullptr;
       while ((targetAcc = rel.Next()))
         if (targetAcc->Role() == roles::COMBOBOX)
           return roles::COMBOBOX_LIST;
     }
 
   } else if (aRole == roles::OPTION) {
     if (mParent && mParent->Role() == roles::COMBOBOX_LIST)
@@ -1979,84 +1979,86 @@ Accessible::GetAtomicRegion() const
   while (loopContent && !loopContent->GetAttr(kNameSpaceID_None, nsGkAtoms::aria_atomic, atomic))
     loopContent = loopContent->GetParent();
 
   return atomic.EqualsLiteral("true") ? loopContent : nullptr;
 }
 
 // nsIAccessible getRelationByType()
 NS_IMETHODIMP
-Accessible::GetRelationByType(uint32_t aType,
-                                nsIAccessibleRelation** aRelation)
+Accessible::GetRelationByType(uint32_t aType, nsIAccessibleRelation** aRelation)
 {
   NS_ENSURE_ARG_POINTER(aRelation);
   *aRelation = nullptr;
+
+  NS_ENSURE_ARG(aType <= static_cast<uint32_t>(RelationType::LAST));
+
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
-  Relation rel = RelationByType(aType);
+  Relation rel = RelationByType(static_cast<RelationType>(aType));
   NS_ADDREF(*aRelation = new nsAccessibleRelation(aType, &rel));
   return *aRelation ? NS_OK : NS_ERROR_FAILURE;
 }
 
 Relation
-Accessible::RelationByType(uint32_t aType)
+Accessible::RelationByType(RelationType aType)
 {
   if (!HasOwnContent())
     return Relation();
 
   // Relationships are defined on the same content node that the role would be
   // defined on.
   switch (aType) {
-    case nsIAccessibleRelation::RELATION_LABELLED_BY: {
+    case RelationType::LABELLED_BY: {
       Relation rel(new IDRefsIterator(mDoc, mContent,
                                       nsGkAtoms::aria_labelledby));
       if (mContent->IsHTML()) {
         rel.AppendIter(new HTMLLabelIterator(Document(), this));
       } else if (mContent->IsXUL()) {
         rel.AppendIter(new XULLabelIterator(Document(), mContent));
       }
 
       return rel;
     }
 
-    case nsIAccessibleRelation::RELATION_LABEL_FOR: {
+    case RelationType::LABEL_FOR: {
       Relation rel(new RelatedAccIterator(Document(), mContent,
                                           nsGkAtoms::aria_labelledby));
       if (mContent->Tag() == nsGkAtoms::label && mContent->IsXUL())
         rel.AppendIter(new IDRefsIterator(mDoc, mContent, nsGkAtoms::control));
 
       return rel;
     }
 
-    case nsIAccessibleRelation::RELATION_DESCRIBED_BY: {
+    case RelationType::DESCRIBED_BY: {
       Relation rel(new IDRefsIterator(mDoc, mContent,
                                       nsGkAtoms::aria_describedby));
       if (mContent->IsXUL())
         rel.AppendIter(new XULDescriptionIterator(Document(), mContent));
 
       return rel;
     }
 
-    case nsIAccessibleRelation::RELATION_DESCRIPTION_FOR: {
+    case RelationType::DESCRIPTION_FOR: {
       Relation rel(new RelatedAccIterator(Document(), mContent,
                                           nsGkAtoms::aria_describedby));
 
       // This affectively adds an optional control attribute to xul:description,
       // which only affects accessibility, by allowing the description to be
       // tied to a control.
       if (mContent->Tag() == nsGkAtoms::description &&
           mContent->IsXUL())
         rel.AppendIter(new IDRefsIterator(mDoc, mContent,
                                           nsGkAtoms::control));
 
       return rel;
     }
 
-    case nsIAccessibleRelation::RELATION_NODE_CHILD_OF: {
+    case RelationType::NODE_CHILD_OF: {
       Relation rel(new RelatedAccIterator(Document(), mContent,
                                           nsGkAtoms::aria_owns));
 
       // This is an ARIA tree or treegrid that doesn't use owns, so we need to
       // get the parent the hard way.
       if (mRoleMapEntry && (mRoleMapEntry->role == roles::OUTLINEITEM ||
                             mRoleMapEntry->role == roles::LISTITEM ||
                             mRoleMapEntry->role == roles::ROW)) {
@@ -2077,17 +2079,17 @@ Accessible::RelationByType(uint32_t aTyp
           if (scrollFrame || view->GetWidget() || !frame->GetParent())
             rel.AppendTarget(Parent());
         }
       }
 
       return rel;
     }
 
-    case nsIAccessibleRelation::RELATION_NODE_PARENT_OF: {
+    case RelationType::NODE_PARENT_OF: {
       Relation rel(new IDRefsIterator(mDoc, mContent, nsGkAtoms::aria_owns));
 
       // ARIA tree or treegrid can do the hierarchy by @aria-level, ARIA trees
       // also can be organized by groups.
       if (mRoleMapEntry &&
           (mRoleMapEntry->role == roles::OUTLINEITEM ||
            mRoleMapEntry->role == roles::LISTITEM ||
            mRoleMapEntry->role == roles::ROW ||
@@ -2095,46 +2097,46 @@ Accessible::RelationByType(uint32_t aTyp
            mRoleMapEntry->role == roles::LIST ||
            mRoleMapEntry->role == roles::TREE_TABLE)) {
         rel.AppendIter(new ItemIterator(this));
       }
 
       return rel;
     }
 
-    case nsIAccessibleRelation::RELATION_CONTROLLED_BY:
+    case RelationType::CONTROLLED_BY:
       return Relation(new RelatedAccIterator(Document(), mContent,
                                              nsGkAtoms::aria_controls));
 
-    case nsIAccessibleRelation::RELATION_CONTROLLER_FOR: {
+    case RelationType::CONTROLLER_FOR: {
       Relation rel(new IDRefsIterator(mDoc, mContent,
                                       nsGkAtoms::aria_controls));
       rel.AppendIter(new HTMLOutputIterator(Document(), mContent));
       return rel;
     }
 
-    case nsIAccessibleRelation::RELATION_FLOWS_TO:
+    case RelationType::FLOWS_TO:
       return Relation(new IDRefsIterator(mDoc, mContent,
                                          nsGkAtoms::aria_flowto));
 
-    case nsIAccessibleRelation::RELATION_FLOWS_FROM:
+    case RelationType::FLOWS_FROM:
       return Relation(new RelatedAccIterator(Document(), mContent,
                                              nsGkAtoms::aria_flowto));
 
-    case nsIAccessibleRelation::RELATION_MEMBER_OF:
+    case RelationType::MEMBER_OF:
           return Relation(mDoc, GetAtomicRegion());
 
-    case nsIAccessibleRelation::RELATION_SUBWINDOW_OF:
-    case nsIAccessibleRelation::RELATION_EMBEDS:
-    case nsIAccessibleRelation::RELATION_EMBEDDED_BY:
-    case nsIAccessibleRelation::RELATION_POPUP_FOR:
-    case nsIAccessibleRelation::RELATION_PARENT_WINDOW_OF:
+    case RelationType::SUBWINDOW_OF:
+    case RelationType::EMBEDS:
+    case RelationType::EMBEDDED_BY:
+    case RelationType::POPUP_FOR:
+    case RelationType::PARENT_WINDOW_OF:
       return Relation();
 
-    case nsIAccessibleRelation::RELATION_DEFAULT_BUTTON: {
+    case RelationType::DEFAULT_BUTTON: {
       if (mContent->IsHTML()) {
         // HTML form controls implements nsIFormControl interface.
         nsCOMPtr<nsIFormControl> control(do_QueryInterface(mContent));
         if (control) {
           nsCOMPtr<nsIForm> form(do_QueryInterface(control->GetFormElement()));
           if (form) {
             nsCOMPtr<nsIContent> formContent =
               do_QueryInterface(form->GetDefaultSubmitElement());
--- a/accessible/src/generic/Accessible.h
+++ b/accessible/src/generic/Accessible.h
@@ -2,16 +2,17 @@
 /* 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/. */
 
 #ifndef _Accessible_H_
 #define _Accessible_H_
 
 #include "mozilla/a11y/AccTypes.h"
+#include "mozilla/a11y/RelationType.h"
 #include "mozilla/a11y/Role.h"
 #include "mozilla/a11y/States.h"
 #include "nsAccessNode.h"
 
 #include "nsIAccessible.h"
 #include "nsIAccessibleHyperLink.h"
 #include "nsIAccessibleSelectable.h"
 #include "nsIAccessibleValue.h"
@@ -289,17 +290,17 @@ public:
    * @param  aSetSize   [out] the group size
    */
   virtual void GetPositionAndSizeInternal(int32_t *aPosInSet,
                                           int32_t *aSetSize);
 
   /**
    * Get the relation of the given type.
    */
-  virtual mozilla::a11y::Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType);
 
   //////////////////////////////////////////////////////////////////////////////
   // Initializing methods
 
   /**
    * Set the ARIA role map entry for a new accessible.
    */
   void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry)
--- a/accessible/src/generic/ApplicationAccessible.cpp
+++ b/accessible/src/generic/ApplicationAccessible.cpp
@@ -136,17 +136,17 @@ ApplicationAccessible::FocusedChild()
   Accessible* focus = FocusMgr()->FocusedAccessible();
   if (focus && focus->Parent() == this)
     return focus;
 
   return nullptr;
 }
 
 Relation
-ApplicationAccessible::RelationByType(uint32_t aRelationType)
+ApplicationAccessible::RelationByType(RelationType aRelationType)
 {
   return Relation();
 }
 
 NS_IMETHODIMP
 ApplicationAccessible::GetBounds(int32_t* aX, int32_t* aY,
                                  int32_t* aWidth, int32_t* aHeight)
 {
--- a/accessible/src/generic/ApplicationAccessible.h
+++ b/accessible/src/generic/ApplicationAccessible.h
@@ -65,17 +65,17 @@ public:
   virtual GroupPos GroupPosition();
   virtual ENameValueFlag Name(nsString& aName);
   virtual void ApplyARIAState(uint64_t* aState) const;
   virtual void Description(nsString& aDescription);
   virtual void Value(nsString& aValue);
   virtual mozilla::a11y::role NativeRole();
   virtual uint64_t State();
   virtual uint64_t NativeState();
-  virtual Relation RelationByType(uint32_t aRelType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 
   virtual Accessible* ChildAtPoint(int32_t aX, int32_t aY,
                                    EWhichChildAtPoint aWhichChild);
   virtual Accessible* FocusedChild();
 
   virtual void InvalidateChildren();
 
   // ActionAccessible
--- a/accessible/src/generic/RootAccessible.cpp
+++ b/accessible/src/generic/RootAccessible.cpp
@@ -476,19 +476,19 @@ RootAccessible::Shutdown()
   if (!PresShell())
     return;  // Already shutdown
 
   DocAccessibleWrap::Shutdown();
 }
 
 // nsIAccessible method
 Relation
-RootAccessible::RelationByType(uint32_t aType)
+RootAccessible::RelationByType(RelationType aType)
 {
-  if (!mDocumentNode || aType != nsIAccessibleRelation::RELATION_EMBEDS)
+  if (!mDocumentNode || aType != RelationType::EMBEDS)
     return DocAccessibleWrap::RelationByType(aType);
 
   nsIDOMWindow* rootWindow = mDocumentNode->GetWindow();
   if (rootWindow) {
     nsCOMPtr<nsIDOMWindow> contentWindow;
     rootWindow->GetContent(getter_AddRefs(contentWindow));
     if (contentWindow) {
       nsCOMPtr<nsIDOMDocument> contentDOMDocument;
--- a/accessible/src/generic/RootAccessible.h
+++ b/accessible/src/generic/RootAccessible.h
@@ -29,17 +29,17 @@ public:
   // nsIDOMEventListener
   NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
 
   // nsAccessNode
   virtual void Shutdown();
 
   // Accessible
   virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
   virtual mozilla::a11y::role NativeRole();
   virtual uint64_t NativeState();
 
   // RootAccessible
 
   /**
    * Notify that the sub document presshell was activated.
    */
--- a/accessible/src/html/HTMLElementAccessibles.cpp
+++ b/accessible/src/html/HTMLElementAccessibles.cpp
@@ -60,20 +60,20 @@ NS_IMPL_ISUPPORTS_INHERITED0(HTMLLabelAc
 ENameValueFlag
 HTMLLabelAccessible::NativeName(nsString& aName)
 {
   nsTextEquivUtils::GetNameFromSubtree(this, aName);
   return aName.IsEmpty() ? eNameOK : eNameFromSubtree;
 }
 
 Relation
-HTMLLabelAccessible::RelationByType(uint32_t aType)
+HTMLLabelAccessible::RelationByType(RelationType aType)
 {
   Relation rel = AccessibleWrap::RelationByType(aType);
-  if (aType == nsIAccessibleRelation::RELATION_LABEL_FOR) {
+  if (aType == RelationType::LABEL_FOR) {
     nsRefPtr<dom::HTMLLabelElement> label = dom::HTMLLabelElement::FromContent(mContent);
     rel.AppendTarget(mDoc, label->GetControl());
   }
 
   return rel;
 }
 
 role
@@ -84,20 +84,20 @@ HTMLLabelAccessible::NativeRole()
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsHTMLOuputAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_IMPL_ISUPPORTS_INHERITED0(HTMLOutputAccessible, HyperTextAccessible)
 
 Relation
-HTMLOutputAccessible::RelationByType(uint32_t aType)
+HTMLOutputAccessible::RelationByType(RelationType aType)
 {
   Relation rel = AccessibleWrap::RelationByType(aType);
-  if (aType == nsIAccessibleRelation::RELATION_CONTROLLED_BY)
+  if (aType == RelationType::CONTROLLED_BY)
     rel.AppendIter(new IDRefsIterator(mDoc, mContent, nsGkAtoms::_for));
 
   return rel;
 }
 
 role
 HTMLOutputAccessible::NativeRole()
 {
--- a/accessible/src/html/HTMLElementAccessibles.h
+++ b/accessible/src/html/HTMLElementAccessibles.h
@@ -56,17 +56,17 @@ public:
 
   HTMLLabelAccessible(nsIContent* aContent, DocAccessible* aDoc) :
     HyperTextAccessibleWrap(aContent, aDoc) {}
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // Accessible
   virtual a11y::role NativeRole();
-  virtual Relation RelationByType(uint32_t aType) MOZ_OVERRIDE;
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 
 protected:
   virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
 };
 
 /**
  * Used for HTML output element.
  */
@@ -77,15 +77,15 @@ public:
   HTMLOutputAccessible(nsIContent* aContent, DocAccessible* aDoc) :
     HyperTextAccessibleWrap(aContent, aDoc) {}
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // Accessible
   virtual a11y::role NativeRole();
   virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/src/html/HTMLFormControlAccessible.cpp
+++ b/accessible/src/html/HTMLFormControlAccessible.cpp
@@ -654,41 +654,41 @@ HTMLGroupboxAccessible::NativeName(nsStr
   nsIContent* legendContent = GetLegend();
   if (legendContent)
     nsTextEquivUtils::AppendTextEquivFromContent(this, legendContent, &aName);
 
   return eNameOK;
 }
 
 Relation
-HTMLGroupboxAccessible::RelationByType(uint32_t aType)
+HTMLGroupboxAccessible::RelationByType(RelationType aType)
 {
   Relation rel = HyperTextAccessibleWrap::RelationByType(aType);
     // No override for label, so use <legend> for this <fieldset>
-  if (aType == nsIAccessibleRelation::RELATION_LABELLED_BY)
+  if (aType == RelationType::LABELLED_BY)
     rel.AppendTarget(mDoc, GetLegend());
 
   return rel;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLLegendAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 HTMLLegendAccessible::
   HTMLLegendAccessible(nsIContent* aContent, DocAccessible* aDoc) :
   HyperTextAccessibleWrap(aContent, aDoc)
 {
 }
 
 Relation
-HTMLLegendAccessible::RelationByType(uint32_t aType)
+HTMLLegendAccessible::RelationByType(RelationType aType)
 {
   Relation rel = HyperTextAccessibleWrap::RelationByType(aType);
-  if (aType != nsIAccessibleRelation::RELATION_LABEL_FOR)
+  if (aType != RelationType::LABEL_FOR)
     return rel;
 
   Accessible* groupbox = Parent();
   if (groupbox && groupbox->Role() == roles::GROUPING)
     rel.AppendTarget(groupbox);
 
   return rel;
 }
@@ -737,20 +737,20 @@ HTMLFigureAccessible::NativeName(nsStrin
   nsIContent* captionContent = Caption();
   if (captionContent)
     nsTextEquivUtils::AppendTextEquivFromContent(this, captionContent, &aName);
 
   return eNameOK;
 }
 
 Relation
-HTMLFigureAccessible::RelationByType(uint32_t aType)
+HTMLFigureAccessible::RelationByType(RelationType aType)
 {
   Relation rel = HyperTextAccessibleWrap::RelationByType(aType);
-  if (aType == nsIAccessibleRelation::RELATION_LABELLED_BY)
+  if (aType == RelationType::LABELLED_BY)
     rel.AppendTarget(mDoc, Caption());
 
   return rel;
 }
 
 nsIContent*
 HTMLFigureAccessible::Caption() const
 {
@@ -777,20 +777,20 @@ HTMLFigcaptionAccessible::
 
 role
 HTMLFigcaptionAccessible::NativeRole()
 {
   return roles::CAPTION;
 }
 
 Relation
-HTMLFigcaptionAccessible::RelationByType(uint32_t aType)
+HTMLFigcaptionAccessible::RelationByType(RelationType aType)
 {
   Relation rel = HyperTextAccessibleWrap::RelationByType(aType);
-  if (aType != nsIAccessibleRelation::RELATION_LABEL_FOR)
+  if (aType != RelationType::LABEL_FOR)
     return rel;
 
   Accessible* figure = Parent();
   if (figure &&
       figure->GetContent()->NodeInfo()->Equals(nsGkAtoms::figure,
                                                mContent->GetNameSpaceID())) {
     rel.AppendTarget(figure);
   }
--- a/accessible/src/html/HTMLFormControlAccessible.h
+++ b/accessible/src/html/HTMLFormControlAccessible.h
@@ -188,17 +188,17 @@ public:
  */
 class HTMLGroupboxAccessible : public HyperTextAccessibleWrap
 {
 public:
   HTMLGroupboxAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual mozilla::a11y::role NativeRole();
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 
 protected:
   // Accessible
   virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
 
   // HTMLGroupboxAccessible
   nsIContent* GetLegend();
 };
@@ -209,31 +209,31 @@ protected:
  */
 class HTMLLegendAccessible : public HyperTextAccessibleWrap
 {
 public:
   HTMLLegendAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual mozilla::a11y::role NativeRole();
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 };
 
 /**
  * Accessible for HTML5 figure element.
  */
 class HTMLFigureAccessible : public HyperTextAccessibleWrap
 {
 public:
   HTMLFigureAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
   virtual mozilla::a11y::role NativeRole();
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 
 protected:
   // Accessible
   virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
 
   // HTMLLegendAccessible
   nsIContent* Caption() const;
 };
@@ -244,15 +244,15 @@ protected:
  */
 class HTMLFigcaptionAccessible : public HyperTextAccessibleWrap
 {
 public:
   HTMLFigcaptionAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual mozilla::a11y::role NativeRole();
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/src/html/HTMLTableAccessible.cpp
+++ b/accessible/src/html/HTMLTableAccessible.cpp
@@ -446,20 +446,20 @@ HTMLTableAccessible::NativeAttributes()
 
   return attributes.forget();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLTableAccessible: nsIAccessible implementation
 
 Relation
-HTMLTableAccessible::RelationByType(uint32_t aType)
+HTMLTableAccessible::RelationByType(RelationType aType)
 {
   Relation rel = AccessibleWrap::RelationByType(aType);
-  if (aType == nsIAccessibleRelation::RELATION_LABELLED_BY)
+  if (aType == RelationType::LABELLED_BY)
     rel.AppendTarget(Caption());
 
   return rel;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLTableAccessible: nsIAccessibleTable implementation
 
@@ -1113,20 +1113,20 @@ HTMLTableAccessible::IsProbablyLayoutTab
 }
 
 
 ////////////////////////////////////////////////////////////////////////////////
 // HTMLCaptionAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 Relation
-HTMLCaptionAccessible::RelationByType(uint32_t aType)
+HTMLCaptionAccessible::RelationByType(RelationType aType)
 {
   Relation rel = HyperTextAccessible::RelationByType(aType);
-  if (aType == nsIAccessibleRelation::RELATION_LABEL_FOR)
+  if (aType == RelationType::LABEL_FOR)
     rel.AppendTarget(Parent());
 
   return rel;
 }
 
 role
 HTMLCaptionAccessible::NativeRole()
 {
--- a/accessible/src/html/HTMLTableAccessible.h
+++ b/accessible/src/html/HTMLTableAccessible.h
@@ -167,17 +167,17 @@ public:
   virtual void Shutdown();
 
   // Accessible
   virtual TableAccessible* AsTable() { return this; }
   virtual void Description(nsString& aDescription);
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
   virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
-  virtual Relation RelationByType(uint32_t aRelationType);
+  virtual Relation RelationByType(RelationType aRelationType) MOZ_OVERRIDE;
 
 protected:
   // Accessible
   virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
   virtual void CacheChildren();
 
   // HTMLTableAccessible
 
@@ -226,15 +226,15 @@ public:
   HTMLCaptionAccessible(nsIContent* aContent, DocAccessible* aDoc) :
     HyperTextAccessibleWrap(aContent, aDoc) { }
   virtual ~HTMLCaptionAccessible() { }
 
   // nsIAccessible
 
   // Accessible
   virtual a11y::role NativeRole();
-  virtual Relation RelationByType(uint32_t aRelationType);
+  virtual Relation RelationByType(RelationType aRelationType) MOZ_OVERRIDE;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
--- a/accessible/src/mac/mozAccessible.mm
+++ b/accessible/src/mac/mozAccessible.mm
@@ -188,17 +188,17 @@ GetClosestInterestingAccessible(id anObj
     return [self size];
   if ([attribute isEqualToString:NSAccessibilityWindowAttribute])
     return [self window];
   if ([attribute isEqualToString:NSAccessibilityTopLevelUIElementAttribute])
     return [self window];
   if ([attribute isEqualToString:NSAccessibilityTitleAttribute])
     return [self title];
   if ([attribute isEqualToString:NSAccessibilityTitleUIElementAttribute]) {
-    Relation rel = mGeckoAccessible->RelationByType(nsIAccessibleRelation::RELATION_LABELLED_BY);
+    Relation rel = mGeckoAccessible->RelationByType(RelationType::LABELLED_BY);
     Accessible* tempAcc = rel.Next();
     return tempAcc ? GetNativeFromGeckoAccessible(tempAcc) : nil;
   }
   if ([attribute isEqualToString:NSAccessibilityHelpAttribute])
     return [self help];
     
 #ifdef DEBUG
  NSLog (@"!!! %@ can't respond to attribute %@", self, attribute);
--- a/accessible/src/windows/ia2/ia2Accessible.cpp
+++ b/accessible/src/windows/ia2/ia2Accessible.cpp
@@ -81,20 +81,20 @@ ia2Accessible::get_relation(long aRelati
   *aRelation = nullptr;
 
   AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
   if (acc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   long relIdx = 0;
   for (unsigned int idx = 0; idx < ArrayLength(sRelationTypesForIA2); idx++) {
-    uint32_t relType = sRelationTypesForIA2[idx];
-    Relation rel = acc->RelationByType(relType);
+    RelationType relationType = sRelationTypesForIA2[idx];
+    Relation rel = acc->RelationByType(relationType);
     nsRefPtr<ia2AccessibleRelation> ia2Relation =
-      new ia2AccessibleRelation(relType, &rel);
+      new ia2AccessibleRelation(relationType, &rel);
     if (ia2Relation->HasTargets()) {
       if (relIdx == aRelationIndex) {
         ia2Relation.forget(aRelation);
         return S_OK;
       }
 
       relIdx++;
     }
@@ -117,20 +117,20 @@ ia2Accessible::get_relations(long aMaxRe
   *aNRelations = 0;
 
   AccessibleWrap* acc = static_cast<AccessibleWrap*>(this);
   if (acc->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   for (unsigned int idx = 0; idx < ArrayLength(sRelationTypesForIA2) &&
        *aNRelations < aMaxRelations; idx++) {
-    uint32_t relType = sRelationTypesForIA2[idx];
-    Relation rel = acc->RelationByType(relType);
+    RelationType relationType = sRelationTypesForIA2[idx];
+    Relation rel = acc->RelationByType(relationType);
     nsRefPtr<ia2AccessibleRelation> ia2Rel =
-      new ia2AccessibleRelation(relType, &rel);
+      new ia2AccessibleRelation(relationType, &rel);
     if (ia2Rel->HasTargets()) {
       ia2Rel.forget(aRelation + (*aNRelations));
       (*aNRelations)++;
     }
   }
   return S_OK;
 
   A11Y_TRYBLOCK_END
--- a/accessible/src/windows/ia2/ia2AccessibleRelation.cpp
+++ b/accessible/src/windows/ia2/ia2AccessibleRelation.cpp
@@ -3,131 +3,99 @@
  */
 /* 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 "ia2AccessibleRelation.h"
 
 #include "Relation.h"
-#include "IUnknownImpl.h"
 #include "nsIAccessibleRelation.h"
 #include "nsID.h"
 
 #include "AccessibleRelation_i.c"
 
 using namespace mozilla::a11y;
 
-ia2AccessibleRelation::ia2AccessibleRelation(uint32_t aType, Relation* aRel) :
-  mType(aType), mReferences(0)
+ia2AccessibleRelation::ia2AccessibleRelation(RelationType aType, Relation* aRel) :
+  mType(aType)
 {
   Accessible* target = nullptr;
   while ((target = aRel->Next()))
     mTargets.AppendElement(target);
 }
 
 // IUnknown
 
-STDMETHODIMP
-ia2AccessibleRelation::QueryInterface(REFIID iid, void** ppv)
-{
-  if (!ppv)
-    return E_INVALIDARG;
-
-  *ppv = nullptr;
-
-  if (IID_IAccessibleRelation == iid || IID_IUnknown == iid) {
-    *ppv = static_cast<IAccessibleRelation*>(this);
-    (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
-    return S_OK;
-  }
-
-  return E_NOINTERFACE;
-}
-
-ULONG STDMETHODCALLTYPE
-ia2AccessibleRelation::AddRef()
-{
-  return mReferences++;
-}
-
-ULONG STDMETHODCALLTYPE 
-ia2AccessibleRelation::Release()
-{
-  mReferences--;
-  ULONG references = mReferences;
-  if (!mReferences)
-    delete this;
-
-  return references;
-}
+IMPL_IUNKNOWN_QUERY_HEAD(ia2AccessibleRelation)
+  IMPL_IUNKNOWN_QUERY_IFACE(IAccessibleRelation)
+  IMPL_IUNKNOWN_QUERY_IFACE(IUnknown)
+IMPL_IUNKNOWN_QUERY_TAIL
 
 // IAccessibleRelation
 
 STDMETHODIMP
 ia2AccessibleRelation::get_relationType(BSTR *aRelationType)
 {
   A11Y_TRYBLOCK_BEGIN
 
   if (!aRelationType)
     return E_INVALIDARG;
 
   *aRelationType = nullptr;
 
   switch (mType) {
-    case nsIAccessibleRelation::RELATION_CONTROLLED_BY:
+    case RelationType::CONTROLLED_BY:
       *aRelationType = ::SysAllocString(IA2_RELATION_CONTROLLED_BY);
       break;
-    case nsIAccessibleRelation::RELATION_CONTROLLER_FOR:
+    case RelationType::CONTROLLER_FOR:
       *aRelationType = ::SysAllocString(IA2_RELATION_CONTROLLER_FOR);
       break;
-    case nsIAccessibleRelation::RELATION_DESCRIBED_BY:
+    case RelationType::DESCRIBED_BY:
       *aRelationType = ::SysAllocString(IA2_RELATION_DESCRIBED_BY);
       break;
-    case nsIAccessibleRelation::RELATION_DESCRIPTION_FOR:
+    case RelationType::DESCRIPTION_FOR:
       *aRelationType = ::SysAllocString(IA2_RELATION_DESCRIPTION_FOR);
       break;
-    case nsIAccessibleRelation::RELATION_EMBEDDED_BY:
+    case RelationType::EMBEDDED_BY:
       *aRelationType = ::SysAllocString(IA2_RELATION_EMBEDDED_BY);
       break;
-    case nsIAccessibleRelation::RELATION_EMBEDS:
+    case RelationType::EMBEDS:
       *aRelationType = ::SysAllocString(IA2_RELATION_EMBEDS);
       break;
-    case nsIAccessibleRelation::RELATION_FLOWS_FROM:
+    case RelationType::FLOWS_FROM:
       *aRelationType = ::SysAllocString(IA2_RELATION_FLOWS_FROM);
       break;
-    case nsIAccessibleRelation::RELATION_FLOWS_TO:
+    case RelationType::FLOWS_TO:
       *aRelationType = ::SysAllocString(IA2_RELATION_FLOWS_TO);
       break;
-    case nsIAccessibleRelation::RELATION_LABEL_FOR:
+    case RelationType::LABEL_FOR:
       *aRelationType = ::SysAllocString(IA2_RELATION_LABEL_FOR);
       break;
-    case nsIAccessibleRelation::RELATION_LABELLED_BY:
+    case RelationType::LABELLED_BY:
       *aRelationType = ::SysAllocString(IA2_RELATION_LABELED_BY);
       break;
-    case nsIAccessibleRelation::RELATION_MEMBER_OF:
+    case RelationType::MEMBER_OF:
       *aRelationType = ::SysAllocString(IA2_RELATION_MEMBER_OF);
       break;
-    case nsIAccessibleRelation::RELATION_NODE_CHILD_OF:
+    case RelationType::NODE_CHILD_OF:
       *aRelationType = ::SysAllocString(IA2_RELATION_NODE_CHILD_OF);
       break;
-    case nsIAccessibleRelation::RELATION_NODE_PARENT_OF:
+    case RelationType::NODE_PARENT_OF:
       *aRelationType = ::SysAllocString(IA2_RELATION_NODE_PARENT_OF);
       break;
-    case nsIAccessibleRelation::RELATION_PARENT_WINDOW_OF:
+    case RelationType::PARENT_WINDOW_OF:
       *aRelationType = ::SysAllocString(IA2_RELATION_PARENT_WINDOW_OF);
       break;
-    case nsIAccessibleRelation::RELATION_POPUP_FOR:
+    case RelationType::POPUP_FOR:
       *aRelationType = ::SysAllocString(IA2_RELATION_POPUP_FOR);
       break;
-    case nsIAccessibleRelation::RELATION_SUBWINDOW_OF:
+    case RelationType::SUBWINDOW_OF:
       *aRelationType = ::SysAllocString(IA2_RELATION_SUBWINDOW_OF);
       break;
-    default:
-      return E_FAIL;
   }
 
   return *aRelationType ? S_OK : E_OUTOFMEMORY;
 
   A11Y_TRYBLOCK_END
 }
 
 STDMETHODIMP
--- a/accessible/src/windows/ia2/ia2AccessibleRelation.h
+++ b/accessible/src/windows/ia2/ia2AccessibleRelation.h
@@ -4,35 +4,33 @@
 /* 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/. */
 
 #ifndef _NS_ACCESSIBLE_RELATION_WRAP_H
 #define _NS_ACCESSIBLE_RELATION_WRAP_H
 
 #include "Accessible.h"
+#include "IUnknownImpl.h"
 #include "nsIAccessibleRelation.h"
 
 #include "nsTArray.h"
 
 #include "AccessibleRelation.h"
 
 namespace mozilla {
 namespace a11y {
 
-class ia2AccessibleRelation : public IAccessibleRelation
+class ia2AccessibleRelation MOZ_FINAL : public IAccessibleRelation
 {
 public:
-  ia2AccessibleRelation(uint32_t aType, Relation* aRel);
-  virtual ~ia2AccessibleRelation() { }
+  ia2AccessibleRelation(RelationType aType, Relation* aRel);
 
   // IUnknown
-  virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID aIID, void** aOutPtr);
-  virtual ULONG STDMETHODCALLTYPE AddRef();
-  virtual ULONG STDMETHODCALLTYPE Release();
+  DECL_IUNKNOWN
 
   // IAccessibleRelation
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_relationType(
       /* [retval][out] */ BSTR *relationType);
 
   virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_localizedRelationType(
       /* [retval][out] */ BSTR *localizedRelationType);
 
@@ -51,41 +49,40 @@ public:
   inline bool HasTargets() const
     { return mTargets.Length(); }
 
 private:
   ia2AccessibleRelation();
   ia2AccessibleRelation(const ia2AccessibleRelation&);
   ia2AccessibleRelation& operator = (const ia2AccessibleRelation&);
 
-  uint32_t mType;
+  RelationType mType;
   nsTArray<nsRefPtr<Accessible> > mTargets;
-  ULONG mReferences;
 };
 
 
 /**
  * Relations exposed to IAccessible2.
  */
-static const uint32_t sRelationTypesForIA2[] = {
-  nsIAccessibleRelation::RELATION_LABELLED_BY,
-  nsIAccessibleRelation::RELATION_LABEL_FOR,
-  nsIAccessibleRelation::RELATION_DESCRIBED_BY,
-  nsIAccessibleRelation::RELATION_DESCRIPTION_FOR,
-  nsIAccessibleRelation::RELATION_NODE_CHILD_OF,
-  nsIAccessibleRelation::RELATION_NODE_PARENT_OF,
-  nsIAccessibleRelation::RELATION_CONTROLLED_BY,
-  nsIAccessibleRelation::RELATION_CONTROLLER_FOR,
-  nsIAccessibleRelation::RELATION_FLOWS_TO,
-  nsIAccessibleRelation::RELATION_FLOWS_FROM,
-  nsIAccessibleRelation::RELATION_MEMBER_OF,
-  nsIAccessibleRelation::RELATION_SUBWINDOW_OF,
-  nsIAccessibleRelation::RELATION_EMBEDS,
-  nsIAccessibleRelation::RELATION_EMBEDDED_BY,
-  nsIAccessibleRelation::RELATION_POPUP_FOR,
-  nsIAccessibleRelation::RELATION_PARENT_WINDOW_OF
+static const RelationType sRelationTypesForIA2[] = {
+  RelationType::LABELLED_BY,
+  RelationType::LABEL_FOR,
+  RelationType::DESCRIBED_BY,
+  RelationType::DESCRIPTION_FOR,
+  RelationType::NODE_CHILD_OF,
+  RelationType::NODE_PARENT_OF,
+  RelationType::CONTROLLED_BY,
+  RelationType::CONTROLLER_FOR,
+  RelationType::FLOWS_TO,
+  RelationType::FLOWS_FROM,
+  RelationType::MEMBER_OF,
+  RelationType::SUBWINDOW_OF,
+  RelationType::EMBEDS,
+  RelationType::EMBEDDED_BY,
+  RelationType::POPUP_FOR,
+  RelationType::PARENT_WINDOW_OF
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
 
--- a/accessible/src/windows/msaa/AccessibleWrap.cpp
+++ b/accessible/src/windows/msaa/AccessibleWrap.cpp
@@ -916,75 +916,75 @@ AccessibleWrap::accNavigate(
     case NAVDIR_DOWN:
     case NAVDIR_LEFT:
     case NAVDIR_RIGHT:
     case NAVDIR_UP:
       return E_NOTIMPL;
 
     // MSAA relationship extensions to accNavigate
     case NAVRELATION_CONTROLLED_BY:
-      xpRelation = nsIAccessibleRelation::RELATION_CONTROLLED_BY;
+      xpRelation = RelationType::CONTROLLED_BY;
       break;
     case NAVRELATION_CONTROLLER_FOR:
-      xpRelation = nsIAccessibleRelation::RELATION_CONTROLLER_FOR;
+      xpRelation = RelationType::CONTROLLER_FOR;
       break;
     case NAVRELATION_LABEL_FOR:
-      xpRelation = nsIAccessibleRelation::RELATION_LABEL_FOR;
+      xpRelation = RelationType::LABEL_FOR;
       break;
     case NAVRELATION_LABELLED_BY:
-      xpRelation = nsIAccessibleRelation::RELATION_LABELLED_BY;
+      xpRelation = RelationType::LABELLED_BY;
       break;
     case NAVRELATION_MEMBER_OF:
-      xpRelation = nsIAccessibleRelation::RELATION_MEMBER_OF;
+      xpRelation = RelationType::MEMBER_OF;
       break;
     case NAVRELATION_NODE_CHILD_OF:
-      xpRelation = nsIAccessibleRelation::RELATION_NODE_CHILD_OF;
+      xpRelation = RelationType::NODE_CHILD_OF;
       break;
     case NAVRELATION_FLOWS_TO:
-      xpRelation = nsIAccessibleRelation::RELATION_FLOWS_TO;
+      xpRelation = RelationType::FLOWS_TO;
       break;
     case NAVRELATION_FLOWS_FROM:
-      xpRelation = nsIAccessibleRelation::RELATION_FLOWS_FROM;
+      xpRelation = RelationType::FLOWS_FROM;
       break;
     case NAVRELATION_SUBWINDOW_OF:
-      xpRelation = nsIAccessibleRelation::RELATION_SUBWINDOW_OF;
+      xpRelation = RelationType::SUBWINDOW_OF;
       break;
     case NAVRELATION_EMBEDS:
-      xpRelation = nsIAccessibleRelation::RELATION_EMBEDS;
+      xpRelation = RelationType::EMBEDS;
       break;
     case NAVRELATION_EMBEDDED_BY:
-      xpRelation = nsIAccessibleRelation::RELATION_EMBEDDED_BY;
+      xpRelation = RelationType::EMBEDDED_BY;
       break;
     case NAVRELATION_POPUP_FOR:
-      xpRelation = nsIAccessibleRelation::RELATION_POPUP_FOR;
+      xpRelation = RelationType::POPUP_FOR;
       break;
     case NAVRELATION_PARENT_WINDOW_OF:
-      xpRelation = nsIAccessibleRelation::RELATION_PARENT_WINDOW_OF;
+      xpRelation = RelationType::PARENT_WINDOW_OF;
       break;
     case NAVRELATION_DEFAULT_BUTTON:
-      xpRelation = nsIAccessibleRelation::RELATION_DEFAULT_BUTTON;
+      xpRelation = RelationType::DEFAULT_BUTTON;
       break;
     case NAVRELATION_DESCRIBED_BY:
-      xpRelation = nsIAccessibleRelation::RELATION_DESCRIBED_BY;
+      xpRelation = RelationType::DESCRIBED_BY;
       break;
     case NAVRELATION_DESCRIPTION_FOR:
-      xpRelation = nsIAccessibleRelation::RELATION_DESCRIPTION_FOR;
+      xpRelation = RelationType::DESCRIPTION_FOR;
       break;
     case NAVRELATION_NODE_PARENT_OF:
-      xpRelation = nsIAccessibleRelation::RELATION_NODE_PARENT_OF;
+      xpRelation = RelationType::NODE_PARENT_OF;
       break;
 
     default:
       return E_INVALIDARG;
   }
 
   pvarEndUpAt->vt = VT_EMPTY;
 
   if (xpRelation >= 0) {
-    Relation rel = RelationByType(xpRelation);
+    Relation rel = RelationByType(static_cast<RelationType>(xpRelation));
     navAccessible = rel.Next();
   }
 
   if (!navAccessible)
     return E_FAIL;
 
   pvarEndUpAt->pdispVal = NativeAccessible(navAccessible);
   pvarEndUpAt->vt = VT_DISPATCH;
--- a/accessible/src/xul/XULElementAccessibles.cpp
+++ b/accessible/src/xul/XULElementAccessibles.cpp
@@ -82,20 +82,20 @@ uint64_t
 XULLabelAccessible::NativeState()
 {
   // Labels and description have read only state
   // They are not focusable or selectable
   return HyperTextAccessibleWrap::NativeState() | states::READONLY;
 }
 
 Relation
-XULLabelAccessible::RelationByType(uint32_t aType)
+XULLabelAccessible::RelationByType(RelationType aType)
 {
   Relation rel = HyperTextAccessibleWrap::RelationByType(aType);
-  if (aType == nsIAccessibleRelation::RELATION_LABEL_FOR) {
+  if (aType == RelationType::LABEL_FOR) {
     // Caption is the label for groupbox
     nsIContent* parent = mContent->GetFlattenedTreeParent();
     if (parent && parent->Tag() == nsGkAtoms::caption) {
       Accessible* parent = Parent();
       if (parent && parent->Role() == roles::GROUPING)
         rel.AppendTarget(parent);
     }
   }
--- a/accessible/src/xul/XULElementAccessibles.h
+++ b/accessible/src/xul/XULElementAccessibles.h
@@ -21,17 +21,17 @@ class XULLabelAccessible : public HyperT
 {
 public:
   XULLabelAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual void Shutdown();
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
-  virtual Relation RelationByType(uint32_t aRelationType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 
   void UpdateLabelValue(const nsString& aValue);
 
 protected:
   // Accessible
   virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
   virtual void CacheChildren() MOZ_OVERRIDE;
 
--- a/accessible/src/xul/XULFormControlAccessible.cpp
+++ b/accessible/src/xul/XULFormControlAccessible.cpp
@@ -380,40 +380,39 @@ XULGroupboxAccessible::NativeRole()
   return roles::GROUPING;
 }
 
 ENameValueFlag
 XULGroupboxAccessible::NativeName(nsString& aName)
 {
   // XXX: we use the first related accessible only.
   Accessible* label =
-    RelationByType(nsIAccessibleRelation::RELATION_LABELLED_BY).Next();
+    RelationByType(RelationType::LABELLED_BY).Next();
   if (label)
     return label->Name(aName);
 
   return eNameOK;
 }
 
 Relation
-XULGroupboxAccessible::RelationByType(uint32_t aType)
+XULGroupboxAccessible::RelationByType(RelationType aType)
 {
   Relation rel = AccessibleWrap::RelationByType(aType);
-  if (aType != nsIAccessibleRelation::RELATION_LABELLED_BY)
+  if (aType != RelationType::LABELLED_BY)
     return rel;
 
   // The label for xul:groupbox is generated from xul:label that is
   // inside the anonymous content of the xul:caption.
   // The xul:label has an accessible object but the xul:caption does not
   uint32_t childCount = ChildCount();
   for (uint32_t childIdx = 0; childIdx < childCount; childIdx++) {
     Accessible* childAcc = GetChildAt(childIdx);
     if (childAcc->Role() == roles::LABEL) {
       // Ensure that it's our label
-      Relation reverseRel =
-        childAcc->RelationByType(nsIAccessibleRelation::RELATION_LABEL_FOR);
+      Relation reverseRel = childAcc->RelationByType(RelationType::LABEL_FOR);
       Accessible* testGroupbox = nullptr;
       while ((testGroupbox = reverseRel.Next()))
         if (testGroupbox == this) {
           // The <label> points back to this groupbox
           rel.AppendTarget(childAcc);
         }
     }
   }
--- a/accessible/src/xul/XULFormControlAccessible.h
+++ b/accessible/src/xul/XULFormControlAccessible.h
@@ -110,17 +110,17 @@ private:
  */
 class XULGroupboxAccessible : public AccessibleWrap
 {
 public:
   XULGroupboxAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual mozilla::a11y::role NativeRole();
-  virtual Relation RelationByType(uint32_t aRelationType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 
 protected:
   // Accessible
   virtual ENameValueFlag NativeName(nsString& aName) MOZ_OVERRIDE;
 };
 
 /**
  * Used for XUL radio element (radio button).
--- a/accessible/src/xul/XULTabAccessible.cpp
+++ b/accessible/src/xul/XULTabAccessible.cpp
@@ -103,20 +103,20 @@ uint64_t
 XULTabAccessible::NativeInteractiveState() const
 {
   uint64_t state = Accessible::NativeInteractiveState();
   return (state & states::UNAVAILABLE) ? state : state | states::SELECTABLE;
 }
 
 // nsIAccessible
 Relation
-XULTabAccessible::RelationByType(uint32_t aType)
+XULTabAccessible::RelationByType(RelationType aType)
 {
   Relation rel = AccessibleWrap::RelationByType(aType);
-  if (aType != nsIAccessibleRelation::RELATION_LABEL_FOR)
+  if (aType != RelationType::LABEL_FOR)
     return rel;
 
   // Expose 'LABEL_FOR' relation on tab accessible for tabpanel accessible.
   nsCOMPtr<nsIDOMXULRelatedElement> tabsElm =
     do_QueryInterface(mContent->GetParent());
   if (!tabsElm)
     return rel;
 
@@ -190,20 +190,20 @@ XULTabpanelAccessible::
 
 role
 XULTabpanelAccessible::NativeRole()
 {
   return roles::PROPERTYPAGE;
 }
 
 Relation
-XULTabpanelAccessible::RelationByType(uint32_t aType)
+XULTabpanelAccessible::RelationByType(RelationType aType)
 {
   Relation rel = AccessibleWrap::RelationByType(aType);
-  if (aType != nsIAccessibleRelation::RELATION_LABELLED_BY)
+  if (aType != RelationType::LABELLED_BY)
     return rel;
 
   // Expose 'LABELLED_BY' relation on tabpanel accessible for tab accessible.
   nsCOMPtr<nsIDOMXULRelatedElement> tabpanelsElm =
     do_QueryInterface(mContent->GetParent());
   if (!tabpanelsElm)
     return rel;
 
--- a/accessible/src/xul/XULTabAccessible.h
+++ b/accessible/src/xul/XULTabAccessible.h
@@ -26,17 +26,17 @@ public:
   // nsIAccessible
   NS_IMETHOD GetActionName(uint8_t aIndex, nsAString& aName);
   NS_IMETHOD DoAction(uint8_t index);
 
   // Accessible
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
   virtual uint64_t NativeInteractiveState() const;
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 
   // ActionAccessible
   virtual uint8_t ActionCount();
 };
 
 
 /**
  * A container of tab objects, xul:tabs element.
@@ -86,16 +86,16 @@ public:
  */
 class XULTabpanelAccessible : public AccessibleWrap
 {
 public:
   XULTabpanelAccessible(nsIContent* aContent, DocAccessible* aDoc);
 
   // Accessible
   virtual a11y::role NativeRole();
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 };
 
 } // namespace a11y
 } // namespace mozilla
 
 #endif
 
--- a/accessible/src/xul/XULTreeAccessible.cpp
+++ b/accessible/src/xul/XULTreeAccessible.cpp
@@ -437,19 +437,19 @@ XULTreeAccessible::ChildCount() const
   int32_t rowCount = 0;
   mTreeView->GetRowCount(&rowCount);
   childCount += rowCount;
 
   return childCount;
 }
 
 Relation
-XULTreeAccessible::RelationByType(uint32_t aType)
+XULTreeAccessible::RelationByType(RelationType aType)
 {
-  if (aType == nsIAccessibleRelation::RELATION_NODE_PARENT_OF) {
+  if (aType == RelationType::NODE_PARENT_OF) {
     if (mTreeView)
       return Relation(new XULTreeItemIterator(this, mTreeView, -1));
 
     return Relation();
   }
 
   return Accessible::RelationByType(aType);
 }
@@ -803,33 +803,33 @@ XULTreeItemAccessibleBase::TakeFocus()
   if (selection)
     selection->SetCurrentIndex(mRow);
 
   // focus event will be fired here
   return Accessible::TakeFocus();
 }
 
 Relation
-XULTreeItemAccessibleBase::RelationByType(uint32_t aType)
+XULTreeItemAccessibleBase::RelationByType(RelationType aType)
 {
 
   switch (aType) {
-    case nsIAccessibleRelation::RELATION_NODE_CHILD_OF: {
+    case RelationType::NODE_CHILD_OF: {
       int32_t parentIndex = -1;
       if (!NS_SUCCEEDED(mTreeView->GetParentIndex(mRow, &parentIndex)))
         return Relation();
 
       if (parentIndex == -1)
         return Relation(mParent);
 
       XULTreeAccessible* treeAcc = mParent->AsXULTree();
       return Relation(treeAcc->GetTreeItemAccessible(parentIndex));
     }
 
-    case nsIAccessibleRelation::RELATION_NODE_PARENT_OF: {
+    case RelationType::NODE_PARENT_OF: {
       bool isTrue = false;
       if (NS_FAILED(mTreeView->IsContainerEmpty(mRow, &isTrue)) || isTrue)
         return Relation();
 
       if (NS_FAILED(mTreeView->IsContainerOpen(mRow, &isTrue)) || !isTrue)
         return Relation();
 
       XULTreeAccessible* tree = mParent->AsXULTree();
--- a/accessible/src/xul/XULTreeAccessible.h
+++ b/accessible/src/xul/XULTreeAccessible.h
@@ -45,17 +45,17 @@ public:
   virtual void Value(nsString& aValue);
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
   virtual Accessible* ChildAtPoint(int32_t aX, int32_t aY,
                                    EWhichChildAtPoint aWhichChild);
 
   virtual Accessible* GetChildAt(uint32_t aIndex);
   virtual uint32_t ChildCount() const;
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
 
   // SelectAccessible
   virtual already_AddRefed<nsIArray> SelectedItems();
   virtual uint32_t SelectedItemCount();
   virtual Accessible* GetSelectedItem(uint32_t aIndex);
   virtual bool IsItemSelected(uint32_t aIndex);
   virtual bool AddItemToSelection(uint32_t aIndex);
   virtual bool RemoveItemFromSelection(uint32_t aIndex);
@@ -158,17 +158,17 @@ public:
   // nsAccessNode
   virtual void Shutdown();
 
   // Accessible
   virtual GroupPos GroupPosition();
   virtual uint64_t NativeState();
   virtual uint64_t NativeInteractiveState() const;
   virtual int32_t IndexInParent() const;
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
   virtual Accessible* FocusedChild();
 
   // ActionAccessible
   virtual uint8_t ActionCount();
 
   // Widgets
   virtual Accessible* ContainerWidget() const;
 
--- a/accessible/src/xul/XULTreeGridAccessible.cpp
+++ b/accessible/src/xul/XULTreeGridAccessible.cpp
@@ -757,17 +757,17 @@ XULTreeGridCellAccessible::NativeInterac
 
 int32_t
 XULTreeGridCellAccessible::IndexInParent() const
 {
   return ColIdx();
 }
 
 Relation
-XULTreeGridCellAccessible::RelationByType(uint32_t aType)
+XULTreeGridCellAccessible::RelationByType(RelationType aType)
 {
   return Relation();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeGridCellAccessible: public implementation
 
 void
--- a/accessible/src/xul/XULTreeGridAccessible.h
+++ b/accessible/src/xul/XULTreeGridAccessible.h
@@ -155,17 +155,17 @@ public:
 
   // Accessible
   virtual TableCellAccessible* AsTableCell() { return this; }
   virtual void Shutdown();
   virtual ENameValueFlag Name(nsString& aName);
   virtual Accessible* FocusedChild();
   virtual already_AddRefed<nsIPersistentProperties> NativeAttributes() MOZ_OVERRIDE;
   virtual int32_t IndexInParent() const;
-  virtual Relation RelationByType(uint32_t aType);
+  virtual Relation RelationByType(RelationType aType) MOZ_OVERRIDE;
   virtual a11y::role NativeRole();
   virtual uint64_t NativeState();
   virtual uint64_t NativeInteractiveState() const;
 
   // ActionAccessible
   virtual uint8_t ActionCount();
 
   // TableCellAccessible