forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ax_range.h
116 lines (93 loc) · 2.94 KB
/
ax_range.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// 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.
#ifndef UI_ACCESSIBILITY_AX_RANGE_H_
#define UI_ACCESSIBILITY_AX_RANGE_H_
#include <memory>
#include <utility>
#include "base/strings/string16.h"
namespace ui {
// A range of ax positions.
//
// In order to avoid any confusion regarding whether a deep or a shallow copy is
// being performed, this class can be moved but not copied.
template <class AXPositionType>
class AXRange {
public:
AXRange()
: anchor_(AXPositionType::CreateNullPosition()),
focus_(AXPositionType::CreateNullPosition()) {}
AXRange(std::unique_ptr<AXPositionType> anchor,
std::unique_ptr<AXPositionType> focus) {
if (anchor) {
anchor_ = std::move(anchor);
} else {
anchor_ = AXPositionType::CreateNullPosition();
}
if (focus) {
focus_ = std::move(focus);
} else {
focus = AXPositionType::CreateNullPosition();
}
}
AXRange(const AXRange& other) = delete;
AXRange(AXRange&& other) : AXRange() {
anchor_.swap(other.anchor_);
focus_.swap(other.focus_);
}
AXRange& operator=(const AXRange& other) = delete;
AXRange& operator=(const AXRange&& other) {
if (this != other) {
anchor_ = AXPositionType::CreateNullPosition();
focus_ = AXPositionType::CreateNullPosition();
anchor_.swap(other.anchor_);
focus_.swap(other.focus_);
}
return *this;
}
virtual ~AXRange() {}
bool IsNull() const {
return !anchor_ || !focus_ || anchor_->IsNullPosition() ||
focus_->IsNullPosition();
}
AXPositionType* anchor() const {
DCHECK(anchor_);
return anchor_.get();
}
AXPositionType* focus() const {
DCHECK(focus_);
return focus_.get();
}
base::string16 GetText() const {
base::string16 text;
if (IsNull())
return text;
std::unique_ptr<AXPositionType> start, end;
if (*anchor_ < *focus_) {
start = anchor_->AsLeafTextPosition();
end = focus_->AsLeafTextPosition();
} else {
start = focus_->AsLeafTextPosition();
end = anchor_->AsLeafTextPosition();
}
int start_offset = start->text_offset();
DCHECK_GE(start_offset, 0);
int end_offset = end->text_offset();
DCHECK_GE(end_offset, 0);
do {
text += start->GetInnerText();
start = start->CreateNextTextAnchorPosition();
} while (!start->IsNullPosition() && *start <= *end);
if (static_cast<size_t>(start_offset) > text.length())
return base::string16();
text = text.substr(start_offset, base::string16::npos);
size_t text_length = text.length() - end->GetInnerText().length() +
static_cast<size_t>(end_offset);
return text.substr(0, text_length);
}
private:
std::unique_ptr<AXPositionType> anchor_;
std::unique_ptr<AXPositionType> focus_;
};
} // namespace ui
#endif // UI_ACCESSIBILITY_AX_RANGE_H_