diff options
author | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-07-07 10:45:41 +0200 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@digia.com> | 2014-07-10 15:56:48 +0200 |
commit | 6ac1bf6434f2a508b895f6da7997bd90a5a8c08a (patch) | |
tree | 8717c7c6e89c8a3de08b68899ed7a84782c3fb5d | |
parent | a9853701193c81c65f80a606943864cd9b1f4431 (diff) |
Widget based accessibility glue code
With this patch the accessibility hierarchy inside webengine becomes
available when navigating from QWidget based web views.
Change-Id: Ib3625a6ec93b4d3f298fb845ab85209b348349ba
Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
Reviewed-by: Andras Becsi <andras.becsi@digia.com>
6 files changed, 159 insertions, 0 deletions
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h index eaeae9a78..6d8d2ddd8 100644 --- a/src/webenginewidgets/api/qwebenginepage.h +++ b/src/webenginewidgets/api/qwebenginepage.h @@ -215,6 +215,7 @@ private: friend class QWebEngineView; friend class QWebEngineViewPrivate; + friend class QWebEngineViewAccessible; }; diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp index 47afca8ce..71d854ac2 100644 --- a/src/webenginewidgets/api/qwebengineview.cpp +++ b/src/webenginewidgets/api/qwebengineview.cpp @@ -89,11 +89,20 @@ void QWebEngineViewPrivate::bind(QWebEngineView *view, QWebEnginePage *page) } } + +static QAccessibleInterface *webAccessibleFactory(const QString &, QObject *object) +{ + if (QWebEngineView *v = qobject_cast<QWebEngineView*>(object)) + return new QWebEngineViewAccessible(v); + return Q_NULLPTR; +} + QWebEngineViewPrivate::QWebEngineViewPrivate() : QWidgetPrivate(QObjectPrivateVersion) , page(0) , m_pendingContextMenuEvent(false) { + QAccessible::installFactory(&webAccessibleFactory); } QWebEngineView::QWebEngineView(QWidget *parent) @@ -242,6 +251,20 @@ void QWebEngineView::contextMenuEvent(QContextMenuEvent *event) menu->popup(event->globalPos()); } +int QWebEngineViewAccessible::childCount() const +{ + if (view() && child(0)) + return 1; + return 0; +} + +QAccessibleInterface *QWebEngineViewAccessible::child(int index) const +{ + if (index == 0 && view() && view()->page()) + return view()->page()->d_func()->adapter->browserAccessible(); + return Q_NULLPTR; +} + QT_END_NAMESPACE #include "moc_qwebengineview.cpp" diff --git a/src/webenginewidgets/api/qwebengineview_p.h b/src/webenginewidgets/api/qwebengineview_p.h index 774386a21..9f0790117 100644 --- a/src/webenginewidgets/api/qwebengineview_p.h +++ b/src/webenginewidgets/api/qwebengineview_p.h @@ -45,6 +45,8 @@ #include <QtWidgets/private/qwidget_p.h> #include <QtWebEngineWidgets/qwebengineview.h> +#include <QtWidgets/qaccessiblewidget.h> + QT_BEGIN_NAMESPACE class QWebEngineView; @@ -62,6 +64,20 @@ public: bool m_pendingContextMenuEvent; }; +class QWebEngineViewAccessible : public QAccessibleWidget +{ +public: + QWebEngineViewAccessible(QWebEngineView *o) : QAccessibleWidget(o, QAccessible::Document) + {} + + int childCount() const Q_DECL_OVERRIDE; + QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; + +private: + QWebEngineView *view() const { return static_cast<QWebEngineView*>(object()); } +}; + + QT_END_NAMESPACE #endif // QWEBENGINEVIEW_P_H diff --git a/tests/auto/widgets/qwebengineaccessibility/qwebengineaccessibility.pro b/tests/auto/widgets/qwebengineaccessibility/qwebengineaccessibility.pro new file mode 100644 index 000000000..ff6c49628 --- /dev/null +++ b/tests/auto/widgets/qwebengineaccessibility/qwebengineaccessibility.pro @@ -0,0 +1,2 @@ +include(../tests.pri) +exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc diff --git a/tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp b/tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp new file mode 100644 index 000000000..6cc7ac799 --- /dev/null +++ b/tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp @@ -0,0 +1,116 @@ +/* + Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <qtest.h> +#include "../util.h" + +#include <qaccessible.h> +#include <qwebengineview.h> +#include <qwebenginepage.h> +#include <qwidget.h> + +class tst_QWebEngineView : public QObject +{ + Q_OBJECT + +public Q_SLOTS: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private Q_SLOTS: + void noPage(); + void hierarchy(); +}; + +// This will be called before the first test function is executed. +// It is only called once. +void tst_QWebEngineView::initTestCase() +{ + QWebEngineWidgets::initialize(); +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_QWebEngineView::cleanupTestCase() +{ +} + +// This will be called before each test function is executed. +void tst_QWebEngineView::init() +{ +} + +// This will be called after every test function. +void tst_QWebEngineView::cleanup() +{ +} + +void tst_QWebEngineView::noPage() +{ + QWebEngineView webView; + webView.show(); + + QTest::qWait(1000); + QAccessibleInterface *view = QAccessible::queryAccessibleInterface(&webView); + QVERIFY(view); + QCOMPARE(view->childCount(), 1); + QAccessibleInterface *document = view->child(0); + QCOMPARE(document->role(), QAccessible::Document); + QCOMPARE(document->parent(), view); + QCOMPARE(document->childCount(), 0); +} + +void tst_QWebEngineView::hierarchy() +{ + QWebEngineView webView; + webView.setHtml("<html><body>" \ + "Hello world" \ + "<input type='text'/><br>" \ + "</body></html>"); + webView.show(); + ::waitForSignal(&webView, SIGNAL(loadFinished(bool))); + + QAccessibleInterface *view = QAccessible::queryAccessibleInterface(&webView); + QVERIFY(view); + QCOMPARE(view->childCount(), 1); + // Wait for accessibility to be fully initialized + QTRY_VERIFY(view->child(0)->childCount() == 1); + QAccessibleInterface *document = view->child(0); + QCOMPARE(document->role(), QAccessible::Document); + QCOMPARE(document->parent(), view); + QCOMPARE(document->childCount(), 1); + QAccessibleInterface *grouping = document->child(0); + QVERIFY(grouping); + QCOMPARE(grouping->parent(), document); + QCOMPARE(grouping->childCount(), 2); + QAccessibleInterface *text = grouping->child(0); + QCOMPARE(text->role(), QAccessible::StaticText); + QCOMPARE(text->parent(), grouping); + QEXPECT_FAIL("", "FIXME: static text should probably not have a child element", Continue); + QCOMPARE(text->childCount(), 0); + QAccessibleInterface *input = grouping->child(1); + QCOMPARE(input->role(), QAccessible::EditableText); + QCOMPARE(input->parent(), grouping); + QCOMPARE(input->childCount(), 0); +} + +QTEST_MAIN(tst_QWebEngineView) +#include "tst_qwebengineaccessibility.moc" diff --git a/tests/auto/widgets/widgets.pro b/tests/auto/widgets/widgets.pro index cb6cae103..40d3b40bb 100644 --- a/tests/auto/widgets/widgets.pro +++ b/tests/auto/widgets/widgets.pro @@ -3,6 +3,7 @@ TEMPLATE = subdirs CONFIG += ordered SUBDIRS += \ + qwebengineaccessibility \ qwebengineframe \ qwebenginepage \ qwebenginehistoryinterface \ |