| // Copyright 2016 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/browser/accessibility/ax_platform_position.h" |
| |
| #include "content/browser/accessibility/browser_accessibility.h" |
| #include "content/browser/accessibility/browser_accessibility_manager.h" |
| #include "ui/accessibility/ax_enums.h" |
| |
| namespace content { |
| |
| AXPlatformPosition::AXPlatformPosition() {} |
| |
| AXPlatformPosition::~AXPlatformPosition() {} |
| |
| AXPlatformPosition::AXPositionInstance AXPlatformPosition::Clone() const { |
| return AXPositionInstance(new AXPlatformPosition(*this)); |
| } |
| |
| base::string16 AXPlatformPosition::GetInnerText() const { |
| if (IsNullPosition()) |
| return base::string16(); |
| DCHECK(GetAnchor()); |
| return GetAnchor()->GetText(); |
| } |
| |
| void AXPlatformPosition::AnchorChild(int child_index, |
| AXTreeID* tree_id, |
| int32_t* child_id) const { |
| DCHECK(tree_id); |
| DCHECK(child_id); |
| |
| if (!GetAnchor() || child_index < 0 || child_index >= AnchorChildCount()) { |
| *tree_id = INVALID_TREE_ID; |
| *child_id = INVALID_ANCHOR_ID; |
| return; |
| } |
| |
| BrowserAccessibility* child = nullptr; |
| if (GetAnchor()->PlatformIsLeaf()) { |
| child = GetAnchor()->InternalGetChild(child_index); |
| } else { |
| child = GetAnchor()->PlatformGetChild(child_index); |
| } |
| DCHECK(child); |
| *tree_id = child->manager()->ax_tree_id(); |
| *child_id = child->GetId(); |
| } |
| |
| int AXPlatformPosition::AnchorChildCount() const { |
| if (!GetAnchor()) |
| return 0; |
| |
| if (GetAnchor()->PlatformIsLeaf()) { |
| return static_cast<int>(GetAnchor()->InternalChildCount()); |
| } else { |
| return static_cast<int>(GetAnchor()->PlatformChildCount()); |
| } |
| } |
| |
| int AXPlatformPosition::AnchorIndexInParent() const { |
| return GetAnchor() ? static_cast<int>(GetAnchor()->GetIndexInParent()) |
| : AXPosition::INVALID_INDEX; |
| } |
| |
| void AXPlatformPosition::AnchorParent(AXTreeID* tree_id, |
| int32_t* parent_id) const { |
| DCHECK(tree_id); |
| DCHECK(parent_id); |
| |
| if (!GetAnchor() || !GetAnchor()->PlatformGetParent()) { |
| *tree_id = AXPosition::INVALID_TREE_ID; |
| *parent_id = AXPosition::INVALID_ANCHOR_ID; |
| return; |
| } |
| |
| BrowserAccessibility* parent = GetAnchor()->PlatformGetParent(); |
| *tree_id = parent->manager()->ax_tree_id(); |
| *parent_id = parent->GetId(); |
| } |
| |
| BrowserAccessibility* AXPlatformPosition::GetNodeInTree(AXTreeID tree_id, |
| int32_t node_id) const { |
| if (tree_id == AXPosition::INVALID_TREE_ID || |
| node_id == AXPosition::INVALID_ANCHOR_ID) { |
| return nullptr; |
| } |
| |
| auto* manager = BrowserAccessibilityManager::FromID(tree_id); |
| if (!manager) |
| return nullptr; |
| return manager->GetFromID(node_id); |
| } |
| |
| int AXPlatformPosition::MaxTextOffset() const { |
| if (IsNullPosition()) |
| return INVALID_OFFSET; |
| return static_cast<int>(GetInnerText().length()); |
| } |
| |
| // On some platforms, most objects are represented in the text of their parents |
| // with a special (embedded object) character and not with their actual text |
| // contents. |
| int AXPlatformPosition::MaxTextOffsetInParent() const { |
| #if defined(OS_WIN) || \ |
| (defined(OS_LINUX) && defined(USE_X11) && !defined(OS_CHROMEOS)) |
| if (IsNullPosition()) |
| return INVALID_OFFSET; |
| if (GetAnchor()->IsTextOnlyObject()) |
| return MaxTextOffset(); |
| return 1; |
| #else |
| return MaxTextOffset(); |
| #endif |
| } |
| |
| bool AXPlatformPosition::IsInLineBreak() const { |
| if (IsNullPosition()) |
| return false; |
| |
| DCHECK(GetAnchor()); |
| return GetAnchor()->IsLineBreakObject(); |
| } |
| |
| std::vector<int32_t> AXPlatformPosition::GetWordStartOffsets() const { |
| if (IsNullPosition()) |
| return std::vector<int32_t>(); |
| DCHECK(GetAnchor()); |
| return GetAnchor()->GetIntListAttribute(ui::AX_ATTR_WORD_STARTS); |
| } |
| |
| std::vector<int32_t> AXPlatformPosition::GetWordEndOffsets() const { |
| if (IsNullPosition()) |
| return std::vector<int32_t>(); |
| DCHECK(GetAnchor()); |
| return GetAnchor()->GetIntListAttribute(ui::AX_ATTR_WORD_ENDS); |
| } |
| |
| int32_t AXPlatformPosition::GetNextOnLineID(int32_t node_id) const { |
| if (IsNullPosition()) |
| return INVALID_ANCHOR_ID; |
| BrowserAccessibility* node = GetNodeInTree(tree_id(), node_id); |
| int next_on_line_id; |
| if (!node || |
| !node->GetIntAttribute(ui::AX_ATTR_NEXT_ON_LINE_ID, &next_on_line_id)) { |
| return INVALID_ANCHOR_ID; |
| } |
| return static_cast<int32_t>(next_on_line_id); |
| } |
| |
| int32_t AXPlatformPosition::GetPreviousOnLineID(int32_t node_id) const { |
| if (IsNullPosition()) |
| return INVALID_ANCHOR_ID; |
| BrowserAccessibility* node = GetNodeInTree(tree_id(), node_id); |
| int previous_on_line_id; |
| if (!node || |
| !node->GetIntAttribute(ui::AX_ATTR_PREVIOUS_ON_LINE_ID, |
| &previous_on_line_id)) { |
| return INVALID_ANCHOR_ID; |
| } |
| return static_cast<int32_t>(previous_on_line_id); |
| } |
| |
| } // namespace content |