Flutter Engine
The Flutter Engine
Classes | Public Types | Public Member Functions | Static Public Member Functions | List of all members
ui::AXRange< AXPositionType > Class Template Reference

#include <ax_range.h>

Classes

class  Iterator
 

Public Types

using AXPositionInstance = std::unique_ptr< AXPositionType >
 

Public Member Functions

 AXRange ()
 
 AXRange (AXPositionInstance anchor, AXPositionInstance focus)
 
 AXRange (const AXRange &other)=delete
 
 AXRange (AXRange &&other)
 
virtual ~AXRange ()=default
 
AXPositionType * anchor () const
 
AXPositionType * focus () const
 
AXRangeoperator= (const AXRange &other)=delete
 
AXRangeoperator= (AXRange &&other)
 
bool operator== (const AXRange &other) const
 
bool operator!= (const AXRange &other) const
 
AXRange AsForwardRange () const
 
AXRange AsBackwardRange () const
 
bool IsCollapsed () const
 
bool IsLeafTextRange () const
 
bool IsNull () const
 
std::string ToString () const
 
Iterator begin () const
 
Iterator end () const
 
std::u16string GetText (AXTextConcatenationBehavior concatenation_behavior=AXTextConcatenationBehavior::kAsTextContent, int max_count=-1, bool include_ignored=false, size_t *appended_newlines_count=nullptr) const
 
std::vector< gfx::RectGetRects (AXRangeRectDelegate *delegate) const
 

Static Public Member Functions

static std::optional< intCompareEndpoints (const AXPositionType *first, const AXPositionType *second)
 

Detailed Description

template<class AXPositionType>
class ui::AXRange< AXPositionType >

Definition at line 51 of file ax_range.h.

Member Typedef Documentation

◆ AXPositionInstance

template<class AXPositionType >
using ui::AXRange< AXPositionType >::AXPositionInstance = std::unique_ptr<AXPositionType>

Definition at line 53 of file ax_range.h.

Constructor & Destructor Documentation

◆ AXRange() [1/4]

template<class AXPositionType >
ui::AXRange< AXPositionType >::AXRange ( )
inline

Definition at line 55 of file ax_range.h.

56 : anchor_(AXPositionType::CreateNullPosition()),
57 focus_(AXPositionType::CreateNullPosition()) {}

◆ AXRange() [2/4]

template<class AXPositionType >
ui::AXRange< AXPositionType >::AXRange ( AXPositionInstance  anchor,
AXPositionInstance  focus 
)
inline

Definition at line 59 of file ax_range.h.

59 {
60 anchor_ = anchor ? std::move(anchor) : AXPositionType::CreateNullPosition();
61 focus_ = focus ? std::move(focus) : AXPositionType::CreateNullPosition();
62 }
AXPositionType * anchor() const
Definition: ax_range.h:73
AXPositionType * focus() const
Definition: ax_range.h:78

◆ AXRange() [3/4]

template<class AXPositionType >
ui::AXRange< AXPositionType >::AXRange ( const AXRange< AXPositionType > &  other)
delete

◆ AXRange() [4/4]

template<class AXPositionType >
ui::AXRange< AXPositionType >::AXRange ( AXRange< AXPositionType > &&  other)
inline

Definition at line 66 of file ax_range.h.

66 : AXRange() {
67 anchor_.swap(other.anchor_);
68 focus_.swap(other.focus_);
69 }

◆ ~AXRange()

template<class AXPositionType >
virtual ui::AXRange< AXPositionType >::~AXRange ( )
virtualdefault

Member Function Documentation

◆ anchor()

template<class AXPositionType >
AXPositionType * ui::AXRange< AXPositionType >::anchor ( ) const
inline

Definition at line 73 of file ax_range.h.

73 {
74 BASE_DCHECK(anchor_);
75 return anchor_.get();
76 }
#define BASE_DCHECK(condition)
Definition: logging.h:63

◆ AsBackwardRange()

template<class AXPositionType >
AXRange ui::AXRange< AXPositionType >::AsBackwardRange ( ) const
inline

Definition at line 135 of file ax_range.h.

135 {
136 return (CompareEndpoints(anchor(), focus()).value_or(0) < 0)
137 ? AXRange(focus_->Clone(), anchor_->Clone())
138 : AXRange(anchor_->Clone(), focus_->Clone());
139 }
static std::optional< int > CompareEndpoints(const AXPositionType *first, const AXPositionType *second)
Definition: ax_range.h:117

◆ AsForwardRange()

template<class AXPositionType >
AXRange ui::AXRange< AXPositionType >::AsForwardRange ( ) const
inline

Definition at line 129 of file ax_range.h.

129 {
130 return (CompareEndpoints(anchor(), focus()).value_or(0) > 0)
131 ? AXRange(focus_->Clone(), anchor_->Clone())
132 : AXRange(anchor_->Clone(), focus_->Clone());
133 }

◆ begin()

template<class AXPositionType >
Iterator ui::AXRange< AXPositionType >::begin ( ) const
inline

Definition at line 258 of file ax_range.h.

258 {
259 if (IsNull())
260 return Iterator(nullptr, nullptr);
261 AXRange forward_range = AsForwardRange();
262 return Iterator(std::move(forward_range.anchor_),
263 std::move(forward_range.focus_));
264 }
AXRange AsForwardRange() const
Definition: ax_range.h:129
bool IsNull() const
Definition: ax_range.h:150

◆ CompareEndpoints()

template<class AXPositionType >
static std::optional< int > ui::AXRange< AXPositionType >::CompareEndpoints ( const AXPositionType *  first,
const AXPositionType *  second 
)
inlinestatic

Definition at line 117 of file ax_range.h.

118 {
119 std::optional<int> tree_position_comparison =
120 first->AsTreePosition()->CompareTo(*second->AsTreePosition());
121
122 // When the tree comparison is nullopt, using value_or(1) forces a default
123 // value of 1, making the following statement return nullopt as well.
124 return (tree_position_comparison.value_or(1) != 0)
125 ? tree_position_comparison
126 : first->CompareTo(*second);
127 }

◆ end()

template<class AXPositionType >
Iterator ui::AXRange< AXPositionType >::end ( ) const
inline

Definition at line 266 of file ax_range.h.

266 {
267 if (IsNull())
268 return Iterator(nullptr, nullptr);
269 AXRange forward_range = AsForwardRange();
270 return Iterator(nullptr, std::move(forward_range.focus_));
271 }

◆ focus()

template<class AXPositionType >
AXPositionType * ui::AXRange< AXPositionType >::focus ( ) const
inline

Definition at line 78 of file ax_range.h.

78 {
79 BASE_DCHECK(focus_);
80 return focus_.get();
81 }

◆ GetRects()

template<class AXPositionType >
std::vector< gfx::Rect > ui::AXRange< AXPositionType >::GetRects ( AXRangeRectDelegate delegate) const
inline

Definition at line 378 of file ax_range.h.

378 {
379 std::vector<gfx::Rect> rects;
380
381 for (const AXRange& leaf_text_range : *this) {
382 BASE_DCHECK(leaf_text_range.IsLeafTextRange());
383 AXPositionType* current_line_start = leaf_text_range.anchor();
384 AXPositionType* current_line_end = leaf_text_range.focus();
385
386 // For text anchors, we retrieve the bounding rectangles of its text
387 // content. For non-text anchors (such as checkboxes, images, etc.), we
388 // want to directly retrieve their bounding rectangles.
389 AXOffscreenResult offscreen_result;
390 gfx::Rect current_rect =
391 (current_line_start->IsInLineBreak() ||
392 current_line_start->IsInTextObject())
393 ? delegate->GetInnerTextRangeBoundsRect(
394 current_line_start->tree_id(),
395 current_line_start->anchor_id(),
396 current_line_start->text_offset(),
397 current_line_end->text_offset(),
398 ui::AXClippingBehavior::kUnclipped, &offscreen_result)
399 : delegate->GetBoundsRect(current_line_start->tree_id(),
400 current_line_start->anchor_id(),
401 &offscreen_result);
402
403 // If the bounding box of the current range is clipped because it lies
404 // outside an ancestor’s bounds, then the bounding box is pushed to the
405 // nearest edge of such ancestor's bounds, with its width and height
406 // forced to be 1, and the node will be marked as "offscreen".
407 //
408 // Only add rectangles that are not empty and not marked as "offscreen".
409 //
410 // See the documentation for how bounding boxes are calculated in AXTree:
411 // https://chromium.googlesource.com/chromium/src/+/HEAD/docs/accessibility/offscreen.md
412 if (!current_rect.IsEmpty() &&
413 offscreen_result == AXOffscreenResult::kOnscreen)
414 rects.push_back(current_rect);
415 }
416 return rects;
417 }
Definition: rect.h:36
bool IsEmpty() const
Definition: rect.h:140

◆ GetText()

template<class AXPositionType >
std::u16string ui::AXRange< AXPositionType >::GetText ( AXTextConcatenationBehavior  concatenation_behavior = AXTextConcatenationBehavior::kAsTextContent,
int  max_count = -1,
bool  include_ignored = false,
size_t *  appended_newlines_count = nullptr 
) const
inline

Definition at line 278 of file ax_range.h.

282 {
283 if (max_count == 0 || IsNull())
284 return std::u16string();
285
286 std::optional<int> endpoint_comparison =
288 if (!endpoint_comparison)
289 return std::u16string();
290
291 AXPositionInstance start = (endpoint_comparison.value() < 0)
292 ? anchor_->AsLeafTextPosition()
293 : focus_->AsLeafTextPosition();
294 AXPositionInstance end = (endpoint_comparison.value() < 0)
295 ? focus_->AsLeafTextPosition()
296 : anchor_->AsLeafTextPosition();
297
298 std::u16string range_text;
299 size_t computed_newlines_count = 0;
300 bool is_first_non_whitespace_leaf = true;
301 bool crossed_paragraph_boundary = false;
302 bool is_first_unignored_leaf = true;
303 bool found_trailing_newline = false;
304
305 while (!start->IsNullPosition()) {
306 BASE_DCHECK(start->IsLeafTextPosition());
307 BASE_DCHECK(start->text_offset() >= 0);
308
309 if (include_ignored || !start->IsIgnored()) {
310 if (concatenation_behavior ==
312 !start->IsInWhiteSpace()) {
313 if (is_first_non_whitespace_leaf) {
314 // The first non-whitespace leaf in the range could be preceded by
315 // whitespace spanning even before the start of this range, we need
316 // to check such positions in order to correctly determine if this
317 // is a paragraph's start (see |AXPosition::AtStartOfParagraph|).
318 crossed_paragraph_boundary =
319 !is_first_unignored_leaf && start->AtStartOfParagraph();
320 }
321
322 // When preserving layout line breaks, don't append `\n` next if the
323 // previous leaf position was a <br> (already ending with a newline).
324 if (crossed_paragraph_boundary && !found_trailing_newline) {
325 range_text += base::ASCIIToUTF16("\n");
326 computed_newlines_count++;
327 }
328
329 is_first_non_whitespace_leaf = false;
330 crossed_paragraph_boundary = false;
331 }
332
333 int current_end_offset = (start->GetAnchor() != end->GetAnchor())
334 ? start->MaxTextOffset()
335 : end->text_offset();
336
337 if (current_end_offset > start->text_offset()) {
338 int characters_to_append =
339 (max_count > 0)
340 ? std::min(max_count - static_cast<int>(range_text.length()),
341 current_end_offset - start->text_offset())
342 : current_end_offset - start->text_offset();
343
344 range_text += start->GetText().substr(start->text_offset(),
345 characters_to_append);
346
347 // Collapse all whitespace following any line break.
348 found_trailing_newline =
349 start->IsInLineBreak() ||
350 (found_trailing_newline && start->IsInWhiteSpace());
351 }
352
353 BASE_DCHECK(max_count < 0 ||
354 static_cast<int>(range_text.length()) <= max_count);
355 is_first_unignored_leaf = false;
356 }
357
358 if (start->GetAnchor() == end->GetAnchor() ||
359 static_cast<int>(range_text.length()) == max_count) {
360 break;
361 } else if (concatenation_behavior ==
363 !crossed_paragraph_boundary && !is_first_non_whitespace_leaf) {
364 start = start->CreateNextLeafTextPosition(&crossed_paragraph_boundary);
365 } else {
366 start = start->CreateNextLeafTextPosition();
367 }
368 }
369
370 if (appended_newlines_count)
371 *appended_newlines_count = computed_newlines_count;
372 return range_text;
373 }
Iterator end() const
Definition: ax_range.h:266
std::unique_ptr< AXPositionType > AXPositionInstance
Definition: ax_range.h:53
static float min(float r, float g, float b)
Definition: hsl.cpp:48
std::u16string ASCIIToUTF16(std::string src)
Definition: string_utils.cc:63

◆ IsCollapsed()

template<class AXPositionType >
bool ui::AXRange< AXPositionType >::IsCollapsed ( ) const
inline

Definition at line 141 of file ax_range.h.

141{ return !IsNull() && *anchor_ == *focus_; }

◆ IsLeafTextRange()

template<class AXPositionType >
bool ui::AXRange< AXPositionType >::IsLeafTextRange ( ) const
inline

Definition at line 145 of file ax_range.h.

145 {
146 return !IsNull() && anchor_->GetAnchor() == focus_->GetAnchor() &&
147 anchor_->IsLeafTextPosition() && focus_->IsLeafTextPosition();
148 }

◆ IsNull()

template<class AXPositionType >
bool ui::AXRange< AXPositionType >::IsNull ( ) const
inline

Definition at line 150 of file ax_range.h.

150 {
151 BASE_DCHECK(anchor_ && focus_);
152 return anchor_->IsNullPosition() || focus_->IsNullPosition();
153 }

◆ operator!=()

template<class AXPositionType >
bool ui::AXRange< AXPositionType >::operator!= ( const AXRange< AXPositionType > &  other) const
inline

Definition at line 102 of file ax_range.h.

102{ return !(*this == other); }

◆ operator=() [1/2]

template<class AXPositionType >
AXRange & ui::AXRange< AXPositionType >::operator= ( AXRange< AXPositionType > &&  other)
inline

Definition at line 85 of file ax_range.h.

85 {
86 if (this != &other) {
87 anchor_ = AXPositionType::CreateNullPosition();
88 focus_ = AXPositionType::CreateNullPosition();
89 anchor_.swap(other.anchor_);
90 focus_.swap(other.focus_);
91 }
92 return *this;
93 }

◆ operator=() [2/2]

template<class AXPositionType >
AXRange & ui::AXRange< AXPositionType >::operator= ( const AXRange< AXPositionType > &  other)
delete

◆ operator==()

template<class AXPositionType >
bool ui::AXRange< AXPositionType >::operator== ( const AXRange< AXPositionType > &  other) const
inline

Definition at line 95 of file ax_range.h.

95 {
96 if (IsNull())
97 return other.IsNull();
98 return !other.IsNull() && *anchor_ == *other.anchor() &&
99 *focus_ == *other.focus();
100 }

◆ ToString()

template<class AXPositionType >
std::string ui::AXRange< AXPositionType >::ToString ( ) const
inline

Definition at line 155 of file ax_range.h.

155 {
156 return "Range\nAnchor:" + anchor_->ToString() +
157 "\nFocus:" + focus_->ToString();
158 }

The documentation for this class was generated from the following files: