diff options
author | Peter Varga <pvarga@inf.u-szeged.hu> | 2018-04-18 16:46:31 +0200 |
---|---|---|
committer | Peter Varga <pvarga@inf.u-szeged.hu> | 2018-04-26 14:11:38 +0000 |
commit | 216240a31baae6e54e38de8157332f272ddf57a7 (patch) | |
tree | f9c14206827960bc8e91c9d1704398568012fb07 /tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp | |
parent | b3b95a5bf3f04c18182fcc4519ec8285e290037d (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.cpp | 136 |
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"); |