| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "modules/accessibility/AXRange.h" |
| 6 |
| 7 #include "core/dom/AXObjectCache.h" |
| 8 #include "core/editing/FrameSelection.h" |
| 9 #include "core/editing/Position.h" |
| 10 #include "core/editing/SelectionTemplate.h" |
| 11 #include "core/frame/LocalFrame.h" |
| 12 #include "core/html/TextControlElement.h" |
| 13 #include "modules/accessibility/AXObject.h" |
| 14 #include "modules/accessibility/AXObjectCacheImpl.h" |
| 15 |
| 16 namespace blink { |
| 17 |
| 18 AXRange::AXRange(VisibleSelectionInFlatTree& selection) : AXRange() { |
| 19 if (!selection.IsNonOrphanedCaretOrRange()) |
| 20 return; |
| 21 PositionInFlatTree base = selection.VisibleBase().ToParentAnchoredPosition(); |
| 22 PositionInFlatTree extent = |
| 23 selection.VisibleExtent().ToParentAnchoredPosition(); |
| 24 Document* document = base.GetDocument(); |
| 25 if (!document || document != extent.GetDocument()) |
| 26 return; |
| 27 AXObjectCache* ax_object_cache = document->AxObjectCache(); |
| 28 if (!ax_object_cache) |
| 29 return; |
| 30 |
| 31 AXObjectCacheImpl* ax_object_cache_impl = |
| 32 static_cast<AXObjectCacheImpl*>(ax_object_cache); |
| 33 anchor_object_ = ax_object_cache_impl->GetOrCreate(base.AnchorNode()); |
| 34 anchor_offset_ = base.OffsetInContainerNode(); |
| 35 focus_object_ = ax_object_cache_impl->GetOrCreate(extent.AnchorNode()); |
| 36 focus_offset_ = extent.OffsetInContainerNode(); |
| 37 affinity_ = selection.Affinity(); |
| 38 } |
| 39 |
| 40 bool AXRange::IsValid() const { |
| 41 if (!anchor_object_ || !focus_object_ || anchor_offset_ < 0 || |
| 42 focus_offset_ < 0) { |
| 43 return false; |
| 44 } |
| 45 if (anchor_object_->IsDetached() || focus_object_->IsDetached()) |
| 46 return false; |
| 47 if (!anchor_object_->GetNode() || !focus_object_->GetNode() || |
| 48 !anchor_object_->GetNode()->isConnected() || |
| 49 !focus_object_->GetNode()->isConnected()) { |
| 50 return false; |
| 51 } |
| 52 // We don't support ranges that span across documents. |
| 53 if (anchor_object_->GetDocument() != focus_object_->GetDocument()) |
| 54 return false; |
| 55 return true; |
| 56 } |
| 57 |
| 58 VisibleSelectionInFlatTree AXRange::AsVisibleSelectionInFlatTree() const { |
| 59 if (!IsValid()) |
| 60 return VisibleSelectionInFlatTree(); |
| 61 PositionInFlatTree base = PositionInFlatTree::EditingPositionOf( |
| 62 anchor_object_->GetNode(), anchor_offset_); |
| 63 PositionInFlatTree extent = PositionInFlatTree::EditingPositionOf( |
| 64 focus_object_->GetNode(), focus_offset_); |
| 65 SelectionInFlatTree::Builder selection_builder; |
| 66 selection_builder.SetBaseAndExtent(base, extent); |
| 67 selection_builder.SetAffinity(affinity_); |
| 68 return CreateVisibleSelection(selection_builder.Build()); |
| 69 } |
| 70 |
| 71 void AXRange::Select() { |
| 72 if (!IsValid()) |
| 73 return; |
| 74 if (IsSimple() && IsTextControlElement(focus_object_->GetNode())) { |
| 75 TextControlElement* text_control = |
| 76 ToTextControlElement(focus_object_->GetNode()); |
| 77 if (anchor_offset_ <= focus_offset_) { |
| 78 text_control->SetSelectionRange(anchor_offset_, focus_offset_, |
| 79 kSelectionHasForwardDirection); |
| 80 } else { |
| 81 text_control->SetSelectionRange(anchor_offset_, focus_offset_, |
| 82 kSelectionHasBackwardDirection); |
| 83 } |
| 84 return; |
| 85 } |
| 86 |
| 87 SelectionInFlatTree selection = AsVisibleSelectionInFlatTree().AsSelection(); |
| 88 DCHECK(selection.AssertValid()); |
| 89 Document* document = selection.Base().GetDocument(); |
| 90 if (!document) |
| 91 return; |
| 92 LocalFrame* frame = document->GetFrame(); |
| 93 if (!frame) |
| 94 return; |
| 95 FrameSelection& frame_selection = frame->Selection(); |
| 96 frame_selection.SetSelection(selection); |
| 97 } |
| 98 |
| 99 } // namespace blink |
| OLD | NEW |