summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2014-07-14 18:32:31 +0200
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2014-07-15 16:33:48 +0200
commitd5fa096056b033203d9a54497e1554f153a19d93 (patch)
tree587561be12137594d389834d1ed09f4be59b0220
parent28f493a9310b370d23a874e4893587b7fb931fa5 (diff)
Implement accessible text interface
Change-Id: I3a9143c61ecda98513be031fc554fd4bfcef7b7c Reviewed-by: Michael Bruning <michael.bruning@digia.com>
-rw-r--r--src/core/browser_accessibility_manager_qt.cpp33
-rw-r--r--src/core/browser_accessibility_qt.cpp103
-rw-r--r--src/core/browser_accessibility_qt.h17
-rw-r--r--tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp35
4 files changed, 184 insertions, 4 deletions
diff --git a/src/core/browser_accessibility_manager_qt.cpp b/src/core/browser_accessibility_manager_qt.cpp
index 8c2c3444a..7d1050774 100644
--- a/src/core/browser_accessibility_manager_qt.cpp
+++ b/src/core/browser_accessibility_manager_qt.cpp
@@ -84,7 +84,6 @@ void BrowserAccessibilityManagerQt::NotifyAccessibilityEvent(blink::WebAXEvent e
break;
}
case WebAXEventCheckedStateChanged: {
- BrowserAccessibilityQt *iface = static_cast<BrowserAccessibilityQt*>(node);
QAccessible::State change;
change.checked = true;
QAccessibleStateChangeEvent event(iface, change);
@@ -105,12 +104,38 @@ void BrowserAccessibilityManagerQt::NotifyAccessibilityEvent(blink::WebAXEvent e
break;
case WebAXEventLoadComplete:
break;
- case WebAXEventTextChanged:
+
+ case WebAXEventTextChanged: {
+ QAccessibleTextUpdateEvent event(iface, -1, QString(), QString());
+ QAccessible::updateAccessibility(&event);
break;
- case WebAXEventTextInserted:
+ }
+ case WebAXEventTextInserted: {
+ QAccessibleTextInsertEvent event(iface, -1, QString());
+ QAccessible::updateAccessibility(&event);
break;
- case WebAXEventTextRemoved:
+ }
+ case WebAXEventTextRemoved: {
+ QAccessibleTextRemoveEvent event(iface, -1, QString());
+ QAccessible::updateAccessibility(&event);
+ break;
+ }
+ case WebAXEventSelectedTextChanged: {
+ QAccessibleTextInterface *textIface = iface->textInterface();
+ if (textIface) {
+ int start = 0;
+ int end = 0;
+ textIface->selection(0, &start, &end);
+ if (start == end) {
+ QAccessibleTextCursorEvent event(iface, start);
+ QAccessible::updateAccessibility(&event);
+ } else {
+ QAccessibleTextSelectionEvent event(iface, start, end);
+ QAccessible::updateAccessibility(&event);
+ }
+ }
break;
+ }
default:
break;
}
diff --git a/src/core/browser_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp
index cf2d305be..7a7895a94 100644
--- a/src/core/browser_accessibility_qt.cpp
+++ b/src/core/browser_accessibility_qt.cpp
@@ -41,6 +41,7 @@
#include "browser_accessibility_qt.h"
+#include "qtwebenginecoreglobal.h"
#include "content/common/accessibility_node_data.h"
#include "third_party/WebKit/public/web/WebAXEnums.h"
#include "type_conversion.h"
@@ -70,6 +71,19 @@ QAccessibleInterface *BrowserAccessibilityQt::childAt(int x, int y) const
return 0;
}
+void *BrowserAccessibilityQt::interface_cast(QAccessible::InterfaceType type)
+{
+ switch (type) {
+ case QAccessible::TextInterface:
+ if (IsEditableText())
+ return static_cast<QAccessibleTextInterface*>(this);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
QAccessibleInterface *BrowserAccessibilityQt::parent() const
{
BrowserAccessibility *p = BrowserAccessibility::parent();
@@ -384,6 +398,8 @@ QAccessible::State BrowserAccessibilityQt::state() const
{} // FIXME
if (s & (1 << WebAXStateVisited))
{} // FIXME
+ if (IsEditableText())
+ state.editable = true;
return state;
}
@@ -403,4 +419,91 @@ void BrowserAccessibilityQt::NativeReleaseReference()
QAccessible::deleteAccessibleInterface(interfaceId);
}
+void BrowserAccessibilityQt::addSelection(int startOffset, int endOffset)
+{
+ manager()->SetTextSelection(*this, startOffset, 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(AccessibilityNodeData::ATTR_TEXT_SEL_START, &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(AccessibilityNodeData::ATTR_TEXT_SEL_START, &start);
+ GetIntAttribute(AccessibilityNodeData::ATTR_TEXT_SEL_END, &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(AccessibilityNodeData::ATTR_TEXT_SEL_START, startOffset);
+ GetIntAttribute(AccessibilityNodeData::ATTR_TEXT_SEL_END, endOffset);
+}
+
+QString BrowserAccessibilityQt::text(int startOffset, int endOffset) const
+{
+ return text(QAccessible::Value).mid(startOffset, endOffset - startOffset);
+}
+
+void BrowserAccessibilityQt::removeSelection(int selectionIndex)
+{
+ manager()->SetTextSelection(*this, 0, 0);
+}
+
+void BrowserAccessibilityQt::setCursorPosition(int position)
+{
+ manager()->SetTextSelection(*this, position, position);
+}
+
+void BrowserAccessibilityQt::setSelection(int selectionIndex, int startOffset, int endOffset)
+{
+ if (selectionIndex != 0)
+ return;
+ manager()->SetTextSelection(*this, startOffset, 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, GetLocalBoundsForRange(startIndex, endIndex - startIndex));
+}
+
} // namespace content
diff --git a/src/core/browser_accessibility_qt.h b/src/core/browser_accessibility_qt.h
index 839fedeb8..cda205bf2 100644
--- a/src/core/browser_accessibility_qt.h
+++ b/src/core/browser_accessibility_qt.h
@@ -50,6 +50,7 @@ namespace content {
class BrowserAccessibilityQt
: public BrowserAccessibility
, public QAccessibleInterface
+ , public QAccessibleTextInterface
{
public:
BrowserAccessibilityQt();
@@ -58,6 +59,7 @@ public:
virtual bool isValid() const Q_DECL_OVERRIDE;
virtual QObject *object() const Q_DECL_OVERRIDE;
virtual QAccessibleInterface *childAt(int x, int y) const Q_DECL_OVERRIDE;
+ virtual void *interface_cast(QAccessible::InterfaceType type) Q_DECL_OVERRIDE;
// navigation, hierarchy
virtual QAccessibleInterface *parent() const Q_DECL_OVERRIDE;
@@ -76,6 +78,21 @@ public:
void NativeAddReference() Q_DECL_OVERRIDE;
void NativeReleaseReference() Q_DECL_OVERRIDE;
bool IsNative() const Q_DECL_OVERRIDE { return true; }
+
+ // QAccessibleTextInterface
+ void addSelection(int startOffset, int endOffset) Q_DECL_OVERRIDE;
+ QString attributes(int offset, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE;
+ int cursorPosition() const Q_DECL_OVERRIDE;
+ QRect characterRect(int offset) const Q_DECL_OVERRIDE;
+ int selectionCount() const Q_DECL_OVERRIDE;
+ int offsetAtPoint(const QPoint &point) const Q_DECL_OVERRIDE;
+ void selection(int selectionIndex, int *startOffset, int *endOffset) const Q_DECL_OVERRIDE;
+ QString text(int startOffset, int endOffset) const Q_DECL_OVERRIDE;
+ void removeSelection(int selectionIndex) Q_DECL_OVERRIDE;
+ void setCursorPosition(int position) Q_DECL_OVERRIDE;
+ void setSelection(int selectionIndex, int startOffset, int endOffset) Q_DECL_OVERRIDE;
+ int characterCount() const Q_DECL_OVERRIDE;
+ void scrollToSubstring(int startIndex, int endIndex) Q_DECL_OVERRIDE;
};
}
diff --git a/tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp b/tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp
index 9fd008ab1..9bf4c69e2 100644
--- a/tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp
+++ b/tests/auto/widgets/qwebengineaccessibility/tst_qwebengineaccessibility.cpp
@@ -38,6 +38,7 @@ public Q_SLOTS:
private Q_SLOTS:
void noPage();
void hierarchy();
+ void text();
};
// This will be called before the first test function is executed.
@@ -126,5 +127,39 @@ void tst_QWebEngineView::hierarchy()
QCOMPARE(input->text(QAccessible::Value), QStringLiteral("some text"));
}
+void tst_QWebEngineView::text()
+{
+ QWebEngineView webView;
+ webView.setHtml("<html><body>" \
+ "<input type='text' value='Good morning!'></input>" \
+ "</body></html>");
+ webView.show();
+ ::waitForSignal(&webView, SIGNAL(loadFinished(bool)));
+
+ QAccessibleInterface *view = QAccessible::queryAccessibleInterface(&webView);
+ // Wait for accessibility to be fully initialized
+ QTRY_VERIFY(view->child(0)->childCount() == 1);
+ QAccessibleInterface *document = view->child(0);
+ QAccessibleInterface *grouping = document->child(0);
+ QVERIFY(grouping);
+
+ QAccessibleInterface *input = grouping->child(0);
+ QCOMPARE(input->role(), QAccessible::EditableText);
+ QCOMPARE(input->text(QAccessible::Name), QString());
+ QCOMPARE(input->text(QAccessible::Description), QString());
+ QCOMPARE(input->text(QAccessible::Value), QStringLiteral("Good morning!"));
+
+ QAccessibleTextInterface *textInterface = input->textInterface();
+ QVERIFY(textInterface);
+ QCOMPARE(textInterface->characterCount(), 13);
+ QCOMPARE(textInterface->selectionCount(), 0);
+ QCOMPARE(textInterface->text(2, 9), QStringLiteral("od morn"));
+ int start = -1;
+ int end = -1;
+ QCOMPARE(textInterface->textAtOffset(8, QAccessible::WordBoundary, &start, &end), QStringLiteral("morning"));
+ textInterface->setCursorPosition(3);
+ QTRY_COMPARE(textInterface->cursorPosition(), 3);
+}
+
QTEST_MAIN(tst_QWebEngineView)
#include "tst_qwebengineaccessibility.moc"