summaryrefslogtreecommitdiffstats
path: root/src/core/browser_accessibility_qt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/browser_accessibility_qt.cpp')
-rw-r--r--src/core/browser_accessibility_qt.cpp693
1 files changed, 438 insertions, 255 deletions
diff --git a/src/core/browser_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp
index de78eb85d..de3347df3 100644
--- a/src/core/browser_accessibility_qt.cpp
+++ b/src/core/browser_accessibility_qt.cpp
@@ -1,88 +1,197 @@
-/****************************************************************************
-**
-** 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) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// 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;
+#if QT_CONFIG(accessibility)
+#include "content/browser/accessibility/browser_accessibility.h"
+#include "ui/accessibility/ax_enums.mojom.h"
-namespace content {
+#include <QtGui/qaccessible.h>
+
+namespace QtWebEngineCore {
+class BrowserAccessibilityInterface;
+
+class BrowserAccessibilityQt
+ : public content::BrowserAccessibility
+{
+public:
+ BrowserAccessibilityQt(content::BrowserAccessibilityManager *manager, ui::AXNode *node);
+ ~BrowserAccessibilityQt();
+
+ bool isReady() const;
+
+ QtWebEngineCore::BrowserAccessibilityInterface *interface = nullptr;
+};
+
+class BrowserAccessibilityInterface
+ : public QAccessibleInterface
+ , public QAccessibleActionInterface
+ , public QAccessibleTextInterface
+ , public QAccessibleValueInterface
+ , public QAccessibleTableInterface
+ , public QAccessibleTableCellInterface
+{
+public:
+ BrowserAccessibilityInterface(BrowserAccessibilityQt *chromiumInterface);
+ ~BrowserAccessibilityInterface() override;
+
+ void destroy();
+
+ // QAccessibleInterface
+ bool isValid() const override;
+ QObject *object() const override;
+ QAccessibleInterface *childAt(int x, int y) const override;
+ void *interface_cast(QAccessible::InterfaceType type) override;
+
+ // navigation, hierarchy
+ QAccessibleInterface *parent() const override;
+ QAccessibleInterface *child(int index) const override;
+ QAccessibleInterface *focusChild() const override;
+ int childCount() const override;
+ int indexOfChild(const QAccessibleInterface *) const override;
+
+ // properties and state
+ QString text(QAccessible::Text t) const override;
+ void setText(QAccessible::Text t, const QString &text) override;
+ QRect rect() const override;
+ QAccessible::Role role() const override;
+ QAccessible::State state() const override;
+
+ // QAccessibleActionInterface
+ QStringList actionNames() const override;
+ void doAction(const QString &actionName) override;
+ QStringList keyBindingsForAction(const QString &actionName) const override;
+
+ // QAccessibleTextInterface
+ void addSelection(int startOffset, int endOffset) override;
+ QString attributes(int offset, int *startOffset, int *endOffset) const override;
+ int cursorPosition() const override;
+ QRect characterRect(int offset) const override;
+ int selectionCount() const override;
+ int offsetAtPoint(const QPoint &point) const override;
+ void selection(int selectionIndex, int *startOffset, int *endOffset) const override;
+ QString text(int startOffset, int endOffset) const override;
+ void removeSelection(int selectionIndex) override;
+ void setCursorPosition(int position) override;
+ void setSelection(int selectionIndex, int startOffset, int endOffset) override;
+ int characterCount() const override;
+ void scrollToSubstring(int startIndex, int endIndex) override;
+
+ // QAccessibleValueInterface
+ QVariant currentValue() const override;
+ void setCurrentValue(const QVariant &value) override;
+ QVariant maximumValue() const override;
+ QVariant minimumValue() const override;
+ QVariant minimumStepSize() const override;
+
+ // QAccessibleTableInterface
+ QAccessibleInterface *cellAt(int row, int column) const override;
+ QAccessibleInterface *caption() const override;
+ QAccessibleInterface *summary() const override;
+ QString columnDescription(int column) const override;
+ QString rowDescription(int row) const override;
+ int columnCount() const override;
+ int rowCount() const override;
+ // selection
+ int selectedCellCount() const override;
+ int selectedColumnCount() const override;
+ int selectedRowCount() const override;
+ QList<QAccessibleInterface *> selectedCells() const override;
+ QList<int> selectedColumns() const override;
+ QList<int> selectedRows() const override;
+ bool isColumnSelected(int column) const override;
+ bool isRowSelected(int row) const override;
+ bool selectRow(int row) override;
+ bool selectColumn(int column) override;
+ bool unselectRow(int row) override;
+ bool unselectColumn(int column) override;
+
+ // QAccessibleTableCellInterface
+ int columnExtent() const override;
+ QList<QAccessibleInterface *> columnHeaderCells() const override;
+ int columnIndex() const override;
+ int rowExtent() const override;
+ QList<QAccessibleInterface *> rowHeaderCells() const override;
+ int rowIndex() const override;
+ bool isSelected() const override;
+ QAccessibleInterface *table() const override;
+
+ void modelChange(QAccessibleTableModelChangeEvent *event) override;
+
+private:
+ content::BrowserAccessibility *findTable() const;
+
+ QObject *m_object = nullptr;
+ QAccessible::Id m_id = 0;
+ BrowserAccessibilityQt *q;
+};
+
+BrowserAccessibilityQt::BrowserAccessibilityQt(content::BrowserAccessibilityManager *manager,
+ ui::AXNode *node)
+ : content::BrowserAccessibility(manager, node)
+ , interface(new BrowserAccessibilityInterface(this))
+{
+}
+
+BrowserAccessibilityQt::~BrowserAccessibilityQt()
+{
+ if (interface)
+ interface->destroy();
+}
+
+bool BrowserAccessibilityQt::isReady() const
+{
+ // FIXME: This is just a workaround, remove this when the commented out assert in
+ // BrowserAccessibilityManager::GetFromID(int32_t id) gets fixed.
+ return manager()->GetFromID(node()->id()) != nullptr;
+}
+
+BrowserAccessibilityInterface::BrowserAccessibilityInterface(BrowserAccessibilityQt *chromiumInterface)
+ : q(chromiumInterface)
+{
+ if (parent() && parent()->object()) {
+ m_object = new QObject(parent()->object());
+ QString name = toQt(q->GetAuthorUniqueId());
+ if (!name.isEmpty())
+ m_object->setObjectName(name);
+ }
-const BrowserAccessibilityQt *ToBrowserAccessibilityQt(const BrowserAccessibility *obj)
-{
- return static_cast<const BrowserAccessibilityQt *>(obj);
+ m_id = QAccessible::registerAccessibleInterface(this);
}
-QAccessibleInterface *toQAccessibleInterface(BrowserAccessibility *obj)
+BrowserAccessibilityInterface::~BrowserAccessibilityInterface()
{
- return static_cast<BrowserAccessibilityQt *>(obj);
+ q->interface = nullptr;
}
-BrowserAccessibilityQt::BrowserAccessibilityQt()
+void BrowserAccessibilityInterface::destroy()
{
- QAccessible::registerAccessibleInterface(this);
+ QAccessible::deleteAccessibleInterface(m_id);
}
-bool BrowserAccessibilityQt::isValid() const
+bool BrowserAccessibilityInterface::isValid() const
{
- auto managerQt = static_cast<BrowserAccessibilityManagerQt *>(manager_);
+ if (!q->isReady())
+ return false;
+
+ auto managerQt = static_cast<content::BrowserAccessibilityManagerQt *>(q->manager());
return managerQt && managerQt->isValid();
}
-QObject *BrowserAccessibilityQt::object() const
+QObject *BrowserAccessibilityInterface::object() const
{
- return 0;
+ return m_object;
}
-QAccessibleInterface *BrowserAccessibilityQt::childAt(int x, int y) const
+QAccessibleInterface *BrowserAccessibilityInterface::childAt(int x, int y) const
{
for (int i = 0; i < childCount(); ++i) {
QAccessibleInterface *childIface = child(i);
@@ -90,10 +199,10 @@ QAccessibleInterface *BrowserAccessibilityQt::childAt(int x, int y) const
if (childIface->rect().contains(x,y))
return childIface;
}
- return 0;
+ return nullptr;
}
-void *BrowserAccessibilityQt::interface_cast(QAccessible::InterfaceType type)
+void *BrowserAccessibilityInterface::interface_cast(QAccessible::InterfaceType type)
{
switch (type) {
case QAccessible::ActionInterface:
@@ -101,7 +210,7 @@ void *BrowserAccessibilityQt::interface_cast(QAccessible::InterfaceType type)
return static_cast<QAccessibleActionInterface*>(this);
break;
case QAccessible::TextInterface:
- if (HasState(ax::mojom::State::kEditable))
+ if (q->HasState(ax::mojom::State::kEditable))
return static_cast<QAccessibleTextInterface*>(this);
break;
case QAccessible::ValueInterface: {
@@ -123,35 +232,36 @@ void *BrowserAccessibilityQt::interface_cast(QAccessible::InterfaceType type)
}
case QAccessible::TableCellInterface: {
QAccessible::Role r = role();
- if (r == QAccessible::Cell ||
- r == QAccessible::ListItem ||
- r == QAccessible::TreeItem)
- return static_cast<QAccessibleTableCellInterface*>(this);
+ if (r == QAccessible::Cell || r == QAccessible::ListItem || r == QAccessible::TreeItem) {
+ if (findTable())
+ return static_cast<QAccessibleTableCellInterface *>(this);
+ }
break;
}
default:
break;
}
- return 0;
+ return nullptr;
}
-QAccessibleInterface *BrowserAccessibilityQt::parent() const
+QAccessibleInterface *BrowserAccessibilityInterface::parent() const
{
- BrowserAccessibility *p = PlatformGetParent();
- if (p)
- return static_cast<BrowserAccessibilityQt*>(p);
- return static_cast<BrowserAccessibilityManagerQt*>(manager())->rootParentAccessible();
+ content::BrowserAccessibility *chromiumParent = q->PlatformGetParent();
+ if (chromiumParent)
+ return toQAccessibleInterface(chromiumParent);
+ return static_cast<content::BrowserAccessibilityManagerQt*>(q->manager())->rootParentAccessible();
}
-QAccessibleInterface *BrowserAccessibilityQt::child(int index) const
+QAccessibleInterface *BrowserAccessibilityInterface::child(int index) const
{
- return static_cast<BrowserAccessibilityQt*>(BrowserAccessibility::PlatformGetChild(index));
+ content::BrowserAccessibility *chromiumChild = q->PlatformGetChild(index);
+ return chromiumChild ? toQAccessibleInterface(chromiumChild) : nullptr;
}
-QAccessibleInterface *BrowserAccessibilityQt::focusChild() const
+QAccessibleInterface *BrowserAccessibilityInterface::focusChild() const
{
if (state().focused)
- return const_cast<BrowserAccessibilityQt *>(this);
+ return const_cast<BrowserAccessibilityInterface *>(this);
for (int i = 0; i < childCount(); ++i) {
if (QAccessibleInterface *iface = child(i)->focusChild())
@@ -161,57 +271,65 @@ QAccessibleInterface *BrowserAccessibilityQt::focusChild() const
return nullptr;
}
-int BrowserAccessibilityQt::childCount() const
+int BrowserAccessibilityInterface::childCount() const
{
- return PlatformChildCount();
+ return q->PlatformChildCount();
}
-int BrowserAccessibilityQt::indexOfChild(const QAccessibleInterface *iface) const
+int BrowserAccessibilityInterface::indexOfChild(const QAccessibleInterface *iface) const
{
- const BrowserAccessibilityQt *child = static_cast<const BrowserAccessibilityQt*>(iface);
- return const_cast<BrowserAccessibilityQt *>(child)->GetIndexInParent();
+ const BrowserAccessibilityInterface *child = static_cast<const BrowserAccessibilityInterface *>(iface);
+ return const_cast<BrowserAccessibilityInterface *>(child)->q->GetIndexInParent().value();
}
-QString BrowserAccessibilityQt::text(QAccessible::Text t) const
+QString BrowserAccessibilityInterface::text(QAccessible::Text t) const
{
+ if (!q->isReady())
+ return QString();
+
switch (t) {
case QAccessible::Name:
- return toQt(GetStringAttribute(ax::mojom::StringAttribute::kName));
+ return toQt(q->GetStringAttribute(ax::mojom::StringAttribute::kName));
case QAccessible::Description:
- return toQt(GetStringAttribute(ax::mojom::StringAttribute::kDescription));
+ return toQt(q->GetStringAttribute(ax::mojom::StringAttribute::kDescription));
case QAccessible::Value:
- return toQt(GetStringAttribute(ax::mojom::StringAttribute::kValue));
+ return toQt(q->GetStringAttribute(ax::mojom::StringAttribute::kValue));
case QAccessible::Accelerator:
- return toQt(GetStringAttribute(ax::mojom::StringAttribute::kKeyShortcuts));
+ return toQt(q->GetStringAttribute(ax::mojom::StringAttribute::kKeyShortcuts));
default:
break;
}
return QString();
}
-void BrowserAccessibilityQt::setText(QAccessible::Text t, const QString &text)
+void BrowserAccessibilityInterface::setText(QAccessible::Text t, const QString &text)
{
}
-QRect BrowserAccessibilityQt::rect() const
+QRect BrowserAccessibilityInterface::rect() const
{
- if (!manager()) // needed implicitly by GetScreenBoundsRect()
+ if (!q->manager() || !q->isReady()) // needed implicitly by GetScreenBoundsRect()
return QRect();
- gfx::Rect bounds = GetUnclippedScreenBoundsRect();
+ gfx::Rect bounds = q->GetUnclippedScreenBoundsRect();
+ bounds = gfx::ScaleToRoundedRect(bounds, 1.f / q->manager()->device_scale_factor()); // FIXME: check
return QRect(bounds.x(), bounds.y(), bounds.width(), bounds.height());
}
-QAccessible::Role BrowserAccessibilityQt::role() const
+QAccessible::Role BrowserAccessibilityInterface::role() const
{
- switch (GetRole()) {
+ switch (q->GetRole()) {
case ax::mojom::Role::kNone:
case ax::mojom::Role::kUnknown:
return QAccessible::NoRole;
+ // Internal roles (matching auralinux and win)
+ case ax::mojom::Role::kKeyboard:
+ case ax::mojom::Role::kImeCandidate:
+ 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;
@@ -223,8 +341,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const
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:
@@ -261,10 +377,11 @@ QAccessible::Role BrowserAccessibilityQt::role() const
case ax::mojom::Role::kComboBoxMenuButton:
case ax::mojom::Role::kTextFieldWithComboBox:
return QAccessible::ComboBox;
+ case ax::mojom::Role::kComboBoxSelect:
+ return QAccessible::PopupMenu;
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:
@@ -328,6 +445,11 @@ QAccessible::Role BrowserAccessibilityQt::role() const
case ax::mojom::Role::kDocIndex:
case ax::mojom::Role::kDocIntroduction:
case ax::mojom::Role::kDocNotice:
+ return QAccessible::Section;
+ case ax::mojom::Role::kDocPageFooter:
+ return QAccessible::Footer;
+ case ax::mojom::Role::kDocPageHeader:
+ return QAccessible::Heading;
case ax::mojom::Role::kDocPageList:
case ax::mojom::Role::kDocPart:
case ax::mojom::Role::kDocPreface:
@@ -353,7 +475,8 @@ QAccessible::Role BrowserAccessibilityQt::role() const
case ax::mojom::Role::kFigure:
return QAccessible::Section;
case ax::mojom::Role::kFooter:
- return QAccessible::Footer;
+ // CORE-AAM recommends LANDMARK instead of FOOTER.
+ return QAccessible::Section;
case ax::mojom::Role::kFooterAsNonLandmark:
return QAccessible::Section;
case ax::mojom::Role::kForm:
@@ -377,23 +500,16 @@ QAccessible::Role BrowserAccessibilityQt::role() const
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:
@@ -423,7 +539,50 @@ QAccessible::Role BrowserAccessibilityQt::role() const
case ax::mojom::Role::kMarquee:
return QAccessible::Section;
case ax::mojom::Role::kMath:
+ case ax::mojom::Role::kMathMLMath:
return QAccessible::Equation;
+ case ax::mojom::Role::kMathMLFraction:
+ return QAccessible::Grouping;
+ case ax::mojom::Role::kMathMLIdentifier:
+ return QAccessible::StaticText;
+ case ax::mojom::Role::kMathMLMultiscripts:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLNoneScript:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLNumber:
+ return QAccessible::StaticText;
+ case ax::mojom::Role::kMathMLOperator:
+ return QAccessible::StaticText;
+ case ax::mojom::Role::kMathMLOver:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLPrescriptDelimiter:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLRoot:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLRow:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLSquareRoot:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLStringLiteral:
+ return QAccessible::StaticText;
+ case ax::mojom::Role::kMathMLSub:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLSubSup:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLSup:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLTable:
+ return QAccessible::Table;
+ case ax::mojom::Role::kMathMLTableCell:
+ return QAccessible::Cell;
+ case ax::mojom::Role::kMathMLTableRow:
+ return QAccessible::Row;
+ case ax::mojom::Role::kMathMLText:
+ return QAccessible::StaticText;
+ case ax::mojom::Role::kMathMLUnder:
+ return QAccessible::Section;
+ case ax::mojom::Role::kMathMLUnderOver:
+ return QAccessible::Section;
case ax::mojom::Role::kMenu:
return QAccessible::PopupMenu;
case ax::mojom::Role::kMenuBar:
@@ -434,8 +593,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const
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:
@@ -450,12 +607,18 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::Pane;
case ax::mojom::Role::kParagraph:
return QAccessible::Paragraph;
+ case ax::mojom::Role::kPdfActionableHighlight:
+ return QAccessible::Button;
+ case ax::mojom::Role::kPdfRoot:
+ return QAccessible::Document;
+ case ax::mojom::Role::kPluginObject:
+ return QAccessible::Grouping;
case ax::mojom::Role::kPopUpButton:
return QAccessible::ComboBox;
+ case ax::mojom::Role::kPortal:
+ return QAccessible::Button;
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:
@@ -464,8 +627,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const
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:
@@ -473,7 +634,7 @@ QAccessible::Role BrowserAccessibilityQt::role() const
case ax::mojom::Role::kRowHeader:
return QAccessible::RowHeader;
case ax::mojom::Role::kRuby:
- return QAccessible::StaticText;
+ return QAccessible::Grouping;
case ax::mojom::Role::kRubyAnnotation:
return QAccessible::StaticText;
case ax::mojom::Role::kScrollBar:
@@ -487,7 +648,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const
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;
@@ -499,10 +659,14 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::Indicator;
case ax::mojom::Role::kStrong:
return QAccessible::StaticText;
+ case ax::mojom::Role::kSubscript:
+ return QAccessible::Grouping;
case ax::mojom::Role::kSuggestion:
return QAccessible::Section;
+ case ax::mojom::Role::kSuperscript:
+ return QAccessible::Grouping;
case ax::mojom::Role::kSvgRoot:
- return QAccessible::Graphic;
+ return QAccessible::WebDocument;
case ax::mojom::Role::kSwitch:
return QAccessible::Button;
case ax::mojom::Role::kTable:
@@ -544,63 +708,68 @@ QAccessible::Role BrowserAccessibilityQt::role() const
return QAccessible::NoRole;
}
-QAccessible::State BrowserAccessibilityQt::state() const
+QAccessible::State BrowserAccessibilityInterface::state() const
{
QAccessible::State state = QAccessible::State();
- if (HasState(ax::mojom::State::kCollapsed))
+ if (!q->isReady()) {
+ state.invalid = true;
+ return state;
+ }
+
+ if (q->HasState(ax::mojom::State::kCollapsed))
state.collapsed = true;
- if (HasState(ax::mojom::State::kDefault))
+ if (q->HasState(ax::mojom::State::kDefault))
state.defaultButton = true;
- if (HasState(ax::mojom::State::kEditable))
+ if (q->HasState(ax::mojom::State::kEditable))
state.editable = true;
- if (HasState(ax::mojom::State::kExpanded))
+ if (q->HasState(ax::mojom::State::kExpanded))
state.expanded = true;
- if (HasState(ax::mojom::State::kFocusable))
+ if (q->HasState(ax::mojom::State::kFocusable))
state.focusable = true;
- if (HasState(ax::mojom::State::kHorizontal))
+ if (q->HasState(ax::mojom::State::kHorizontal))
{} // FIXME
- if (HasState(ax::mojom::State::kHovered))
+ if (q->HasState(ax::mojom::State::kHovered))
state.hotTracked = true;
- if (HasState(ax::mojom::State::kIgnored))
+ if (q->HasState(ax::mojom::State::kIgnored))
{} // FIXME
- if (HasState(ax::mojom::State::kInvisible))
+ if (q->HasState(ax::mojom::State::kInvisible))
state.invisible = true;
- if (HasState(ax::mojom::State::kLinked))
+ if (q->HasState(ax::mojom::State::kLinked))
state.linked = true;
- if (HasState(ax::mojom::State::kMultiline))
+ if (q->HasState(ax::mojom::State::kMultiline))
state.multiLine = true;
- if (HasState(ax::mojom::State::kMultiselectable))
+ if (q->HasState(ax::mojom::State::kMultiselectable))
state.multiSelectable = true;
- if (HasState(ax::mojom::State::kProtected))
+ if (q->HasState(ax::mojom::State::kProtected))
state.passwordEdit = true;
- if (HasState(ax::mojom::State::kRequired))
+ if (q->HasState(ax::mojom::State::kRequired))
{} // FIXME
- if (HasState(ax::mojom::State::kRichlyEditable))
+ if (q->HasState(ax::mojom::State::kRichlyEditable))
{} // FIXME
- if (HasState(ax::mojom::State::kVertical))
+ if (q->HasState(ax::mojom::State::kVertical))
{} // FIXME
- if (HasState(ax::mojom::State::kVisited))
+ if (q->HasState(ax::mojom::State::kVisited))
state.traversed = true;
- if (IsOffscreen())
+ if (q->IsOffscreen())
state.offscreen = true;
- if (manager()->GetFocus() == this)
+ if (q->manager()->GetFocus() == q)
state.focused = true;
- if (GetBoolAttribute(ax::mojom::BoolAttribute::kBusy))
+ if (q->GetBoolAttribute(ax::mojom::BoolAttribute::kBusy))
state.busy = true;
- if (GetBoolAttribute(ax::mojom::BoolAttribute::kModal))
+ if (q->GetBoolAttribute(ax::mojom::BoolAttribute::kModal))
state.modal = true;
- if (HasBoolAttribute(ax::mojom::BoolAttribute::kSelected)) {
+ if (q->HasBoolAttribute(ax::mojom::BoolAttribute::kSelected)) {
state.selectable = true;
- state.selected = GetBoolAttribute(ax::mojom::BoolAttribute::kSelected);
+ state.selected = q->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected);
}
- if (HasIntAttribute(ax::mojom::IntAttribute::kCheckedState)) {
+ if (q->HasIntAttribute(ax::mojom::IntAttribute::kCheckedState)) {
state.checkable = true;
const ax::mojom::CheckedState checkedState =
- static_cast<ax::mojom::CheckedState>(GetIntAttribute(ax::mojom::IntAttribute::kCheckedState));
+ static_cast<ax::mojom::CheckedState>(q->GetIntAttribute(ax::mojom::IntAttribute::kCheckedState));
switch (checkedState) {
case ax::mojom::CheckedState::kTrue:
- if (GetRole() == ax::mojom::Role::kToggleButton)
+ if (q->GetRole() == ax::mojom::Role::kToggleButton)
state.pressed = true;
else
state.checked = true;
@@ -613,8 +782,8 @@ QAccessible::State BrowserAccessibilityQt::state() const
break;
}
}
- if (HasIntAttribute(ax::mojom::IntAttribute::kRestriction)) {
- const ax::mojom::Restriction restriction = static_cast<ax::mojom::Restriction>(GetIntAttribute(ax::mojom::IntAttribute::kRestriction));
+ if (q->HasIntAttribute(ax::mojom::IntAttribute::kRestriction)) {
+ const ax::mojom::Restriction restriction = static_cast<ax::mojom::Restriction>(q->GetIntAttribute(ax::mojom::IntAttribute::kRestriction));
switch (restriction) {
case ax::mojom::Restriction::kReadOnly:
state.readOnly = true;
@@ -626,8 +795,8 @@ QAccessible::State BrowserAccessibilityQt::state() const
break;
}
}
- if (HasIntAttribute(ax::mojom::IntAttribute::kHasPopup)) {
- const ax::mojom::HasPopup hasPopup = static_cast<ax::mojom::HasPopup>(GetIntAttribute(ax::mojom::IntAttribute::kHasPopup));
+ if (q->HasIntAttribute(ax::mojom::IntAttribute::kHasPopup)) {
+ const ax::mojom::HasPopup hasPopup = static_cast<ax::mojom::HasPopup>(q->GetIntAttribute(ax::mojom::IntAttribute::kHasPopup));
switch (hasPopup) {
case ax::mojom::HasPopup::kFalse:
break;
@@ -644,356 +813,370 @@ QAccessible::State BrowserAccessibilityQt::state() const
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 BrowserAccessibilityInterface::actionNames() const
{
QStringList actions;
- if (HasState(ax::mojom::State::kFocusable))
+ if (q->HasState(ax::mojom::State::kFocusable))
actions << QAccessibleActionInterface::setFocusAction();
return actions;
}
-void BrowserAccessibilityQt::doAction(const QString &actionName)
+void BrowserAccessibilityInterface::doAction(const QString &actionName)
{
if (actionName == QAccessibleActionInterface::setFocusAction())
- manager()->SetFocus(*this);
+ q->manager()->SetFocus(*q);
}
-QStringList BrowserAccessibilityQt::keyBindingsForAction(const QString &actionName) const
+QStringList
+BrowserAccessibilityInterface::keyBindingsForAction(const QString & /*actionName*/) const
{
QT_NOT_YET_IMPLEMENTED
return QStringList();
}
-void BrowserAccessibilityQt::addSelection(int startOffset, int endOffset)
+void BrowserAccessibilityInterface::addSelection(int startOffset, int endOffset)
{
- manager()->SetSelection(AXPlatformRange(CreatePositionAt(startOffset), CreatePositionAt(endOffset)));
+ q->manager()->SetSelection(content::BrowserAccessibility::AXRange(q->CreatePositionAt(startOffset), q->CreatePositionAt(endOffset)));
}
-QString BrowserAccessibilityQt::attributes(int offset, int *startOffset, int *endOffset) const
+QString BrowserAccessibilityInterface::attributes(int offset, int *startOffset, int *endOffset) const
{
*startOffset = offset;
*endOffset = offset;
return QString();
}
-int BrowserAccessibilityQt::cursorPosition() const
+int BrowserAccessibilityInterface::cursorPosition() const
{
int pos = 0;
- GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart, &pos);
+ q->GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart, &pos);
return pos;
}
-QRect BrowserAccessibilityQt::characterRect(int /*offset*/) const
+QRect BrowserAccessibilityInterface::characterRect(int /*offset*/) const
{
QT_NOT_YET_IMPLEMENTED
return QRect();
}
-int BrowserAccessibilityQt::selectionCount() const
+int BrowserAccessibilityInterface::selectionCount() const
{
int start = 0;
int end = 0;
- GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart, &start);
- GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, &end);
+ q->GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart, &start);
+ q->GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, &end);
if (start != end)
return 1;
return 0;
}
-int BrowserAccessibilityQt::offsetAtPoint(const QPoint &/*point*/) const
+int BrowserAccessibilityInterface::offsetAtPoint(const QPoint &/*point*/) const
{
QT_NOT_YET_IMPLEMENTED
return 0;
}
-void BrowserAccessibilityQt::selection(int selectionIndex, int *startOffset, int *endOffset) const
+void BrowserAccessibilityInterface::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);
+ q->GetIntAttribute(ax::mojom::IntAttribute::kTextSelStart, startOffset);
+ q->GetIntAttribute(ax::mojom::IntAttribute::kTextSelEnd, endOffset);
}
-QString BrowserAccessibilityQt::text(int startOffset, int endOffset) const
+QString BrowserAccessibilityInterface::text(int startOffset, int endOffset) const
{
return text(QAccessible::Value).mid(startOffset, endOffset - startOffset);
}
-void BrowserAccessibilityQt::removeSelection(int selectionIndex)
+void BrowserAccessibilityInterface::removeSelection(int selectionIndex)
{
- manager()->SetSelection(AXPlatformRange(CreatePositionAt(0), CreatePositionAt(0)));
+ q->manager()->SetSelection(content::BrowserAccessibility::AXRange(q->CreatePositionAt(0), q->CreatePositionAt(0)));
}
-void BrowserAccessibilityQt::setCursorPosition(int position)
+void BrowserAccessibilityInterface::setCursorPosition(int position)
{
- manager()->SetSelection(AXPlatformRange(CreatePositionAt(position), CreatePositionAt(position)));
+ q->manager()->SetSelection(content::BrowserAccessibility::AXRange(q->CreatePositionAt(position), q->CreatePositionAt(position)));
}
-void BrowserAccessibilityQt::setSelection(int selectionIndex, int startOffset, int endOffset)
+void BrowserAccessibilityInterface::setSelection(int selectionIndex, int startOffset, int endOffset)
{
if (selectionIndex != 0)
return;
- manager()->SetSelection(AXPlatformRange(CreatePositionAt(startOffset), CreatePositionAt(endOffset)));
+ q->manager()->SetSelection(content::BrowserAccessibility::AXRange(q->CreatePositionAt(startOffset), q->CreatePositionAt(endOffset)));
}
-int BrowserAccessibilityQt::characterCount() const
+int BrowserAccessibilityInterface::characterCount() const
{
return text(QAccessible::Value).length();
}
-void BrowserAccessibilityQt::scrollToSubstring(int startIndex, int endIndex)
+void BrowserAccessibilityInterface::scrollToSubstring(int startIndex, int endIndex)
{
int count = characterCount();
if (startIndex < endIndex && endIndex < count)
- manager()->ScrollToMakeVisible(*this,
- GetRootFrameHypertextRangeBoundsRect(
- startIndex,
- endIndex - startIndex,
- ui::AXClippingBehavior::kUnclipped));
+ q->manager()->ScrollToMakeVisible(*q,
+ q->GetRootFrameHypertextRangeBoundsRect(
+ startIndex,
+ endIndex - startIndex,
+ ui::AXClippingBehavior::kUnclipped));
}
-QVariant BrowserAccessibilityQt::currentValue() const
+QVariant BrowserAccessibilityInterface::currentValue() const
{
QVariant result;
float value;
- if (GetFloatAttribute(ax::mojom::FloatAttribute::kValueForRange, &value)) {
+ if (q->GetFloatAttribute(ax::mojom::FloatAttribute::kValueForRange, &value)) {
result = (double) value;
}
return result;
}
-void BrowserAccessibilityQt::setCurrentValue(const QVariant &value)
+void BrowserAccessibilityInterface::setCurrentValue(const QVariant &value)
{
// not yet implemented anywhere in blink
QT_NOT_YET_IMPLEMENTED
}
-QVariant BrowserAccessibilityQt::maximumValue() const
+QVariant BrowserAccessibilityInterface::maximumValue() const
{
QVariant result;
float value;
- if (GetFloatAttribute(ax::mojom::FloatAttribute::kMaxValueForRange, &value)) {
+ if (q->GetFloatAttribute(ax::mojom::FloatAttribute::kMaxValueForRange, &value)) {
result = (double) value;
}
return result;
}
-QVariant BrowserAccessibilityQt::minimumValue() const
+QVariant BrowserAccessibilityInterface::minimumValue() const
{
QVariant result;
float value;
- if (GetFloatAttribute(ax::mojom::FloatAttribute::kMinValueForRange, &value)) {
+ if (q->GetFloatAttribute(ax::mojom::FloatAttribute::kMinValueForRange, &value)) {
result = (double) value;
}
return result;
}
-QVariant BrowserAccessibilityQt::minimumStepSize() const
+QVariant BrowserAccessibilityInterface::minimumStepSize() const
{
QVariant result;
float value;
- if (GetFloatAttribute(ax::mojom::FloatAttribute::kStepValueForRange, &value)) {
+ if (q->GetFloatAttribute(ax::mojom::FloatAttribute::kStepValueForRange, &value)) {
result = (double) value;
}
return result;
}
-QAccessibleInterface *BrowserAccessibilityQt::cellAt(int row, int column) const
+QAccessibleInterface *BrowserAccessibilityInterface::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 (!q->GetIntAttribute(ax::mojom::IntAttribute::kTableColumnCount, &columns)
+ || !q->GetIntAttribute(ax::mojom::IntAttribute::kTableRowCount, &rows)
+ || columns <= 0
+ || rows <= 0) {
+ return nullptr;
}
if (row < 0 || row >= rows || column < 0 || column >= columns)
- return 0;
+ return nullptr;
- 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;
- }
+ absl::optional<int> cell_id = q->GetCellId(row, column);
+ content::BrowserAccessibility *cell = cell_id ? q->manager()->GetFromID(*cell_id) : nullptr;
+ if (cell)
+ return content::toQAccessibleInterface(cell);
return nullptr;
}
-QAccessibleInterface *BrowserAccessibilityQt::caption() const
+QAccessibleInterface *BrowserAccessibilityInterface::caption() const
{
return nullptr;
}
-QAccessibleInterface *BrowserAccessibilityQt::summary() const
+QAccessibleInterface *BrowserAccessibilityInterface::summary() const
{
return nullptr;
}
-QString BrowserAccessibilityQt::columnDescription(int column) const
+QString BrowserAccessibilityInterface::columnDescription(int column) const
{
return QString();
}
-QString BrowserAccessibilityQt::rowDescription(int row) const
+QString BrowserAccessibilityInterface::rowDescription(int row) const
{
return QString();
}
-int BrowserAccessibilityQt::columnCount() const
+int BrowserAccessibilityInterface::columnCount() const
{
int columns = 0;
- if (GetIntAttribute(ax::mojom::IntAttribute::kTableColumnCount, &columns))
+ if (q->GetIntAttribute(ax::mojom::IntAttribute::kTableColumnCount, &columns))
return columns;
-
return 0;
}
-int BrowserAccessibilityQt::rowCount() const
+int BrowserAccessibilityInterface::rowCount() const
{
int rows = 0;
- if (GetIntAttribute(ax::mojom::IntAttribute::kTableRowCount, &rows))
- return rows;
+ if (q->GetIntAttribute(ax::mojom::IntAttribute::kTableRowCount, &rows))
+ return rows;
return 0;
}
-int BrowserAccessibilityQt::selectedCellCount() const
+int BrowserAccessibilityInterface::selectedCellCount() const
{
return 0;
}
-int BrowserAccessibilityQt::selectedColumnCount() const
+int BrowserAccessibilityInterface::selectedColumnCount() const
{
return 0;
}
-int BrowserAccessibilityQt::selectedRowCount() const
+int BrowserAccessibilityInterface::selectedRowCount() const
{
return 0;
}
-QList<QAccessibleInterface *> BrowserAccessibilityQt::selectedCells() const
+QList<QAccessibleInterface *> BrowserAccessibilityInterface::selectedCells() const
{
return QList<QAccessibleInterface *>();
}
-QList<int> BrowserAccessibilityQt::selectedColumns() const
+QList<int> BrowserAccessibilityInterface::selectedColumns() const
{
return QList<int>();
}
-QList<int> BrowserAccessibilityQt::selectedRows() const
+QList<int> BrowserAccessibilityInterface::selectedRows() const
{
return QList<int>();
}
-bool BrowserAccessibilityQt::isColumnSelected(int /*column*/) const
+bool BrowserAccessibilityInterface::isColumnSelected(int /*column*/) const
{
return false;
}
-bool BrowserAccessibilityQt::isRowSelected(int /*row*/) const
+bool BrowserAccessibilityInterface::isRowSelected(int /*row*/) const
{
return false;
}
-bool BrowserAccessibilityQt::selectRow(int /*row*/)
+bool BrowserAccessibilityInterface::selectRow(int /*row*/)
{
return false;
}
-bool BrowserAccessibilityQt::selectColumn(int /*column*/)
+bool BrowserAccessibilityInterface::selectColumn(int /*column*/)
{
return false;
}
-bool BrowserAccessibilityQt::unselectRow(int /*row*/)
+bool BrowserAccessibilityInterface::unselectRow(int /*row*/)
{
return false;
}
-bool BrowserAccessibilityQt::unselectColumn(int /*column*/)
+bool BrowserAccessibilityInterface::unselectColumn(int /*column*/)
{
return false;
}
-int BrowserAccessibilityQt::columnExtent() const
+int BrowserAccessibilityInterface::columnExtent() const
{
return 1;
}
-QList<QAccessibleInterface *> BrowserAccessibilityQt::columnHeaderCells() const
+QList<QAccessibleInterface *> BrowserAccessibilityInterface::columnHeaderCells() const
{
return QList<QAccessibleInterface*>();
}
-int BrowserAccessibilityQt::columnIndex() const
+int BrowserAccessibilityInterface::columnIndex() const
{
int column = 0;
- if (GetIntAttribute(ax::mojom::IntAttribute::kTableCellColumnIndex, &column))
- return column;
+ if (q->GetIntAttribute(ax::mojom::IntAttribute::kTableCellColumnIndex, &column))
+ return column;
return 0;
}
-int BrowserAccessibilityQt::rowExtent() const
+int BrowserAccessibilityInterface::rowExtent() const
{
return 1;
}
-QList<QAccessibleInterface *> BrowserAccessibilityQt::rowHeaderCells() const
+QList<QAccessibleInterface *> BrowserAccessibilityInterface::rowHeaderCells() const
{
return QList<QAccessibleInterface*>();
}
-int BrowserAccessibilityQt::rowIndex() const
+int BrowserAccessibilityInterface::rowIndex() const
{
int row = 0;
- if (GetIntAttribute(ax::mojom::IntAttribute::kTableCellRowIndex, &row))
- return row;
+ if (q->GetIntAttribute(ax::mojom::IntAttribute::kTableCellRowIndex, &row))
+ return row;
return 0;
}
-bool BrowserAccessibilityQt::isSelected() const
+bool BrowserAccessibilityInterface::isSelected() const
{
return false;
}
-QAccessibleInterface *BrowserAccessibilityQt::table() const
+content::BrowserAccessibility *BrowserAccessibilityInterface::findTable() 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);
+ content::BrowserAccessibility *parent = q->PlatformGetParent();
+ while (parent && parent->GetRole() != ax::mojom::Role::kTable)
+ parent = parent->PlatformGetParent();
+
+ return parent;
}
-void BrowserAccessibilityQt::modelChange(QAccessibleTableModelChangeEvent *)
+QAccessibleInterface *BrowserAccessibilityInterface::table() const
{
+ content::BrowserAccessibility *table = findTable();
+ Q_ASSERT(table);
+ return content::toQAccessibleInterface(table);
+}
+void BrowserAccessibilityInterface::modelChange(QAccessibleTableModelChangeEvent *)
+{
}
-} // namespace content
+} // namespace QtWebEngineCore
#endif // QT_CONFIG(accessibility)
+namespace content {
+
+// static
+std::unique_ptr<BrowserAccessibility> BrowserAccessibility::Create(BrowserAccessibilityManager *man, ui::AXNode *node)
+{
+#if QT_CONFIG(accessibility)
+ return std::unique_ptr<BrowserAccessibility>(new QtWebEngineCore::BrowserAccessibilityQt(man, node));
+#else
+ Q_UNUSED(man);
+ Q_UNUSED(node);
+ return nullptr;
+#endif // #if QT_CONFIG(accessibility)
+}
+
+#if QT_CONFIG(accessibility)
+QAccessibleInterface *toQAccessibleInterface(BrowserAccessibility *obj)
+{
+ return static_cast<QtWebEngineCore::BrowserAccessibilityQt *>(obj)->interface;
+}
+
+const QAccessibleInterface *toQAccessibleInterface(const BrowserAccessibility *obj)
+{
+ return static_cast<const QtWebEngineCore::BrowserAccessibilityQt *>(obj)->interface;
+}
+#endif // #if QT_CONFIG(accessibility)
+
+} // namespace content