Backed out changeset 2084a929ec4c (bug 1492866) for browser_accessibility_walker.js faiures CLOSED TREE
authorCiure Andrei <aciure@mozilla.com>
Wed, 10 Oct 2018 23:46:13 +0300
changeset 499066 fee847bb2f45afbe782ffec903004a64ed2169c9
parent 499065 c51832c62e768f6089510fb8c2736957eff811f9
child 499067 ae464c376e720fce7701ee625ec912467468a264
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1492866
milestone64.0a1
backs out2084a929ec4cbf31dda4df9935ba4bb38002a6bd
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 2084a929ec4c (bug 1492866) for browser_accessibility_walker.js faiures CLOSED TREE
devtools/client/accessibility/accessibility-startup.js
devtools/client/accessibility/accessibility-view.js
devtools/client/accessibility/accessibility.css
devtools/client/accessibility/actions/details.js
devtools/client/accessibility/actions/ui.js
devtools/client/accessibility/components/AccessibilityRow.js
devtools/client/accessibility/components/Accessible.js
devtools/client/accessibility/components/MainFrame.js
devtools/client/accessibility/components/RightSidebar.js
devtools/client/accessibility/constants.js
devtools/client/accessibility/panel.js
devtools/client/accessibility/reducers/details.js
devtools/client/accessibility/reducers/ui.js
devtools/client/accessibility/test/browser/browser.ini
devtools/client/accessibility/test/browser/browser_accessibility_relation_navigation.js
devtools/client/accessibility/test/browser/head.js
devtools/client/accessibility/test/mochitest/chrome.ini
devtools/client/accessibility/test/mochitest/test_accessible_openLink.html
devtools/client/accessibility/test/mochitest/test_accessible_relations.html
devtools/server/actors/accessibility.js
devtools/server/tests/browser/browser_accessibility_node.js
devtools/server/tests/browser/doc_accessibility.html
devtools/shared/specs/accessibility.js
--- a/devtools/client/accessibility/accessibility-startup.js
+++ b/devtools/client/accessibility/accessibility-startup.js
@@ -42,24 +42,21 @@ class AccessibilityStartup {
   initAccessibility() {
     if (!this._initAccessibility) {
       this._initAccessibility = (async function() {
         this._accessibility = this.target.getFront("accessibility");
         // We must call a method on an accessibility front here (such as getWalker), in
         // oreder to be able to check actor's backward compatibility via actorHasMethod.
         // See targe.js@getActorDescription for more information.
         this._walker = await this._accessibility.getWalker();
-        this._supports = {};
         // Only works with FF61+ targets
-        this._supports.enableDisable =
+        this._supportsLatestAccessibility =
           await this.target.actorHasMethod("accessibility", "enable");
 
-        if (this._supports.enableDisable) {
-          this._supports.relations =
-            await this.target.actorHasMethod("accessible", "getRelations");
+        if (this._supportsLatestAccessibility) {
           await this._accessibility.bootstrap();
         }
 
         this._updateToolHighlight();
 
         this._accessibility.on("init", this._updateToolHighlight);
         this._accessibility.on("shutdown", this._updateToolHighlight);
       }.bind(this))();
--- a/devtools/client/accessibility/accessibility-view.js
+++ b/devtools/client/accessibility/accessibility-view.js
@@ -42,28 +42,23 @@ function AccessibilityView(localStore) {
 AccessibilityView.prototype = {
   /**
    * Initialize accessibility view, create its top level component and set the
    * data store.
    *
    * @param {Object} accessibility  front that can initialize accessibility
    *                                walker and enable/disable accessibility
    *                                services.
-   * @param {Object} walker         front for accessibility walker actor responsible for
-   *                                managing accessible objects actors/fronts.
-   * @param {JSON}   supports       a collection of flags indicating which accessibility
-   *                                panel features are supported by the current serverside
-   *                                version.
    */
-  async initialize(accessibility, walker, supports) {
+  async initialize(accessibility, walker, supportsLatestAccessibility) {
     // Make sure state is reset every time accessibility panel is initialized.
-    await this.store.dispatch(reset(accessibility, supports));
+    await this.store.dispatch(reset(accessibility));
     const container = document.getElementById("content");
 
-    if (!supports.enableDisable) {
+    if (!supportsLatestAccessibility) {
       ReactDOM.render(OldVersionDescription(), container);
       return;
     }
 
     const mainFrame = MainFrame({ accessibility, walker });
     // Render top level component
     const provider = createElement(Provider, { store: this.store }, mainFrame);
     this.mainFrame = ReactDOM.render(provider, container);
--- a/devtools/client/accessibility/accessibility.css
+++ b/devtools/client/accessibility/accessibility.css
@@ -5,40 +5,29 @@
 :root {
   --accessibility-font-size: 12px;
   --accessibility-toolbar-height: 24px;
   --accessibility-toolbar-height-tall: 35px;
   --accessibility-toolbar-focus: var(--blue-50);
   --accessibility-toolbar-focus-alpha30: rgba(10, 132, 255, 0.3);
   --accessibility-full-length-minus-splitter: calc(100% - 1px);
   --accessibility-horizontal-padding: 5px;
-  --accessibility-properties-item-width: calc(100% - var(--accessibility-horizontal-padding));
   --accessibility-arrow-horizontal-padding: 4px;
   --accessibility-tree-row-height: 21px;
   --accessibility-unfocused-tree-focused-node-background: var(--grey-20);
   --accessibility-tree-focused-node-twisty-brightness: brightness(20%);
   --accessibility-link-color: var(--blue-60);
   --accessibility-link-color-active: var(--blue-70);
-  --accessible-role-active-background-color: var(--blue-50);
-  --accessible-role-active-border-color: #FFFFFFB3;
-  --accessible-role-background-color: white;
-  --accessible-role-border-color: #CACAD1;
-  --accessible-role-color: var(--grey-60);
 }
 
 :root.theme-dark {
   --accessibility-unfocused-tree-focused-node-background: var(--grey-70);
   --accessibility-tree-focused-node-twisty-brightness: unset;
   --accessibility-link-color: var(--theme-highlight-blue);
   --accessibility-link-color-active: var(--blue-40);
-  --accessible-role-active-background-color: var(--blue-60);
-  --accessible-role-active-border-color: #FFF6;
-  --accessible-role-background-color: var(--grey-80);
-  --accessible-role-border-color: var(--grey-50);
-  --accessible-role-color: var(--grey-40);
 }
 
 /* General */
 html,
 body {
   height: 100%;
   margin: 0;
   padding: 0;
@@ -348,17 +337,17 @@ body {
 /* NOTE: total height of the node (height + padding + border + margin) must
    be exactly the same as the value of TREE_ROW_HEIGHT constant in
    devtools/client/accessibility/constants.js */
 .accessible .tree .node {
   padding: 0 var(--accessibility-horizontal-padding);
   position: relative;
   display: flex;
   height: var(--accessibility-tree-row-height);
-  width: var(--accessibility-properties-item-width);
+  width: calc(100% - var(--accessibility-horizontal-padding));
   cursor: default;
   align-items: center;
 }
 
 .accessible .tree:focus {
   outline: 0;
 }
 
@@ -411,53 +400,26 @@ body {
 .accessible .tree .object-delimiter {
   padding-inline-end: var(--accessibility-arrow-horizontal-padding);
 }
 
 .accessible .tree .object-label {
   color: var(--theme-highlight-blue);
 }
 
-.accessible .tree .objectBox-accessible .accessible-role {
-  background-color: var(--accessible-role-background-color);
-  color: var(--accessible-role-color);
-  border: 1px solid var(--accessible-role-border-color);
-  border-radius: 3px;
-  padding: 0px 2px;
-  margin-inline-start: 5px;
-}
-
-.accessible .tree:focus .node.focused .objectBox-accessible .accessible-role {
-  background-color: var(--accessible-role-active-background-color);
-  border-color: var(--accessible-role-active-border-color);
-  color: var(--theme-selection-color);
-}
-
-.accessible .tree:focus .node.focused .open-accessibility-inspector {
-  background-color: var(--grey-30);
-}
-
-.accessible .tree:focus .node.focused:hover .open-accessibility-inspector {
-  background-color: var(--theme-selection-color);
-}
-
-.accessible .tree .objectBox-accessible,
 .accessible .tree .objectBox-node {
   width: 100%;
   display: flex;
-  align-items: center;
 }
 
-.accessible .tree .objectBox-accessible .accessible-name,
 .accessible .tree .objectBox-node .attrName {
   overflow: hidden;
   text-overflow: ellipsis;
 }
 
-.accessible .tree .objectBox-accessible .open-accessibility-inspector,
 .accessible .tree .objectBox-node .open-inspector{
   width: 17px;
   cursor: pointer;
 }
 
 .accessible .tree .objectBox-object,
 .accessible .tree .objectBox-string,
 .accessible .tree .objectBox-text,
--- a/devtools/client/accessibility/actions/details.js
+++ b/devtools/client/accessibility/actions/details.js
@@ -5,16 +5,14 @@
 
 const { UPDATE_DETAILS } = require("../constants");
 
 /**
  * Update details with the given accessible object.
  *
  * @param {Object} dom walker front
  * @param {Object} accessible front
- * @param {Object} list of supported serverside features.
  */
-exports.updateDetails = (domWalker, accessible, supports) =>
-  dispatch => Promise.all([
-    domWalker.getNodeFromActor(accessible.actorID, ["rawAccessible", "DOMNode"]),
-    supports.relations ? accessible.getRelations() : []
-  ]).then(response => dispatch({ accessible, type: UPDATE_DETAILS, response }))
-    .catch(error => dispatch({ accessible, type: UPDATE_DETAILS, error }));
+exports.updateDetails = (domWalker, accessible) =>
+  dispatch =>
+    domWalker.getNodeFromActor(accessible.actorID, ["rawAccessible", "DOMNode"])
+      .then(response => dispatch({ accessible, type: UPDATE_DETAILS, response }))
+      .catch(error => dispatch({ accessible, type: UPDATE_DETAILS, error }));
--- a/devtools/client/accessibility/actions/ui.js
+++ b/devtools/client/accessibility/actions/ui.js
@@ -9,18 +9,18 @@ const {
   RESET,
   UPDATE_CAN_BE_DISABLED,
   UPDATE_CAN_BE_ENABLED
 } = require("../constants");
 
 /**
  * Reset accessibility panel UI.
  */
-exports.reset = (accessibility, supports) =>
-  dispatch => dispatch({ accessibility, supports, type: RESET });
+exports.reset = accessibility =>
+  dispatch => dispatch({ accessibility, type: RESET });
 
 /**
  * Update a "canBeDisabled" flag for accessibility service.
  */
 exports.updateCanBeDisabled = canBeDisabled =>
   dispatch => dispatch({ canBeDisabled, type: UPDATE_CAN_BE_DISABLED });
 
 /**
--- a/devtools/client/accessibility/components/AccessibilityRow.js
+++ b/devtools/client/accessibility/components/AccessibilityRow.js
@@ -87,19 +87,19 @@ class AccessibilityRow extends Component
   }
 
   scrollIntoView() {
     const row = findDOMNode(this);
     row.scrollIntoView({ block: "center" });
   }
 
   updateAndScrollIntoViewIfNeeded() {
-    const { dispatch, member, supports } = this.props;
+    const { dispatch, member } = this.props;
     if (gToolbox) {
-      dispatch(updateDetails(gToolbox.walker, member.object, supports));
+      dispatch(updateDetails(gToolbox.walker, member.object));
     }
 
     this.scrollIntoView();
     window.emit(EVENTS.NEW_ACCESSIBLE_FRONT_SELECTED, member.object);
   }
 
   flashValue() {
     const row = findDOMNode(this);
@@ -148,13 +148,9 @@ class AccessibilityRow extends Component
       onMouseOver: () => this.highlight(object),
       onMouseOut: () => this.unhighlight()
     });
 
     return (HighlightableTreeRow(props));
   }
 }
 
-const mapStateToProps = ({ ui }) => ({
-  supports: ui.supports
-});
-
-module.exports = connect(mapStateToProps)(AccessibilityRow);
+module.exports = connect()(AccessibilityRow);
--- a/devtools/client/accessibility/components/Accessible.js
+++ b/devtools/client/accessibility/components/Accessible.js
@@ -13,31 +13,26 @@ const { findDOMNode } = require("devtool
 const { connect } = require("devtools/client/shared/vendor/react-redux");
 
 const { TREE_ROW_HEIGHT, ORDERED_PROPS, ACCESSIBLE_EVENTS, VALUE_FLASHING_DURATION } =
   require("../constants");
 const { L10N } = require("../utils/l10n");
 const {flashElementOn, flashElementOff} =
       require("devtools/client/inspector/markup/utils");
 const { updateDetails } = require("../actions/details");
-const { select, unhighlight } = require("../actions/accessibles");
 
 const Tree = createFactory(require("devtools/client/shared/components/VirtualizedTree"));
 // Reps
 const { REPS, MODE } = require("devtools/client/shared/components/reps/reps");
-const { Rep, ElementNode, Accessible: AccessibleRep, Obj } = REPS;
-
-const { translateNodeFrontToGrip } = require("devtools/client/inspector/shared/utils");
+const { Rep, ElementNode } = REPS;
 
 loader.lazyRequireGetter(this, "openContentLink", "devtools/client/shared/link", true);
 
 const TELEMETRY_NODE_INSPECTED_COUNT = "devtools.accessibility.node_inspected_count";
 
-const TREE_DEPTH_PADDING_INCREMENT = 15;
-
 class AccessiblePropertyClass extends Component {
   static get propTypes() {
     return {
       accessible: PropTypes.string,
       object: PropTypes.any,
       focused: PropTypes.bool,
       children: PropTypes.func
     };
@@ -76,20 +71,17 @@ const AccessibleProperty = createFactory
 class Accessible extends Component {
   static get propTypes() {
     return {
       accessible: PropTypes.object,
       dispatch: PropTypes.func.isRequired,
       DOMNode: PropTypes.object,
       items: PropTypes.array,
       labelledby: PropTypes.string.isRequired,
-      parents: PropTypes.object,
-      relations: PropTypes.object,
-      supports: PropTypes.object,
-      walker: PropTypes.object.isRequired
+      parents: PropTypes.object
     };
   }
 
   constructor(props) {
     super(props);
 
     this.state = {
       expanded: new Set(),
@@ -132,19 +124,19 @@ class Accessible extends Component {
   onAccessibleInspected() {
     const { props } = this.refs;
     if (props) {
       props.refs.tree.focus();
     }
   }
 
   update() {
-    const { dispatch, accessible, supports } = this.props;
+    const { dispatch, accessible } = this.props;
     if (gToolbox) {
-      dispatch(updateDetails(gToolbox.walker, accessible, supports));
+      dispatch(updateDetails(gToolbox.walker, accessible));
     }
   }
 
   setExpanded(item, isExpanded) {
     const { expanded } = this.state;
 
     if (isExpanded) {
       expanded.add(item.path);
@@ -166,80 +158,29 @@ class Accessible extends Component {
   hideHighlighter() {
     if (!gToolbox) {
       return;
     }
 
     gToolbox.highlighterUtils.unhighlight();
   }
 
-  showAccessibleHighlighter(accessible) {
-    const { walker, dispatch } = this.props;
-    dispatch(unhighlight());
-
-    if (!accessible || !walker) {
-      return;
-    }
-
-    walker.highlightAccessible(accessible).catch(error => {
-      // Only report an error where there's still a toolbox. Ignore cases where toolbox is
-      // already destroyed.
-      if (gToolbox) {
-        console.error(error);
-      }
-    });
-  }
-
-  hideAccessibleHighlighter() {
-    const { walker, dispatch } = this.props;
-    dispatch(unhighlight());
-
-    if (!walker) {
-      return;
-    }
-
-    walker.unhighlight().catch(error => {
-      // Only report an error where there's still a toolbox. Ignore cases where toolbox is
-      // already destroyed.
-      if (gToolbox) {
-        console.error(error);
-      }
-    });
-  }
-
   selectNode(nodeFront, reason = "accessibility") {
     if (gTelemetry) {
       gTelemetry.scalarAdd(TELEMETRY_NODE_INSPECTED_COUNT, 1);
     }
 
     if (!gToolbox) {
       return;
     }
 
     gToolbox.selectTool("inspector").then(() =>
       gToolbox.selection.setNodeFront(nodeFront, reason));
   }
 
-  async selectAccessible(accessible) {
-    const { walker, dispatch } = this.props;
-    if (!walker) {
-      return;
-    }
-
-    await dispatch(select(walker, accessible));
-
-    const { props } = this.refs;
-    if (props) {
-      props.refs.tree.blur();
-    }
-    await this.setState({ focused: null });
-
-    window.emit(EVENTS.NEW_ACCESSIBLE_FRONT_INSPECTED);
-  }
-
   openLink(link, e) {
     openContentLink(link);
   }
 
   renderItem(item, depth, focused, arrow, expanded) {
     const object = item.contents;
     const valueProps = {
       object,
@@ -248,48 +189,30 @@ class Accessible extends Component {
       openLink: this.openLink
     };
 
     if (isNode(object)) {
       valueProps.defaultRep = ElementNode;
       valueProps.onDOMNodeMouseOut = () => this.hideHighlighter();
       valueProps.onDOMNodeMouseOver = () => this.showHighlighter(this.props.DOMNode);
       valueProps.onInspectIconClick = () => this.selectNode(this.props.DOMNode);
-    } else if (isAccessible(object)) {
-      const target = findAccessibleTarget(this.props.relations, object.actor);
-      valueProps.defaultRep = AccessibleRep;
-      valueProps.onAccessibleMouseOut = () => this.hideAccessibleHighlighter();
-      valueProps.onAccessibleMouseOver = () => this.showAccessibleHighlighter(target);
-      valueProps.onInspectIconClick = (obj, e) => {
-        e.stopPropagation();
-        this.selectAccessible(target);
-      };
-      valueProps.separatorText = "";
-    } else if (item.name === "relations") {
-      valueProps.defaultRep = Obj;
     } else {
       valueProps.noGrip = true;
     }
 
     const classList = [ "node", "object-node" ];
     if (focused) {
       classList.push("focused");
     }
 
-    const depthPadding = depth * TREE_DEPTH_PADDING_INCREMENT;
-
     return AccessibleProperty(
       { object, focused, accessible: this.props.accessible.actorID },
       () => div({
         className: classList.join(" "),
-        style: {
-          paddingInlineStart: depthPadding,
-          "inline-size":
-            `calc(var(--accessibility-properties-item-width) - ${depthPadding}px)`
-        },
+        style: { paddingInlineStart: depth * 15 },
         onClick: e => {
           if (e.target.classList.contains("theme-twisty")) {
             this.setExpanded(item, !expanded);
           }
         }
       },
         arrow,
         span({ className: "object-label" }, item.name),
@@ -318,55 +241,30 @@ class Accessible extends Component {
         onFocus: item => {
           if (this.state.focused !== item.path) {
             this.setState({ focused: item.path });
           }
         },
         onActivate: ({ contents }) => {
           if (isNode(contents)) {
             this.selectNode(this.props.DOMNode, "accessibility-keyboard");
-          } else if (isAccessible(contents)) {
-            const target = findAccessibleTarget(this.props.relations, contents.actor);
-            if (target) {
-              this.selectAccessible(target);
-            }
           }
         },
         focused: findFocused(focused, items),
         renderItem: this.renderItem,
         labelledby
       });
     }
 
     return div({ className: "info" },
                L10N.getStr("accessibility.accessible.notAvailable"));
   }
 }
 
 /**
- * Match accessibility object from relations targets to the grip that's being activated.
- * @param  {Object} relations  Object containing relations grouped by type and targets.
- * @param  {String} actorID    Actor ID to match to the relation target.
- * @return {Object}            Accessible front that matches the relation target.
- */
-const findAccessibleTarget = (relations, actorID) => {
-  for (const relationType in relations) {
-    let targets = relations[relationType];
-    targets = Array.isArray(targets) ? targets : [targets];
-    for (const target of targets) {
-      if (target.actorID === actorID) {
-        return target;
-      }
-    }
-  }
-
-  return null;
-};
-
-/**
  * Find currently focused item.
  * @param  {String} focused Key of the currently focused item.
  * @param  {Array}  items   Accessibility properties array.
  * @return {Object?}        Possibly found focused item.
  */
 const findFocused = (focused, items) => {
   for (const item of items) {
     if (item.path === focused) {
@@ -383,64 +281,63 @@ const findFocused = (focused, items) => 
 /**
  * Check if a given property is a DOMNode actor.
  * @param  {Object?} value A property to check for being a DOMNode.
  * @return {Boolean}       A flag that indicates whether a property is a DOMNode.
  */
 const isNode = value => value && value.typeName === "domnode";
 
 /**
- * Check if a given property is an Accessible actor.
- * @param  {Object?} value A property to check for being an Accessible.
- * @return {Boolean}       A flag that indicates whether a property is an Accessible.
- */
-const isAccessible = value => value && value.typeName === "accessible";
-
-/**
  * While waiting for a reps fix in https://github.com/devtools-html/reps/issues/92,
- * translate accessibleFront to a grip-like object that can be used with an Accessible
- * rep.
+ * translate nodeFront to a grip-like object that can be used with an ElementNode rep.
  *
- * @params  {accessibleFront} accessibleFront
- *          The AccessibleFront for which we want to create a grip-like object.
+ * @params  {NodeFront} nodeFront
+ *          The NodeFront for which we want to create a grip-like object.
  * @returns {Object} a grip-like object that can be used with Reps.
  */
-const translateAccessibleFrontToGrip = accessibleFront => ({
-  actor: accessibleFront.actorID,
-  typeName: accessibleFront.typeName,
-  preview: {
-    name: accessibleFront.name,
-    role: accessibleFront.role,
-    // All the grid containers are assumed to be in the Accessibility tree.
-    isConnected: true
+const translateNodeFrontToGrip = nodeFront => {
+  const { attributes, actorID, typeName, nodeName, nodeType } = nodeFront;
+
+  // The main difference between NodeFront and grips is that attributes are treated as
+  // a map in grips and as an array in NodeFronts.
+  const attributesMap = {};
+  for (const { name, value } of attributes) {
+    attributesMap[name] = value;
   }
-});
 
-const translateNodeFrontToGripWrapper = nodeFront => ({
-  ...translateNodeFrontToGrip(nodeFront),
-  typeName: nodeFront.typeName
-});
+  return {
+    actor: actorID,
+    typeName,
+    preview: {
+      attributes: attributesMap,
+      attributesLength: attributes.length,
+      // All the grid containers are assumed to be in the DOM tree.
+      isConnected: true,
+      // nodeName is already lowerCased in Node grips
+      nodeName: nodeName.toLowerCase(),
+      nodeType
+    }
+  };
+};
 
 /**
  * Build props ingestible by Tree component.
  * @param  {Object} props      Component properties to be processed.
  * @param  {String} parentPath Unique path that is used to identify a Tree Node.
  * @return {Object}            Processed properties.
  */
 const makeItemsForDetails = (props, parentPath) =>
   Object.getOwnPropertyNames(props).map(name => {
     let children = [];
     const path = `${parentPath}/${name}`;
     let contents = props[name];
 
     if (contents) {
       if (isNode(contents)) {
-        contents = translateNodeFrontToGripWrapper(contents);
-      } else if (isAccessible(contents)) {
-        contents = translateAccessibleFrontToGrip(contents);
+        contents = translateNodeFrontToGrip(contents);
       } else if (Array.isArray(contents) || typeof contents === "object") {
         children = makeItemsForDetails(contents, path);
       }
     }
 
     return { name, path, contents, children };
   });
 
@@ -455,34 +352,24 @@ const makeParentMap = (items) => {
       }
     }
   }
 
   items.forEach(_traverse);
   return map;
 };
 
-const mapStateToProps = ({ details, ui }) => {
-  const { accessible, DOMNode, relations } = details;
-  const { supports } = ui;
+const mapStateToProps = ({ details }) => {
+  const { accessible, DOMNode } = details;
   if (!accessible || !DOMNode) {
     return {};
   }
 
   const items = makeItemsForDetails(ORDERED_PROPS.reduce((props, key) => {
-    if (key === "DOMNode") {
-      props.DOMNode = DOMNode;
-    } else if (key === "relations") {
-      if (supports.relations) {
-        props.relations = relations;
-      }
-    } else {
-      props[key] = accessible[key];
-    }
-
+    props[key] = key === "DOMNode" ? DOMNode : accessible[key];
     return props;
   }, {}), "");
   const parents = makeParentMap(items);
 
-  return { accessible, DOMNode, items, parents, relations, supports };
+  return { accessible, DOMNode, items, parents };
 };
 
 module.exports = connect(mapStateToProps)(Accessible);
--- a/devtools/client/accessibility/components/MainFrame.js
+++ b/devtools/client/accessibility/components/MainFrame.js
@@ -104,17 +104,17 @@ class MainFrame extends Component {
           minSize: "10px",
           maxSize: "80%",
           splitterSize: 1,
           endPanelControl: true,
           startPanel: div({
             className: "main-panel",
             role: "presentation"
           }, AccessibilityTree({ walker })),
-          endPanel: RightSidebar({ walker }),
+          endPanel: RightSidebar(),
           vert: this.useLandscapeMode,
         })
       ));
   }
 }
 
 const mapStateToProps = ({ ui }) => ({
   enabled: ui.enabled
--- a/devtools/client/accessibility/components/RightSidebar.js
+++ b/devtools/client/accessibility/components/RightSidebar.js
@@ -1,48 +1,40 @@
 /* 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/. */
 "use strict";
 
 // React
 const { Component, createFactory } = require("devtools/client/shared/vendor/react");
-const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
 const { div } = require("devtools/client/shared/vendor/react-dom-factories");
 
 const { L10N } = require("../utils/l10n");
 const Accessible = createFactory(require("./Accessible"));
 
 // Component that is responsible for rendering accessible panel's sidebar.
 class RightSidebar extends Component {
-  static get propTypes() {
-    return {
-      walker: PropTypes.object.isRequired
-    };
-  }
-
   /**
    * Render the sidebar component.
    * @returns Sidebar React component.
    */
   render() {
     const headerID = "accessibility-right-sidebar-header";
-    const { walker } = this.props;
     return (
       div({
         className: "right-sidebar",
         role: "presentation"
       },
         div({
           className: "_header",
           id: headerID,
           role: "heading"
         }, L10N.getStr("accessibility.properties")),
         div({
           className: "_content accessible",
           role: "presentation"
-        }, Accessible({ walker, labelledby: headerID }))
+        }, Accessible({ labelledby: headerID }))
       )
     );
   }
 }
 
 module.exports = RightSidebar;
--- a/devtools/client/accessibility/constants.js
+++ b/devtools/client/accessibility/constants.js
@@ -37,17 +37,16 @@ exports.ORDERED_PROPS = [
   "actions",
   "value",
   "DOMNode",
   "description",
   "keyboardShortcut",
   "childCount",
   "indexInParent",
   "states",
-  "relations",
   "attributes"
 ];
 
 // Accessible events (emitted by accessible front) that the accessible component
 // listens to for a current accessible.
 exports.ACCESSIBLE_EVENTS = [
   "actions-change",
   "attributes-change",
--- a/devtools/client/accessibility/panel.js
+++ b/devtools/client/accessibility/panel.js
@@ -72,17 +72,17 @@ AccessibilityPanel.prototype = {
     this.panelWin.on(EVENTS.ACCESSIBILITY_INSPECTOR_UPDATED,
       this.onAccessibilityInspectorUpdated);
 
     this.shouldRefresh = true;
     this.panelWin.gToolbox = this._toolbox;
 
     await this._toolbox.initInspector();
     await this.startup.initAccessibility();
-    if (this.supports.enableDisable) {
+    if (this.supportsLatestAccessibility) {
       this.picker = new Picker(this);
     }
 
     this.updateA11YServiceDurationTimer();
     this.front.on("init", this.updateA11YServiceDurationTimer);
     this.front.on("shutdown", this.updateA11YServiceDurationTimer);
 
     this.front.on("init", this.forceUpdatePickerButton);
@@ -128,17 +128,19 @@ AccessibilityPanel.prototype = {
     }
 
     // Do not refresh if it isn't necessary.
     if (!this.shouldRefresh) {
       return;
     }
     // Alright reset the flag we are about to refresh the panel.
     this.shouldRefresh = false;
-    this.postContentMessage("initialize", this.front, this.walker, this.supports);
+    this.postContentMessage("initialize", this.front,
+                                          this.walker,
+                                          this.supportsLatestAccessibility);
   },
 
   updateA11YServiceDurationTimer() {
     if (this.front.enabled) {
       this._telemetry.start(A11Y_SERVICE_DURATION, this);
     } else {
       this._telemetry.finish(A11Y_SERVICE_DURATION, this);
     }
@@ -201,18 +203,18 @@ AccessibilityPanel.prototype = {
   get front() {
     return this.startup.accessibility;
   },
 
   get walker() {
     return this.startup.walker;
   },
 
-  get supports() {
-    return this.startup._supports;
+  get supportsLatestAccessibility() {
+    return this.startup._supportsLatestAccessibility;
   },
 
   /**
    * Return true if the Accessibility panel is currently selected.
    */
   get isVisible() {
     return this._toolbox.currentToolId === "accessibility";
   },
--- a/devtools/client/accessibility/reducers/details.js
+++ b/devtools/client/accessibility/reducers/details.js
@@ -28,23 +28,18 @@ function details(state = getInitialState
 
 /**
  * Handle details update for an accessible object
  * @param {Object} state  Current accessible object details.
  * @param {Object} action Redux action object
  * @return {Object}  updated state
  */
 function onUpdateDetails(state, action) {
-  const { accessible, response, error } = action;
+  const { accessible, response: DOMNode, error } = action;
   if (error) {
     console.warn("Error fetching DOMNode for accessible", accessible, error);
     return state;
   }
 
-  const [ DOMNode, relationObjects ] = response;
-  const relations = {};
-  relationObjects.forEach(({ type, targets }) => {
-    relations[type] = targets.length === 1 ? targets[0] : targets;
-  });
-  return { accessible, DOMNode, relations };
+  return { accessible, DOMNode };
 }
 
 exports.details = details;
--- a/devtools/client/accessibility/reducers/ui.js
+++ b/devtools/client/accessibility/reducers/ui.js
@@ -127,24 +127,19 @@ function onCanBeEnabledChange(state, { c
 }
 
 /**
  * Handle reset action for the accessibility panel UI.
  * @param  {Object}  state   Current ui state.
  * @param  {Object}  action  Redux action object
  * @return {Object}  updated state
  */
-function onReset(state, { accessibility, supports }) {
+function onReset(state, { accessibility }) {
   const { enabled, canBeDisabled, canBeEnabled } = accessibility;
-  const newState = { ...state, enabled, canBeDisabled, canBeEnabled };
-  if (supports) {
-    newState.supports = supports;
-  }
-
-  return newState;
+  return Object.assign({}, state, { enabled, canBeDisabled, canBeEnabled });
 }
 
 /**
  * Handle accessibilty service enabling/disabling.
  * @param {Object}  state   Current accessibility services enabled state.
  * @param {Object}  action  Redux action object
  * @param {Boolean} enabled New enabled state.
  * @return {Object}  updated state
--- a/devtools/client/accessibility/test/browser/browser.ini
+++ b/devtools/client/accessibility/test/browser/browser.ini
@@ -10,13 +10,12 @@ support-files =
   !/devtools/client/shared/test/shared-redux-head.js
   !/devtools/client/shared/test/telemetry-test-helpers.js
 
 [browser_accessibility_context_menu_browser.js]
 [browser_accessibility_context_menu_inspector.js]
 [browser_accessibility_mutations.js]
 [browser_accessibility_panel_highlighter.js]
 [browser_accessibility_panel_highlighter_multi_tab.js]
-[browser_accessibility_relation_navigation.js]
 [browser_accessibility_reload.js]
 [browser_accessibility_sidebar.js]
 [browser_accessibility_tree.js]
 [browser_accessibility_tree_nagivation.js]
deleted file mode 100644
--- a/devtools/client/accessibility/test/browser/browser_accessibility_relation_navigation.js
+++ /dev/null
@@ -1,110 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const TEST_URI = `<html>
-  <head>
-    <meta charset="utf-8"/>
-    <title>Accessibility Panel Test</title>
-  </head>
-  <body>
-    <h1>Top level header</h1>
-    <p>This is a paragraph.</p>
-  </body>
-</html>`;
-
-/**
- * Test data has the format of:
- * {
- *   desc     {String}    description for better logging
- *   action   {Function}  An optional action that needs to be performed before
- *                        the state of the tree and the sidebar can be checked.
- *   expected {JSON}      An expected states for the tree and the sidebar.
- * }
- */
-const tests = [{
-  desc: "Test the initial accessibility tree and sidebar states.",
-  expected: {
-    tree: [{
-      role: "document",
-      name: `"Accessibility Panel Test"`
-    }],
-    sidebar: {
-      name: "Accessibility Panel Test",
-      role: "document",
-      actions: [],
-      value: "",
-      description: "",
-      keyboardShortcut: "",
-      childCount: 2,
-      indexInParent: 0,
-      states: ["readonly", "focusable", "opaque", "enabled", "sensitive"]
-    }
-  }
-}, {
-  desc: "Expand first tree node.",
-  action: async ({ doc }) => toggleRow(doc, 0),
-  expected: {
-    tree: [{
-      role: "document",
-      name: `"Accessibility Panel Test"`
-    }, {
-      role: "heading",
-      name: `"Top level header"`
-    }, {
-      role: "paragraph",
-      name: `""`
-    } ]
-  }
-}, {
-  desc: "Select second tree node.",
-  action: async ({ doc }) => selectRow(doc, 1),
-  expected: {
-    sidebar: {
-      name: "Top level header",
-      role: "heading",
-      actions: [],
-      value: "",
-      description: "",
-      keyboardShortcut: "",
-      childCount: 1,
-      indexInParent: 0,
-      relations: {
-        "containing document": {
-          role: "document",
-          name: "Accessibility Panel Test"
-        }
-      },
-      states: ["selectable text", "opaque", "enabled", "sensitive"]
-    }
-  }
-}, {
-  desc: "Select containing document.",
-  action: async ({ doc, win }) => {
-    const relations = await selectProperty(doc, "/relations");
-    EventUtils.sendMouseEvent({ type: "click" }, relations.querySelector(".arrow"), win);
-    const containingDocRelation =
-      await selectProperty(doc, "/relations/containing document");
-    EventUtils.sendMouseEvent({ type: "click" },
-      containingDocRelation.querySelector(".open-accessibility-inspector"), win);
-  },
-  expected: {
-    sidebar: {
-      name: "Accessibility Panel Test",
-      role: "document",
-      actions: [],
-      value: "",
-      description: "",
-      keyboardShortcut: "",
-      childCount: 2,
-      indexInParent: 0,
-      states: ["readonly", "focusable", "opaque", "enabled", "sensitive"]
-    }
-  }
-}];
-
-/**
- * Check navigation within the tree.
- */
-addA11yPanelTestsTask(tests, TEST_URI, "Test Accessibility panel relation navigation.");
--- a/devtools/client/accessibility/test/browser/head.js
+++ b/devtools/client/accessibility/test/browser/head.js
@@ -173,124 +173,45 @@ async function checkTreeState(doc, expec
       row.querySelector(".treeLabelCell").textContent === expected[i].role &&
       row.querySelector(".treeValueCell").textContent === expected[i].name),
     "Wait for the right tree update.");
 
   ok(hasExpectedStructure, "Tree structure is correct.");
 }
 
 /**
- * Check if relations object matches what is expected. Note: targets are matched by their
- * name and role.
- * @param  {Object} relations  Relations to test.
- * @param  {Object} expected   Expected relations.
- * @return {Boolean}           True if relation types and their targers match what is
- *                             expected.
- */
-function relationsMatch(relations, expected) {
-  for (const relationType in expected) {
-    let expTargets = expected[relationType];
-    expTargets = Array.isArray(expTargets) ? expTargets : [expTargets];
-
-    let targets = relations[relationType];
-    targets = Array.isArray(targets) ? targets : [targets];
-
-    for (const index in expTargets) {
-      if (expTargets[index].name !== targets[index].name ||
-          expTargets[index].role !== targets[index].role) {
-        return false;
-      }
-    }
-  }
-
-  return true;
-}
-
-/**
  * Check the state of the accessibility sidebar.
  * @param  {Object} store         React store for the panel (includes store for
  *                                the sidebar).
  * @param  {Object} expectedState Expected state of the sidebar.
  */
 async function checkSidebarState(store, expectedState) {
   info("Checking sidebar state.");
   await waitUntilState(store, ({ details }) => {
     for (const key of ORDERED_PROPS) {
       const expected = expectedState[key];
       if (expected === undefined) {
         continue;
       }
 
-      if (key === "relations") {
-        if (!relationsMatch(details.relations, expected)) {
-          return false;
-        }
-      } else if (EXPANDABLE_PROPS.includes(key)) {
+      if (EXPANDABLE_PROPS.includes(key)) {
         if (JSON.stringify(details.accessible[key]) !== JSON.stringify(expected)) {
           return false;
         }
       } else if (details.accessible && details.accessible[key] !== expected) {
         return false;
       }
     }
 
     ok(true, "Sidebar state is correct.");
     return true;
   });
 }
 
 /**
- * Focus accessibility properties tree in the a11y inspector sidebar. If focused for the
- * first time, the tree will select first rendered node as defult selection for keyboard
- * purposes.
- *
- * @param  {Document} doc  accessibility inspector panel document.
- */
-async function focusAccessibleProperties(doc) {
-  const tree = doc.querySelector(".tree");
-  if (doc.activeElement !== tree) {
-    tree.focus();
-    await BrowserTestUtils.waitForCondition(() =>
-      tree.querySelector(".node.focused"), "Tree selected.");
-  }
-}
-
-/**
- * Select accessibility property in the sidebar.
- * @param  {Document} doc  accessibility inspector panel document.
- * @param  {String} id     id of the property to be selected.
- * @return {DOMNode}       Node that corresponds to the selected accessibility property.
- */
-async function selectProperty(doc, id) {
-  const win = doc.defaultView;
-  let selected = false;
-  let node;
-
-  await focusAccessibleProperties(doc);
-  await BrowserTestUtils.waitForCondition(() => {
-    node = doc.getElementById(`${id}`);
-    if (node) {
-      if (selected) {
-        return node.firstChild.classList.contains("focused");
-      }
-
-      EventUtils.sendMouseEvent({ type: "click" }, node, win);
-      selected = true;
-    } else {
-      const tree = doc.querySelector(".tree");
-      tree.scrollTop = parseFloat(win.getComputedStyle(tree).height);
-    }
-
-    return false;
-  });
-
-  return node;
-}
-
-/**
  * Select tree row.
  * @param  {document} doc       panel documnent.
  * @param  {Number}   rowNumber number of the row/tree node to be selected.
  */
 function selectRow(doc, rowNumber) {
   info(`Selecting row ${rowNumber}.`);
   EventUtils.sendMouseEvent({ type: "click" },
     doc.querySelectorAll(".treeRow")[rowNumber], doc.defaultView);
--- a/devtools/client/accessibility/test/mochitest/chrome.ini
+++ b/devtools/client/accessibility/test/mochitest/chrome.ini
@@ -1,7 +1,6 @@
 [DEFAULT]
 support-files =
   head.js
 
 [test_accessible_learnMoreLink.html]
 [test_accessible_openLink.html]
-[test_accessible_relations.html]
--- a/devtools/client/accessibility/test/mochitest/test_accessible_openLink.html
+++ b/devtools/client/accessibility/test/mochitest/test_accessible_openLink.html
@@ -54,17 +54,17 @@ window.onload = async function() {
     }
 
     const a = Accessible({ labelledby: "Test Accessible" });
     ok(a, "Should be able to create Accessible instances");
 
     let URL = "http://example.com";
     const mockStore = createStore((state, action) =>
       action ? { ...state, ...action } : state,
-      { details: { DOMNode: {}, accessible: { value: URL } }, ui: { supports: {} } });
+      { details: { DOMNode: {}, accessible: { value: URL } } });
     const provider = createElement(Provider, { store: mockStore }, a);
     const accessible = ReactDOM.render(provider, window.document.body);
     ok(accessible, "Should be able to mount Accessible instances");
 
     let link = document.querySelector(".url");
     testLinkClicked(link, null, URL, "tab");
 
     URL = "non-URL";
deleted file mode 100644
--- a/devtools/client/accessibility/test/mochitest/test_accessible_relations.html
+++ /dev/null
@@ -1,122 +0,0 @@
-<!-- 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/. -->
-<!DOCTYPE HTML>
-<html>
-<!--
-Test that openLink function is called if accessible object property is rendered as a link.
--->
-<head>
-  <meta charset="utf-8">
-  <title>Accessible component test</title>
-  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
-  <link rel="stylesheet" href="chrome://devtools/skin/light-theme.css" type="text/css">
-</head>
-<body>
-<pre id="test">
-<script src="head.js" type="application/javascript"></script>
-<script type="application/javascript">
-
-"use strict";
-
-window.onload = async function() {
-  try {
-    const ReactDOM = browserRequire("devtools/client/shared/vendor/react-dom");
-    const { createFactory, createElement } =
-      browserRequire("devtools/client/shared/vendor/react");
-    const { Provider } = require("devtools/client/shared/vendor/react-redux");
-    const createStore = require("devtools/client/shared/redux/create-store")();
-    const { Simulate } =
-      browserRequire("devtools/client/shared/vendor/react-dom-test-utils");
-    const Accessible = createFactory(
-      browserRequire("devtools/client/accessibility/components/Accessible"));
-
-    const a = Accessible({ labelledby: "Test Accessible" });
-    ok(a, "Should be able to create Accessible instances");
-
-    const mockState = {
-      details: {
-        DOMNode: {},
-        accessible: {
-          on: () => {},
-          off: () => {}
-        }
-      },
-      ui: {
-        supports: {}
-      }
-    };
-
-    const mockStore = createStore((state, action) =>
-      action ? { ...state, ...action } : state, mockState);
-    const provider = createElement(Provider, { store: mockStore }, a);
-    const accessible = ReactDOM.render(provider, window.document.body);
-    ok(accessible, "Should be able to mount Accessible instances");
-
-    info("Render accessible object when relations are not supported.");
-    let relationsNode = document.getElementById("/relations");
-    ok(!relationsNode, "Relations are not rendered when not supported.");
-
-    info("Render accessible object when relations are supported but are empty.");
-    let state = {
-      ...mockState,
-      ui: {
-        supports: {
-          relations: true
-        }
-      }
-    };
-    await mockStore.dispatch({ type: "update", ...state });
-    relationsNode = document.getElementById("/relations");
-    ok(relationsNode, "Relations are rendered when supported.");
-    let arrow = relationsNode.querySelector(".arrow.theme-twisty");
-    is(arrow.style.visibility, "hidden", "Relations are empty.");
-
-    info("Render accessible object with relations.");
-    state = {
-      details: {
-        ...mockState.details,
-        relations: {
-          "containing document": {
-            actorID: "server1.conn2.child1/accessible29",
-            typeName: "accessible",
-            name: "New Tab",
-            role: "document"
-          }
-        }
-      },
-      ui: {
-        supports: {
-          relations: true
-        }
-      }
-    };
-    await mockStore.dispatch({ type: "update", ...state });
-    relationsNode = document.getElementById("/relations");
-    ok(relationsNode, "Relations are rendered when supported.");
-    arrow = relationsNode.querySelector(".arrow.theme-twisty");
-    ok(!arrow.style.visibility,
-      "There is at least one relation for the current accessible object.");
-
-    Simulate.click(arrow, null);
-    const relationNode = document.getElementById("/relations/containing document");
-    ok(relationNode, "Relation node is rendered.");
-    ok(relationNode.textContent.includes(
-      state.details.relations["containing document"].name),
-      "Relation target's name is rendered");
-    ok(relationNode.textContent.includes(
-      state.details.relations["containing document"].role),
-      "Relation target's name is rendered");
-    ok(relationNode.querySelector(".open-accessibility-inspector"),
-      "Select accessible button is rendered.");
-  } catch (e) {
-    ok(false, "Got an error: " + DevToolsUtils.safeErrorString(e));
-  } finally {
-    SimpleTest.finish();
-  }
-};
-</script>
-</pre>
-</body>
-</html>
--- a/devtools/server/actors/accessibility.js
+++ b/devtools/server/actors/accessibility.js
@@ -21,27 +21,18 @@ const { isXUL } = require("devtools/serv
 const { isWindowIncluded } = require("devtools/shared/layout/utils");
 const { CustomHighlighterActor, register } =
   require("devtools/server/actors/highlighters");
 const { getContrastRatioFor } = require("devtools/server/actors/utils/accessibility");
 const PREF_ACCESSIBILITY_FORCE_DISABLED = "accessibility.force_disabled";
 
 const nsIAccessibleEvent = Ci.nsIAccessibleEvent;
 const nsIAccessibleStateChangeEvent = Ci.nsIAccessibleStateChangeEvent;
-const nsIAccessibleRelation = Ci.nsIAccessibleRelation;
 const nsIAccessibleRole = Ci.nsIAccessibleRole;
 
-const RELATIONS_TO_IGNORE = new Set([
-  nsIAccessibleRelation.RELATION_CONTAINING_APPLICATION,
-  nsIAccessibleRelation.RELATION_CONTAINING_TAB_PANE,
-  nsIAccessibleRelation.RELATION_CONTAINING_WINDOW,
-  nsIAccessibleRelation.RELATION_PARENT_WINDOW_OF,
-  nsIAccessibleRelation.RELATION_SUBWINDOW_OF
-]);
-
 const {
   EVENT_TEXT_CHANGED,
   EVENT_TEXT_INSERTED,
   EVENT_TEXT_REMOVED,
   EVENT_ACCELERATOR_CHANGE,
   EVENT_ACTION_CHANGE,
   EVENT_DEFACTION_CHANGE,
   EVENT_DESCRIPTION_CHANGE,
@@ -358,67 +349,16 @@ const AccessibleActor = ActorClassWithSp
     const left = x, right = x + w, top = y, bottom = y + h;
     if (left === right || top === bottom) {
       return null;
     }
 
     return { x, y, w, h };
   },
 
-  async getRelations() {
-    const relationObjects = [];
-    if (this.isDefunct) {
-      return relationObjects;
-    }
-
-    const relations =
-      [...this.rawAccessible.getRelations().enumerate(nsIAccessibleRelation)];
-    if (relations.length === 0) {
-      return relationObjects;
-    }
-
-    const doc = await this.walker.getDocument();
-    relations.forEach(relation => {
-      if (RELATIONS_TO_IGNORE.has(relation.relationType)) {
-        return;
-      }
-
-      const type = this.walker.a11yService.getStringRelationType(relation.relationType);
-      const targets = [...relation.getTargets().enumerate(Ci.nsIAccessible)];
-      let relationObject;
-      for (const target of targets) {
-        // Target of the relation is not part of the current root document.
-        if (target.rootDocument !== doc.rawAccessible) {
-          continue;
-        }
-
-        let targetAcc;
-        try {
-          targetAcc = this.walker.attachAccessible(target, doc);
-        } catch (e) {
-          // Target is not available.
-        }
-
-        if (targetAcc) {
-          if (!relationObject) {
-            relationObject = { type, targets: [] };
-          }
-
-          relationObject.targets.push(targetAcc);
-        }
-      }
-
-      if (relationObject) {
-        relationObjects.push(relationObject);
-      }
-    });
-
-    return relationObjects;
-  },
-
   form() {
     return {
       actor: this.actorID,
       role: this.role,
       name: this.name,
       value: this.value,
       description: this.description,
       keyboardShortcut: this.keyboardShortcut,
@@ -663,20 +603,16 @@ const AccessibleWalkerActor = ActorClass
   },
 
   async getAncestry(accessible) {
     if (accessible.indexInParent === -1) {
       return [];
     }
     const doc = await this.getDocument();
     const ancestry = [];
-    if (accessible === doc) {
-      return ancestry;
-    }
-
     try {
       let parent = accessible;
       while (parent && (parent = parent.parentAcc) && parent != doc) {
         ancestry.push(parent);
       }
       ancestry.push(doc);
     } catch (error) {
       throw new Error(`Failed to get ancestor for ${accessible}: ${error}`);
@@ -961,39 +897,16 @@ const AccessibleWalkerActor = ActorClass
   /**
    * This pick method also focuses the highlighter's target window.
    */
   pickAndFocus: function() {
     this.pick();
     this.rootWin.focus();
   },
 
-  attachAccessible(rawAccessible, accessibleDocument) {
-    // If raw accessible object is defunct or detached, no need to cache it and
-    // its ancestry.
-    if (!rawAccessible || isDefunct(rawAccessible) || rawAccessible.indexInParent < 0) {
-      return null;
-    }
-
-    const accessible = this.addRef(rawAccessible);
-    // There is a chance that ancestry lookup can fail if the accessible is in
-    // the detached subtree. At that point the root accessible object would be
-    // defunct and accessing it via parent property will throw.
-    try {
-      let parent = accessible;
-      while (parent && parent != accessibleDocument) {
-        parent = parent.parentAcc;
-      }
-    } catch (error) {
-      throw new Error(`Failed to get ancestor for ${accessible}: ${error}`);
-    }
-
-    return accessible;
-  },
-
   /**
    * Find accessible object that corresponds to a DOMNode and attach (lookup its
    * ancestry to the root doc) to the AccessibilityWalker tree.
    *
    * @param  {Object} event
    *         Correspoinding content event.
    * @return {null|Object}
    *         Accessible object, if available, that corresponds to a DOM node.
@@ -1004,19 +917,37 @@ const AccessibleWalkerActor = ActorClass
     // Find a first accessible object in the target's ancestry, including
     // target. Note: not all DOM nodes have corresponding accessible objects
     // (for example, a <DIV> element that is used as a container for other
     // things) thus we need to find one that does.
     while (!rawAccessible && target) {
       rawAccessible = this.getRawAccessibleFor(target);
       target = target.parentNode;
     }
+    // If raw accessible object is defunct or detached, no need to cache it and
+    // its ancestry.
+    if (!rawAccessible || isDefunct(rawAccessible) || rawAccessible.indexInParent < 0) {
+      return null;
+    }
 
     const doc = await this.getDocument();
-    return this.attachAccessible(rawAccessible, doc);
+    const accessible = this.addRef(rawAccessible);
+    // There is a chance that ancestry lookup can fail if the accessible is in
+    // the detached subtree. At that point the root accessible object would be
+    // defunct and accessing it via parent property will throw.
+    try {
+      let parent = accessible;
+      while (parent && parent != doc) {
+        parent = parent.parentAcc;
+      }
+    } catch (error) {
+      throw new Error(`Failed to get ancestor for ${accessible}: ${error}`);
+    }
+
+    return accessible;
   },
 
   /**
    * Start picker content listeners.
    */
   _startPickerListeners: function() {
     const target = this.targetActor.chromeEventHandler;
     target.addEventListener("mousemove", this.onHovered, true);
--- a/devtools/server/tests/browser/browser_accessibility_node.js
+++ b/devtools/server/tests/browser/browser_accessibility_node.js
@@ -43,31 +43,13 @@ add_task(async function() {
   info("Children");
   const children = await accessibleFront.children();
   is(children.length, 1, "Accessible Front has correct number of children");
   checkA11yFront(children[0], {
     name: "Accessible Button",
     role: "text leaf"
   });
 
-  info("Relations");
-  const labelNode = await walker.querySelector(walker.rootNode, "#label");
-  const controlNode = await walker.querySelector(walker.rootNode, "#control");
-  const labelAccessibleFront = await a11yWalker.getAccessibleFor(labelNode);
-  const controlAccessibleFront = await a11yWalker.getAccessibleFor(controlNode);
-  const docAccessibleFront = await a11yWalker.getAccessibleFor(walker.rootNode);
-  const relations = await labelAccessibleFront.getRelations();
-  is(relations.length, 2, "Accessible front has a correct number of relations");
-  is(relations[0].type, "label for", "Label has a label for relation");
-  is(relations[0].targets.length, 1, "Label is a label for one target");
-  is(relations[0].targets[0], controlAccessibleFront,
-     "Label is a label for control accessible front");
-  is(relations[1].type, "containing document",
-     "Label has a containing document relation");
-  is(relations[1].targets.length, 1, "Label is contained by just one document");
-  is(relations[1].targets[0], docAccessibleFront,
-     "Label's containing document is a root document");
-
   await accessibility.disable();
   await waitForA11yShutdown();
   await target.destroy();
   gBrowser.removeCurrentTab();
 });
--- a/devtools/server/tests/browser/doc_accessibility.html
+++ b/devtools/server/tests/browser/doc_accessibility.html
@@ -3,13 +3,10 @@
   <head>
     <meta charset="utf-8">
   </head>
 <body>
   <h1 id="h1">Accessibility Test</h1>
   <button id="button" aria-describedby="h1" accesskey="b">Accessible Button</button>
   <div id="slider" role="slider" aria-valuenow="5"
        aria-valuemin="0" aria-valuemax="7">slider</div>
-  <label id="label" for="control">Label
-    <input id="control">
-  </label>
 </body>
 </html>
--- a/devtools/shared/specs/accessibility.js
+++ b/devtools/shared/specs/accessibility.js
@@ -15,26 +15,16 @@ types.addActorType("accessible");
  */
 types.addDictType("accessibleWithChildren", {
   // Accessible
   accessible: "accessible",
   // Accessible's children
   children: "array:accessible"
 });
 
-/**
- * Accessible relation object described by its type that also includes relation targets.
- */
-types.addDictType("accessibleRelation", {
-  // Accessible relation type
-  type: "string",
-  // Accessible relation's targets
-  targets: "array:accessible"
-});
-
 const accessibleSpec = generateActorSpec({
   typeName: "accessible",
 
   events: {
     "actions-change": {
       type: "actionsChange",
       actions: Arg(0, "array:string")
     },
@@ -80,22 +70,16 @@ const accessibleSpec = generateActorSpec
   },
 
   methods: {
     children: {
       request: {},
       response: {
         children: RetVal("array:accessible")
       }
-    },
-    getRelations: {
-      request: {},
-      response: {
-        relations: RetVal("array:accessibleRelation")
-      }
     }
   }
 });
 
 const accessibleWalkerSpec = generateActorSpec({
   typeName: "accessiblewalker",
 
   events: {