summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/webengine/api/qquickwebenginetestsupport.cpp47
-rw-r--r--src/webengine/api/qquickwebenginetestsupport_p.h22
-rw-r--r--src/webengine/api/qquickwebengineview.cpp3
-rw-r--r--src/webengine/plugin/testsupport/plugin.cpp2
-rw-r--r--src/webengine/plugin/testsupport/testsupport.pro2
-rw-r--r--src/webengine/render_widget_host_view_qt_delegate_quick.cpp9
-rw-r--r--tests/auto/quick/qmltests/data/tst_inputMethod.qml76
-rw-r--r--tests/auto/quick/qmltests/qmltests.pro1
-rw-r--r--tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp49
-rw-r--r--tests/auto/quick/qquickwebengineviewgraphics/qquickwebengineviewgraphics.pro2
-rw-r--r--tests/auto/quick/shared/util.h22
11 files changed, 211 insertions, 24 deletions
diff --git a/src/webengine/api/qquickwebenginetestsupport.cpp b/src/webengine/api/qquickwebenginetestsupport.cpp
index a946cc0e4..41f374766 100644
--- a/src/webengine/api/qquickwebenginetestsupport.cpp
+++ b/src/webengine/api/qquickwebenginetestsupport.cpp
@@ -62,8 +62,48 @@ void QQuickWebEngineErrorPage::loadStarted(const QUrl &provisionalUrl)
Q_EMIT loadingChanged(&loadRequest);
}
+
+QQuickWebEngineTestInputContext::QQuickWebEngineTestInputContext()
+ : m_visible(false)
+{
+}
+
+QQuickWebEngineTestInputContext::~QQuickWebEngineTestInputContext()
+{
+ release();
+}
+
+void QQuickWebEngineTestInputContext::create()
+{
+ QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
+ inputMethodPrivate->testContext = this;
+}
+
+void QQuickWebEngineTestInputContext::release()
+{
+ QInputMethodPrivate *inputMethodPrivate = QInputMethodPrivate::get(qApp->inputMethod());
+ inputMethodPrivate->testContext = 0;
+}
+
+void QQuickWebEngineTestInputContext::showInputPanel()
+{
+ m_visible = true;
+}
+
+void QQuickWebEngineTestInputContext::hideInputPanel()
+{
+ m_visible = false;
+}
+
+bool QQuickWebEngineTestInputContext::isInputPanelVisible() const
+{
+ return m_visible;
+}
+
+
QQuickWebEngineTestSupport::QQuickWebEngineTestSupport()
- : m_errorPage(new QQuickWebEngineErrorPage())
+ : m_errorPage(new QQuickWebEngineErrorPage)
+ , m_testInputContext(new QQuickWebEngineTestInputContext)
{
}
@@ -72,6 +112,11 @@ QQuickWebEngineErrorPage *QQuickWebEngineTestSupport::errorPage() const
return m_errorPage.data();
}
+QQuickWebEngineTestInputContext *QQuickWebEngineTestSupport::testInputContext() const
+{
+ return m_testInputContext.data();
+}
+
QT_END_NAMESPACE
#include "moc_qquickwebenginetestsupport_p.cpp"
diff --git a/src/webengine/api/qquickwebenginetestsupport_p.h b/src/webengine/api/qquickwebenginetestsupport_p.h
index cca8d1df4..a84d00307 100644
--- a/src/webengine/api/qquickwebenginetestsupport_p.h
+++ b/src/webengine/api/qquickwebenginetestsupport_p.h
@@ -51,6 +51,7 @@
// We mean it.
//
+#include <private/qinputmethod_p.h>
#include <private/qtwebengineglobal_p.h>
#include <QObject>
@@ -73,13 +74,33 @@ Q_SIGNALS:
void loadingChanged(QQuickWebEngineLoadRequest *loadRequest);
};
+class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineTestInputContext : public QPlatformInputContext {
+ Q_OBJECT
+
+public:
+ QQuickWebEngineTestInputContext();
+ ~QQuickWebEngineTestInputContext();
+
+ Q_INVOKABLE void create();
+ Q_INVOKABLE void release();
+
+ virtual void showInputPanel();
+ virtual void hideInputPanel();
+ virtual bool isInputPanelVisible() const;
+
+private:
+ bool m_visible;
+};
+
class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineTestSupport : public QObject {
Q_OBJECT
Q_PROPERTY(QQuickWebEngineErrorPage *errorPage READ errorPage CONSTANT FINAL)
+ Q_PROPERTY(QQuickWebEngineTestInputContext *testInputContext READ testInputContext CONSTANT FINAL)
public:
QQuickWebEngineTestSupport();
QQuickWebEngineErrorPage *errorPage() const;
+ QQuickWebEngineTestInputContext *testInputContext() const;
Q_SIGNALS:
void windowCloseRejected();
@@ -87,6 +108,7 @@ Q_SIGNALS:
private:
QScopedPointer<QQuickWebEngineErrorPage> m_errorPage;
+ QScopedPointer<QQuickWebEngineTestInputContext> m_testInputContext;
};
QT_END_NAMESPACE
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index 68a290df9..bf3ea955c 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -873,8 +873,7 @@ QQuickWebEngineView::QQuickWebEngineView(QQuickItem *parent)
Q_D(QQuickWebEngineView);
d->q_ptr = this;
this->setActiveFocusOnTab(true);
- this->setFlags(QQuickItem::ItemIsFocusScope | QQuickItem::ItemAcceptsInputMethod
- | QQuickItem::ItemAcceptsDrops);
+ this->setFlags(QQuickItem::ItemIsFocusScope | QQuickItem::ItemAcceptsDrops);
#ifndef QT_NO_ACCESSIBILITY
QQuickAccessibleAttached *accessible = QQuickAccessibleAttached::qmlAttachedProperties(this);
diff --git a/src/webengine/plugin/testsupport/plugin.cpp b/src/webengine/plugin/testsupport/plugin.cpp
index 9352e3666..c7eda2405 100644
--- a/src/webengine/plugin/testsupport/plugin.cpp
+++ b/src/webengine/plugin/testsupport/plugin.cpp
@@ -58,6 +58,8 @@ public:
qmlRegisterType<QQuickWebEngineTestSupport>(uri, 1, 0, "WebEngineTestSupport");
qmlRegisterUncreatableType<QQuickWebEngineErrorPage>(uri, 1, 0, "WebEngineErrorPage",
tr("Cannot create a separate instance of WebEngineErrorPage"));
+ qmlRegisterUncreatableType<QQuickWebEngineTestInputContext>(uri, 1, 0, "TestInputContext",
+ tr("Cannot create a separate instance of WebEngineErrorPage"));
}
};
diff --git a/src/webengine/plugin/testsupport/testsupport.pro b/src/webengine/plugin/testsupport/testsupport.pro
index 1a45ad56a..2804635f8 100644
--- a/src/webengine/plugin/testsupport/testsupport.pro
+++ b/src/webengine/plugin/testsupport/testsupport.pro
@@ -4,7 +4,7 @@ TARGETPATH = QtWebEngine/testsupport
IMPORT_VERSION = 1.0
QT += webengine qml quick
-QT_PRIVATE += webengine-private
+QT_PRIVATE += webengine-private gui-private
INCLUDEPATH += $$QTWEBENGINE_ROOT/src/core $$QTWEBENGINE_ROOT/src/webengine $$QTWEBENGINE_ROOT/src/webengine/api
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
index 749a2e0d8..86f3aaa64 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
@@ -228,14 +228,15 @@ void RenderWidgetHostViewQtDelegateQuick::resize(int width, int height)
void RenderWidgetHostViewQtDelegateQuick::inputMethodStateChanged(bool editorVisible)
{
- if (qApp->inputMethod()->isVisible() == editorVisible)
- return;
+ setFlag(QQuickItem::ItemAcceptsInputMethod, editorVisible);
+
+ if (parentItem())
+ parentItem()->setFlag(QQuickItem::ItemAcceptsInputMethod, editorVisible);
- if (parentItem() && parentItem()->flags() & QQuickItem::ItemAcceptsInputMethod) {
+ if (qApp->inputMethod()->isVisible() != editorVisible) {
qApp->inputMethod()->update(Qt::ImQueryInput | Qt::ImEnabled | Qt::ImHints);
qApp->inputMethod()->setVisible(editorVisible);
}
-
}
bool RenderWidgetHostViewQtDelegateQuick::event(QEvent *event)
diff --git a/tests/auto/quick/qmltests/data/tst_inputMethod.qml b/tests/auto/quick/qmltests/data/tst_inputMethod.qml
new file mode 100644
index 000000000..c09a8bdd9
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_inputMethod.qml
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 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:GPL-EXCEPT$
+** 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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtTest 1.0
+import QtWebEngine 1.4
+import QtWebEngine.testsupport 1.0
+
+TestWebEngineView {
+ id: webEngineView
+ width: 200
+ height: 400
+
+ testSupport: WebEngineTestSupport { }
+
+ TestCase {
+ name: "WebEngineViewInputMethod"
+ when: windowShown
+
+ function init() {
+ testSupport.testInputContext.create();
+ }
+
+ function cleanup() {
+ testSupport.testInputContext.release();
+ }
+
+ function test_softwareInputPanel() {
+ verify(!Qt.inputMethod.visible);
+ webEngineView.loadHtml(
+ "<html><body>" +
+ " <form><input id='textInput' type='text' /></form>" +
+ "</body></html");
+ verify(webEngineView.waitForLoadSucceeded());
+
+ verify(!getActiveElementId());
+ verify(!Qt.inputMethod.visible);
+
+ // Show input panel
+ webEngineView.runJavaScript("document.getElementById('textInput').focus()");
+ webEngineView.verifyElementHasFocus("textInput");
+ tryVerify(function() { return Qt.inputMethod.visible; });
+
+ // Hide input panel
+ webEngineView.runJavaScript("document.getElementById('textInput').blur()");
+ verify(!getActiveElementId());
+ tryVerify(function() { return !Qt.inputMethod.visible; });
+ }
+ }
+}
+
diff --git a/tests/auto/quick/qmltests/qmltests.pro b/tests/auto/quick/qmltests/qmltests.pro
index 40fba4512..3973ede14 100644
--- a/tests/auto/quick/qmltests/qmltests.pro
+++ b/tests/auto/quick/qmltests/qmltests.pro
@@ -52,6 +52,7 @@ OTHER_FILES += \
$$PWD/data/tst_focusOnNavigation.qml \
$$PWD/data/tst_formValidation.qml \
$$PWD/data/tst_geopermission.qml \
+ $$PWD/data/tst_inputMethod.qml \
$$PWD/data/tst_javaScriptDialogs.qml \
$$PWD/data/tst_linkHovered.qml \
$$PWD/data/tst_loadFail.qml \
diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
index 49f1a0f2a..8af5a2808 100644
--- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
+++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp
@@ -437,50 +437,69 @@ void tst_QQuickWebEngineView::transparentWebEngineViews()
void tst_QQuickWebEngineView::inputMethod()
{
-#if !defined(QQUICKWEBENGINEVIEW_ITEMACCEPTSINPUTMETHOD)
- QSKIP("QQUICKWEBENGINEVIEW_ITEMACCEPTSINPUTMETHOD");
-#else
+ m_window->show();
+ QTRY_VERIFY(qApp->focusObject());
+ QQuickItem *input;
+
QQuickWebEngineView *view = webEngineView();
view->setUrl(urlFromTestPath("html/inputmethod.html"));
QVERIFY(waitForLoadSucceeded(view));
+ input = qobject_cast<QQuickItem *>(qApp->focusObject());
+ QVERIFY(!input->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
QVERIFY(!view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
+
runJavaScript("document.getElementById('inputField').focus();");
+ QTRY_COMPARE(activeElementId(view), QStringLiteral("inputField"));
+ input = qobject_cast<QQuickItem *>(qApp->focusObject());
+ QTRY_VERIFY(input->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
QVERIFY(view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
+
runJavaScript("document.getElementById('inputField').blur();");
+ QTRY_VERIFY(activeElementId(view).isEmpty());
+ input = qobject_cast<QQuickItem *>(qApp->focusObject());
+ QTRY_VERIFY(!input->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
QVERIFY(!view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
-#endif
}
void tst_QQuickWebEngineView::inputMethodHints()
{
-#if !defined(QQUICKWEBENGINEVIEW_ITEMACCEPTSINPUTMETHOD)
- QSKIP("QQUICKWEBENGINEVIEW_ITEMACCEPTSINPUTMETHOD");
-#else
- QQuickWebEngineView *view = webEngineView();
+ m_window->show();
+ QTRY_VERIFY(qApp->focusObject());
+ QQuickItem *input;
+ QQuickWebEngineView *view = webEngineView();
view->setUrl(urlFromTestPath("html/inputmethod.html"));
QVERIFY(waitForLoadSucceeded(view));
+ // Initialize input fields with values to check input method query is being updated.
+ runJavaScript("document.getElementById('emailInputField').value = 'a@b.com';");
+ runJavaScript("document.getElementById('editableDiv').innerText = 'bla';");
+
// Setting focus on an input element results in an element in its shadow tree becoming the focus node.
// Input hints should not be set from this shadow tree node but from the input element itself.
runJavaScript("document.getElementById('emailInputField').focus();");
+ QTRY_COMPARE(activeElementId(view), QStringLiteral("emailInputField"));
+ input = qobject_cast<QQuickItem *>(qApp->focusObject());
+ QTRY_COMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("a@b.com"));
+ QVERIFY(input->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
QVERIFY(view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
QInputMethodQueryEvent query(Qt::ImHints);
- QGuiApplication::sendEvent(view, &query);
- Qt::InputMethodHints hints(query.value(Qt::ImHints).toUInt() & Qt::ImhExclusiveInputMask);
- QCOMPARE(hints, Qt::ImhEmailCharactersOnly);
+ QGuiApplication::sendEvent(input, &query);
+ QTRY_COMPARE(Qt::InputMethodHints(query.value(Qt::ImHints).toUInt() & Qt::ImhExclusiveInputMask), Qt::ImhEmailCharactersOnly);
// The focus of an editable DIV is given directly to it, so no shadow root element
// is necessary. This tests the WebPage::editorState() method ability to get the
// right element without breaking.
runJavaScript("document.getElementById('editableDiv').focus();");
+ QTRY_COMPARE(activeElementId(view), QStringLiteral("editableDiv"));
+ input = qobject_cast<QQuickItem *>(qApp->focusObject());
+ QTRY_COMPARE(input->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("bla"));
+ QVERIFY(input->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
QVERIFY(view->flags().testFlag(QQuickItem::ItemAcceptsInputMethod));
query = QInputMethodQueryEvent(Qt::ImHints);
- QGuiApplication::sendEvent(view, &query);
- hints = Qt::InputMethodHints(query.value(Qt::ImHints).toUInt());
- QCOMPARE(hints, Qt::ImhNone);
-#endif
+ QGuiApplication::sendEvent(input, &query);
+ QTRY_COMPARE(Qt::InputMethodHints(query.value(Qt::ImHints).toUInt()), Qt::ImhPreferLowercase | Qt::ImhMultiLine);
}
void tst_QQuickWebEngineView::setZoomFactor()
diff --git a/tests/auto/quick/qquickwebengineviewgraphics/qquickwebengineviewgraphics.pro b/tests/auto/quick/qquickwebengineviewgraphics/qquickwebengineviewgraphics.pro
index 9471def00..2a2155e44 100644
--- a/tests/auto/quick/qquickwebengineviewgraphics/qquickwebengineviewgraphics.pro
+++ b/tests/auto/quick/qquickwebengineviewgraphics/qquickwebengineviewgraphics.pro
@@ -1,4 +1,4 @@
include(../tests.pri)
CONFIG -= testcase # remove, once this passes in the CI
exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc
-QT_PRIVATE += webengine-private
+QT_PRIVATE += webengine-private gui-private
diff --git a/tests/auto/quick/shared/util.h b/tests/auto/quick/shared/util.h
index dce0afb8e..98f19bd49 100644
--- a/tests/auto/quick/shared/util.h
+++ b/tests/auto/quick/shared/util.h
@@ -142,4 +142,26 @@ inline QString bodyInnerText(QQuickWebEngineView *webEngineView)
return arguments.at(1).toString();
}
+inline QString activeElementId(QQuickWebEngineView *webEngineView)
+{
+ qRegisterMetaType<QQuickWebEngineView::JavaScriptConsoleMessageLevel>("JavaScriptConsoleMessageLevel");
+ QSignalSpy consoleMessageSpy(webEngineView, &QQuickWebEngineView::javaScriptConsoleMessage);
+
+ webEngineView->runJavaScript(
+ "if (document.activeElement == null)"
+ " console.log('');"
+ "else"
+ " console.log(document.activeElement.id);"
+ );
+
+ if (!consoleMessageSpy.wait())
+ return QString();
+
+ QList<QVariant> arguments = consoleMessageSpy.takeFirst();
+ if (static_cast<QQuickWebEngineView::JavaScriptConsoleMessageLevel>(arguments.at(0).toInt()) != QQuickWebEngineView::InfoMessageLevel)
+ return QString();
+
+ return arguments.at(1).toString();
+}
+
#endif /* UTIL_H */