summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2014-07-07 10:45:41 +0200
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2014-07-10 15:56:48 +0200
commit6ac1bf6434f2a508b895f6da7997bd90a5a8c08a (patch)
tree8717c7c6e89c8a3de08b68899ed7a84782c3fb5d
parenta9853701193c81c65f80a606943864cd9b1f4431 (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>
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h1
-rw-r--r--src/webenginewidgets/api/qwebengineview.cpp23
-rw-r--r--src/webenginewidgets/api/qwebengineview_p.h16
-rw-r--r--tests/auto/widgets/qwebengineaccessibility/qwebengineaccessibility.pro2
-rw-r--r--tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp116
-rw-r--r--tests/auto/widgets/widgets.pro1
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 \