diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-01-05 14:30:32 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2022-01-08 07:53:40 +0000 |
commit | bcb7ab3412275f97d71baa819c1f715a8e225bf1 (patch) | |
tree | 2158f984955a4e8ff0296d6bda37d64b2cb98624 | |
parent | 368ae18df30b800add91f162302ca8bf087634a2 (diff) |
Add objectName to webengine accessibility objects
This requires adding a QObject to represent the backing node.
Fixes: QTBUG-99485
Change-Id: I4d8c722a0dfb1f374995f3feab23b93ed5d8752a
Reviewed-by: Kirill Burtsev <kirill.burtsev@qt.io>
(cherry picked from commit d95f6a6b23e3052c39a32f50d6e604cf17e698e3)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/core/browser_accessibility_manager_qt.cpp | 24 | ||||
-rw-r--r-- | src/core/browser_accessibility_manager_qt.h | 8 | ||||
-rw-r--r-- | src/core/browser_accessibility_qt.cpp | 24 | ||||
-rw-r--r-- | src/core/browser_accessibility_qt.h | 5 | ||||
-rw-r--r-- | tests/auto/widgets/accessibility/tst_accessibility.cpp | 53 |
5 files changed, 95 insertions, 19 deletions
diff --git a/src/core/browser_accessibility_manager_qt.cpp b/src/core/browser_accessibility_manager_qt.cpp index b1d7f1a22..8587229d1 100644 --- a/src/core/browser_accessibility_manager_qt.cpp +++ b/src/core/browser_accessibility_manager_qt.cpp @@ -55,12 +55,9 @@ BrowserAccessibilityManager *BrowserAccessibilityManager::Create( { #if QT_CONFIG(accessibility) Q_ASSERT(delegate); - QObject *parent = nullptr; - if (delegate->AccessibilityIsMainFrame()) { - auto *access = static_cast<QtWebEngineCore::WebContentsAccessibilityQt *>(delegate->AccessibilityGetWebContentsAccessibility()); - parent = access ? access->accessibilityParentObject() : nullptr; - } - return new BrowserAccessibilityManagerQt(parent, initialTree, delegate); + QtWebEngineCore::WebContentsAccessibilityQt *access = nullptr; + access = static_cast<QtWebEngineCore::WebContentsAccessibilityQt *>(delegate->AccessibilityGetWebContentsAccessibility()); + return new BrowserAccessibilityManagerQt(access, initialTree, delegate); #else return nullptr; #endif // QT_CONFIG(accessibility) @@ -79,10 +76,11 @@ BrowserAccessibilityManager *BrowserAccessibilityManager::Create( #if QT_CONFIG(accessibility) BrowserAccessibilityManagerQt::BrowserAccessibilityManagerQt( - QObject *parentObject, const ui::AXTreeUpdate &initialTree, + QtWebEngineCore::WebContentsAccessibilityQt *webContentsAccessibility, + const ui::AXTreeUpdate &initialTree, BrowserAccessibilityDelegate* delegate) : BrowserAccessibilityManager(delegate) - , m_parentObject(parentObject) + , m_webContentsAccessibility(webContentsAccessibility) { Initialize(initialTree); m_valid = true; // BrowserAccessibilityQt can start using the AXTree @@ -95,7 +93,15 @@ BrowserAccessibilityManagerQt::~BrowserAccessibilityManagerQt() QAccessibleInterface *BrowserAccessibilityManagerQt::rootParentAccessible() { - return QAccessible::queryAccessibleInterface(m_parentObject); + content::BrowserAccessibility *parent_node = GetParentNodeFromParentTree(); + if (!parent_node) { + Q_ASSERT(m_webContentsAccessibility); + return QAccessible::queryAccessibleInterface(m_webContentsAccessibility->accessibilityParentObject()); + } + + auto *parent_manager = + static_cast<BrowserAccessibilityManagerQt *>(parent_node->manager()); + return parent_manager->rootParentAccessible(); } void BrowserAccessibilityManagerQt::FireBlinkEvent(ax::mojom::Event event_type, diff --git a/src/core/browser_accessibility_manager_qt.h b/src/core/browser_accessibility_manager_qt.h index 2a1d273b9..de0022a49 100644 --- a/src/core/browser_accessibility_manager_qt.h +++ b/src/core/browser_accessibility_manager_qt.h @@ -49,12 +49,16 @@ QT_FORWARD_DECLARE_CLASS(QAccessibleInterface) +namespace QtWebEngineCore { +class WebContentsAccessibilityQt; +} + namespace content { class BrowserAccessibilityManagerQt : public BrowserAccessibilityManager { public: - BrowserAccessibilityManagerQt(QObject *parentObject, + BrowserAccessibilityManagerQt(QtWebEngineCore::WebContentsAccessibilityQt *webContentsAccessibility, const ui::AXTreeUpdate &initialTree, BrowserAccessibilityDelegate *delegate); ~BrowserAccessibilityManagerQt() override; @@ -68,7 +72,7 @@ public: private: Q_DISABLE_COPY(BrowserAccessibilityManagerQt) - QObject *m_parentObject; + QtWebEngineCore::WebContentsAccessibilityQt *m_webContentsAccessibility; bool m_valid = false; }; diff --git a/src/core/browser_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp index 76e76c12e..7cb7c81d1 100644 --- a/src/core/browser_accessibility_qt.cpp +++ b/src/core/browser_accessibility_qt.cpp @@ -59,11 +59,7 @@ namespace content { // static BrowserAccessibility *BrowserAccessibility::Create() { -#if QT_CONFIG(accessibility) return new BrowserAccessibilityQt(); -#else - return nullptr; -#endif // QT_CONFIG(accessibility) } const BrowserAccessibilityQt *ToBrowserAccessibilityQt(const BrowserAccessibility *obj) @@ -78,7 +74,6 @@ QAccessibleInterface *toQAccessibleInterface(BrowserAccessibility *obj) BrowserAccessibilityQt::BrowserAccessibilityQt() { - QAccessible::registerAccessibleInterface(this); } bool BrowserAccessibilityQt::isValid() const @@ -89,7 +84,7 @@ bool BrowserAccessibilityQt::isValid() const QObject *BrowserAccessibilityQt::object() const { - return nullptr; + return m_object; } QAccessibleInterface *BrowserAccessibilityQt::childAt(int x, int y) const @@ -655,11 +650,24 @@ QAccessible::State BrowserAccessibilityQt::state() const return state; } +void BrowserAccessibilityQt::Init(BrowserAccessibilityManager *manager, ui::AXNode *node) +{ + BrowserAccessibility::Init(manager, node); + + Q_ASSERT(parent()); + Q_ASSERT(parent()->object()); + m_object = new QObject(parent()->object()); + QString name = toQt(GetAuthorUniqueId()); + if (!name.isEmpty()) + m_object->setObjectName(name); + + m_id = QAccessible::registerAccessibleInterface(this); +} + void BrowserAccessibilityQt::Destroy() { // delete this - QAccessible::Id interfaceId = QAccessible::uniqueId(this); - QAccessible::deleteAccessibleInterface(interfaceId); + QAccessible::deleteAccessibleInterface(m_id); } QStringList BrowserAccessibilityQt::actionNames() const diff --git a/src/core/browser_accessibility_qt.h b/src/core/browser_accessibility_qt.h index 32a4fc76b..c02e51c8f 100644 --- a/src/core/browser_accessibility_qt.h +++ b/src/core/browser_accessibility_qt.h @@ -80,6 +80,7 @@ public: QAccessible::State state() const override; // BrowserAccessible + void Init(BrowserAccessibilityManager *manager, ui::AXNode *node) override; void Destroy() override; // QAccessibleActionInterface @@ -142,6 +143,10 @@ public: QAccessibleInterface* table() const override; void modelChange(QAccessibleTableModelChangeEvent *event) override; + +private: + QObject *m_object = nullptr; + QAccessible::Id m_id; }; const BrowserAccessibilityQt *ToBrowserAccessibilityQt(const BrowserAccessibility *obj); diff --git a/tests/auto/widgets/accessibility/tst_accessibility.cpp b/tests/auto/widgets/accessibility/tst_accessibility.cpp index 054559f13..4429ff8bf 100644 --- a/tests/auto/widgets/accessibility/tst_accessibility.cpp +++ b/tests/auto/widgets/accessibility/tst_accessibility.cpp @@ -48,6 +48,8 @@ private Q_SLOTS: void value(); void roles_data(); void roles(); + void objectName(); + void crossTreeParent(); }; // This will be called before the first test function is executed. @@ -552,6 +554,57 @@ void tst_Accessibility::roles() QCOMPARE(element->role(), role); } +void tst_Accessibility::objectName() +{ + QWebEngineView webView; + QSignalSpy spyFinished(&webView, &QWebEngineView::loadFinished); + webView.setHtml("<html><body><p id='my_id'></p></body></html>"); + webView.show(); + QVERIFY(spyFinished.wait()); + QAccessibleInterface *view = QAccessible::queryAccessibleInterface(&webView); + QAccessibleInterface *document = view->child(0); + QTRY_COMPARE(document->childCount(), 1); + QAccessibleInterface *p = document->child(0); + QVERIFY(p); + QVERIFY(p->object()); + QCOMPARE(p->role(), QAccessible::Paragraph); + QCOMPARE(p->object()->objectName(), QStringLiteral("my_id")); +} + +void tst_Accessibility::crossTreeParent() +{ + QWebEngineView webView; + QSignalSpy spyFinished(&webView, &QWebEngineView::loadFinished); + webView.setHtml("<html><body><iframe src='data:text/html,<html><body><p id=my_id></p></body></html>'>Fallback text</iframe></body></html>"); + webView.show(); + QVERIFY(spyFinished.wait()); + QAccessibleInterface *view = QAccessible::queryAccessibleInterface(&webView); + QAccessibleInterface *document = view->child(0); + QCOMPARE(document->role(), QAccessible::WebDocument); + QTRY_COMPARE(document->childCount(), 1); + QAccessibleInterface *p = document->child(0); + QVERIFY(p); + QCOMPARE(p->parent(), document); + p = p->child(0); + QVERIFY(p); + QCOMPARE(p->role(), QAccessible::WebDocument); + QCOMPARE(p->parent()->parent(), document); + QTRY_COMPARE(p->childCount(), 1); + p = p->child(0); + QVERIFY(p); + QAccessibleInterface *subdocument = p; + QCOMPARE(p->role(), QAccessible::WebDocument); + QCOMPARE(p->parent()->parent()->parent(), document); + p = p->child(0); + QVERIFY(p); + QVERIFY(p->object()); + QCOMPARE(p->role(), QAccessible::Paragraph); + QCOMPARE(p->parent(), subdocument); + QCOMPARE(p->parent()->parent()->parent()->parent(), document); + QCOMPARE(p->parent()->parent()->parent()->parent()->parent(), view); + QCOMPARE(p->object()->objectName(), QStringLiteral("my_id")); +} + static QByteArrayList params = QByteArrayList() << "--force-renderer-accessibility" << "--enable-features=AccessibilityExposeARIAAnnotations"; |