summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
diff options
context:
space:
mode:
authorPeter Varga <pvarga@inf.u-szeged.hu>2018-04-18 16:46:31 +0200
committerPeter Varga <pvarga@inf.u-szeged.hu>2018-04-26 14:11:38 +0000
commit216240a31baae6e54e38de8157332f272ddf57a7 (patch)
treef9c14206827960bc8e91c9d1704398568012fb07 /tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
parentb3b95a5bf3f04c18182fcc4519ec8285e290037d (diff)
Fix finishing IME composition
Call RenderWidgetHostImpl::ImeCommitText() instead of RenderWidgetHostImpl::ImeFinishComposingText() to trigger the necessary JavaScript events on composing. This fixes IME composition (eg. for dead keys) on web pages which use custom JavaScript IME handler like facebook. Task-number: QTBUG-66046 Change-Id: Ibc177995ba6e85eca42ae333decacfe6e788ce41 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp')
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp136
1 files changed, 136 insertions, 0 deletions
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 207836bef..24e581870 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -173,6 +173,7 @@ private Q_SLOTS:
void imeCompositionQueryEvent_data();
void imeCompositionQueryEvent();
void newlineInTextarea();
+ void imeJSInputEvents();
void mouseLeave();
@@ -2249,6 +2250,141 @@ void tst_QWebEngineView::newlineInTextarea()
QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("\n\nthird line"));
}
+void tst_QWebEngineView::imeJSInputEvents()
+{
+ QWebEngineView view;
+ view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
+ view.show();
+
+ auto logLines = [&view]() -> QStringList {
+ return evaluateJavaScriptSync(view.page(), "log.textContent").toString().split("\n").filter(QRegExp(".+"));
+ };
+
+ QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
+ view.page()->setHtml("<html>"
+ "<head><script>"
+ " var input, log;"
+ " function verboseEvent(ev) {"
+ " log.textContent += ev + ' ' + ev.type + ' ' + ev.data + '\\n';"
+ " }"
+ " function clear(ev) {"
+ " log.textContent = '';"
+ " input.textContent = '';"
+ " }"
+ " function init() {"
+ " input = document.getElementById('input');"
+ " log = document.getElementById('log');"
+ " events = [ 'textInput', 'beforeinput', 'input', 'compositionstart', 'compositionupdate', 'compositionend' ];"
+ " for (var e in events)"
+ " input.addEventListener(events[e], verboseEvent);"
+ " }"
+ "</script></head>"
+ "<body onload='init()'>"
+ " <div id='input' contenteditable='true' style='border-style: solid;'></div>"
+ " <pre id='log'></pre>"
+ "</body></html>");
+ QVERIFY(loadFinishedSpy.wait());
+
+ evaluateJavaScriptSync(view.page(), "document.getElementById('input').focus()");
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input"));
+
+ // 1. Commit text (this is how dead keys work on Linux).
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent event("", attributes);
+ event.setCommitString("commit");
+ QApplication::sendEvent(view.focusProxy(), &event);
+ qApp->processEvents();
+ }
+
+ // Simply committing text should not trigger any JS composition event.
+ QTRY_COMPARE(logLines().count(), 3);
+ QCOMPARE(logLines()[0], "[object InputEvent] beforeinput commit");
+ QCOMPARE(logLines()[1], "[object TextEvent] textInput commit");
+ QCOMPARE(logLines()[2], "[object InputEvent] input commit");
+
+ evaluateJavaScriptSync(view.page(), "clear()");
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "log.textContent + input.textContent").toString().isEmpty());
+
+ // 2. Start composition then commit text (this is how dead keys work on macOS).
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent event("preedit", attributes);
+ QApplication::sendEvent(view.focusProxy(), &event);
+ qApp->processEvents();
+ }
+
+ QTRY_COMPARE(logLines().count(), 4);
+ QCOMPARE(logLines()[0], "[object CompositionEvent] compositionstart ");
+ QCOMPARE(logLines()[1], "[object InputEvent] beforeinput preedit");
+ QCOMPARE(logLines()[2], "[object CompositionEvent] compositionupdate preedit");
+ QCOMPARE(logLines()[3], "[object InputEvent] input preedit");
+
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent event("", attributes);
+ event.setCommitString("commit");
+ QApplication::sendEvent(view.focusProxy(), &event);
+ qApp->processEvents();
+ }
+
+ QTRY_COMPARE(logLines().count(), 9);
+ QCOMPARE(logLines()[4], "[object InputEvent] beforeinput commit");
+ QCOMPARE(logLines()[5], "[object CompositionEvent] compositionupdate commit");
+ QCOMPARE(logLines()[6], "[object TextEvent] textInput commit");
+ QCOMPARE(logLines()[7], "[object InputEvent] input commit");
+ QCOMPARE(logLines()[8], "[object CompositionEvent] compositionend commit");
+
+ evaluateJavaScriptSync(view.page(), "clear()");
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "log.textContent + input.textContent").toString().isEmpty());
+
+ // 3. Start composition then cancel it with an empty IME event.
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent event("preedit", attributes);
+ QApplication::sendEvent(view.focusProxy(), &event);
+ qApp->processEvents();
+ }
+
+ QTRY_COMPARE(logLines().count(), 4);
+ QCOMPARE(logLines()[0], "[object CompositionEvent] compositionstart ");
+ QCOMPARE(logLines()[1], "[object InputEvent] beforeinput preedit");
+ QCOMPARE(logLines()[2], "[object CompositionEvent] compositionupdate preedit");
+ QCOMPARE(logLines()[3], "[object InputEvent] input preedit");
+
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent event("", attributes);
+ QApplication::sendEvent(view.focusProxy(), &event);
+ qApp->processEvents();
+ }
+
+ QTRY_COMPARE(logLines().count(), 9);
+ QCOMPARE(logLines()[4], "[object InputEvent] beforeinput ");
+ QCOMPARE(logLines()[5], "[object CompositionEvent] compositionupdate ");
+ QCOMPARE(logLines()[6], "[object TextEvent] textInput ");
+ QCOMPARE(logLines()[7], "[object InputEvent] input null");
+ QCOMPARE(logLines()[8], "[object CompositionEvent] compositionend ");
+
+ evaluateJavaScriptSync(view.page(), "clear()");
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "log.textContent + input.textContent").toString().isEmpty());
+
+ // 4. Send empty IME event.
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent event("", attributes);
+ QApplication::sendEvent(view.focusProxy(), &event);
+ qApp->processEvents();
+ }
+
+ // No JS event is expected.
+ QTest::qWait(100);
+ QVERIFY(logLines().isEmpty());
+
+ evaluateJavaScriptSync(view.page(), "clear()");
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "log.textContent + input.textContent").toString().isEmpty());
+}
+
void tst_QWebEngineView::imeCompositionQueryEvent_data()
{
QTest::addColumn<QString>("receiverObjectName");