Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(328)

Unified Diff: ui/accessibility/ax_position.h

Issue 2934953004: De-templatize ui::AXPosition
Patch Set: rebase Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/accessibility/ax_node_position_unittest.cc ('k') | ui/accessibility/ax_position.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/accessibility/ax_position.h
diff --git a/ui/accessibility/ax_position.h b/ui/accessibility/ax_position.h
index c38d9511128976a2f0f726799a4a89ff6c464d06..1072586c5cbf00462d72c22f17687503789104a1 100644
--- a/ui/accessibility/ax_position.h
+++ b/ui/accessibility/ax_position.h
@@ -13,11 +13,13 @@
#include <utility>
#include <vector>
+#include "base/memory/ptr_util.h"
#include "base/stl_util.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/accessibility/ax_enums.h"
+#include "ui/accessibility/ax_export.h"
namespace ui {
@@ -31,14 +33,19 @@ namespace ui {
enum class AXPositionKind { NULL_POSITION, TREE_POSITION, TEXT_POSITION };
// Forward declarations.
-template <class AXPositionType, class AXNodeType>
-class AXPosition;
-template <class AXPositionType, class AXNodeType>
-bool operator==(const AXPosition<AXPositionType, AXNodeType>& first,
- const AXPosition<AXPositionType, AXNodeType>& second);
-template <class AXPositionType, class AXNodeType>
-bool operator!=(const AXPosition<AXPositionType, AXNodeType>& first,
- const AXPosition<AXPositionType, AXNodeType>& second);
+class AXPositionBase;
+AX_EXPORT bool operator==(const AXPositionBase& first,
+ const AXPositionBase& second);
+AX_EXPORT bool operator!=(const AXPositionBase& first,
+ const AXPositionBase& second);
+AX_EXPORT bool operator<(const AXPositionBase& first,
+ const AXPositionBase& second);
+AX_EXPORT bool operator<=(const AXPositionBase& first,
+ const AXPositionBase& second);
+AX_EXPORT bool operator>(const AXPositionBase& first,
+ const AXPositionBase& second);
+AX_EXPORT bool operator>=(const AXPositionBase& first,
+ const AXPositionBase& second);
// A position in the accessibility tree.
//
@@ -69,51 +76,30 @@ bool operator!=(const AXPosition<AXPositionType, AXNodeType>& first,
//
// This class can be copied using the |Clone| method. It is designed to be
// immutable.
-template <class AXPositionType, class AXNodeType>
-class AXPosition {
+class AX_EXPORT AXPositionBase {
public:
- using AXPositionInstance =
- std::unique_ptr<AXPosition<AXPositionType, AXNodeType>>;
-
- static const int INVALID_TREE_ID = -1;
- static const int32_t INVALID_ANCHOR_ID = -1;
- static const int BEFORE_TEXT = -1;
- static const int INVALID_INDEX = -2;
- static const int INVALID_OFFSET = -1;
-
- static AXPositionInstance CreateNullPosition() {
- AXPositionInstance new_position(new AXPositionType());
- new_position->Initialize(AXPositionKind::NULL_POSITION, INVALID_TREE_ID,
- INVALID_ANCHOR_ID, INVALID_INDEX, INVALID_OFFSET,
- AX_TEXT_AFFINITY_DOWNSTREAM);
- return new_position;
- }
-
- static AXPositionInstance CreateTreePosition(int tree_id,
- int32_t anchor_id,
- int child_index) {
- AXPositionInstance new_position(new AXPositionType());
- new_position->Initialize(AXPositionKind::TREE_POSITION, tree_id, anchor_id,
- child_index, INVALID_OFFSET,
- AX_TEXT_AFFINITY_DOWNSTREAM);
- return new_position;
- }
+ using AXPositionInstance = std::unique_ptr<AXPositionBase>;
+ using OpaqueAnchor = void*;
- static AXPositionInstance CreateTextPosition(int tree_id,
- int32_t anchor_id,
- int text_offset,
- AXTextAffinity affinity) {
- AXPositionInstance new_position(new AXPositionType());
- new_position->Initialize(AXPositionKind::TEXT_POSITION, tree_id, anchor_id,
- INVALID_INDEX, text_offset, affinity);
- return new_position;
- }
+ static constexpr int INVALID_TREE_ID = -1;
+ static constexpr int32_t INVALID_ANCHOR_ID = -1;
+ static constexpr int BEFORE_TEXT = -1;
+ static constexpr int INVALID_INDEX = -2;
+ static constexpr int INVALID_OFFSET = -1;
- AXPosition() {}
- virtual ~AXPosition() {}
+ AXPositionBase() {}
+ virtual ~AXPositionBase() {}
virtual AXPositionInstance Clone() const = 0;
-
+ virtual AXPositionInstance CreateNullPosition() const = 0;
+ virtual AXPositionInstance CreateTreePosition(int tree_id,
+ int32_t anchor_id,
+ int child_index) const = 0;
+ virtual AXPositionInstance CreateTextPosition(
+ int tree_id,
+ int32_t anchor_id,
+ int text_offset,
+ AXTextAffinity affinity) const = 0;
std::string ToString() const {
std::string str;
switch (kind_) {
@@ -168,12 +154,12 @@ class AXPosition {
int tree_id() const { return tree_id_; }
int32_t anchor_id() const { return anchor_id_; }
- AXNodeType* GetAnchor() const {
+ OpaqueAnchor GetOpaqueAnchor() const {
if (tree_id_ == INVALID_TREE_ID || anchor_id_ == INVALID_ANCHOR_ID)
return nullptr;
DCHECK_GE(tree_id_, 0);
DCHECK_GE(anchor_id_, 0);
- return GetNodeInTree(tree_id_, anchor_id_);
+ return GetOpaqueNodeInTree(tree_id_, anchor_id_);
}
AXPositionKind kind() const { return kind_; }
@@ -182,19 +168,19 @@ class AXPosition {
AXTextAffinity affinity() const { return affinity_; }
bool IsNullPosition() const {
- return kind_ == AXPositionKind::NULL_POSITION || !GetAnchor();
+ return kind_ == AXPositionKind::NULL_POSITION || !GetOpaqueAnchor();
}
bool IsTreePosition() const {
- return GetAnchor() && kind_ == AXPositionKind::TREE_POSITION;
+ return GetOpaqueAnchor() && kind_ == AXPositionKind::TREE_POSITION;
}
bool IsTextPosition() const {
- return GetAnchor() && kind_ == AXPositionKind::TEXT_POSITION;
+ return GetOpaqueAnchor() && kind_ == AXPositionKind::TEXT_POSITION;
}
bool AtStartOfAnchor() const {
- if (!GetAnchor())
+ if (!GetOpaqueAnchor())
return false;
switch (kind_) {
@@ -212,7 +198,7 @@ class AXPosition {
}
bool AtEndOfAnchor() const {
- if (!GetAnchor())
+ if (!GetOpaqueAnchor())
return false;
switch (kind_) {
@@ -310,26 +296,26 @@ class AXPosition {
// Also, this method uses position instead of tree logic to traverse the tree,
// because positions can handle moving across multiple trees, while trees
// cannot.
- AXPositionInstance LowestCommonAncestor(
- const AXPosition<AXPositionType, AXNodeType>& second) const {
+ AXPositionInstance LowestCommonAncestor(const AXPositionBase& second) const {
if (IsNullPosition() || second.IsNullPosition())
return CreateNullPosition();
- if (GetAnchor() == second.GetAnchor())
+ if (GetOpaqueAnchor() == second.GetOpaqueAnchor())
return Clone();
std::stack<AXPositionInstance> ancestors1;
- ancestors1.push(std::move(Clone()));
+ ancestors1.push(Clone());
while (!ancestors1.top()->IsNullPosition())
- ancestors1.push(std::move(ancestors1.top()->CreateParentPosition()));
+ ancestors1.push(ancestors1.top()->CreateParentPosition());
std::stack<AXPositionInstance> ancestors2;
- ancestors2.push(std::move(second.Clone()));
+ ancestors2.push(second.Clone());
while (!ancestors2.top()->IsNullPosition())
- ancestors2.push(std::move(ancestors2.top()->CreateParentPosition()));
+ ancestors2.push(ancestors2.top()->CreateParentPosition());
AXPositionInstance common_ancestor;
while (!ancestors1.empty() && !ancestors2.empty() &&
- ancestors1.top()->GetAnchor() == ancestors2.top()->GetAnchor()) {
+ ancestors1.top()->GetOpaqueAnchor() ==
+ ancestors2.top()->GetOpaqueAnchor()) {
common_ancestor = std::move(ancestors1.top());
ancestors1.pop();
ancestors2.pop();
@@ -665,7 +651,7 @@ class AXPosition {
// be in the shadow DOM if the original position was not.
AXPositionInstance common_ancestor =
text_position->LowestCommonAncestor(*this);
- if (GetAnchor() == common_ancestor->GetAnchor())
+ if (GetOpaqueAnchor() == common_ancestor->GetOpaqueAnchor())
text_position = std::move(common_ancestor);
if (was_tree_position)
@@ -714,7 +700,7 @@ class AXPosition {
// be in the shadow DOM if the original position was not.
AXPositionInstance common_ancestor =
text_position->LowestCommonAncestor(*this);
- if (GetAnchor() == common_ancestor->GetAnchor())
+ if (GetOpaqueAnchor() == common_ancestor->GetOpaqueAnchor())
text_position = std::move(common_ancestor);
if (was_tree_position)
@@ -760,7 +746,7 @@ class AXPosition {
// be in the shadow DOM if the original position was not.
AXPositionInstance common_ancestor =
text_position->LowestCommonAncestor(*this);
- if (GetAnchor() == common_ancestor->GetAnchor())
+ if (GetOpaqueAnchor() == common_ancestor->GetOpaqueAnchor())
text_position = std::move(common_ancestor);
if (was_tree_position)
@@ -808,7 +794,7 @@ class AXPosition {
// be in the shadow DOM if the original position was not.
AXPositionInstance common_ancestor =
text_position->LowestCommonAncestor(*this);
- if (GetAnchor() == common_ancestor->GetAnchor())
+ if (GetOpaqueAnchor() == common_ancestor->GetOpaqueAnchor())
text_position = std::move(common_ancestor);
if (was_tree_position)
@@ -842,7 +828,7 @@ class AXPosition {
// be in the shadow DOM if the original position was not.
AXPositionInstance common_ancestor =
text_position->LowestCommonAncestor(*this);
- if (GetAnchor() == common_ancestor->GetAnchor())
+ if (GetOpaqueAnchor() == common_ancestor->GetOpaqueAnchor())
text_position = std::move(common_ancestor);
if (was_tree_position)
@@ -874,7 +860,7 @@ class AXPosition {
// be in the shadow DOM if the original position was not.
AXPositionInstance common_ancestor =
text_position->LowestCommonAncestor(*this);
- if (GetAnchor() == common_ancestor->GetAnchor())
+ if (GetOpaqueAnchor() == common_ancestor->GetOpaqueAnchor())
text_position = std::move(common_ancestor);
if (was_tree_position)
@@ -914,7 +900,7 @@ class AXPosition {
// be in the shadow DOM if the original position was not.
AXPositionInstance common_ancestor =
text_position->LowestCommonAncestor(*this);
- if (GetAnchor() == common_ancestor->GetAnchor())
+ if (GetOpaqueAnchor() == common_ancestor->GetOpaqueAnchor())
text_position = std::move(common_ancestor);
if (was_tree_position)
@@ -950,7 +936,7 @@ class AXPosition {
// be in the shadow DOM if the original position was not.
AXPositionInstance common_ancestor =
text_position->LowestCommonAncestor(*this);
- if (GetAnchor() == common_ancestor->GetAnchor())
+ if (GetOpaqueAnchor() == common_ancestor->GetOpaqueAnchor())
text_position = std::move(common_ancestor);
if (was_tree_position)
@@ -967,16 +953,15 @@ class AXPosition {
virtual base::string16 GetInnerText() const = 0;
protected:
- AXPosition(const AXPosition<AXPositionType, AXNodeType>& other) = default;
- virtual AXPosition<AXPositionType, AXNodeType>& operator=(
- const AXPosition<AXPositionType, AXNodeType>& other) = default;
-
- virtual void Initialize(AXPositionKind kind,
- int tree_id,
- int32_t anchor_id,
- int child_index,
- int text_offset,
- AXTextAffinity affinity) {
+ AXPositionBase(const AXPositionBase& other) = default;
+ virtual AXPositionBase& operator=(const AXPositionBase& other) = default;
+
+ void Initialize(AXPositionKind kind,
+ int tree_id,
+ int32_t anchor_id,
+ int child_index,
+ int text_offset,
+ AXTextAffinity affinity) {
kind_ = kind;
tree_id_ = tree_id;
anchor_id_ = anchor_id;
@@ -984,7 +969,7 @@ class AXPosition {
text_offset_ = text_offset;
affinity_ = affinity;
- if (!GetAnchor() || kind_ == AXPositionKind::NULL_POSITION ||
+ if (!GetOpaqueAnchor() || kind_ == AXPositionKind::NULL_POSITION ||
(kind_ == AXPositionKind::TREE_POSITION &&
(child_index_ != BEFORE_TEXT &&
(child_index_ < 0 || child_index_ > AnchorChildCount()))) ||
@@ -1091,14 +1076,15 @@ class AXPosition {
virtual int AnchorChildCount() const = 0;
virtual int AnchorIndexInParent() const = 0;
virtual void AnchorParent(int* tree_id, int32_t* parent_id) const = 0;
- virtual AXNodeType* GetNodeInTree(int tree_id, int32_t node_id) const = 0;
+ virtual OpaqueAnchor GetOpaqueNodeInTree(int tree_id,
+ int32_t node_id) const = 0;
// Returns the length of the text that is present inside the anchor node,
// including any text found in descendant text nodes.
virtual int MaxTextOffset() const = 0;
// Returns the length of text that this anchor node takes up in its parent.
// On some platforms, embedded objects are represented in their parent with a
// single embedded object character.
- virtual int MaxTextOffsetInParent() const { return MaxTextOffset(); }
+ virtual int MaxTextOffsetInParent() const;
virtual bool IsInLineBreak() const = 0;
virtual std::vector<int32_t> GetWordStartOffsets() const = 0;
virtual std::vector<int32_t> GetWordEndOffsets() const = 0;
@@ -1121,77 +1107,80 @@ class AXPosition {
};
template <class AXPositionType, class AXNodeType>
-const int AXPosition<AXPositionType, AXNodeType>::INVALID_TREE_ID;
-template <class AXPositionType, class AXNodeType>
-const int32_t AXPosition<AXPositionType, AXNodeType>::INVALID_ANCHOR_ID;
-template <class AXPositionType, class AXNodeType>
-const int AXPosition<AXPositionType, AXNodeType>::BEFORE_TEXT;
-template <class AXPositionType, class AXNodeType>
-const int AXPosition<AXPositionType, AXNodeType>::INVALID_INDEX;
-template <class AXPositionType, class AXNodeType>
-const int AXPosition<AXPositionType, AXNodeType>::INVALID_OFFSET;
+class AXPosition : public AXPositionBase {
+ public:
+ using AXPositionInstance = AXPositionBase::AXPositionInstance;
+ using ConcreteNodeType = AXNodeType;
+ using ConcreteInstance =
+ std::unique_ptr<AXPosition<AXPositionType, AXNodeType>>;
-template <class AXPositionType, class AXNodeType>
-bool operator==(const AXPosition<AXPositionType, AXNodeType>& first,
- const AXPosition<AXPositionType, AXNodeType>& second) {
- if (first.IsNullPosition() && second.IsNullPosition())
- return true;
- return first.tree_id() == second.tree_id() &&
- first.anchor_id() == second.anchor_id() &&
- first.child_index() == second.child_index() &&
- first.text_offset() == second.text_offset() &&
- first.affinity() == second.affinity();
-}
+ static ConcreteInstance CreateConcreteNullPosition() {
+ ConcreteInstance new_position(new AXPositionType());
+ new_position->Initialize(AXPositionKind::NULL_POSITION, INVALID_TREE_ID,
+ INVALID_ANCHOR_ID, INVALID_INDEX, INVALID_OFFSET,
+ AX_TEXT_AFFINITY_DOWNSTREAM);
+ return new_position;
+ }
-template <class AXPositionType, class AXNodeType>
-bool operator!=(const AXPosition<AXPositionType, AXNodeType>& first,
- const AXPosition<AXPositionType, AXNodeType>& second) {
- return !(first == second);
-}
+ static ConcreteInstance CreateConcreteTreePosition(int tree_id,
+ int32_t anchor_id,
+ int child_index) {
+ ConcreteInstance new_position(new AXPositionType());
+ new_position->Initialize(AXPositionKind::TREE_POSITION, tree_id, anchor_id,
+ child_index, INVALID_OFFSET,
+ AX_TEXT_AFFINITY_DOWNSTREAM);
+ return new_position;
+ }
-template <class AXPositionType, class AXNodeType>
-bool operator<(const AXPosition<AXPositionType, AXNodeType>& first,
- const AXPosition<AXPositionType, AXNodeType>& second) {
- if (first.IsNullPosition() || second.IsNullPosition())
- return false;
+ static ConcreteInstance CreateConcreteTextPosition(int tree_id,
+ int32_t anchor_id,
+ int text_offset,
+ AXTextAffinity affinity) {
+ ConcreteInstance new_position(new AXPositionType());
+ new_position->Initialize(AXPositionKind::TEXT_POSITION, tree_id, anchor_id,
+ INVALID_INDEX, text_offset, affinity);
+ return new_position;
+ }
- std::unique_ptr<AXPosition<AXPositionType, AXNodeType>> first_ancestor =
- first.LowestCommonAncestor(second)->AsTreePosition();
- std::unique_ptr<AXPosition<AXPositionType, AXNodeType>> second_ancestor =
- second.LowestCommonAncestor(first)->AsTreePosition();
- DCHECK_EQ(first_ancestor->GetAnchor(), second_ancestor->GetAnchor());
- return !first_ancestor->IsNullPosition() &&
- first_ancestor->AsTextPosition()->text_offset() <
- second_ancestor->AsTextPosition()->text_offset();
-}
+ static ConcreteInstance FromBase(AXPositionInstance instance) {
+ return ConcreteInstance(static_cast<AXPosition*>(instance.release()));
+ }
-template <class AXPositionType, class AXNodeType>
-bool operator<=(const AXPosition<AXPositionType, AXNodeType>& first,
- const AXPosition<AXPositionType, AXNodeType>& second) {
- return first == second || first < second;
-}
+ AXNodeType* GetAnchor() const {
+ return static_cast<AXNodeType*>(GetOpaqueAnchor());
+ }
+ virtual ConcreteInstance CloneConcrete() const = 0;
+ virtual AXNodeType* GetNodeInTree(int tree_id, int32_t node_id) const = 0;
-template <class AXPositionType, class AXNodeType>
-bool operator>(const AXPosition<AXPositionType, AXNodeType>& first,
- const AXPosition<AXPositionType, AXNodeType>& second) {
- if (first.IsNullPosition() || second.IsNullPosition())
- return false;
+ AXPositionInstance Clone() const override {
+ return base::WrapUnique<AXPositionBase>(CloneConcrete().release());
+ }
+ virtual OpaqueAnchor GetOpaqueNodeInTree(int tree_id, int32_t node_id) const {
+ return GetNodeInTree(tree_id, node_id);
+ }
- std::unique_ptr<AXPosition<AXPositionType, AXNodeType>> first_ancestor =
- first.LowestCommonAncestor(second)->AsTreePosition();
- std::unique_ptr<AXPosition<AXPositionType, AXNodeType>> second_ancestor =
- second.LowestCommonAncestor(first)->AsTreePosition();
- DCHECK_EQ(first_ancestor->GetAnchor(), second_ancestor->GetAnchor());
- return !first_ancestor->IsNullPosition() &&
- first_ancestor->AsTextPosition()->text_offset() >
- second_ancestor->AsTextPosition()->text_offset();
-}
+ AXPositionInstance CreateNullPosition() const override {
+ return base::WrapUnique<AXPositionBase>(
+ CreateConcreteNullPosition().release());
+ }
-template <class AXPositionType, class AXNodeType>
-bool operator>=(const AXPosition<AXPositionType, AXNodeType>& first,
- const AXPosition<AXPositionType, AXNodeType>& second) {
- return first == second || first > second;
-}
+ AXPositionInstance CreateTreePosition(int tree_id,
+ int32_t anchor_id,
+ int child_index) const override {
+ return base::WrapUnique<AXPositionBase>(
+ CreateConcreteTreePosition(tree_id, anchor_id, child_index).release());
+ }
+
+ AXPositionInstance CreateTextPosition(
+ int tree_id,
+ int32_t anchor_id,
+ int text_offset,
+ AXTextAffinity affinity) const override {
+ return base::WrapUnique<AXPositionBase>(
+ CreateConcreteTextPosition(tree_id, anchor_id, text_offset, affinity)
+ .release());
+ }
+};
} // namespace ui
« no previous file with comments | « ui/accessibility/ax_node_position_unittest.cc ('k') | ui/accessibility/ax_position.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698