Commit 48831bf2 authored by Nektarios Paisios's avatar Nektarios Paisios Committed by Commit Bot

Implements selection behavior that determines how AXRange is mapped to a DOM range

Still preliminary until patches implementing tree ordering operators on AXObject and support for aria-labels and alt text positions are in.
R=dmazzoni@chromium.org

Change-Id: Ia19131b53d8a20d299a431695641b11ddc805280
Reviewed-on: https://chromium-review.googlesource.com/954182
Commit-Queue: Nektarios Paisios <nektar@chromium.org>
Reviewed-by: default avatarNektarios Paisios <nektar@chromium.org>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#547299}
parent cb273cd9
...@@ -223,11 +223,41 @@ bool AXPosition::IsTextPosition() const { ...@@ -223,11 +223,41 @@ bool AXPosition::IsTextPosition() const {
return IsValid() && container_object_->GetNode()->IsTextNode(); return IsValid() && container_object_->GetNode()->IsTextNode();
} }
const PositionWithAffinity AXPosition::ToPositionWithAffinity() const { const AXPosition AXPosition::CreateNextPosition() const {
if (IsTextPosition()) {
if (!ContainerObject()->NextInTreeObject())
return {};
return CreatePositionBeforeObject(*ContainerObject()->NextInTreeObject());
}
if (!ObjectAfterPosition())
return {};
return CreatePositionBeforeObject(*ObjectAfterPosition());
}
const AXPosition AXPosition::CreatePreviousPosition() const {
if (!ContainerObject()->PreviousInTreeObject())
return {};
return CreatePositionAfterObject(*ContainerObject()->PreviousInTreeObject());
}
const PositionWithAffinity AXPosition::ToPositionWithAffinity(
const AXPositionAdjustmentBehavior adjustment_behavior) const {
if (!IsValid()) if (!IsValid())
return {}; return {};
const Node* container_node = container_object_->GetNode(); const Node* container_node = container_object_->GetNode();
if (!container_node) {
switch (adjustment_behavior) {
case AXPositionAdjustmentBehavior::kMoveRight:
CreateNextPosition().ToPositionWithAffinity(adjustment_behavior);
break;
case AXPositionAdjustmentBehavior::kMoveLeft:
CreatePreviousPosition().ToPositionWithAffinity(adjustment_behavior);
break;
}
}
if (!IsTextPosition()) { if (!IsTextPosition()) {
if (ChildIndex() == if (ChildIndex() ==
static_cast<int>(container_object_->Children().size())) { static_cast<int>(container_object_->Children().size())) {
......
...@@ -20,6 +20,11 @@ namespace blink { ...@@ -20,6 +20,11 @@ namespace blink {
class AXObject; class AXObject;
// When converting to a DOM position from an |AXPosition| and the corresponding
// DOM position is invalid or doesn't exist, determines how to adjust the
// |AXPosition| in order to make it valid.
enum class AXPositionAdjustmentBehavior { kMoveLeft, kMoveRight };
// Describes a position in the Blink accessibility tree. // Describes a position in the Blink accessibility tree.
// A position is either anchored to before or after a child object inside a // A position is either anchored to before or after a child object inside a
// container object, or is anchored to a character inside a text object. // container object, or is anchored to a character inside a text object.
...@@ -58,7 +63,12 @@ class MODULES_EXPORT AXPosition final { ...@@ -58,7 +63,12 @@ class MODULES_EXPORT AXPosition final {
// object. // object.
bool IsTextPosition() const; bool IsTextPosition() const;
const PositionWithAffinity ToPositionWithAffinity() const; const AXPosition CreateNextPosition() const;
const AXPosition CreatePreviousPosition() const;
const PositionWithAffinity ToPositionWithAffinity(
const AXPositionAdjustmentBehavior =
AXPositionAdjustmentBehavior::kMoveLeft) const;
private: private:
AXPosition(); AXPosition();
......
...@@ -94,12 +94,38 @@ bool AXSelection::IsValid() const { ...@@ -94,12 +94,38 @@ bool AXSelection::IsValid() const {
return true; return true;
} }
const SelectionInDOMTree AXSelection::AsSelection() const { const SelectionInDOMTree AXSelection::AsSelection(
const AXSelectionBehavior selection_behavior) const {
if (!IsValid()) if (!IsValid())
return {}; return {};
const auto dom_base = base_.ToPositionWithAffinity(); AXPositionAdjustmentBehavior base_adjustment =
const auto dom_extent = extent_.ToPositionWithAffinity(); AXPositionAdjustmentBehavior::kMoveLeft;
AXPositionAdjustmentBehavior extent_adjustment =
AXPositionAdjustmentBehavior::kMoveLeft;
switch (selection_behavior) {
case AXSelectionBehavior::kShrinkToValidDOMRange:
if (base_ <= extent_) {
base_adjustment = AXPositionAdjustmentBehavior::kMoveRight;
extent_adjustment = AXPositionAdjustmentBehavior::kMoveLeft;
} else {
base_adjustment = AXPositionAdjustmentBehavior::kMoveLeft;
extent_adjustment = AXPositionAdjustmentBehavior::kMoveRight;
}
break;
case AXSelectionBehavior::kExtendToValidDOMRange:
if (base_ <= extent_) {
base_adjustment = AXPositionAdjustmentBehavior::kMoveLeft;
extent_adjustment = AXPositionAdjustmentBehavior::kMoveRight;
} else {
base_adjustment = AXPositionAdjustmentBehavior::kMoveRight;
extent_adjustment = AXPositionAdjustmentBehavior::kMoveLeft;
}
break;
}
const auto dom_base = base_.ToPositionWithAffinity(base_adjustment);
const auto dom_extent = extent_.ToPositionWithAffinity(extent_adjustment);
SelectionInDOMTree::Builder selection_builder; SelectionInDOMTree::Builder selection_builder;
selection_builder.SetBaseAndExtent(dom_base.GetPosition(), selection_builder.SetBaseAndExtent(dom_base.GetPosition(),
dom_extent.GetPosition()); dom_extent.GetPosition());
...@@ -107,13 +133,13 @@ const SelectionInDOMTree AXSelection::AsSelection() const { ...@@ -107,13 +133,13 @@ const SelectionInDOMTree AXSelection::AsSelection() const {
return selection_builder.Build(); return selection_builder.Build();
} }
void AXSelection::Select() { void AXSelection::Select(const AXSelectionBehavior selection_behavior) {
if (!IsValid()) { if (!IsValid()) {
NOTREACHED(); NOTREACHED();
return; return;
} }
const SelectionInDOMTree selection = AsSelection(); const SelectionInDOMTree selection = AsSelection(selection_behavior);
DCHECK(selection.AssertValid()); DCHECK(selection.AssertValid());
Document* document = selection.Base().GetDocument(); Document* document = selection.Base().GetDocument();
if (!document) { if (!document) {
......
...@@ -16,6 +16,15 @@ ...@@ -16,6 +16,15 @@
namespace blink { namespace blink {
// If the |AXSelection| is defined by endpoints that are present in the
// accessibility tree but not in the DOM tree, determines whether setting the
// selection will shrink or extend the |AXSelection| to encompass endpoints that
// are in the DOM.
enum class AXSelectionBehavior {
kShrinkToValidDOMRange,
kExtendToValidDOMRange
};
class MODULES_EXPORT AXSelection final { class MODULES_EXPORT AXSelection final {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
...@@ -33,10 +42,13 @@ class MODULES_EXPORT AXSelection final { ...@@ -33,10 +42,13 @@ class MODULES_EXPORT AXSelection final {
// invalid, or if the positions are in two separate documents. // invalid, or if the positions are in two separate documents.
bool IsValid() const; bool IsValid() const;
const SelectionInDOMTree AsSelection() const; const SelectionInDOMTree AsSelection(
const AXSelectionBehavior =
AXSelectionBehavior::kExtendToValidDOMRange) const;
// Tries to set the DOM selection to this. // Tries to set the DOM selection to this.
void Select(); void Select(
const AXSelectionBehavior = AXSelectionBehavior::kExtendToValidDOMRange);
private: private:
AXSelection(); AXSelection();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment