| Index: third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
|
| diff --git a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
|
| index b5aec8edff793ec59181233ac71434ae9484578d..50d23d71df04d06bde367ca4b1228810907691c4 100644
|
| --- a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
|
| +++ b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
|
| @@ -37,7 +37,6 @@
|
| #include "core/dom/shadow/ShadowRoot.h"
|
| #include "core/editing/EditingUtilities.h"
|
| #include "core/editing/FrameSelection.h"
|
| -#include "core/editing/RenderedPosition.h"
|
| #include "core/editing/TextAffinity.h"
|
| #include "core/editing/VisibleUnits.h"
|
| #include "core/editing/iterators/CharacterIterator.h"
|
| @@ -1723,313 +1722,6 @@ Element* AXLayoutObject::AnchorElement() const {
|
| return 0;
|
| }
|
|
|
| -//
|
| -// Functions that retrieve the current selection.
|
| -//
|
| -
|
| -AXObjectImpl::AXRange AXLayoutObject::Selection() const {
|
| - AXRange text_selection = TextControlSelection();
|
| - if (text_selection.IsValid())
|
| - return text_selection;
|
| -
|
| - if (!GetLayoutObject() || !GetLayoutObject()->GetFrame())
|
| - return AXRange();
|
| -
|
| - VisibleSelection selection =
|
| - GetLayoutObject()
|
| - ->GetFrame()
|
| - ->Selection()
|
| - .ComputeVisibleSelectionInDOMTreeDeprecated();
|
| - if (selection.IsNone())
|
| - return AXRange();
|
| -
|
| - VisiblePosition visible_start = selection.VisibleStart();
|
| - Position start = visible_start.ToParentAnchoredPosition();
|
| - TextAffinity start_affinity = visible_start.Affinity();
|
| - VisiblePosition visible_end = selection.VisibleEnd();
|
| - Position end = visible_end.ToParentAnchoredPosition();
|
| - TextAffinity end_affinity = visible_end.Affinity();
|
| -
|
| - Node* anchor_node = start.AnchorNode();
|
| - DCHECK(anchor_node);
|
| -
|
| - AXLayoutObject* anchor_object = nullptr;
|
| - // Find the closest node that has a corresponding AXObjectImpl.
|
| - // This is because some nodes may be aria hidden or might not even have
|
| - // a layout object if they are part of the shadow DOM.
|
| - while (anchor_node) {
|
| - anchor_object = GetUnignoredObjectFromNode(*anchor_node);
|
| - if (anchor_object)
|
| - break;
|
| -
|
| - if (anchor_node->nextSibling())
|
| - anchor_node = anchor_node->nextSibling();
|
| - else
|
| - anchor_node = anchor_node->parentNode();
|
| - }
|
| -
|
| - Node* focus_node = end.AnchorNode();
|
| - DCHECK(focus_node);
|
| -
|
| - AXLayoutObject* focus_object = nullptr;
|
| - while (focus_node) {
|
| - focus_object = GetUnignoredObjectFromNode(*focus_node);
|
| - if (focus_object)
|
| - break;
|
| -
|
| - if (focus_node->previousSibling())
|
| - focus_node = focus_node->previousSibling();
|
| - else
|
| - focus_node = focus_node->parentNode();
|
| - }
|
| -
|
| - if (!anchor_object || !focus_object)
|
| - return AXRange();
|
| -
|
| - int anchor_offset = anchor_object->IndexForVisiblePosition(visible_start);
|
| - DCHECK_GE(anchor_offset, 0);
|
| - int focus_offset = focus_object->IndexForVisiblePosition(visible_end);
|
| - DCHECK_GE(focus_offset, 0);
|
| - return AXRange(anchor_object, anchor_offset, start_affinity, focus_object,
|
| - focus_offset, end_affinity);
|
| -}
|
| -
|
| -// Gets only the start and end offsets of the selection computed using the
|
| -// current object as the starting point. Returns a null selection if there is
|
| -// no selection in the subtree rooted at this object.
|
| -AXObjectImpl::AXRange AXLayoutObject::SelectionUnderObject() const {
|
| - AXRange text_selection = TextControlSelection();
|
| - if (text_selection.IsValid())
|
| - return text_selection;
|
| -
|
| - if (!GetNode() || !GetLayoutObject()->GetFrame())
|
| - return AXRange();
|
| -
|
| - VisibleSelection selection =
|
| - GetLayoutObject()
|
| - ->GetFrame()
|
| - ->Selection()
|
| - .ComputeVisibleSelectionInDOMTreeDeprecated();
|
| - Range* selection_range = CreateRange(FirstEphemeralRangeOf(selection));
|
| - ContainerNode* parent_node = GetNode()->parentNode();
|
| - int node_index = GetNode()->NodeIndex();
|
| - if (!selection_range
|
| - // Selection is contained in node.
|
| - || !(parent_node &&
|
| - selection_range->comparePoint(parent_node, node_index,
|
| - IGNORE_EXCEPTION_FOR_TESTING) < 0 &&
|
| - selection_range->comparePoint(parent_node, node_index + 1,
|
| - IGNORE_EXCEPTION_FOR_TESTING) > 0)) {
|
| - return AXRange();
|
| - }
|
| -
|
| - int start = IndexForVisiblePosition(selection.VisibleStart());
|
| - DCHECK_GE(start, 0);
|
| - int end = IndexForVisiblePosition(selection.VisibleEnd());
|
| - DCHECK_GE(end, 0);
|
| -
|
| - return AXRange(start, end);
|
| -}
|
| -
|
| -AXObjectImpl::AXRange AXLayoutObject::TextControlSelection() const {
|
| - if (!GetLayoutObject())
|
| - return AXRange();
|
| -
|
| - LayoutObject* layout = nullptr;
|
| - if (GetLayoutObject()->IsTextControl()) {
|
| - layout = GetLayoutObject();
|
| - } else {
|
| - Element* focused_element = GetDocument()->FocusedElement();
|
| - if (focused_element && focused_element->GetLayoutObject() &&
|
| - focused_element->GetLayoutObject()->IsTextControl())
|
| - layout = focused_element->GetLayoutObject();
|
| - }
|
| -
|
| - if (!layout)
|
| - return AXRange();
|
| -
|
| - AXObjectImpl* ax_object = AxObjectCache().GetOrCreate(layout);
|
| - if (!ax_object || !ax_object->IsAXLayoutObject())
|
| - return AXRange();
|
| -
|
| - VisibleSelection selection =
|
| - layout->GetFrame()
|
| - ->Selection()
|
| - .ComputeVisibleSelectionInDOMTreeDeprecated();
|
| - TextControlElement* text_control =
|
| - ToLayoutTextControl(layout)->GetTextControlElement();
|
| - DCHECK(text_control);
|
| - int start = text_control->selectionStart();
|
| - int end = text_control->selectionEnd();
|
| -
|
| - return AXRange(ax_object, start, selection.VisibleStart().Affinity(),
|
| - ax_object, end, selection.VisibleEnd().Affinity());
|
| -}
|
| -
|
| -int AXLayoutObject::IndexForVisiblePosition(
|
| - const VisiblePosition& position) const {
|
| - if (GetLayoutObject() && GetLayoutObject()->IsTextControl()) {
|
| - TextControlElement* text_control =
|
| - ToLayoutTextControl(GetLayoutObject())->GetTextControlElement();
|
| - return text_control->IndexForVisiblePosition(position);
|
| - }
|
| -
|
| - if (!GetNode())
|
| - return 0;
|
| -
|
| - Position index_position = position.DeepEquivalent();
|
| - if (index_position.IsNull())
|
| - return 0;
|
| -
|
| - Range* range = Range::Create(*GetDocument());
|
| - range->setStart(GetNode(), 0, IGNORE_EXCEPTION_FOR_TESTING);
|
| - range->setEnd(index_position, IGNORE_EXCEPTION_FOR_TESTING);
|
| -
|
| - return TextIterator::RangeLength(range->StartPosition(),
|
| - range->EndPosition());
|
| -}
|
| -
|
| -AXLayoutObject* AXLayoutObject::GetUnignoredObjectFromNode(Node& node) const {
|
| - if (IsDetached())
|
| - return nullptr;
|
| -
|
| - AXObjectImpl* ax_object = AxObjectCache().GetOrCreate(&node);
|
| - if (!ax_object)
|
| - return nullptr;
|
| -
|
| - if (ax_object->IsAXLayoutObject() && !ax_object->AccessibilityIsIgnored())
|
| - return ToAXLayoutObject(ax_object);
|
| -
|
| - return nullptr;
|
| -}
|
| -
|
| -//
|
| -// Modify or take an action on an object.
|
| -//
|
| -
|
| -// Convert from an accessible object and offset to a VisiblePosition.
|
| -static VisiblePosition ToVisiblePosition(AXObjectImpl* obj, int offset) {
|
| - if (!obj->GetNode())
|
| - return VisiblePosition();
|
| -
|
| - Node* node = obj->GetNode();
|
| - if (!node->IsTextNode()) {
|
| - int child_count = obj->Children().size();
|
| -
|
| - // Place position immediately before the container node, if there was no
|
| - // children.
|
| - if (child_count == 0) {
|
| - if (!obj->ParentObject())
|
| - return VisiblePosition();
|
| - return ToVisiblePosition(obj->ParentObject(), obj->IndexInParent());
|
| - }
|
| -
|
| - // The offsets are child offsets over the AX tree. Note that we allow
|
| - // for the offset to equal the number of children as |Range| does.
|
| - if (offset < 0 || offset > child_count)
|
| - return VisiblePosition();
|
| -
|
| - // Clamp to between 0 and child count - 1.
|
| - int clamped_offset =
|
| - static_cast<unsigned>(offset) > (obj->Children().size() - 1)
|
| - ? offset - 1
|
| - : offset;
|
| - AXObjectImpl* child_obj = obj->Children()[clamped_offset];
|
| - Node* child_node = child_obj->GetNode();
|
| - if (!child_node || !child_node->parentNode())
|
| - return VisiblePosition();
|
| -
|
| - // The index in parent.
|
| - int adjusted_offset = child_node->NodeIndex();
|
| -
|
| - // If we had to clamp the offset above, the client wants to select the
|
| - // end of the node.
|
| - if (clamped_offset != offset)
|
| - adjusted_offset++;
|
| -
|
| - return CreateVisiblePosition(
|
| - Position::EditingPositionOf(child_node->parentNode(), adjusted_offset));
|
| - }
|
| -
|
| - // If it is a text node, we need to call some utility functions that use a
|
| - // TextIterator to walk the characters of the node and figure out the position
|
| - // corresponding to the visible character at position |offset|.
|
| - ContainerNode* parent = node->parentNode();
|
| - if (!parent)
|
| - return VisiblePosition();
|
| -
|
| - VisiblePosition node_position = blink::VisiblePositionBeforeNode(*node);
|
| - int node_index = blink::IndexForVisiblePosition(node_position, parent);
|
| - return blink::VisiblePositionForIndex(node_index + offset, parent);
|
| -}
|
| -
|
| -void AXLayoutObject::SetSelection(const AXRange& selection) {
|
| - if (!GetLayoutObject() || !selection.IsValid())
|
| - return;
|
| -
|
| - AXObjectImpl* anchor_object =
|
| - selection.anchor_object ? selection.anchor_object.Get() : this;
|
| - AXObjectImpl* focus_object =
|
| - selection.focus_object ? selection.focus_object.Get() : this;
|
| -
|
| - if (!IsValidSelectionBound(anchor_object) ||
|
| - !IsValidSelectionBound(focus_object)) {
|
| - return;
|
| - }
|
| -
|
| - // The selection offsets are offsets into the accessible value.
|
| - if (anchor_object == focus_object &&
|
| - anchor_object->GetLayoutObject()->IsTextControl()) {
|
| - TextControlElement* text_control =
|
| - ToLayoutTextControl(anchor_object->GetLayoutObject())
|
| - ->GetTextControlElement();
|
| - if (selection.anchor_offset <= selection.focus_offset) {
|
| - text_control->SetSelectionRange(selection.anchor_offset,
|
| - selection.focus_offset,
|
| - kSelectionHasForwardDirection);
|
| - } else {
|
| - text_control->SetSelectionRange(selection.focus_offset,
|
| - selection.anchor_offset,
|
| - kSelectionHasBackwardDirection);
|
| - }
|
| - return;
|
| - }
|
| -
|
| - LocalFrame* frame = GetLayoutObject()->GetFrame();
|
| - if (!frame)
|
| - return;
|
| -
|
| - // TODO(editing-dev): Use of updateStyleAndLayoutIgnorePendingStylesheets
|
| - // needs to be audited. see http://crbug.com/590369 for more details.
|
| - // This callsite should probably move up the stack.
|
| - frame->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
|
| -
|
| - // Set the selection based on visible positions, because the offsets in
|
| - // accessibility nodes are based on visible indexes, which often skips
|
| - // redundant whitespace, for example.
|
| - VisiblePosition anchor_visible_position =
|
| - ToVisiblePosition(anchor_object, selection.anchor_offset);
|
| - VisiblePosition focus_visible_position =
|
| - ToVisiblePosition(focus_object, selection.focus_offset);
|
| - if (anchor_visible_position.IsNull() || focus_visible_position.IsNull())
|
| - return;
|
| -
|
| - frame->Selection().SetSelection(
|
| - SelectionInDOMTree::Builder()
|
| - .Collapse(anchor_visible_position.ToPositionWithAffinity())
|
| - .Extend(focus_visible_position.DeepEquivalent())
|
| - .Build());
|
| -}
|
| -
|
| -bool AXLayoutObject::IsValidSelectionBound(
|
| - const AXObjectImpl* bound_object) const {
|
| - return GetLayoutObject() && bound_object && !bound_object->IsDetached() &&
|
| - bound_object->IsAXLayoutObject() && bound_object->GetLayoutObject() &&
|
| - bound_object->GetLayoutObject()->GetFrame() ==
|
| - GetLayoutObject()->GetFrame() &&
|
| - &bound_object->AxObjectCache() == &AxObjectCache();
|
| -}
|
| -
|
| void AXLayoutObject::SetValue(const String& string) {
|
| if (!GetNode() || !GetNode()->IsElementNode())
|
| return;
|
|
|