| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the QtWebEngine module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Lesser General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Lesser |
| ** General Public License version 3 as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
| ** packaging of this file. Please review the following information to |
| ** ensure the GNU Lesser General Public License version 3 requirements |
| ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 2.0 or (at your option) the GNU General |
| ** Public license version 3 or any later version approved by the KDE Free |
| ** Qt Foundation. The licenses are as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
| ** https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| // Copyright (c) 2012 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.Chromium file. |
| |
| #include "browser_accessibility_qt.h" |
| |
| #if QT_CONFIG(accessibility) |
| |
| #include "ui/accessibility/ax_enums.mojom.h" |
| |
| #include "browser_accessibility_manager_qt.h" |
| #include "qtwebenginecoreglobal_p.h" |
| #include "type_conversion.h" |
| |
| using namespace blink; |
| using QtWebEngineCore::toQt; |
| |
| namespace content { |
| |
| const BrowserAccessibilityQt *ToBrowserAccessibilityQt(const BrowserAccessibility *obj) |
| { |
| return static_cast<const BrowserAccessibilityQt *>(obj); |
| } |
| |
| QAccessibleInterface *toQAccessibleInterface(BrowserAccessibility *obj) |
| { |
| return static_cast<BrowserAccessibilityQt *>(obj); |
| } |
| |
| BrowserAccessibilityQt::BrowserAccessibilityQt() |
| { |
| QAccessible::registerAccessibleInterface(this); |
| } |
| |
| bool BrowserAccessibilityQt::isValid() const |
| { |
| auto managerQt = static_cast<BrowserAccessibilityManagerQt *>(manager_); |
| return managerQt && managerQt->isValid(); |
| } |
| |
| QObject *BrowserAccessibilityQt::object() const |
| { |
| return 0; |
| } |
| |
| QAccessibleInterface *BrowserAccessibilityQt::childAt(int x, int y) const |
| { |
| for (int i = 0; i < childCount(); ++i) { |
| QAccessibleInterface *childIface = child(i); |
| Q_ASSERT(childIface); |
| if (childIface->rect().contains(x,y)) |
| return childIface; |
| } |
| return 0; |
| } |
| |
| void *BrowserAccessibilityQt::interface_cast(QAccessible::InterfaceType type) |
| { |
| switch (type) { |
| case QAccessible::ActionInterface: |
| if (!actionNames().isEmpty()) |
| return static_cast<QAccessibleActionInterface*>(this); |
| break; |
| case QAccessible::TextInterface: |
| if (HasState(ax::mojom::State::kEditable)) |
| return static_cast<QAccessibleTextInterface*>(this); |
| break; |
| case QAccessible::ValueInterface: { |
| QAccessible::Role r = role(); |
| if (r == QAccessible::ProgressBar || |
| r == QAccessible::Slider || |
| r == QAccessible::ScrollBar || |
| r == QAccessible::SpinBox) |
| return static_cast<QAccessibleValueInterface*>(this); |
| break; |
| } |
| case QAccessible::TableInterface: { |
| QAccessible::Role r = role(); |
| if (r == QAccessible::Table || |
| r == QAccessible::List || |
| r == QAccessible::Tree) |
| return static_cast<QAccessibleTableInterface*>(this); |
| break; |
| } |
| case QAccessible::TableCellInterface: { |
| QAccessible::Role r = role(); |
| if (r == QAccessible::Cell || |
| r == QAccessible::ListItem || |
| r == QAccessible::TreeItem) |
| return static_cast<QAccessibleTableCellInterface*>(this); |
| break; |
| } |
| default: |
| break; |
| } |
| return 0; |
| } |
| |
| QAccessibleInterface *BrowserAccessibilityQt::parent() const |
| { |
| BrowserAccessibility *p = PlatformGetParent(); |
| if (p) |
| return static_cast<BrowserAccessibilityQt*>(p); |
| return static_cast<BrowserAccessibilityManagerQt*>(manager())->rootParentAccessible(); |
| } |
| |
| QAccessibleInterface *BrowserAccessibilityQt::child(int index) const |
| { |
| return static_cast<BrowserAccessibilityQt*>(BrowserAccessibility::PlatformGetChild(index)); |
| } |
| |
| QAccessibleInterface *BrowserAccessibilityQt::focusChild() const |
| { |
| if (state().focused) |
| return const_cast<BrowserAccessibilityQt *>(this); |
| |
| for (int i = 0; i < childCount(); ++i) { |
| if (QAccessibleInterface *iface = child(i)->focusChild()) |
| return iface; |
| } |
| |
| return nullptr; |
| } |
| |
| int BrowserAccessibilityQt::childCount() const |
| { |
| return PlatformChildCount(); |
| } |
| |
| int BrowserAccessibilityQt::indexOfChild(const QAccessibleInterface *iface) const |
| { |
| |
| const BrowserAccessibilityQt *child = static_cast<const BrowserAccessibilityQt*>(iface); |
| return const_cast<BrowserAccessibilityQt *>(child)->GetIndexInParent(); |
| } |
| |
| QString BrowserAccessibilityQt::text(QAccessible::Text t) const |
| { |
| switch (t) { |
| case QAccessible::Name: |
| return toQt(GetStringAttribute(ax::mojom::StringAttribute::kName)); |
| case QAccessible::Description: |
| return toQt(GetStringAttribute(ax::mojom::StringAttribute::kDescription)); |
| case QAccessible::Value: |
| return toQt(GetStringAttribute(ax::mojom::StringAttribute::kValue)); |
| case QAccessible::Accelerator: |
| return toQt(GetStringAttribute(ax::mojom::StringAttribute::kKeyShortcuts)); |
| default: |
| break; |
| } |
| return QString(); |
| } |
| |
| void BrowserAccessibilityQt::setText(QAccessible::Text t, const QString &text) |
| { |
| } |
| |
| QRect BrowserAccessibilityQt::rect() const |
| { |
| if (!manager()) // needed implicitly by GetScreenBoundsRect() |
| return QRect(); |
| gfx::Rect bounds = GetUnclippedScreenBoundsRect(); |
| return QRect(bounds.x(), bounds.y(), bounds.width(), bounds.height()); |
| } |
| |
| QAccessible::Role BrowserAccessibilityQt::role() const |
| { |
| switch (GetRole()) { |
| case ax::mojom::Role::kNone: |
| case ax::mojom::Role::kUnknown: |
| return QAccessible::NoRole; |
| |
| // Used by Chromium to distinguish between the root of the tree |
| // for this page, and a web area for a frame within this page. |
| case ax::mojom::Role::kWebArea: |
| case ax::mojom::Role::kWebView: |
| case ax::mojom::Role::kRootWebArea: // not sure if we need to make a diff here, but this seems common |
| return QAccessible::WebDocument; |
| |
| // These roles all directly correspond to blink accessibility roles, |
| // keep these alphabetical. |
| case ax::mojom::Role::kAbbr: |
| return QAccessible::StaticText; |
| case ax::mojom::Role::kAlert: |
| case ax::mojom::Role::kAlertDialog: |
| return QAccessible::AlertMessage; |
| case ax::mojom::Role::kAnchor: |
| return QAccessible::Link; |
| case ax::mojom::Role::kApplication: |
| return QAccessible::Document; // returning Application here makes Qt return the top level app object |
| case ax::mojom::Role::kArticle: |
| return QAccessible::Section; |
| case ax::mojom::Role::kAudio: |
| return QAccessible::Sound; |
| case ax::mojom::Role::kBanner: |
| return QAccessible::Section; |
| case ax::mojom::Role::kBlockquote: |
| return QAccessible::Section; |
| case ax::mojom::Role::kButton: |
| return QAccessible::Button; |
| case ax::mojom::Role::kCanvas: |
| return QAccessible::Canvas; |
| case ax::mojom::Role::kCaption: |
| return QAccessible::Heading; |
| case ax::mojom::Role::kCaret: |
| return QAccessible::NoRole; // FIXME: https://codereview.chromium.org/2781613003 |
| case ax::mojom::Role::kCell: |
| return QAccessible::Cell; |
| case ax::mojom::Role::kCheckBox: |
| return QAccessible::CheckBox; |
| case ax::mojom::Role::kClient: |
| return QAccessible::Client; |
| case ax::mojom::Role::kCode: |
| return QAccessible::StaticText; |
| case ax::mojom::Role::kColorWell: |
| return QAccessible::ColorChooser; |
| case ax::mojom::Role::kColumn: |
| return QAccessible::Column; |
| case ax::mojom::Role::kColumnHeader: |
| return QAccessible::ColumnHeader; |
| case ax::mojom::Role::kComboBoxGrouping: |
| case ax::mojom::Role::kComboBoxMenuButton: |
| case ax::mojom::Role::kTextFieldWithComboBox: |
| return QAccessible::ComboBox; |
| case ax::mojom::Role::kComplementary: |
| return QAccessible::ComplementaryContent; |
| case ax::mojom::Role::kComment: |
| case ax::mojom::Role::kCommentSection: |
| return QAccessible::Section; |
| case ax::mojom::Role::kContentDeletion: |
| case ax::mojom::Role::kContentInsertion: |
| return QAccessible::Grouping; |
| case ax::mojom::Role::kContentInfo: |
| return QAccessible::Section; |
| case ax::mojom::Role::kDate: |
| case ax::mojom::Role::kDateTime: |
| return QAccessible::Clock; |
| case ax::mojom::Role::kDefinition: |
| return QAccessible::Paragraph; |
| case ax::mojom::Role::kDescriptionList: |
| return QAccessible::List; |
| case ax::mojom::Role::kDescriptionListDetail: |
| return QAccessible::Paragraph; |
| case ax::mojom::Role::kDescriptionListTerm: |
| return QAccessible::ListItem; |
| case ax::mojom::Role::kDetails: |
| return QAccessible::Grouping; |
| case ax::mojom::Role::kDesktop: |
| return QAccessible::Pane; |
| case ax::mojom::Role::kDialog: |
| return QAccessible::Dialog; |
| case ax::mojom::Role::kDirectory: |
| return QAccessible::List; |
| case ax::mojom::Role::kDisclosureTriangle: |
| return QAccessible::Button; |
| case ax::mojom::Role::kGenericContainer: |
| return QAccessible::Section; |
| case ax::mojom::Role::kDocCover: |
| return QAccessible::Graphic; |
| case ax::mojom::Role::kDocBackLink: |
| case ax::mojom::Role::kDocBiblioRef: |
| case ax::mojom::Role::kDocGlossRef: |
| case ax::mojom::Role::kDocNoteRef: |
| return QAccessible::Link; |
| case ax::mojom::Role::kDocBiblioEntry: |
| case ax::mojom::Role::kDocEndnote: |
| case ax::mojom::Role::kDocFootnote: |
| return QAccessible::ListItem; |
| case ax::mojom::Role::kDocPageBreak: |
| return QAccessible::Separator; |
| case ax::mojom::Role::kDocAbstract: |
| case ax::mojom::Role::kDocAcknowledgments: |
| case ax::mojom::Role::kDocAfterword: |
| case ax::mojom::Role::kDocAppendix: |
| case ax::mojom::Role::kDocBibliography: |
| case ax::mojom::Role::kDocChapter: |
| case ax::mojom::Role::kDocColophon: |
| case ax::mojom::Role::kDocConclusion: |
| case ax::mojom::Role::kDocCredit: |
| case ax::mojom::Role::kDocCredits: |
| case ax::mojom::Role::kDocDedication: |
| case ax::mojom::Role::kDocEndnotes: |
| case ax::mojom::Role::kDocEpigraph: |
| case ax::mojom::Role::kDocEpilogue: |
| case ax::mojom::Role::kDocErrata: |
| case ax::mojom::Role::kDocExample: |
| case ax::mojom::Role::kDocForeword: |
| case ax::mojom::Role::kDocGlossary: |
| case ax::mojom::Role::kDocIndex: |
| case ax::mojom::Role::kDocIntroduction: |
| case ax::mojom::Role::kDocNotice: |
| case ax::mojom::Role::kDocPageList: |
| case ax::mojom::Role::kDocPart: |
| case ax::mojom::Role::kDocPreface: |
| case ax::mojom::Role::kDocPrologue: |
| case ax::mojom::Role::kDocPullquote: |
| case ax::mojom::Role::kDocQna: |
| return QAccessible::Section; |
| case ax::mojom::Role::kDocSubtitle: |
| return QAccessible::Heading; |
| case ax::mojom::Role::kDocTip: |
| case ax::mojom::Role::kDocToc: |
| return QAccessible::Section; |
| case ax::mojom::Role::kDocument: |
| return QAccessible::Document; |
| case ax::mojom::Role::kEmbeddedObject: |
| return QAccessible::Grouping; |
| case ax::mojom::Role::kEmphasis: |
| return QAccessible::StaticText; |
| case ax::mojom::Role::kFeed: |
| return QAccessible::Section; |
| case ax::mojom::Role::kFigcaption: |
| return QAccessible::Heading; |
| case ax::mojom::Role::kFigure: |
| return QAccessible::Section; |
| case ax::mojom::Role::kFooter: |
| return QAccessible::Footer; |
| case ax::mojom::Role::kFooterAsNonLandmark: |
| return QAccessible::Section; |
| case ax::mojom::Role::kForm: |
| return QAccessible::Form; |
| case ax::mojom::Role::kGraphicsDocument: |
| return QAccessible::Document; |
| case ax::mojom::Role::kGraphicsObject: |
| return QAccessible::Pane; |
| case ax::mojom::Role::kGraphicsSymbol: |
| return QAccessible::Graphic; |
| case ax::mojom::Role::kGrid: |
| return QAccessible::Table; |
| case ax::mojom::Role::kGroup: |
| return QAccessible::Grouping; |
| case ax::mojom::Role::kHeader: |
| case ax::mojom::Role::kHeaderAsNonLandmark: |
| return QAccessible::Section; |
| case ax::mojom::Role::kHeading: |
| return QAccessible::Heading; |
| case ax::mojom::Role::kIframe: |
| return QAccessible::WebDocument; |
| case ax::mojom::Role::kIframePresentational: |
| return QAccessible::Grouping; |
| case ax::mojom::Role::kIgnored: |
| return QAccessible::NoRole; |
| case ax::mojom::Role::kImage: |
| return QAccessible::Graphic; |
| case ax::mojom::Role::kImageMap: |
| return QAccessible::Document; |
| case ax::mojom::Role::kInlineTextBox: |
| return QAccessible::StaticText; |
| case ax::mojom::Role::kInputTime: |
| return QAccessible::SpinBox; |
| case ax::mojom::Role::kKeyboard: |
| return QAccessible::NoRole; // FIXME |
| case ax::mojom::Role::kLabelText: |
| return QAccessible::StaticText; |
| case ax::mojom::Role::kLayoutTable: |
| case ax::mojom::Role::kLayoutTableCell: |
| case ax::mojom::Role::kLayoutTableColumn: |
| case ax::mojom::Role::kLayoutTableRow: |
| return QAccessible::Section; |
| case ax::mojom::Role::kLegend: |
| return QAccessible::StaticText; |
| case ax::mojom::Role::kLineBreak: |
| return QAccessible::Separator; |
| case ax::mojom::Role::kLink: |
| return QAccessible::Link; |
| case ax::mojom::Role::kList: |
| return QAccessible::List; |
| case ax::mojom::Role::kListBox: |
| return QAccessible::ComboBox; |
| case ax::mojom::Role::kListBoxOption: |
| return QAccessible::ListItem; |
| case ax::mojom::Role::kListItem: |
| return QAccessible::ListItem; |
| case ax::mojom::Role::kListGrid: |
| return QAccessible::List; |
| case ax::mojom::Role::kListMarker: |
| return QAccessible::StaticText; |
| case ax::mojom::Role::kLog: |
| return QAccessible::Section; |
| case ax::mojom::Role::kMain: |
| return QAccessible::Grouping; |
| case ax::mojom::Role::kMark: |
| return QAccessible::StaticText; |
| case ax::mojom::Role::kMarquee: |
| return QAccessible::Section; |
| case ax::mojom::Role::kMath: |
| return QAccessible::Equation; |
| case ax::mojom::Role::kMenu: |
| return QAccessible::PopupMenu; |
| case ax::mojom::Role::kMenuBar: |
| return QAccessible::MenuBar; |
| case ax::mojom::Role::kMenuItem: |
| return QAccessible::MenuItem; |
| case ax::mojom::Role::kMenuItemCheckBox: |
| return QAccessible::CheckBox; |
| case ax::mojom::Role::kMenuItemRadio: |
| return QAccessible::RadioButton; |
| case ax::mojom::Role::kMenuButton: |
| return QAccessible::MenuItem; |
| case ax::mojom::Role::kMenuListOption: |
| return QAccessible::MenuItem; |
| case ax::mojom::Role::kMenuListPopup: |
| return QAccessible::PopupMenu; |
| case ax::mojom::Role::kMeter: |
| return QAccessible::Chart; |
| case ax::mojom::Role::kNavigation: |
| return QAccessible::Section; |
| case ax::mojom::Role::kNote: |
| return QAccessible::Note; |
| case ax::mojom::Role::kPane: |
| return QAccessible::Pane; |
| case ax::mojom::Role::kParagraph: |
| return QAccessible::Paragraph; |
| case ax::mojom::Role::kPopUpButton: |
| return QAccessible::ComboBox; |
| case ax::mojom::Role::kPre: |
| return QAccessible::Section; |
| case ax::mojom::Role::kPresentational: |
| return QAccessible::NoRole; // FIXME |
| case ax::mojom::Role::kProgressIndicator: |
| return QAccessible::ProgressBar; |
| case ax::mojom::Role::kRadioButton: |
| return QAccessible::RadioButton; |
| case ax::mojom::Role::kRadioGroup: |
| return QAccessible::Grouping; |
| case ax::mojom::Role::kRegion: |
| return QAccessible::Section; |
| case ax::mojom::Role::kRevision: |
| return QAccessible::Section; |
| case ax::mojom::Role::kRow: |
| return QAccessible::Row; |
| case ax::mojom::Role::kRowGroup: |
| return QAccessible::Section; |
| case ax::mojom::Role::kRowHeader: |
| return QAccessible::RowHeader; |
| case ax::mojom::Role::kRuby: |
| return QAccessible::StaticText; |
| case ax::mojom::Role::kRubyAnnotation: |
| return QAccessible::StaticText; |
| case ax::mojom::Role::kScrollBar: |
| return QAccessible::ScrollBar; |
| case ax::mojom::Role::kScrollView: |
| return QAccessible::Pane; |
| case ax::mojom::Role::kSearch: |
| return QAccessible::Section; |
| case ax::mojom::Role::kSearchBox: |
| return QAccessible::EditableText; |
| case ax::mojom::Role::kSection: |
| return QAccessible::Section; |
| case ax::mojom::Role::kSlider: |
| case ax::mojom::Role::kSliderThumb: |
| return QAccessible::Slider; |
| case ax::mojom::Role::kSpinButton: |
| return QAccessible::SpinBox; |
| case ax::mojom::Role::kSplitter: |
| return QAccessible::Splitter; |
| case ax::mojom::Role::kStaticText: |
| return QAccessible::StaticText; |
| case ax::mojom::Role::kStatus: |
| return QAccessible::Indicator; |
| case ax::mojom::Role::kStrong: |
| return QAccessible::StaticText; |
| case ax::mojom::Role::kSuggestion: |
| return QAccessible::Section; |
| case ax::mojom::Role::kSvgRoot: |
| return QAccessible::Graphic; |
| case ax::mojom::Role::kSwitch: |
| return QAccessible::Button; |
| case ax::mojom::Role::kTable: |
| return QAccessible::Table; |
| case ax::mojom::Role::kTableHeaderContainer: |
| return QAccessible::Section; |
| case ax::mojom::Role::kTab: |
| return QAccessible::PageTab; |
| case ax::mojom::Role::kTabList: |
| return QAccessible::PageTabList; |
| case ax::mojom::Role::kTabPanel: |
| return QAccessible::Pane; |
| case ax::mojom::Role::kTerm: |
| return QAccessible::StaticText; |
| case ax::mojom::Role::kTextField: |
| return QAccessible::EditableText; |
| case ax::mojom::Role::kTime: |
| case ax::mojom::Role::kTimer: |
| return QAccessible::Clock; |
| case ax::mojom::Role::kTitleBar: |
| return QAccessible::Document; |
| case ax::mojom::Role::kToggleButton: |
| return QAccessible::Button; |
| case ax::mojom::Role::kToolbar: |
| return QAccessible::ToolBar; |
| case ax::mojom::Role::kTooltip: |
| return QAccessible::ToolTip; |
| case ax::mojom::Role::kTree: |
| return QAccessible::Tree; |
| case ax::mojom::Role::kTreeGrid: |
| return QAccessible::Tree; |
| case ax::mojom::Role::kTreeItem: |
| return QAccessible::TreeItem; |
| case ax::mojom::Role::kVideo: |
| return QAccessible::Animation; |
| case ax::mojom::Role::kWindow: |
| return QAccessible::Window; |
| } |
| return QAccessible::NoRole; |
| } |
| |
| QAccessible::State BrowserAccessibilityQt::state() const |
| { |
| QAccessible::State state = QAccessible::State(); |
| if (HasState(ax::mojom::State::kCollapsed)) |
| state.collapsed = true; |
| if (HasState(ax::mojom::State::kDefault)) |
| state.defaultButton = true; |
| if (HasState(ax::mojom::State::kEditable)) |
| state.editable = true; |
| if (HasState(ax::mojom::State::kExpanded)) |
| state.expanded = true; |
| if (HasState(ax::mojom::State::kFocusable)) |
| state.focusable = true; |
| if (HasState(ax::mojom::State::kHorizontal)) |
| {} // FIXME |
| if (HasState(ax::mojom::State::kHovered)) |
| state.hotTracked = true; |
| if (HasState(ax::mojom::State::kIgnored)) |
| {} // FIXME |
| if (HasState(ax::mojom::State::kInvisible)) |
| state.invisible = true; |
| if (HasState(ax::mojom::State::kLinked)) |
| state.linked = true; |
| if (HasState(ax::mojom::State::kMultiline)) |
| state.multiLine = true; |
| if (HasState(ax::mojom::State::kMultiselectable)) |
| state.multiSelectable = true; |
| if (HasState(ax::mojom::State::kProtected)) |
| state.passwordEdit = true; |
| if (HasState(ax::mojom::State::kRequired)) |
| {} // FIXME |
| if (HasState(ax::mojom::State::kRichlyEditable)) |
| {} // FIXME |
| if (HasState(ax::mojom::State::kVertical)) |
| {} // FIXME |
| if (HasState(ax::mojom::State::kVisited)) |
| state.traversed = true; |
| |
| if (IsOffscreen()) |
| state.offscreen = true; |
| if (manager()->GetFocus() == this) |
| state.focused = true; |
| if (GetBoolAttribute(ax::mojom::BoolAttribute::kBusy)) |
| state.busy = true; |
| if (GetBoolAttribute(ax::mojom::BoolAttribute::kModal)) |
| state.modal = true; |
| if (HasBoolAttribute(ax::mojom::BoolAttribute::kSelected)) { |
| state.selectable = true; |
| state.selected = GetBoolAttribute(ax::mojom::BoolAttribute::kSelected); |
| } |
| if (HasIntAttribute(ax::mojom::IntAttribute::kCheckedState)) { |
| state.checkable = true; |
| const ax::mojom::CheckedState checkedState = |
| static_cast<ax::mojom::CheckedState>(GetIntAttribute(ax::mojom::IntAttribute::kCheckedState)); |
| switch (checkedState) { |
| case ax::mojom::CheckedState::kTrue: |
| if (GetRole() == ax::mojom::Role::kToggleButton) |
| state.pressed = true; |
| else |
| state.checked = true; |
| break; |
| case ax::mojom::CheckedState::kMixed: |
| state.checkStateMixed = true; |
| break; |
| case ax::mojom::CheckedState::kFalse: |
| case ax::mojom::CheckedState::kNone: |
| break; |
| } |
| } |
| if (HasIntAttribute(ax::mojom::IntAttribute::kRestriction)) { |
| const ax::mojom::Restriction restriction = static_cast<ax::mojom::Restriction>(GetIntAttribute(ax::mojom::IntAttribute::kRestriction)); |
| switch (restriction) { |
| case ax::mojom::Restriction::kReadOnly: |
| state.readOnly = true; |
| break; |
| case ax::mojom::Restriction::kDisabled: |
| state.disabled = true; |
| break; |
| case ax::mojom::Restriction::kNone: |
| break; |
| } |
| } |
| if (HasIntAttribute(ax::mojom::IntAttribute::kHasPopup)) { |
| const ax::mojom::HasPopup hasPopup = static_cast<ax::mojom::HasPopup>(GetIntAttribute(ax::mojom::IntAttribute::kHasPopup)); |
| switch (hasPopup) { |
| case ax::mojom::HasPopup::kFalse: |
| break; |
| case ax::mojom::HasPopup::kTrue: |
| case ax::mojom::HasPopup::kMenu: |
| case ax::mojom::HasPopup::kListbox: |
| case ax::mojom::HasPopup::kTree: |
| case ax::mojom::HasPopup::kGrid: |
| case ax::mojom::HasPopup::kDialog: |
| state.hasPopup = true; |
| break; |
| } |
| } |
| return state; |
| } |
| |
| // Qt does not reference count accessibles |
| void BrowserAccessibilityQt::NativeAddReference() |
| { |
| } |
| |
| // there is no reference counting, but BrowserAccessibility::Destroy |
| // calls this (and that is the only place in the chromium sources, |
| // so we can safely use it to dispose of ourselves here |
| // (the default implementation of this function just contains a "delete this") |
| void BrowserAccessibilityQt::NativeReleaseReference() |
| { |
| // delete this |
| QAccessible::Id interfaceId = QAccessible::uniqueId(this); |
| QAccessible::deleteAccessibleInterface(interfaceId); |
| } |
| |
| QStringList BrowserAccessibilityQt::actionNames() const |
| { |
| QStringList actions; |
| if (HasState(ax::mojom::State::kFocusable)) |
| actions << QAccessibleActionInterface::setFocusAction(); |
| return actions; |
| } |
| |
| void BrowserAccessibilityQt::doAction(const QString &actionName) |
| { |
| if (actionName == QAccessibleActionInterface::setFocusAction()) |
| manager()->SetFocus(*this); |
| } |
| |
| QStringList BrowserAccessibilityQt::keyBindingsForAction(const QString &actionName) const |
| { |
| QT_NOT_YET_IMPLEMENTED |
| return QStringList(); |
| } |
| |
| void BrowserAccessibilityQt::addSelection(int startOffset, int endOffset) |
| { |
| manager()->SetSelection(AXPlatformRange(CreatePositionAt(startOffset), CreatePositionAt(endOffset))); |
| } |
| |
| QString BrowserAccessibilityQt::attributes(int offset, int *startOffset, int *endOffset) const |
| { |
| *startOffset = offset; |
| *endOffset = offset; |
| return QString(); |
| } |
| |
| int BrowserAccessibilityQt::cursorPosition() const |
| { |
| int pos = 0; |
| GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart, &pos); |
| return pos; |
| } |
| |
| QRect BrowserAccessibilityQt::characterRect(int /*offset*/) const |
| { |
| QT_NOT_YET_IMPLEMENTED |
| return QRect(); |
| } |
| |
| int BrowserAccessibilityQt::selectionCount() const |
| { |
| int start = 0; |
| int end = 0; |
| GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart, &start); |
| GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, &end); |
| if (start != end) |
| return 1; |
| return 0; |
| } |
| |
| int BrowserAccessibilityQt::offsetAtPoint(const QPoint &/*point*/) const |
| { |
| QT_NOT_YET_IMPLEMENTED |
| return 0; |
| } |
| |
| void BrowserAccessibilityQt::selection(int selectionIndex, int *startOffset, int *endOffset) const |
| { |
| Q_ASSERT(startOffset && endOffset); |
| *startOffset = 0; |
| *endOffset = 0; |
| if (selectionIndex != 0) |
| return; |
| GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart, startOffset); |
| GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, endOffset); |
| } |
| |
| QString BrowserAccessibilityQt::text(int startOffset, int endOffset) const |
| { |
| return text(QAccessible::Value).mid(startOffset, endOffset - startOffset); |
| } |
| |
| void BrowserAccessibilityQt::removeSelection(int selectionIndex) |
| { |
| manager()->SetSelection(AXPlatformRange(CreatePositionAt(0), CreatePositionAt(0))); |
| } |
| |
| void BrowserAccessibilityQt::setCursorPosition(int position) |
| { |
| manager()->SetSelection(AXPlatformRange(CreatePositionAt(position), CreatePositionAt(position))); |
| } |
| |
| void BrowserAccessibilityQt::setSelection(int selectionIndex, int startOffset, int endOffset) |
| { |
| if (selectionIndex != 0) |
| return; |
| manager()->SetSelection(AXPlatformRange(CreatePositionAt(startOffset), CreatePositionAt(endOffset))); |
| } |
| |
| int BrowserAccessibilityQt::characterCount() const |
| { |
| return text(QAccessible::Value).length(); |
| } |
| |
| void BrowserAccessibilityQt::scrollToSubstring(int startIndex, int endIndex) |
| { |
| int count = characterCount(); |
| if (startIndex < endIndex && endIndex < count) |
| manager()->ScrollToMakeVisible(*this, |
| GetRootFrameHypertextRangeBoundsRect( |
| startIndex, |
| endIndex - startIndex, |
| ui::AXClippingBehavior::kUnclipped)); |
| } |
| |
| QVariant BrowserAccessibilityQt::currentValue() const |
| { |
| QVariant result; |
| float value; |
| if (GetFloatAttribute(ax::mojom::FloatAttribute::kValueForRange, &value)) { |
| result = (double) value; |
| } |
| return result; |
| } |
| |
| void BrowserAccessibilityQt::setCurrentValue(const QVariant &value) |
| { |
| // not yet implemented anywhere in blink |
| QT_NOT_YET_IMPLEMENTED |
| } |
| |
| QVariant BrowserAccessibilityQt::maximumValue() const |
| { |
| QVariant result; |
| float value; |
| if (GetFloatAttribute(ax::mojom::FloatAttribute::kMaxValueForRange, &value)) { |
| result = (double) value; |
| } |
| return result; |
| } |
| |
| QVariant BrowserAccessibilityQt::minimumValue() const |
| { |
| QVariant result; |
| float value; |
| if (GetFloatAttribute(ax::mojom::FloatAttribute::kMinValueForRange, &value)) { |
| result = (double) value; |
| } |
| return result; |
| } |
| |
| QVariant BrowserAccessibilityQt::minimumStepSize() const |
| { |
| QVariant result; |
| float value; |
| if (GetFloatAttribute(ax::mojom::FloatAttribute::kStepValueForRange, &value)) { |
| result = (double) value; |
| } |
| return result; |
| } |
| |
| QAccessibleInterface *BrowserAccessibilityQt::cellAt(int row, int column) const |
| { |
| int columns = 0; |
| int rows = 0; |
| if (!GetIntAttribute(ax::mojom::IntAttribute::kTableColumnCount, &columns) || |
| !GetIntAttribute(ax::mojom::IntAttribute::kTableRowCount, &rows) || |
| columns <= 0 || |
| rows <= 0) { |
| return 0; |
| } |
| |
| if (row < 0 || row >= rows || column < 0 || column >= columns) |
| return 0; |
| |
| base::Optional<int> cell_id = GetCellId(row, column); |
| BrowserAccessibility* cell = cell_id ? manager()->GetFromID(*cell_id) : nullptr; |
| if (cell) { |
| QAccessibleInterface *iface = static_cast<BrowserAccessibilityQt*>(cell); |
| return iface; |
| } |
| |
| return nullptr; |
| } |
| |
| QAccessibleInterface *BrowserAccessibilityQt::caption() const |
| { |
| return nullptr; |
| } |
| |
| QAccessibleInterface *BrowserAccessibilityQt::summary() const |
| { |
| return nullptr; |
| } |
| |
| QString BrowserAccessibilityQt::columnDescription(int column) const |
| { |
| return QString(); |
| } |
| |
| QString BrowserAccessibilityQt::rowDescription(int row) const |
| { |
| return QString(); |
| } |
| |
| int BrowserAccessibilityQt::columnCount() const |
| { |
| int columns = 0; |
| if (GetIntAttribute(ax::mojom::IntAttribute::kTableColumnCount, &columns)) |
| return columns; |
| |
| return 0; |
| } |
| |
| int BrowserAccessibilityQt::rowCount() const |
| { |
| int rows = 0; |
| if (GetIntAttribute(ax::mojom::IntAttribute::kTableRowCount, &rows)) |
| return rows; |
| return 0; |
| } |
| |
| int BrowserAccessibilityQt::selectedCellCount() const |
| { |
| return 0; |
| } |
| |
| int BrowserAccessibilityQt::selectedColumnCount() const |
| { |
| return 0; |
| } |
| |
| int BrowserAccessibilityQt::selectedRowCount() const |
| { |
| return 0; |
| } |
| |
| QList<QAccessibleInterface *> BrowserAccessibilityQt::selectedCells() const |
| { |
| return QList<QAccessibleInterface *>(); |
| } |
| |
| QList<int> BrowserAccessibilityQt::selectedColumns() const |
| { |
| return QList<int>(); |
| } |
| |
| QList<int> BrowserAccessibilityQt::selectedRows() const |
| { |
| return QList<int>(); |
| } |
| |
| bool BrowserAccessibilityQt::isColumnSelected(int /*column*/) const |
| { |
| return false; |
| } |
| |
| bool BrowserAccessibilityQt::isRowSelected(int /*row*/) const |
| { |
| return false; |
| } |
| |
| bool BrowserAccessibilityQt::selectRow(int /*row*/) |
| { |
| return false; |
| } |
| |
| bool BrowserAccessibilityQt::selectColumn(int /*column*/) |
| { |
| return false; |
| } |
| |
| bool BrowserAccessibilityQt::unselectRow(int /*row*/) |
| { |
| return false; |
| } |
| |
| bool BrowserAccessibilityQt::unselectColumn(int /*column*/) |
| { |
| return false; |
| } |
| |
| int BrowserAccessibilityQt::columnExtent() const |
| { |
| return 1; |
| } |
| |
| QList<QAccessibleInterface *> BrowserAccessibilityQt::columnHeaderCells() const |
| { |
| return QList<QAccessibleInterface*>(); |
| } |
| |
| int BrowserAccessibilityQt::columnIndex() const |
| { |
| int column = 0; |
| if (GetIntAttribute(ax::mojom::IntAttribute::kTableCellColumnIndex, &column)) |
| return column; |
| return 0; |
| } |
| |
| int BrowserAccessibilityQt::rowExtent() const |
| { |
| return 1; |
| } |
| |
| QList<QAccessibleInterface *> BrowserAccessibilityQt::rowHeaderCells() const |
| { |
| return QList<QAccessibleInterface*>(); |
| } |
| |
| int BrowserAccessibilityQt::rowIndex() const |
| { |
| int row = 0; |
| if (GetIntAttribute(ax::mojom::IntAttribute::kTableCellRowIndex, &row)) |
| return row; |
| return 0; |
| } |
| |
| bool BrowserAccessibilityQt::isSelected() const |
| { |
| return false; |
| } |
| |
| QAccessibleInterface *BrowserAccessibilityQt::table() const |
| { |
| BrowserAccessibility* find_table = PlatformGetParent(); |
| while (find_table && find_table->GetRole() != ax::mojom::Role::kTable) |
| find_table = find_table->PlatformGetParent(); |
| if (!find_table) |
| return 0; |
| return static_cast<BrowserAccessibilityQt*>(find_table); |
| } |
| |
| void BrowserAccessibilityQt::modelChange(QAccessibleTableModelChangeEvent *) |
| { |
| |
| } |
| |
| } // namespace content |
| |
| #endif // QT_CONFIG(accessibility) |