| // Copyright 2020 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. |
| |
| #include "ui/accessibility/platform/ax_event_intent_mac.h" |
| |
| #include "ui/accessibility/ax_enums.mojom.h" |
| #include "ui/accessibility/ax_event_intent.h" |
| |
| namespace ui { |
| |
| // static |
| AXTextSelection AXTextSelection::FromDirectionAndGranularity( |
| ax::mojom::TextBoundary text_boundary, |
| ax::mojom::MoveDirection move_direction) { |
| bool has_stayed_within_same_text_unit = false; |
| AXTextSelectionDirection direction = AXTextSelectionDirection::kDiscontiguous; |
| AXTextSelectionGranularity granularity = AXTextSelectionGranularity::kUnknown; |
| |
| switch (text_boundary) { |
| case ax::mojom::TextBoundary::kNone: |
| break; |
| case ax::mojom::TextBoundary::kCharacter: |
| granularity = AXTextSelectionGranularity::kCharacter; |
| break; |
| case ax::mojom::TextBoundary::kFormat: |
| break; // Not supported on Mac. |
| case ax::mojom::TextBoundary::kLineEnd: |
| granularity = AXTextSelectionGranularity::kLine; |
| break; |
| case ax::mojom::TextBoundary::kLineStart: |
| granularity = AXTextSelectionGranularity::kLine; |
| break; |
| case ax::mojom::TextBoundary::kLineStartOrEnd: |
| has_stayed_within_same_text_unit = true; |
| granularity = AXTextSelectionGranularity::kLine; |
| break; |
| case ax::mojom::TextBoundary::kObject: |
| break; |
| case ax::mojom::TextBoundary::kPageEnd: |
| granularity = AXTextSelectionGranularity::kPage; |
| break; |
| case ax::mojom::TextBoundary::kPageStart: |
| granularity = AXTextSelectionGranularity::kPage; |
| break; |
| case ax::mojom::TextBoundary::kPageStartOrEnd: |
| has_stayed_within_same_text_unit = true; |
| granularity = AXTextSelectionGranularity::kPage; |
| break; |
| case ax::mojom::TextBoundary::kParagraphEnd: |
| granularity = AXTextSelectionGranularity::kParagraph; |
| break; |
| case ax::mojom::TextBoundary::kParagraphStart: |
| granularity = AXTextSelectionGranularity::kParagraph; |
| break; |
| case ax::mojom::TextBoundary::kParagraphStartOrEnd: |
| has_stayed_within_same_text_unit = true; |
| granularity = AXTextSelectionGranularity::kParagraph; |
| break; |
| case ax::mojom::TextBoundary::kSentenceEnd: |
| granularity = AXTextSelectionGranularity::kSentence; |
| break; |
| case ax::mojom::TextBoundary::kSentenceStart: |
| granularity = AXTextSelectionGranularity::kSentence; |
| break; |
| case ax::mojom::TextBoundary::kSentenceStartOrEnd: |
| has_stayed_within_same_text_unit = true; |
| granularity = AXTextSelectionGranularity::kSentence; |
| break; |
| case ax::mojom::TextBoundary::kWebPage: |
| has_stayed_within_same_text_unit = true; |
| granularity = AXTextSelectionGranularity::kDocument; |
| break; |
| case ax::mojom::TextBoundary::kWordEnd: |
| granularity = AXTextSelectionGranularity::kWord; |
| break; |
| case ax::mojom::TextBoundary::kWordStart: |
| granularity = AXTextSelectionGranularity::kWord; |
| break; |
| case ax::mojom::TextBoundary::kWordStartOrEnd: |
| has_stayed_within_same_text_unit = true; |
| granularity = AXTextSelectionGranularity::kWord; |
| break; |
| } |
| |
| switch (move_direction) { |
| case ax::mojom::MoveDirection::kNone: |
| break; |
| case ax::mojom::MoveDirection::kBackward: |
| if (has_stayed_within_same_text_unit) { |
| direction = AXTextSelectionDirection::kBeginning; |
| } else { |
| direction = AXTextSelectionDirection::kPrevious; |
| } |
| break; |
| case ax::mojom::MoveDirection::kForward: |
| if (has_stayed_within_same_text_unit) { |
| direction = AXTextSelectionDirection::kEnd; |
| } else { |
| direction = AXTextSelectionDirection::kNext; |
| } |
| break; |
| } |
| |
| return AXTextSelection(direction, granularity, /* focus_change */ false); |
| } |
| |
| AXTextSelection::AXTextSelection() = default; |
| |
| AXTextSelection::AXTextSelection(AXTextSelectionDirection direction, |
| AXTextSelectionGranularity granularity, |
| bool focus_change) |
| : direction(direction), |
| granularity(granularity), |
| focus_change(focus_change) {} |
| |
| AXTextSelection::AXTextSelection(const AXTextSelection& selection) = default; |
| |
| AXTextSelection::~AXTextSelection() = default; |
| |
| AXTextSelection& AXTextSelection::operator=(const AXTextSelection& selection) = |
| default; |
| |
| // static |
| AXTextStateChangeIntent |
| AXTextStateChangeIntent::DefaultFocusTextStateChangeIntent() { |
| return AXTextStateChangeIntent( |
| AXTextStateChangeType::kSelectionMove, |
| AXTextSelection(AXTextSelectionDirection::kDiscontiguous, |
| AXTextSelectionGranularity::kUnknown, |
| /* focus_change */ true)); |
| } |
| |
| // static |
| AXTextStateChangeIntent |
| AXTextStateChangeIntent::DefaultSelectionChangeIntent() { |
| return AXTextStateChangeIntent( |
| AXTextStateChangeType::kSelectionMove, |
| AXTextSelection(AXTextSelectionDirection::kDiscontiguous, |
| AXTextSelectionGranularity::kUnknown, |
| /* focus_change */ false)); |
| } |
| |
| AXTextStateChangeIntent::AXTextStateChangeIntent() = default; |
| |
| AXTextStateChangeIntent::AXTextStateChangeIntent(AXTextStateChangeType type, |
| AXTextSelection selection) |
| : type(type), selection(selection) {} |
| |
| AXTextStateChangeIntent::AXTextStateChangeIntent(AXTextEditType edit) |
| : type(AXTextStateChangeType::kEdit), edit(edit) {} |
| |
| AXTextStateChangeIntent::AXTextStateChangeIntent( |
| const AXTextStateChangeIntent& intent) = default; |
| |
| AXTextStateChangeIntent::~AXTextStateChangeIntent() = default; |
| |
| AXTextStateChangeIntent& AXTextStateChangeIntent::operator=( |
| const AXTextStateChangeIntent& intent) = default; |
| |
| AXTextStateChangeIntent FromEventIntent(const AXEventIntent& event_intent) { |
| switch (event_intent.command) { |
| case ax::mojom::Command::kNone: |
| return AXTextStateChangeIntent(); // An unknown intent. |
| case ax::mojom::Command::kClearSelection: |
| return AXTextStateChangeIntent::DefaultSelectionChangeIntent(); |
| case ax::mojom::Command::kDelete: |
| switch (event_intent.input_event_type) { |
| case ax::mojom::InputEventType::kDeleteByCut: |
| case ax::mojom::InputEventType::kDeleteByDrag: |
| return AXTextStateChangeIntent(AXTextEditType::kCut); |
| default: |
| return AXTextStateChangeIntent(AXTextEditType::kDelete); |
| } |
| break; |
| case ax::mojom::Command::kDictate: |
| return AXTextStateChangeIntent(AXTextEditType::kDictation); |
| case ax::mojom::Command::kExtendSelection: |
| return AXTextStateChangeIntent( |
| AXTextStateChangeType::kSelectionExtend, |
| AXTextSelection::FromDirectionAndGranularity( |
| event_intent.text_boundary, event_intent.move_direction)); |
| case ax::mojom::Command::kFormat: |
| return AXTextStateChangeIntent(AXTextEditType::kAttributesChange); |
| case ax::mojom::Command::kHistory: |
| return AXTextStateChangeIntent(); // Not currently implemented on Mac. |
| case ax::mojom::Command::kInsert: |
| switch (event_intent.input_event_type) { |
| case ax::mojom::InputEventType::kInsertText: |
| case ax::mojom::InputEventType::kInsertLineBreak: |
| case ax::mojom::InputEventType::kInsertParagraph: |
| case ax::mojom::InputEventType::kInsertHorizontalRule: |
| return AXTextStateChangeIntent(AXTextEditType::kTyping); |
| case ax::mojom::InputEventType::kInsertFromPaste: |
| case ax::mojom::InputEventType::kInsertFromDrop: |
| case ax::mojom::InputEventType::kInsertFromYank: |
| return AXTextStateChangeIntent(AXTextEditType::kPaste); |
| default: |
| return AXTextStateChangeIntent(AXTextEditType::kInsert); |
| } |
| break; |
| case ax::mojom::Command::kMarker: |
| return AXTextStateChangeIntent(); // Not currently implemented on Mac. |
| case ax::mojom::Command::kMoveSelection: |
| // Mac calls a "kSelectionBoundary" an operation that moves the caret |
| // within an editable element by a given text unit, e.g. by word. |
| return AXTextStateChangeIntent( |
| AXTextStateChangeType::kSelectionBoundary, |
| AXTextSelection::FromDirectionAndGranularity( |
| event_intent.text_boundary, event_intent.move_direction)); |
| case ax::mojom::Command::kSetSelection: |
| // Mac calls a "kSelectionMove" an operation that sets the selection to a |
| // completely new location, such as tabbing to an edit field. |
| if (event_intent.text_boundary == ax::mojom::TextBoundary::kNone) { |
| // No granularity information is available. This means that focus must |
| // have moved to another control, or a new selection has been made using |
| // the mouse or touch in the same control. In the latter case, we'll |
| // also pretend that focus has changed. |
| return AXTextStateChangeIntent::DefaultFocusTextStateChangeIntent(); |
| } |
| |
| return AXTextStateChangeIntent( |
| AXTextStateChangeType::kSelectionMove, |
| AXTextSelection::FromDirectionAndGranularity( |
| event_intent.text_boundary, event_intent.move_direction)); |
| } |
| } |
| |
| } // namespace ui |