// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/shell/test_runner/web_ax_object_proxy.h"

#include <stddef.h>

#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "gin/handle.h"
#include "third_party/blink/public/platform/web_float_rect.h"
#include "third_party/blink/public/platform/web_point.h"
#include "third_party/blink/public/platform/web_rect.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/web/blink.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/skia/include/core/SkMatrix44.h"
#include "ui/accessibility/ax_enums.mojom-shared.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/transform.h"

namespace test_runner {

namespace {

// Map role value to string, matching Safari/Mac platform implementation to
// avoid rebaselining web tests.
std::string RoleToString(ax::mojom::Role role) {
  std::string result = "AXRole: AX";
  switch (role) {
    case ax::mojom::Role::kAbbr:
      return result.append("Abbr");
    case ax::mojom::Role::kAlertDialog:
      return result.append("AlertDialog");
    case ax::mojom::Role::kAlert:
      return result.append("Alert");
    case ax::mojom::Role::kAnchor:
      return result.append("Anchor");
    case ax::mojom::Role::kAnnotationAttribution:
      return result.append("AnnotationAttribution");
    case ax::mojom::Role::kAnnotationCommentary:
      return result.append("AnnotationCommentary");
    case ax::mojom::Role::kAnnotationPresence:
      return result.append("AnnotationPresence");
    case ax::mojom::Role::kAnnotationRevision:
      return result.append("AnnotationRevision");
    case ax::mojom::Role::kAnnotationSuggestion:
      return result.append("AnnotationSuggestion");
    case ax::mojom::Role::kApplication:
      return result.append("Application");
    case ax::mojom::Role::kArticle:
      return result.append("Article");
    case ax::mojom::Role::kAudio:
      return result.append("Audio");
    case ax::mojom::Role::kBanner:
      return result.append("Banner");
    case ax::mojom::Role::kBlockquote:
      return result.append("Blockquote");
    case ax::mojom::Role::kButton:
      return result.append("Button");
    case ax::mojom::Role::kCanvas:
      return result.append("Canvas");
    case ax::mojom::Role::kCaption:
      return result.append("Caption");
    case ax::mojom::Role::kCell:
      return result.append("Cell");
    case ax::mojom::Role::kCode:
      return result.append("Code");
    case ax::mojom::Role::kCheckBox:
      return result.append("CheckBox");
    case ax::mojom::Role::kColorWell:
      return result.append("ColorWell");
    case ax::mojom::Role::kColumnHeader:
      return result.append("ColumnHeader");
    case ax::mojom::Role::kColumn:
      return result.append("Column");
    case ax::mojom::Role::kComboBoxGrouping:
      return result.append("ComboBoxGrouping");
    case ax::mojom::Role::kComboBoxMenuButton:
      return result.append("ComboBoxMenuButton");
    case ax::mojom::Role::kComplementary:
      return result.append("Complementary");
    case ax::mojom::Role::kContentDeletion:
      return result.append("ContentDeletion");
    case ax::mojom::Role::kContentInsertion:
      return result.append("ContentInsertion");
    case ax::mojom::Role::kContentInfo:
      return result.append("ContentInfo");
    case ax::mojom::Role::kDate:
      return result.append("DateField");
    case ax::mojom::Role::kDateTime:
      return result.append("DateTimeField");
    case ax::mojom::Role::kDefinition:
      return result.append("Definition");
    case ax::mojom::Role::kDescriptionListDetail:
      return result.append("DescriptionListDetail");
    case ax::mojom::Role::kDescriptionList:
      return result.append("DescriptionList");
    case ax::mojom::Role::kDescriptionListTerm:
      return result.append("DescriptionListTerm");
    case ax::mojom::Role::kDetails:
      return result.append("Details");
    case ax::mojom::Role::kDialog:
      return result.append("Dialog");
    case ax::mojom::Role::kDirectory:
      return result.append("Directory");
    case ax::mojom::Role::kDisclosureTriangle:
      return result.append("DisclosureTriangle");
    case ax::mojom::Role::kDocAbstract:
      return result.append("DocAbstract");
    case ax::mojom::Role::kDocAcknowledgments:
      return result.append("DocAcknowledgments");
    case ax::mojom::Role::kDocAfterword:
      return result.append("DocAfterword");
    case ax::mojom::Role::kDocAppendix:
      return result.append("DocAppendix");
    case ax::mojom::Role::kDocBackLink:
      return result.append("DocBackLink");
    case ax::mojom::Role::kDocBiblioEntry:
      return result.append("DocBiblioEntry");
    case ax::mojom::Role::kDocBibliography:
      return result.append("DocBibliography");
    case ax::mojom::Role::kDocBiblioRef:
      return result.append("DocBiblioRef");
    case ax::mojom::Role::kDocChapter:
      return result.append("DocChapter");
    case ax::mojom::Role::kDocColophon:
      return result.append("DocColophon");
    case ax::mojom::Role::kDocConclusion:
      return result.append("DocConclusion");
    case ax::mojom::Role::kDocCover:
      return result.append("DocCover");
    case ax::mojom::Role::kDocCredit:
      return result.append("DocCredit");
    case ax::mojom::Role::kDocCredits:
      return result.append("DocCredits");
    case ax::mojom::Role::kDocDedication:
      return result.append("DocDedication");
    case ax::mojom::Role::kDocEndnote:
      return result.append("DocEndnote");
    case ax::mojom::Role::kDocEndnotes:
      return result.append("DocEndnotes");
    case ax::mojom::Role::kDocEpigraph:
      return result.append("DocEpigraph");
    case ax::mojom::Role::kDocEpilogue:
      return result.append("DocEpilogue");
    case ax::mojom::Role::kDocErrata:
      return result.append("DocErrata");
    case ax::mojom::Role::kDocExample:
      return result.append("DocExample");
    case ax::mojom::Role::kDocFootnote:
      return result.append("DocFootnote");
    case ax::mojom::Role::kDocForeword:
      return result.append("DocForeword");
    case ax::mojom::Role::kDocGlossary:
      return result.append("DocGlossary");
    case ax::mojom::Role::kDocGlossRef:
      return result.append("DocGlossRef");
    case ax::mojom::Role::kDocIndex:
      return result.append("DocIndex");
    case ax::mojom::Role::kDocIntroduction:
      return result.append("DocIntroduction");
    case ax::mojom::Role::kDocNoteRef:
      return result.append("DocNoteRef");
    case ax::mojom::Role::kDocNotice:
      return result.append("DocNotice");
    case ax::mojom::Role::kDocPageBreak:
      return result.append("DocPageBreak");
    case ax::mojom::Role::kDocPageList:
      return result.append("DocPageList");
    case ax::mojom::Role::kDocPart:
      return result.append("DocPart");
    case ax::mojom::Role::kDocPreface:
      return result.append("DocPreface");
    case ax::mojom::Role::kDocPrologue:
      return result.append("DocPrologue");
    case ax::mojom::Role::kDocPullquote:
      return result.append("DocPullquote");
    case ax::mojom::Role::kDocQna:
      return result.append("DocQna");
    case ax::mojom::Role::kDocSubtitle:
      return result.append("DocSubtitle");
    case ax::mojom::Role::kDocTip:
      return result.append("DocTip");
    case ax::mojom::Role::kDocToc:
      return result.append("DocToc");
    case ax::mojom::Role::kDocument:
      return result.append("Document");
    case ax::mojom::Role::kEmbeddedObject:
      return result.append("EmbeddedObject");
    case ax::mojom::Role::kEmphasis:
      return result.append("Emphasis");
    case ax::mojom::Role::kFigcaption:
      return result.append("Figcaption");
    case ax::mojom::Role::kFigure:
      return result.append("Figure");
    case ax::mojom::Role::kFooter:
      return result.append("Footer");
    case ax::mojom::Role::kFooterAsNonLandmark:
      return result.append("FooterAsNonLandmark");
    case ax::mojom::Role::kForm:
      return result.append("Form");
    case ax::mojom::Role::kGenericContainer:
      return result.append("GenericContainer");
    case ax::mojom::Role::kGraphicsDocument:
      return result.append("GraphicsDocument");
    case ax::mojom::Role::kGraphicsObject:
      return result.append("GraphicsObject");
    case ax::mojom::Role::kGraphicsSymbol:
      return result.append("GraphicsSymbol");
    case ax::mojom::Role::kGrid:
      return result.append("Grid");
    case ax::mojom::Role::kGroup:
      return result.append("Group");
    case ax::mojom::Role::kHeader:
      return result.append("Header");
    case ax::mojom::Role::kHeaderAsNonLandmark:
      return result.append("HeaderAsNonLandmark");
    case ax::mojom::Role::kHeading:
      return result.append("Heading");
    case ax::mojom::Role::kIgnored:
      return result.append("Ignored");
    case ax::mojom::Role::kImageMap:
      return result.append("ImageMap");
    case ax::mojom::Role::kImage:
      return result.append("Image");
    case ax::mojom::Role::kInlineTextBox:
      return result.append("InlineTextBox");
    case ax::mojom::Role::kInputTime:
      return result.append("InputTime");
    case ax::mojom::Role::kLabelText:
      return result.append("Label");
    case ax::mojom::Role::kLayoutTable:
      return result.append("LayoutTable");
    case ax::mojom::Role::kLayoutTableCell:
      return result.append("LayoutTableCell");
    case ax::mojom::Role::kLayoutTableColumn:
      return result.append("LayoutTableColumn");
    case ax::mojom::Role::kLayoutTableRow:
      return result.append("LayoutTableRow");
    case ax::mojom::Role::kLegend:
      return result.append("Legend");
    case ax::mojom::Role::kLink:
      return result.append("Link");
    case ax::mojom::Role::kLineBreak:
      return result.append("LineBreak");
    case ax::mojom::Role::kListBoxOption:
      return result.append("ListBoxOption");
    case ax::mojom::Role::kListBox:
      return result.append("ListBox");
    case ax::mojom::Role::kListItem:
      return result.append("ListItem");
    case ax::mojom::Role::kListMarker:
      return result.append("ListMarker");
    case ax::mojom::Role::kList:
      return result.append("List");
    case ax::mojom::Role::kLog:
      return result.append("Log");
    case ax::mojom::Role::kMain:
      return result.append("Main");
    case ax::mojom::Role::kMark:
      return result.append("Mark");
    case ax::mojom::Role::kMarquee:
      return result.append("Marquee");
    case ax::mojom::Role::kMath:
      return result.append("Math");
    case ax::mojom::Role::kMenuBar:
      return result.append("MenuBar");
    case ax::mojom::Role::kMenuButton:
      return result.append("MenuButton");
    case ax::mojom::Role::kMenuItem:
      return result.append("MenuItem");
    case ax::mojom::Role::kMenuItemCheckBox:
      return result.append("MenuItemCheckBox");
    case ax::mojom::Role::kMenuItemRadio:
      return result.append("MenuItemRadio");
    case ax::mojom::Role::kMenuListOption:
      return result.append("MenuListOption");
    case ax::mojom::Role::kMenuListPopup:
      return result.append("MenuListPopup");
    case ax::mojom::Role::kMenu:
      return result.append("Menu");
    case ax::mojom::Role::kMeter:
      return result.append("Meter");
    case ax::mojom::Role::kNavigation:
      return result.append("Navigation");
    case ax::mojom::Role::kNone:
      return result.append("None");
    case ax::mojom::Role::kNote:
      return result.append("Note");
    case ax::mojom::Role::kParagraph:
      return result.append("Paragraph");
    case ax::mojom::Role::kPopUpButton:
      return result.append("PopUpButton");
    case ax::mojom::Role::kPre:
      return result.append("Pre");
    case ax::mojom::Role::kPresentational:
      return result.append("Presentational");
    case ax::mojom::Role::kProgressIndicator:
      return result.append("ProgressIndicator");
    case ax::mojom::Role::kRadioButton:
      return result.append("RadioButton");
    case ax::mojom::Role::kRadioGroup:
      return result.append("RadioGroup");
    case ax::mojom::Role::kRegion:
      return result.append("Region");
    case ax::mojom::Role::kRowHeader:
      return result.append("RowHeader");
    case ax::mojom::Role::kRow:
      return result.append("Row");
    case ax::mojom::Role::kRuby:
      return result.append("Ruby");
    case ax::mojom::Role::kRubyAnnotation:
      return result.append("RubyAnnotation");
    case ax::mojom::Role::kSection:
      return result.append("Section");
    case ax::mojom::Role::kSvgRoot:
      return result.append("SVGRoot");
    case ax::mojom::Role::kScrollBar:
      return result.append("ScrollBar");
    case ax::mojom::Role::kSearch:
      return result.append("Search");
    case ax::mojom::Role::kSearchBox:
      return result.append("SearchBox");
    case ax::mojom::Role::kSlider:
      return result.append("Slider");
    case ax::mojom::Role::kSliderThumb:
      return result.append("SliderThumb");
    case ax::mojom::Role::kSpinButton:
      return result.append("SpinButton");
    case ax::mojom::Role::kSplitter:
      return result.append("Splitter");
    case ax::mojom::Role::kStaticText:
      return result.append("StaticText");
    case ax::mojom::Role::kStatus:
      return result.append("Status");
    case ax::mojom::Role::kStrong:
      return result.append("Strong");
      ;
    case ax::mojom::Role::kSwitch:
      return result.append("Switch");
    case ax::mojom::Role::kTabList:
      return result.append("TabList");
    case ax::mojom::Role::kTabPanel:
      return result.append("TabPanel");
    case ax::mojom::Role::kTab:
      return result.append("Tab");
    case ax::mojom::Role::kTableHeaderContainer:
      return result.append("TableHeaderContainer");
    case ax::mojom::Role::kTable:
      return result.append("Table");
    case ax::mojom::Role::kTextField:
      return result.append("TextField");
    case ax::mojom::Role::kTextFieldWithComboBox:
      return result.append("TextFieldWithComboBox");
    case ax::mojom::Role::kTime:
      return result.append("Time");
    case ax::mojom::Role::kTimer:
      return result.append("Timer");
    case ax::mojom::Role::kToggleButton:
      return result.append("ToggleButton");
    case ax::mojom::Role::kToolbar:
      return result.append("Toolbar");
    case ax::mojom::Role::kTreeGrid:
      return result.append("TreeGrid");
    case ax::mojom::Role::kTreeItem:
      return result.append("TreeItem");
    case ax::mojom::Role::kTree:
      return result.append("Tree");
    case ax::mojom::Role::kUnknown:
      return result.append("Unknown");
    case ax::mojom::Role::kTooltip:
      return result.append("UserInterfaceTooltip");
    case ax::mojom::Role::kVideo:
      return result.append("Video");
    case ax::mojom::Role::kRootWebArea:
      return result.append("WebArea");
    default:
      return result.append("Unknown");
  }
}

std::string GetStringValue(const blink::WebAXObject& object) {
  std::string value;
  if (object.Role() == ax::mojom::Role::kColorWell) {
    unsigned int color = object.ColorValue();
    unsigned int red = (color >> 16) & 0xFF;
    unsigned int green = (color >> 8) & 0xFF;
    unsigned int blue = color & 0xFF;
    value = base::StringPrintf("rgba(%d, %d, %d, 1)", red, green, blue);
  } else {
    value = object.StringValue().Utf8();
  }
  return value.insert(0, "AXValue: ");
}

std::string GetRole(const blink::WebAXObject& object) {
  std::string role_string = RoleToString(object.Role());

  // Special-case canvas with fallback content because Chromium wants to treat
  // this as essentially a separate role that it can map differently depending
  // on the platform.
  if (object.Role() == ax::mojom::Role::kCanvas &&
      object.CanvasHasFallbackContent()) {
    role_string += "WithFallbackContent";
  }

  return role_string;
}

std::string GetValueDescription(const blink::WebAXObject& object) {
  std::string value_description = object.ValueDescription().Utf8();
  return value_description.insert(0, "AXValueDescription: ");
}

std::string GetLanguage(const blink::WebAXObject& object) {
  std::string language = object.Language().Utf8();
  return language.insert(0, "AXLanguage: ");
}

std::string GetAttributes(const blink::WebAXObject& object) {
  std::string attributes(object.GetName().Utf8());
  attributes.append("\n");
  attributes.append(GetRole(object));
  return attributes;
}

// New bounds calculation algorithm.  Retrieves the frame-relative bounds
// of an object by calling getRelativeBounds and then applying the offsets
// and transforms recursively on each container of this object.
blink::WebFloatRect BoundsForObject(const blink::WebAXObject& object) {
  blink::WebAXObject container;
  blink::WebFloatRect bounds;
  SkMatrix44 matrix;
  object.GetRelativeBounds(container, bounds, matrix);
  gfx::RectF computedBounds(0, 0, bounds.width, bounds.height);
  while (!container.IsDetached()) {
    computedBounds.Offset(bounds.x, bounds.y);
    computedBounds.Offset(-container.GetScrollOffset().x,
                          -container.GetScrollOffset().y);
    if (!matrix.isIdentity()) {
      gfx::Transform transform(matrix);
      transform.TransformRect(&computedBounds);
    }
    container.GetRelativeBounds(container, bounds, matrix);
  }
  return blink::WebFloatRect(computedBounds.x(), computedBounds.y(),
                             computedBounds.width(), computedBounds.height());
}

blink::WebRect BoundsForCharacter(const blink::WebAXObject& object,
                                  int characterIndex) {
  DCHECK_EQ(object.Role(), ax::mojom::Role::kStaticText);
  int end = 0;
  for (unsigned i = 0; i < object.ChildCount(); i++) {
    blink::WebAXObject inline_text_box = object.ChildAt(i);
    DCHECK_EQ(inline_text_box.Role(), ax::mojom::Role::kInlineTextBox);
    int start = end;
    blink::WebString name = inline_text_box.GetName();
    end += name.length();
    if (characterIndex < start || characterIndex >= end)
      continue;

    blink::WebFloatRect inline_text_box_rect = BoundsForObject(inline_text_box);

    int localIndex = characterIndex - start;
    blink::WebVector<int> character_offsets;
    inline_text_box.CharacterOffsets(character_offsets);
    if (character_offsets.size() != name.length())
      return blink::WebRect();

    switch (inline_text_box.GetTextDirection()) {
      case ax::mojom::TextDirection::kLtr: {
        if (localIndex) {
          int left = inline_text_box_rect.x + character_offsets[localIndex - 1];
          int width =
              character_offsets[localIndex] - character_offsets[localIndex - 1];
          return blink::WebRect(left, inline_text_box_rect.y, width,
                                inline_text_box_rect.height);
        }
        return blink::WebRect(inline_text_box_rect.x, inline_text_box_rect.y,
                              character_offsets[0],
                              inline_text_box_rect.height);
      }
      case ax::mojom::TextDirection::kRtl: {
        int right = inline_text_box_rect.x + inline_text_box_rect.width;

        if (localIndex) {
          int left = right - character_offsets[localIndex];
          int width =
              character_offsets[localIndex] - character_offsets[localIndex - 1];
          return blink::WebRect(left, inline_text_box_rect.y, width,
                                inline_text_box_rect.height);
        }
        int left = right - character_offsets[0];
        return blink::WebRect(left, inline_text_box_rect.y,
                              character_offsets[0],
                              inline_text_box_rect.height);
      }
      case ax::mojom::TextDirection::kTtb: {
        if (localIndex) {
          int top = inline_text_box_rect.y + character_offsets[localIndex - 1];
          int height =
              character_offsets[localIndex] - character_offsets[localIndex - 1];
          return blink::WebRect(inline_text_box_rect.x, top,
                                inline_text_box_rect.width, height);
        }
        return blink::WebRect(inline_text_box_rect.x, inline_text_box_rect.y,
                              inline_text_box_rect.width, character_offsets[0]);
      }
      case ax::mojom::TextDirection::kBtt: {
        int bottom = inline_text_box_rect.y + inline_text_box_rect.height;

        if (localIndex) {
          int top = bottom - character_offsets[localIndex];
          int height =
              character_offsets[localIndex] - character_offsets[localIndex - 1];
          return blink::WebRect(inline_text_box_rect.x, top,
                                inline_text_box_rect.width, height);
        }
        int top = bottom - character_offsets[0];
        return blink::WebRect(inline_text_box_rect.x, top,
                              inline_text_box_rect.width, character_offsets[0]);
      }
      default:
        NOTREACHED();
        return blink::WebRect();
    }
  }

  DCHECK(false);
  return blink::WebRect();
}

std::vector<std::string> GetMisspellings(blink::WebAXObject& object) {
  std::vector<std::string> misspellings;
  std::string text(object.GetName().Utf8());

  blink::WebVector<ax::mojom::MarkerType> marker_types;
  blink::WebVector<int> marker_starts;
  blink::WebVector<int> marker_ends;
  object.Markers(marker_types, marker_starts, marker_ends);
  DCHECK_EQ(marker_types.size(), marker_starts.size());
  DCHECK_EQ(marker_starts.size(), marker_ends.size());

  for (size_t i = 0; i < marker_types.size(); ++i) {
    if (marker_types[i] == ax::mojom::MarkerType::kSpelling) {
      misspellings.push_back(
          text.substr(marker_starts[i], marker_ends[i] - marker_starts[i]));
    }
  }

  return misspellings;
}

void GetBoundariesForOneWord(const blink::WebAXObject& object,
                             int character_index,
                             int& word_start,
                             int& word_end) {
  int end = 0;
  for (size_t i = 0; i < object.ChildCount(); i++) {
    blink::WebAXObject inline_text_box = object.ChildAt(i);
    DCHECK_EQ(inline_text_box.Role(), ax::mojom::Role::kInlineTextBox);
    int start = end;
    blink::WebString name = inline_text_box.GetName();
    end += name.length();
    if (end <= character_index)
      continue;
    int localIndex = character_index - start;

    blink::WebVector<int> starts;
    blink::WebVector<int> ends;
    inline_text_box.GetWordBoundaries(starts, ends);
    size_t word_count = starts.size();
    DCHECK_EQ(ends.size(), word_count);

    // If there are no words, use the InlineTextBox boundaries.
    if (!word_count) {
      word_start = start;
      word_end = end;
      return;
    }

    // Look for a character within any word other than the last.
    for (size_t j = 0; j < word_count - 1; j++) {
      if (localIndex <= ends[j]) {
        word_start = start + starts[j];
        word_end = start + ends[j];
        return;
      }
    }

    // Return the last word by default.
    word_start = start + starts[word_count - 1];
    word_end = start + ends[word_count - 1];
    return;
  }
}

// Collects attributes into a string, delimited by dashes. Used by all methods
// that output lists of attributes: attributesOfLinkedUIElementsCallback,
// AttributesOfChildrenCallback, etc.
class AttributesCollector {
 public:
  AttributesCollector() {}
  ~AttributesCollector() {}

  void CollectAttributes(const blink::WebAXObject& object) {
    attributes_.append("\n------------\n");
    attributes_.append(GetAttributes(object));
  }

  std::string attributes() const { return attributes_; }

 private:
  std::string attributes_;

  DISALLOW_COPY_AND_ASSIGN(AttributesCollector);
};

class SparseAttributeAdapter : public blink::WebAXSparseAttributeClient {
 public:
  SparseAttributeAdapter() {}
  ~SparseAttributeAdapter() override {}

  std::map<blink::WebAXBoolAttribute, bool> bool_attributes;
  std::map<blink::WebAXIntAttribute, int32_t> int_attributes;
  std::map<blink::WebAXUIntAttribute, int32_t> uint_attributes;
  std::map<blink::WebAXStringAttribute, blink::WebString> string_attributes;
  std::map<blink::WebAXObjectAttribute, blink::WebAXObject> object_attributes;
  std::map<blink::WebAXObjectVectorAttribute,
           blink::WebVector<blink::WebAXObject>>
      object_vector_attributes;

 private:
  void AddBoolAttribute(blink::WebAXBoolAttribute attribute,
                        bool value) override {
    bool_attributes[attribute] = value;
  }

  void AddIntAttribute(blink::WebAXIntAttribute attribute,
                       int32_t value) override {
    int_attributes[attribute] = value;
  }

  void AddUIntAttribute(blink::WebAXUIntAttribute attribute,
                        uint32_t value) override {
    uint_attributes[attribute] = value;
  }

  void AddStringAttribute(blink::WebAXStringAttribute attribute,
                          const blink::WebString& value) override {
    string_attributes[attribute] = value;
  }

  void AddObjectAttribute(blink::WebAXObjectAttribute attribute,
                          const blink::WebAXObject& value) override {
    object_attributes[attribute] = value;
  }

  void AddObjectVectorAttribute(
      blink::WebAXObjectVectorAttribute attribute,
      const blink::WebVector<blink::WebAXObject>& value) override {
    object_vector_attributes[attribute] = value;
  }
};

}  // namespace

gin::WrapperInfo WebAXObjectProxy::kWrapperInfo = {gin::kEmbedderNativeGin};

WebAXObjectProxy::WebAXObjectProxy(const blink::WebAXObject& object,
                                   WebAXObjectProxy::Factory* factory)
    : accessibility_object_(object), factory_(factory) {}

WebAXObjectProxy::~WebAXObjectProxy() {}

gin::ObjectTemplateBuilder WebAXObjectProxy::GetObjectTemplateBuilder(
    v8::Isolate* isolate) {
  return gin::Wrappable<WebAXObjectProxy>::GetObjectTemplateBuilder(isolate)
      .SetProperty("role", &WebAXObjectProxy::Role)
      .SetProperty("stringValue", &WebAXObjectProxy::StringValue)
      .SetProperty("language", &WebAXObjectProxy::Language)
      .SetProperty("x", &WebAXObjectProxy::X)
      .SetProperty("y", &WebAXObjectProxy::Y)
      .SetProperty("width", &WebAXObjectProxy::Width)
      .SetProperty("height", &WebAXObjectProxy::Height)
      .SetProperty("inPageLinkTarget", &WebAXObjectProxy::InPageLinkTarget)
      .SetProperty("intValue", &WebAXObjectProxy::IntValue)
      .SetProperty("minValue", &WebAXObjectProxy::MinValue)
      .SetProperty("maxValue", &WebAXObjectProxy::MaxValue)
      .SetProperty("stepValue", &WebAXObjectProxy::StepValue)
      .SetProperty("valueDescription", &WebAXObjectProxy::ValueDescription)
      .SetProperty("childrenCount", &WebAXObjectProxy::ChildrenCount)
      .SetProperty("selectionIsBackward",
                   &WebAXObjectProxy::SelectionIsBackward)
      .SetProperty("selectionAnchorObject",
                   &WebAXObjectProxy::SelectionAnchorObject)
      .SetProperty("selectionAnchorOffset",
                   &WebAXObjectProxy::SelectionAnchorOffset)
      .SetProperty("selectionAnchorAffinity",
                   &WebAXObjectProxy::SelectionAnchorAffinity)
      .SetProperty("selectionFocusObject",
                   &WebAXObjectProxy::SelectionFocusObject)
      .SetProperty("selectionFocusOffset",
                   &WebAXObjectProxy::SelectionFocusOffset)
      .SetProperty("selectionFocusAffinity",
                   &WebAXObjectProxy::SelectionFocusAffinity)
      .SetProperty("isAtomic", &WebAXObjectProxy::IsAtomic)
      .SetProperty("isAutofillAvailable",
                   &WebAXObjectProxy::IsAutofillAvailable)
      .SetProperty("isBusy", &WebAXObjectProxy::IsBusy)
      .SetProperty("isRequired", &WebAXObjectProxy::IsRequired)
      .SetProperty("isEditable", &WebAXObjectProxy::IsEditable)
      .SetProperty("isEditableRoot", &WebAXObjectProxy::IsEditableRoot)
      .SetProperty("isRichlyEditable", &WebAXObjectProxy::IsRichlyEditable)
      .SetProperty("isFocused", &WebAXObjectProxy::IsFocused)
      .SetProperty("isFocusable", &WebAXObjectProxy::IsFocusable)
      .SetProperty("isModal", &WebAXObjectProxy::IsModal)
      .SetProperty("isSelected", &WebAXObjectProxy::IsSelected)
      .SetProperty("isSelectable", &WebAXObjectProxy::IsSelectable)
      .SetProperty("isMultiLine", &WebAXObjectProxy::IsMultiLine)
      .SetProperty("isMultiSelectable", &WebAXObjectProxy::IsMultiSelectable)
      .SetProperty("isSelectedOptionActive",
                   &WebAXObjectProxy::IsSelectedOptionActive)
      .SetProperty("isExpanded", &WebAXObjectProxy::IsExpanded)
      .SetProperty("checked", &WebAXObjectProxy::Checked)
      .SetProperty("isVisible", &WebAXObjectProxy::IsVisible)
      .SetProperty("isVisited", &WebAXObjectProxy::IsVisited)
      .SetProperty("isOffScreen", &WebAXObjectProxy::IsOffScreen)
      .SetProperty("isCollapsed", &WebAXObjectProxy::IsCollapsed)
      .SetProperty("hasPopup", &WebAXObjectProxy::HasPopup)
      .SetProperty("isValid", &WebAXObjectProxy::IsValid)
      .SetProperty("isReadOnly", &WebAXObjectProxy::IsReadOnly)
      .SetProperty("isIgnored", &WebAXObjectProxy::IsIgnored)
      .SetProperty("restriction", &WebAXObjectProxy::Restriction)
      .SetProperty("activeDescendant", &WebAXObjectProxy::ActiveDescendant)
      .SetProperty("backgroundColor", &WebAXObjectProxy::BackgroundColor)
      .SetProperty("color", &WebAXObjectProxy::Color)
      .SetProperty("colorValue", &WebAXObjectProxy::ColorValue)
      .SetProperty("fontFamily", &WebAXObjectProxy::FontFamily)
      .SetProperty("fontSize", &WebAXObjectProxy::FontSize)
      .SetProperty("autocomplete", &WebAXObjectProxy::Autocomplete)
      .SetProperty("current", &WebAXObjectProxy::Current)
      .SetProperty("invalid", &WebAXObjectProxy::Invalid)
      .SetProperty("keyShortcuts", &WebAXObjectProxy::KeyShortcuts)
      .SetProperty("ariaColumnCount", &WebAXObjectProxy::AriaColumnCount)
      .SetProperty("ariaColumnIndex", &WebAXObjectProxy::AriaColumnIndex)
      .SetProperty("ariaColumnSpan", &WebAXObjectProxy::AriaColumnSpan)
      .SetProperty("ariaRowCount", &WebAXObjectProxy::AriaRowCount)
      .SetProperty("ariaRowIndex", &WebAXObjectProxy::AriaRowIndex)
      .SetProperty("ariaRowSpan", &WebAXObjectProxy::AriaRowSpan)
      .SetProperty("live", &WebAXObjectProxy::Live)
      .SetProperty("orientation", &WebAXObjectProxy::Orientation)
      .SetProperty("relevant", &WebAXObjectProxy::Relevant)
      .SetProperty("roleDescription", &WebAXObjectProxy::RoleDescription)
      .SetProperty("sort", &WebAXObjectProxy::Sort)
      .SetProperty("url", &WebAXObjectProxy::Url)
      .SetProperty("hierarchicalLevel", &WebAXObjectProxy::HierarchicalLevel)
      .SetProperty("posInSet", &WebAXObjectProxy::PosInSet)
      .SetProperty("setSize", &WebAXObjectProxy::SetSize)
      .SetProperty("clickPointX", &WebAXObjectProxy::ClickPointX)
      .SetProperty("clickPointY", &WebAXObjectProxy::ClickPointY)
      .SetProperty("rowCount", &WebAXObjectProxy::RowCount)
      .SetProperty("rowHeadersCount", &WebAXObjectProxy::RowHeadersCount)
      .SetProperty("columnCount", &WebAXObjectProxy::ColumnCount)
      .SetProperty("columnHeadersCount", &WebAXObjectProxy::ColumnHeadersCount)
      .SetProperty("isClickable", &WebAXObjectProxy::IsClickable)
      //
      // NEW bounding rect calculation - high-level interface
      //
      .SetProperty("boundsX", &WebAXObjectProxy::BoundsX)
      .SetProperty("boundsY", &WebAXObjectProxy::BoundsY)
      .SetProperty("boundsWidth", &WebAXObjectProxy::BoundsWidth)
      .SetProperty("boundsHeight", &WebAXObjectProxy::BoundsHeight)
      .SetMethod("allAttributes", &WebAXObjectProxy::AllAttributes)
      .SetMethod("attributesOfChildren",
                 &WebAXObjectProxy::AttributesOfChildren)
      .SetMethod("ariaActiveDescendantElement",
                 &WebAXObjectProxy::AriaActiveDescendantElement)
      .SetMethod("ariaControlsElementAtIndex",
                 &WebAXObjectProxy::AriaControlsElementAtIndex)
      .SetMethod("ariaDetailsElement", &WebAXObjectProxy::AriaDetailsElement)
      .SetMethod("ariaErrorMessageElement",
                 &WebAXObjectProxy::AriaErrorMessageElement)
      .SetMethod("ariaFlowToElementAtIndex",
                 &WebAXObjectProxy::AriaFlowToElementAtIndex)
      .SetMethod("ariaOwnsElementAtIndex",
                 &WebAXObjectProxy::AriaOwnsElementAtIndex)
      .SetMethod("boundsForRange", &WebAXObjectProxy::BoundsForRange)
      .SetMethod("childAtIndex", &WebAXObjectProxy::ChildAtIndex)
      .SetMethod("elementAtPoint", &WebAXObjectProxy::ElementAtPoint)
      .SetMethod("rowHeaderAtIndex", &WebAXObjectProxy::RowHeaderAtIndex)
      .SetMethod("columnHeaderAtIndex", &WebAXObjectProxy::ColumnHeaderAtIndex)
      .SetMethod("rowIndexRange", &WebAXObjectProxy::RowIndexRange)
      .SetMethod("columnIndexRange", &WebAXObjectProxy::ColumnIndexRange)
      .SetMethod("cellForColumnAndRow", &WebAXObjectProxy::CellForColumnAndRow)
      .SetMethod("setSelectedTextRange",
                 &WebAXObjectProxy::SetSelectedTextRange)
      .SetMethod("setSelection", &WebAXObjectProxy::SetSelection)
      .SetMethod("isAttributeSettable", &WebAXObjectProxy::IsAttributeSettable)
      .SetMethod("isPressActionSupported",
                 &WebAXObjectProxy::IsPressActionSupported)
      .SetMethod("parentElement", &WebAXObjectProxy::ParentElement)
      .SetMethod("increment", &WebAXObjectProxy::Increment)
      .SetMethod("decrement", &WebAXObjectProxy::Decrement)
      .SetMethod("showMenu", &WebAXObjectProxy::ShowMenu)
      .SetMethod("press", &WebAXObjectProxy::Press)
      .SetMethod("setValue", &WebAXObjectProxy::SetValue)
      .SetMethod("isEqual", &WebAXObjectProxy::IsEqual)
      .SetMethod("setNotificationListener",
                 &WebAXObjectProxy::SetNotificationListener)
      .SetMethod("unsetNotificationListener",
                 &WebAXObjectProxy::UnsetNotificationListener)
      .SetMethod("takeFocus", &WebAXObjectProxy::TakeFocus)
      .SetMethod("scrollToMakeVisible", &WebAXObjectProxy::ScrollToMakeVisible)
      .SetMethod("scrollToMakeVisibleWithSubFocus",
                 &WebAXObjectProxy::ScrollToMakeVisibleWithSubFocus)
      .SetMethod("scrollToGlobalPoint", &WebAXObjectProxy::ScrollToGlobalPoint)
      .SetMethod("scrollX", &WebAXObjectProxy::ScrollX)
      .SetMethod("scrollY", &WebAXObjectProxy::ScrollY)
      .SetMethod("toString", &WebAXObjectProxy::ToString)
      .SetMethod("wordStart", &WebAXObjectProxy::WordStart)
      .SetMethod("wordEnd", &WebAXObjectProxy::WordEnd)
      .SetMethod("nextOnLine", &WebAXObjectProxy::NextOnLine)
      .SetMethod("previousOnLine", &WebAXObjectProxy::PreviousOnLine)
      .SetMethod("misspellingAtIndex", &WebAXObjectProxy::MisspellingAtIndex)
      // TODO(hajimehoshi): This is for backward compatibility. Remove them.
      .SetMethod("addNotificationListener",
                 &WebAXObjectProxy::SetNotificationListener)
      .SetMethod("removeNotificationListener",
                 &WebAXObjectProxy::UnsetNotificationListener)
      //
      // NEW accessible name and description accessors
      //
      .SetProperty("name", &WebAXObjectProxy::Name)
      .SetProperty("nameFrom", &WebAXObjectProxy::NameFrom)
      .SetMethod("nameElementCount", &WebAXObjectProxy::NameElementCount)
      .SetMethod("nameElementAtIndex", &WebAXObjectProxy::NameElementAtIndex)
      .SetProperty("description", &WebAXObjectProxy::Description)
      .SetProperty("descriptionFrom", &WebAXObjectProxy::DescriptionFrom)
      .SetProperty("placeholder", &WebAXObjectProxy::Placeholder)
      .SetProperty("misspellingsCount", &WebAXObjectProxy::MisspellingsCount)
      .SetMethod("descriptionElementCount",
                 &WebAXObjectProxy::DescriptionElementCount)
      .SetMethod("descriptionElementAtIndex",
                 &WebAXObjectProxy::DescriptionElementAtIndex)
      //
      // NEW bounding rect calculation - low-level interface
      //
      .SetMethod("offsetContainer", &WebAXObjectProxy::OffsetContainer)
      .SetMethod("boundsInContainerX", &WebAXObjectProxy::BoundsInContainerX)
      .SetMethod("boundsInContainerY", &WebAXObjectProxy::BoundsInContainerY)
      .SetMethod("boundsInContainerWidth",
                 &WebAXObjectProxy::BoundsInContainerWidth)
      .SetMethod("boundsInContainerHeight",
                 &WebAXObjectProxy::BoundsInContainerHeight)
      .SetMethod("hasNonIdentityTransform",
                 &WebAXObjectProxy::HasNonIdentityTransform);
}

v8::Local<v8::Object> WebAXObjectProxy::GetChildAtIndex(unsigned index) {
  return factory_->GetOrCreate(accessibility_object_.ChildAt(index));
}

bool WebAXObjectProxy::IsRoot() const {
  return false;
}

bool WebAXObjectProxy::IsEqualToObject(const blink::WebAXObject& other) {
  return accessibility_object_.Equals(other);
}

void WebAXObjectProxy::NotificationReceived(
    blink::WebLocalFrame* frame,
    const std::string& notification_name) {
  if (notification_callback_.IsEmpty())
    return;

  v8::Local<v8::Context> context = frame->MainWorldScriptContext();
  if (context.IsEmpty())
    return;

  v8::Isolate* isolate = blink::MainThreadIsolate();

  v8::Local<v8::Value> argv[] = {
      v8::String::NewFromUtf8(isolate, notification_name.data(),
                              v8::NewStringType::kNormal,
                              notification_name.size())
          .ToLocalChecked(),
  };
  // TODO(aboxhall): Can we force this to run in a new task, to avoid
  // dirtying layout during post-layout hooks?
  frame->CallFunctionEvenIfScriptDisabled(
      v8::Local<v8::Function>::New(isolate, notification_callback_),
      context->Global(), base::size(argv), argv);
}

void WebAXObjectProxy::Reset() {
  notification_callback_.Reset();
}

std::string WebAXObjectProxy::Role() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return GetRole(accessibility_object_);
}

std::string WebAXObjectProxy::StringValue() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return GetStringValue(accessibility_object_);
}

std::string WebAXObjectProxy::Language() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return GetLanguage(accessibility_object_);
}

int WebAXObjectProxy::X() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return BoundsForObject(accessibility_object_).x;
}

int WebAXObjectProxy::Y() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return BoundsForObject(accessibility_object_).y;
}

int WebAXObjectProxy::Width() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return BoundsForObject(accessibility_object_).width;
}

int WebAXObjectProxy::Height() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return BoundsForObject(accessibility_object_).height;
}

v8::Local<v8::Value> WebAXObjectProxy::InPageLinkTarget() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  blink::WebAXObject target = accessibility_object_.InPageLinkTarget();
  if (target.IsNull())
    return v8::Null(blink::MainThreadIsolate());
  return factory_->GetOrCreate(target);
}

int WebAXObjectProxy::IntValue() {
  accessibility_object_.UpdateLayoutAndCheckValidity();

  if (accessibility_object_.SupportsRangeValue()) {
    float value = 0.0f;
    accessibility_object_.ValueForRange(&value);
    return static_cast<int>(value);
  } else if (accessibility_object_.Role() == ax::mojom::Role::kHeading) {
    return accessibility_object_.HeadingLevel();
  } else {
    return atoi(accessibility_object_.StringValue().Utf8().data());
  }
}

int WebAXObjectProxy::MinValue() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  float min_value = 0.0f;
  accessibility_object_.MinValueForRange(&min_value);
  return min_value;
}

int WebAXObjectProxy::MaxValue() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  float max_value = 0.0f;
  accessibility_object_.MaxValueForRange(&max_value);
  return max_value;
}

int WebAXObjectProxy::StepValue() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  float step_value = 0.0f;
  accessibility_object_.StepValueForRange(&step_value);
  return step_value;
}

std::string WebAXObjectProxy::ValueDescription() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return GetValueDescription(accessibility_object_);
}

int WebAXObjectProxy::ChildrenCount() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  int count = 1;  // Root object always has only one child, the WebView.
  if (!IsRoot())
    count = accessibility_object_.ChildCount();
  return count;
}

bool WebAXObjectProxy::SelectionIsBackward() {
  accessibility_object_.UpdateLayoutAndCheckValidity();

  bool is_selection_backward = false;
  blink::WebAXObject anchorObject;
  int anchorOffset = -1;
  ax::mojom::TextAffinity anchorAffinity;
  blink::WebAXObject focusObject;
  int focusOffset = -1;
  ax::mojom::TextAffinity focusAffinity;
  accessibility_object_.Selection(is_selection_backward, anchorObject,
                                  anchorOffset, anchorAffinity, focusObject,
                                  focusOffset, focusAffinity);
  return is_selection_backward;
}

v8::Local<v8::Value> WebAXObjectProxy::SelectionAnchorObject() {
  accessibility_object_.UpdateLayoutAndCheckValidity();

  bool is_selection_backward = false;
  blink::WebAXObject anchorObject;
  int anchorOffset = -1;
  ax::mojom::TextAffinity anchorAffinity;
  blink::WebAXObject focusObject;
  int focusOffset = -1;
  ax::mojom::TextAffinity focusAffinity;
  accessibility_object_.Selection(is_selection_backward, anchorObject,
                                  anchorOffset, anchorAffinity, focusObject,
                                  focusOffset, focusAffinity);
  if (anchorObject.IsNull())
    return v8::Null(blink::MainThreadIsolate());

  return factory_->GetOrCreate(anchorObject);
}

int WebAXObjectProxy::SelectionAnchorOffset() {
  accessibility_object_.UpdateLayoutAndCheckValidity();

  bool is_selection_backward = false;
  blink::WebAXObject anchorObject;
  int anchorOffset = -1;
  ax::mojom::TextAffinity anchorAffinity;
  blink::WebAXObject focusObject;
  int focusOffset = -1;
  ax::mojom::TextAffinity focusAffinity;
  accessibility_object_.Selection(is_selection_backward, anchorObject,
                                  anchorOffset, anchorAffinity, focusObject,
                                  focusOffset, focusAffinity);
  if (anchorOffset < 0)
    return -1;

  return anchorOffset;
}

std::string WebAXObjectProxy::SelectionAnchorAffinity() {
  accessibility_object_.UpdateLayoutAndCheckValidity();

  bool is_selection_backward = false;
  blink::WebAXObject anchorObject;
  int anchorOffset = -1;
  ax::mojom::TextAffinity anchorAffinity;
  blink::WebAXObject focusObject;
  int focusOffset = -1;
  ax::mojom::TextAffinity focusAffinity;
  accessibility_object_.Selection(is_selection_backward, anchorObject,
                                  anchorOffset, anchorAffinity, focusObject,
                                  focusOffset, focusAffinity);
  return anchorAffinity == ax::mojom::TextAffinity::kUpstream ? "upstream"
                                                              : "downstream";
}

v8::Local<v8::Value> WebAXObjectProxy::SelectionFocusObject() {
  accessibility_object_.UpdateLayoutAndCheckValidity();

  bool is_selection_backward = false;
  blink::WebAXObject anchorObject;
  int anchorOffset = -1;
  ax::mojom::TextAffinity anchorAffinity;
  blink::WebAXObject focusObject;
  int focusOffset = -1;
  ax::mojom::TextAffinity focusAffinity;
  accessibility_object_.Selection(is_selection_backward, anchorObject,
                                  anchorOffset, anchorAffinity, focusObject,
                                  focusOffset, focusAffinity);
  if (focusObject.IsNull())
    return v8::Null(blink::MainThreadIsolate());

  return factory_->GetOrCreate(focusObject);
}

int WebAXObjectProxy::SelectionFocusOffset() {
  accessibility_object_.UpdateLayoutAndCheckValidity();

  bool is_selection_backward = false;
  blink::WebAXObject anchorObject;
  int anchorOffset = -1;
  ax::mojom::TextAffinity anchorAffinity;
  blink::WebAXObject focusObject;
  int focusOffset = -1;
  ax::mojom::TextAffinity focusAffinity;
  accessibility_object_.Selection(is_selection_backward, anchorObject,
                                  anchorOffset, anchorAffinity, focusObject,
                                  focusOffset, focusAffinity);
  if (focusOffset < 0)
    return -1;

  return focusOffset;
}

std::string WebAXObjectProxy::SelectionFocusAffinity() {
  accessibility_object_.UpdateLayoutAndCheckValidity();

  bool is_selection_backward = false;
  blink::WebAXObject anchorObject;
  int anchorOffset = -1;
  ax::mojom::TextAffinity anchorAffinity;
  blink::WebAXObject focusObject;
  int focusOffset = -1;
  ax::mojom::TextAffinity focusAffinity;
  accessibility_object_.Selection(is_selection_backward, anchorObject,
                                  anchorOffset, anchorAffinity, focusObject,
                                  focusOffset, focusAffinity);
  return focusAffinity == ax::mojom::TextAffinity::kUpstream ? "upstream"
                                                             : "downstream";
}

bool WebAXObjectProxy::IsAtomic() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.LiveRegionAtomic();
}

bool WebAXObjectProxy::IsAutofillAvailable() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.IsAutofillAvailable();
}

bool WebAXObjectProxy::IsBusy() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  SparseAttributeAdapter attribute_adapter;
  accessibility_object_.GetSparseAXAttributes(attribute_adapter);
  return attribute_adapter
      .bool_attributes[blink::WebAXBoolAttribute::kAriaBusy];
}

std::string WebAXObjectProxy::Restriction() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  switch (accessibility_object_.Restriction()) {
    case blink::kWebAXRestrictionReadOnly:
      return "readOnly";
    case blink::kWebAXRestrictionDisabled:
      return "disabled";
    case blink::kWebAXRestrictionNone:
      break;
  }
  return "none";
}

bool WebAXObjectProxy::IsRequired() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.IsRequired();
}

bool WebAXObjectProxy::IsEditableRoot() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.IsEditableRoot();
}

bool WebAXObjectProxy::IsEditable() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.IsEditable();
}

bool WebAXObjectProxy::IsRichlyEditable() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.IsRichlyEditable();
}

bool WebAXObjectProxy::IsFocused() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.IsFocused();
}

bool WebAXObjectProxy::IsFocusable() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.CanSetFocusAttribute();
}

bool WebAXObjectProxy::IsModal() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.IsModal();
}

bool WebAXObjectProxy::IsSelected() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.IsSelected() == blink::kWebAXSelectedStateTrue;
}

bool WebAXObjectProxy::IsSelectable() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.IsSelected() !=
         blink::kWebAXSelectedStateUndefined;
}

bool WebAXObjectProxy::IsMultiLine() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.IsMultiline();
}

bool WebAXObjectProxy::IsMultiSelectable() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.IsMultiSelectable();
}

bool WebAXObjectProxy::IsSelectedOptionActive() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.IsSelectedOptionActive();
}

bool WebAXObjectProxy::IsExpanded() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.IsExpanded() == blink::kWebAXExpandedExpanded;
}

std::string WebAXObjectProxy::Checked() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  switch (accessibility_object_.CheckedState()) {
    case ax::mojom::CheckedState::kTrue:
      return "true";
    case ax::mojom::CheckedState::kMixed:
      return "mixed";
    case ax::mojom::CheckedState::kFalse:
      return "false";
    default:
      return std::string();
  }
}

bool WebAXObjectProxy::IsCollapsed() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.IsExpanded() == blink::kWebAXExpandedCollapsed;
}

bool WebAXObjectProxy::IsVisible() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.IsVisible();
}

bool WebAXObjectProxy::IsVisited() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.IsVisited();
}

bool WebAXObjectProxy::IsOffScreen() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.IsOffScreen();
}

bool WebAXObjectProxy::IsValid() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return !accessibility_object_.IsDetached();
}

bool WebAXObjectProxy::IsReadOnly() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.Restriction() ==
         blink::kWebAXRestrictionReadOnly;
}

bool WebAXObjectProxy::IsIgnored() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.AccessibilityIsIgnored();
}

v8::Local<v8::Object> WebAXObjectProxy::ActiveDescendant() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  blink::WebAXObject element = accessibility_object_.AriaActiveDescendant();
  return factory_->GetOrCreate(element);
}

unsigned int WebAXObjectProxy::BackgroundColor() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.BackgroundColor();
}

unsigned int WebAXObjectProxy::Color() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  unsigned int color = accessibility_object_.GetColor();
  // Remove the alpha because it's always 1 and thus not informative.
  return color & 0xFFFFFF;
}

// For input elements of type color.
unsigned int WebAXObjectProxy::ColorValue() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.ColorValue();
}

std::string WebAXObjectProxy::FontFamily() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  std::string font_family(accessibility_object_.FontFamily().Utf8());
  return font_family.insert(0, "AXFontFamily: ");
}

float WebAXObjectProxy::FontSize() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.FontSize();
}

std::string WebAXObjectProxy::Autocomplete() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.AutoComplete().Utf8();
}

std::string WebAXObjectProxy::Current() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  switch (accessibility_object_.AriaCurrentState()) {
    case ax::mojom::AriaCurrentState::kFalse:
      return "false";
    case ax::mojom::AriaCurrentState::kTrue:
      return "true";
    case ax::mojom::AriaCurrentState::kPage:
      return "page";
    case ax::mojom::AriaCurrentState::kStep:
      return "step";
    case ax::mojom::AriaCurrentState::kLocation:
      return "location";
    case ax::mojom::AriaCurrentState::kDate:
      return "date";
    case ax::mojom::AriaCurrentState::kTime:
      return "time";
    default:
      return std::string();
  }
}

std::string WebAXObjectProxy::HasPopup() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  switch (accessibility_object_.HasPopup()) {
    case ax::mojom::HasPopup::kTrue:
      return "true";
    case ax::mojom::HasPopup::kMenu:
      return "menu";
    case ax::mojom::HasPopup::kListbox:
      return "listbox";
    case ax::mojom::HasPopup::kTree:
      return "tree";
    case ax::mojom::HasPopup::kGrid:
      return "grid";
    case ax::mojom::HasPopup::kDialog:
      return "dialog";
    default:
      return std::string();
  }
}

std::string WebAXObjectProxy::Invalid() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  switch (accessibility_object_.InvalidState()) {
    case ax::mojom::InvalidState::kFalse:
      return "false";
    case ax::mojom::InvalidState::kTrue:
      return "true";
    case ax::mojom::InvalidState::kOther:
      return "other";
    default:
      return std::string();
  }
}

std::string WebAXObjectProxy::KeyShortcuts() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  SparseAttributeAdapter attribute_adapter;
  accessibility_object_.GetSparseAXAttributes(attribute_adapter);
  return attribute_adapter
      .string_attributes[blink::WebAXStringAttribute::kAriaKeyShortcuts]
      .Utf8();
}

int32_t WebAXObjectProxy::AriaColumnCount() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  SparseAttributeAdapter attribute_adapter;
  accessibility_object_.GetSparseAXAttributes(attribute_adapter);
  return attribute_adapter
      .int_attributes[blink::WebAXIntAttribute::kAriaColumnCount];
}

uint32_t WebAXObjectProxy::AriaColumnIndex() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  SparseAttributeAdapter attribute_adapter;
  accessibility_object_.GetSparseAXAttributes(attribute_adapter);
  return attribute_adapter
      .uint_attributes[blink::WebAXUIntAttribute::kAriaColumnIndex];
}

uint32_t WebAXObjectProxy::AriaColumnSpan() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  SparseAttributeAdapter attribute_adapter;
  accessibility_object_.GetSparseAXAttributes(attribute_adapter);
  return attribute_adapter
      .uint_attributes[blink::WebAXUIntAttribute::kAriaColumnSpan];
}

int32_t WebAXObjectProxy::AriaRowCount() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  SparseAttributeAdapter attribute_adapter;
  accessibility_object_.GetSparseAXAttributes(attribute_adapter);
  return attribute_adapter
      .int_attributes[blink::WebAXIntAttribute::kAriaRowCount];
}

uint32_t WebAXObjectProxy::AriaRowIndex() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  SparseAttributeAdapter attribute_adapter;
  accessibility_object_.GetSparseAXAttributes(attribute_adapter);
  return attribute_adapter
      .uint_attributes[blink::WebAXUIntAttribute::kAriaRowIndex];
}

uint32_t WebAXObjectProxy::AriaRowSpan() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  SparseAttributeAdapter attribute_adapter;
  accessibility_object_.GetSparseAXAttributes(attribute_adapter);
  return attribute_adapter
      .uint_attributes[blink::WebAXUIntAttribute::kAriaRowSpan];
}

std::string WebAXObjectProxy::Live() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.LiveRegionStatus().Utf8();
}

std::string WebAXObjectProxy::Orientation() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  if (accessibility_object_.Orientation() == blink::kWebAXOrientationVertical)
    return "AXOrientation: AXVerticalOrientation";
  else if (accessibility_object_.Orientation() ==
           blink::kWebAXOrientationHorizontal)
    return "AXOrientation: AXHorizontalOrientation";

  return std::string();
}

std::string WebAXObjectProxy::Relevant() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.LiveRegionRelevant().Utf8();
}

std::string WebAXObjectProxy::RoleDescription() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  SparseAttributeAdapter attribute_adapter;
  accessibility_object_.GetSparseAXAttributes(attribute_adapter);
  return attribute_adapter
      .string_attributes[blink::WebAXStringAttribute::kAriaRoleDescription]
      .Utf8();
}

std::string WebAXObjectProxy::Sort() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  switch (accessibility_object_.SortDirection()) {
    case ax::mojom::SortDirection::kAscending:
      return "ascending";
    case ax::mojom::SortDirection::kDescending:
      return "descending";
    case ax::mojom::SortDirection::kOther:
      return "other";
    default:
      return std::string();
  }
}

std::string WebAXObjectProxy::Url() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.Url().GetString().Utf8();
}

int WebAXObjectProxy::HierarchicalLevel() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.HierarchicalLevel();
}

int WebAXObjectProxy::PosInSet() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.PosInSet();
}

int WebAXObjectProxy::SetSize() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.SetSize();
}

int WebAXObjectProxy::ClickPointX() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  blink::WebFloatRect bounds = BoundsForObject(accessibility_object_);
  return bounds.x + bounds.width / 2;
}

int WebAXObjectProxy::ClickPointY() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  blink::WebFloatRect bounds = BoundsForObject(accessibility_object_);
  return bounds.y + bounds.height / 2;
}

int32_t WebAXObjectProxy::RowCount() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return static_cast<int32_t>(accessibility_object_.RowCount());
}

int32_t WebAXObjectProxy::RowHeadersCount() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  blink::WebVector<blink::WebAXObject> headers;
  accessibility_object_.RowHeaders(headers);
  return static_cast<int32_t>(headers.size());
}

int32_t WebAXObjectProxy::ColumnCount() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return static_cast<int32_t>(accessibility_object_.ColumnCount());
}

int32_t WebAXObjectProxy::ColumnHeadersCount() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  blink::WebVector<blink::WebAXObject> headers;
  accessibility_object_.ColumnHeaders(headers);
  return static_cast<int32_t>(headers.size());
}

bool WebAXObjectProxy::IsClickable() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.IsClickable();
}

v8::Local<v8::Object> WebAXObjectProxy::AriaActiveDescendantElement() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  SparseAttributeAdapter attribute_adapter;
  accessibility_object_.GetSparseAXAttributes(attribute_adapter);
  blink::WebAXObject element =
      attribute_adapter.object_attributes
          [blink::WebAXObjectAttribute::kAriaActiveDescendant];
  return factory_->GetOrCreate(element);
}

v8::Local<v8::Object> WebAXObjectProxy::AriaControlsElementAtIndex(
    unsigned index) {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  SparseAttributeAdapter attribute_adapter;
  accessibility_object_.GetSparseAXAttributes(attribute_adapter);
  blink::WebVector<blink::WebAXObject> elements =
      attribute_adapter.object_vector_attributes
          [blink::WebAXObjectVectorAttribute::kAriaControls];
  size_t elementCount = elements.size();
  if (index >= elementCount)
    return v8::Local<v8::Object>();

  return factory_->GetOrCreate(elements[index]);
}

v8::Local<v8::Object> WebAXObjectProxy::AriaDetailsElement() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  SparseAttributeAdapter attribute_adapter;
  accessibility_object_.GetSparseAXAttributes(attribute_adapter);
  blink::WebAXObject element =
      attribute_adapter
          .object_attributes[blink::WebAXObjectAttribute::kAriaDetails];
  return factory_->GetOrCreate(element);
}

v8::Local<v8::Object> WebAXObjectProxy::AriaErrorMessageElement() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  SparseAttributeAdapter attribute_adapter;
  accessibility_object_.GetSparseAXAttributes(attribute_adapter);
  blink::WebAXObject element =
      attribute_adapter
          .object_attributes[blink::WebAXObjectAttribute::kAriaErrorMessage];
  return factory_->GetOrCreate(element);
}

v8::Local<v8::Object> WebAXObjectProxy::AriaFlowToElementAtIndex(
    unsigned index) {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  SparseAttributeAdapter attribute_adapter;
  accessibility_object_.GetSparseAXAttributes(attribute_adapter);
  blink::WebVector<blink::WebAXObject> elements =
      attribute_adapter.object_vector_attributes
          [blink::WebAXObjectVectorAttribute::kAriaFlowTo];
  size_t elementCount = elements.size();
  if (index >= elementCount)
    return v8::Local<v8::Object>();

  return factory_->GetOrCreate(elements[index]);
}

v8::Local<v8::Object> WebAXObjectProxy::AriaOwnsElementAtIndex(unsigned index) {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  blink::WebVector<blink::WebAXObject> elements;
  accessibility_object_.AriaOwns(elements);
  size_t elementCount = elements.size();
  if (index >= elementCount)
    return v8::Local<v8::Object>();

  return factory_->GetOrCreate(elements[index]);
}

std::string WebAXObjectProxy::AllAttributes() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return GetAttributes(accessibility_object_);
}

std::string WebAXObjectProxy::AttributesOfChildren() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  AttributesCollector collector;
  unsigned size = accessibility_object_.ChildCount();
  for (unsigned i = 0; i < size; ++i)
    collector.CollectAttributes(accessibility_object_.ChildAt(i));
  return collector.attributes();
}

std::string WebAXObjectProxy::BoundsForRange(int start, int end) {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  if (accessibility_object_.Role() != ax::mojom::Role::kStaticText)
    return std::string();

  if (!accessibility_object_.UpdateLayoutAndCheckValidity())
    return std::string();

  int len = end - start;

  // Get the bounds for each character and union them into one large rectangle.
  // This is just for testing so it doesn't need to be efficient.
  blink::WebRect bounds = BoundsForCharacter(accessibility_object_, start);
  for (int i = 1; i < len; i++) {
    blink::WebRect next = BoundsForCharacter(accessibility_object_, start + i);
    int right = std::max(bounds.x + bounds.width, next.x + next.width);
    int bottom = std::max(bounds.y + bounds.height, next.y + next.height);
    bounds.x = std::min(bounds.x, next.x);
    bounds.y = std::min(bounds.y, next.y);
    bounds.width = right - bounds.x;
    bounds.height = bottom - bounds.y;
  }

  return base::StringPrintf("{x: %d, y: %d, width: %d, height: %d}", bounds.x,
                            bounds.y, bounds.width, bounds.height);
}

v8::Local<v8::Object> WebAXObjectProxy::ChildAtIndex(int index) {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return GetChildAtIndex(index);
}

v8::Local<v8::Object> WebAXObjectProxy::ElementAtPoint(int x, int y) {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  blink::WebPoint point(x, y);
  blink::WebAXObject obj = accessibility_object_.HitTest(point);
  if (obj.IsNull())
    return v8::Local<v8::Object>();

  return factory_->GetOrCreate(obj);
}

v8::Local<v8::Object> WebAXObjectProxy::RowHeaderAtIndex(unsigned index) {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  blink::WebVector<blink::WebAXObject> headers;
  accessibility_object_.RowHeaders(headers);
  size_t headerCount = headers.size();
  if (index >= headerCount)
    return v8::Local<v8::Object>();

  return factory_->GetOrCreate(headers[index]);
}

v8::Local<v8::Object> WebAXObjectProxy::ColumnHeaderAtIndex(unsigned index) {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  blink::WebVector<blink::WebAXObject> headers;
  accessibility_object_.ColumnHeaders(headers);
  size_t headerCount = headers.size();
  if (index >= headerCount)
    return v8::Local<v8::Object>();

  return factory_->GetOrCreate(headers[index]);
}

std::string WebAXObjectProxy::RowIndexRange() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  unsigned row_index = accessibility_object_.CellRowIndex();
  unsigned row_span = accessibility_object_.CellRowSpan();
  return base::StringPrintf("{%d, %d}", row_index, row_span);
}

std::string WebAXObjectProxy::ColumnIndexRange() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  unsigned column_index = accessibility_object_.CellColumnIndex();
  unsigned column_span = accessibility_object_.CellColumnSpan();
  return base::StringPrintf("{%d, %d}", column_index, column_span);
}

v8::Local<v8::Object> WebAXObjectProxy::CellForColumnAndRow(int column,
                                                            int row) {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  blink::WebAXObject obj =
      accessibility_object_.CellForColumnAndRow(column, row);
  if (obj.IsNull())
    return v8::Local<v8::Object>();

  return factory_->GetOrCreate(obj);
}

void WebAXObjectProxy::SetSelectedTextRange(int selection_start, int length) {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  accessibility_object_.SetSelection(accessibility_object_, selection_start,
                                     accessibility_object_,
                                     selection_start + length);
}

bool WebAXObjectProxy::SetSelection(v8::Local<v8::Value> anchor_object,
                                    int anchor_offset,
                                    v8::Local<v8::Value> focus_object,
                                    int focus_offset) {
  if (anchor_object.IsEmpty() || focus_object.IsEmpty() ||
      !anchor_object->IsObject() || !focus_object->IsObject() ||
      anchor_offset < 0 || focus_offset < 0) {
    return false;
  }

  WebAXObjectProxy* web_ax_anchor = nullptr;
  if (!gin::ConvertFromV8(blink::MainThreadIsolate(), anchor_object,
                          &web_ax_anchor)) {
    return false;
  }
  DCHECK(web_ax_anchor);

  WebAXObjectProxy* web_ax_focus = nullptr;
  if (!gin::ConvertFromV8(blink::MainThreadIsolate(), focus_object,
                          &web_ax_focus)) {
    return false;
  }
  DCHECK(web_ax_focus);

  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.SetSelection(
      web_ax_anchor->accessibility_object_, anchor_offset,
      web_ax_focus->accessibility_object_, focus_offset);
}

bool WebAXObjectProxy::IsAttributeSettable(const std::string& attribute) {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  bool settable = false;
  if (attribute == "AXValue")
    settable = accessibility_object_.CanSetValueAttribute();
  return settable;
}

bool WebAXObjectProxy::IsPressActionSupported() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.CanPress();
}

v8::Local<v8::Object> WebAXObjectProxy::ParentElement() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  blink::WebAXObject parent_object = accessibility_object_.ParentObject();
  while (!parent_object.IsNull() &&
         !parent_object.AccessibilityIsIncludedInTree())
    parent_object = parent_object.ParentObject();
  return factory_->GetOrCreate(parent_object);
}

void WebAXObjectProxy::Increment() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  accessibility_object_.Increment();
}

void WebAXObjectProxy::Decrement() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  accessibility_object_.Decrement();
}

void WebAXObjectProxy::ShowMenu() {
  accessibility_object_.ShowContextMenu();
}

void WebAXObjectProxy::Press() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  accessibility_object_.Click();
}

bool WebAXObjectProxy::SetValue(const std::string& value) {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  if (accessibility_object_.Restriction() != blink::kWebAXRestrictionNone ||
      accessibility_object_.StringValue().IsEmpty())
    return false;

  accessibility_object_.SetValue(blink::WebString::FromUTF8(value));
  return true;
}

bool WebAXObjectProxy::IsEqual(v8::Local<v8::Object> proxy) {
  WebAXObjectProxy* unwrapped_proxy = nullptr;
  if (!gin::ConvertFromV8(blink::MainThreadIsolate(), proxy, &unwrapped_proxy))
    return false;
  return unwrapped_proxy->IsEqualToObject(accessibility_object_);
}

void WebAXObjectProxy::SetNotificationListener(
    v8::Local<v8::Function> callback) {
  v8::Isolate* isolate = blink::MainThreadIsolate();
  notification_callback_.Reset(isolate, callback);
}

void WebAXObjectProxy::UnsetNotificationListener() {
  notification_callback_.Reset();
}

void WebAXObjectProxy::TakeFocus() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  accessibility_object_.Focus();
}

void WebAXObjectProxy::ScrollToMakeVisible() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  accessibility_object_.ScrollToMakeVisible();
}

void WebAXObjectProxy::ScrollToMakeVisibleWithSubFocus(int x,
                                                       int y,
                                                       int width,
                                                       int height) {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  accessibility_object_.ScrollToMakeVisibleWithSubFocus(
      blink::WebRect(x, y, width, height));
}

void WebAXObjectProxy::ScrollToGlobalPoint(int x, int y) {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  accessibility_object_.ScrollToGlobalPoint(blink::WebPoint(x, y));
}

int WebAXObjectProxy::ScrollX() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.GetScrollOffset().x;
}

int WebAXObjectProxy::ScrollY() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.GetScrollOffset().y;
}

std::string WebAXObjectProxy::ToString() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.ToString().Utf8();
}

float WebAXObjectProxy::BoundsX() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return BoundsForObject(accessibility_object_).x;
}

float WebAXObjectProxy::BoundsY() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return BoundsForObject(accessibility_object_).y;
}

float WebAXObjectProxy::BoundsWidth() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return BoundsForObject(accessibility_object_).width;
}

float WebAXObjectProxy::BoundsHeight() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return BoundsForObject(accessibility_object_).height;
}

int WebAXObjectProxy::WordStart(int character_index) {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  if (accessibility_object_.Role() != ax::mojom::Role::kStaticText)
    return -1;

  int word_start = 0, word_end = 0;
  GetBoundariesForOneWord(accessibility_object_, character_index, word_start,
                          word_end);
  return word_start;
}

int WebAXObjectProxy::WordEnd(int character_index) {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  if (accessibility_object_.Role() != ax::mojom::Role::kStaticText)
    return -1;

  int word_start = 0, word_end = 0;
  GetBoundariesForOneWord(accessibility_object_, character_index, word_start,
                          word_end);
  return word_end;
}

v8::Local<v8::Object> WebAXObjectProxy::NextOnLine() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  blink::WebAXObject obj = accessibility_object_.NextOnLine();
  if (obj.IsNull())
    return v8::Local<v8::Object>();

  return factory_->GetOrCreate(obj);
}

v8::Local<v8::Object> WebAXObjectProxy::PreviousOnLine() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  blink::WebAXObject obj = accessibility_object_.PreviousOnLine();
  if (obj.IsNull())
    return v8::Local<v8::Object>();

  return factory_->GetOrCreate(obj);
}

std::string WebAXObjectProxy::MisspellingAtIndex(int index) {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  if (index < 0 || index >= MisspellingsCount())
    return std::string();
  return GetMisspellings(accessibility_object_)[index];
}

std::string WebAXObjectProxy::Name() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return accessibility_object_.GetName().Utf8();
}

std::string WebAXObjectProxy::NameFrom() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  ax::mojom::NameFrom nameFrom = ax::mojom::NameFrom::kUninitialized;
  blink::WebVector<blink::WebAXObject> nameObjects;
  accessibility_object_.GetName(nameFrom, nameObjects);
  switch (nameFrom) {
    case ax::mojom::NameFrom::kUninitialized:
    case ax::mojom::NameFrom::kNone:
      return "";
    case ax::mojom::NameFrom::kAttribute:
      return "attribute";
    case ax::mojom::NameFrom::kAttributeExplicitlyEmpty:
      return "attributeExplicitlyEmpty";
    case ax::mojom::NameFrom::kCaption:
      return "caption";
    case ax::mojom::NameFrom::kContents:
      return "contents";
    case ax::mojom::NameFrom::kPlaceholder:
      return "placeholder";
    case ax::mojom::NameFrom::kRelatedElement:
      return "relatedElement";
    case ax::mojom::NameFrom::kValue:
      return "value";
    case ax::mojom::NameFrom::kTitle:
      return "title";
  }

  NOTREACHED();
  return std::string();
}

int WebAXObjectProxy::NameElementCount() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  ax::mojom::NameFrom nameFrom;
  blink::WebVector<blink::WebAXObject> nameObjects;
  accessibility_object_.GetName(nameFrom, nameObjects);
  return static_cast<int>(nameObjects.size());
}

v8::Local<v8::Object> WebAXObjectProxy::NameElementAtIndex(unsigned index) {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  ax::mojom::NameFrom nameFrom;
  blink::WebVector<blink::WebAXObject> nameObjects;
  accessibility_object_.GetName(nameFrom, nameObjects);
  if (index >= nameObjects.size())
    return v8::Local<v8::Object>();
  return factory_->GetOrCreate(nameObjects[index]);
}

std::string WebAXObjectProxy::Description() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  ax::mojom::NameFrom nameFrom;
  blink::WebVector<blink::WebAXObject> nameObjects;
  accessibility_object_.GetName(nameFrom, nameObjects);
  ax::mojom::DescriptionFrom descriptionFrom;
  blink::WebVector<blink::WebAXObject> descriptionObjects;
  return accessibility_object_
      .Description(nameFrom, descriptionFrom, descriptionObjects)
      .Utf8();
}

std::string WebAXObjectProxy::DescriptionFrom() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  ax::mojom::NameFrom nameFrom;
  blink::WebVector<blink::WebAXObject> nameObjects;
  accessibility_object_.GetName(nameFrom, nameObjects);
  ax::mojom::DescriptionFrom descriptionFrom =
      ax::mojom::DescriptionFrom::kUninitialized;
  blink::WebVector<blink::WebAXObject> descriptionObjects;
  accessibility_object_.Description(nameFrom, descriptionFrom,
                                    descriptionObjects);
  switch (descriptionFrom) {
    case ax::mojom::DescriptionFrom::kUninitialized:
    case ax::mojom::DescriptionFrom::kNone:
      return "";
    case ax::mojom::DescriptionFrom::kAttribute:
      return "attribute";
    case ax::mojom::DescriptionFrom::kContents:
      return "contents";
    case ax::mojom::DescriptionFrom::kRelatedElement:
      return "relatedElement";
  }

  NOTREACHED();
  return std::string();
}

std::string WebAXObjectProxy::Placeholder() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  ax::mojom::NameFrom nameFrom;
  blink::WebVector<blink::WebAXObject> nameObjects;
  accessibility_object_.GetName(nameFrom, nameObjects);
  return accessibility_object_.Placeholder(nameFrom).Utf8();
}

int WebAXObjectProxy::MisspellingsCount() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  return GetMisspellings(accessibility_object_).size();
}

int WebAXObjectProxy::DescriptionElementCount() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  ax::mojom::NameFrom nameFrom;
  blink::WebVector<blink::WebAXObject> nameObjects;
  accessibility_object_.GetName(nameFrom, nameObjects);
  ax::mojom::DescriptionFrom descriptionFrom;
  blink::WebVector<blink::WebAXObject> descriptionObjects;
  accessibility_object_.Description(nameFrom, descriptionFrom,
                                    descriptionObjects);
  return static_cast<int>(descriptionObjects.size());
}

v8::Local<v8::Object> WebAXObjectProxy::DescriptionElementAtIndex(
    unsigned index) {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  ax::mojom::NameFrom nameFrom;
  blink::WebVector<blink::WebAXObject> nameObjects;
  accessibility_object_.GetName(nameFrom, nameObjects);
  ax::mojom::DescriptionFrom descriptionFrom;
  blink::WebVector<blink::WebAXObject> descriptionObjects;
  accessibility_object_.Description(nameFrom, descriptionFrom,
                                    descriptionObjects);
  if (index >= descriptionObjects.size())
    return v8::Local<v8::Object>();
  return factory_->GetOrCreate(descriptionObjects[index]);
}

v8::Local<v8::Object> WebAXObjectProxy::OffsetContainer() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  blink::WebAXObject container;
  blink::WebFloatRect bounds;
  SkMatrix44 matrix;
  accessibility_object_.GetRelativeBounds(container, bounds, matrix);
  return factory_->GetOrCreate(container);
}

float WebAXObjectProxy::BoundsInContainerX() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  blink::WebAXObject container;
  blink::WebFloatRect bounds;
  SkMatrix44 matrix;
  accessibility_object_.GetRelativeBounds(container, bounds, matrix);
  return bounds.x;
}

float WebAXObjectProxy::BoundsInContainerY() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  blink::WebAXObject container;
  blink::WebFloatRect bounds;
  SkMatrix44 matrix;
  accessibility_object_.GetRelativeBounds(container, bounds, matrix);
  return bounds.y;
}

float WebAXObjectProxy::BoundsInContainerWidth() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  blink::WebAXObject container;
  blink::WebFloatRect bounds;
  SkMatrix44 matrix;
  accessibility_object_.GetRelativeBounds(container, bounds, matrix);
  return bounds.width;
}

float WebAXObjectProxy::BoundsInContainerHeight() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  blink::WebAXObject container;
  blink::WebFloatRect bounds;
  SkMatrix44 matrix;
  accessibility_object_.GetRelativeBounds(container, bounds, matrix);
  return bounds.height;
}

bool WebAXObjectProxy::HasNonIdentityTransform() {
  accessibility_object_.UpdateLayoutAndCheckValidity();
  blink::WebAXObject container;
  blink::WebFloatRect bounds;
  SkMatrix44 matrix;
  accessibility_object_.GetRelativeBounds(container, bounds, matrix);
  return !matrix.isIdentity();
}

RootWebAXObjectProxy::RootWebAXObjectProxy(const blink::WebAXObject& object,
                                           Factory* factory)
    : WebAXObjectProxy(object, factory) {}

v8::Local<v8::Object> RootWebAXObjectProxy::GetChildAtIndex(unsigned index) {
  if (index)
    return v8::Local<v8::Object>();

  return factory()->GetOrCreate(accessibility_object());
}

bool RootWebAXObjectProxy::IsRoot() const {
  return true;
}

WebAXObjectProxyList::WebAXObjectProxyList()
    : elements_(blink::MainThreadIsolate()) {}

WebAXObjectProxyList::~WebAXObjectProxyList() {
  Clear();
}

void WebAXObjectProxyList::Clear() {
  v8::Isolate* isolate = blink::MainThreadIsolate();
  v8::HandleScope handle_scope(isolate);
  size_t elementCount = elements_.Size();
  for (size_t i = 0; i < elementCount; i++) {
    WebAXObjectProxy* unwrapped_object = nullptr;
    bool result =
        gin::ConvertFromV8(isolate, elements_.Get(i), &unwrapped_object);
    DCHECK(result);
    DCHECK(unwrapped_object);
    unwrapped_object->Reset();
  }
  elements_.Clear();
}

v8::Local<v8::Object> WebAXObjectProxyList::GetOrCreate(
    const blink::WebAXObject& object) {
  if (object.IsNull())
    return v8::Local<v8::Object>();

  v8::Isolate* isolate = blink::MainThreadIsolate();

  size_t elementCount = elements_.Size();
  for (size_t i = 0; i < elementCount; i++) {
    WebAXObjectProxy* unwrapped_object = nullptr;
    bool result =
        gin::ConvertFromV8(isolate, elements_.Get(i), &unwrapped_object);
    DCHECK(result);
    DCHECK(unwrapped_object);
    if (unwrapped_object->IsEqualToObject(object))
      return elements_.Get(i);
  }

  v8::Local<v8::Value> value_handle =
      gin::CreateHandle(isolate, new WebAXObjectProxy(object, this)).ToV8();
  v8::Local<v8::Object> handle;
  if (value_handle.IsEmpty() ||
      !value_handle->ToObject(isolate->GetCurrentContext()).ToLocal(&handle)) {
    return v8::Local<v8::Object>();
  }
  elements_.Append(handle);
  return handle;
}

}  // namespace test_runner
