summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp565
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp385
2 files changed, 385 insertions, 565 deletions
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 4d073e94c..b03418aea 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -120,8 +120,6 @@ private Q_SLOTS:
void testLocalStorageVisibility();
void testEnablePersistentStorage();
void consoleOutput();
- void inputMethods_data();
- void inputMethods();
void errorPageExtension();
void errorPageExtensionLoadFinished();
void userAgentNewlineStripping();
@@ -1631,569 +1629,6 @@ void tst_QWebEnginePage::backActionUpdate()
QVERIFY(action->isEnabled());
}
-void tst_QWebEnginePage::inputMethods_data()
-{
- QTest::addColumn<QString>("viewType");
- QTest::newRow("QWebEngineView") << "QWebEngineView";
- QTest::newRow("QGraphicsWebView") << "QGraphicsWebView";
-}
-
-#if defined(QWEBENGINEPAGE_INPUTMETHODQUERY)
-static void clickOnPage(QWebEnginePage* page, const QPoint& position)
-{
- QMouseEvent evpres(QEvent::MouseButtonPress, position, Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
- page->event(&evpres);
- QMouseEvent evrel(QEvent::MouseButtonRelease, position, Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
- page->event(&evrel);
-}
-#endif
-
-void tst_QWebEnginePage::inputMethods()
-{
-#if !defined(QWEBENGINEPAGE_INPUTMETHODQUERY)
- QSKIP("QWEBENGINEPAGE_INPUTMETHODQUERY");
-#else
- QFETCH(QString, viewType);
- QWebEnginePage* page = new QWebEnginePage;
- QObject* view = 0;
- QScopedPointer<QObject> container(0);
- if (viewType == "QWebEngineView") {
- QWebEngineView* wv = new QWebEngineView;
- wv->setPage(page);
- view = wv;
- container.reset(view);
- } else if (viewType == "QGraphicsWebView") {
- QGraphicsWebView* wv = new QGraphicsWebView;
- wv->setPage(page);
- view = wv;
-
- QGraphicsView* gv = new QGraphicsView;
- QGraphicsScene* scene = new QGraphicsScene(gv);
- gv->setScene(scene);
- scene->addItem(wv);
- wv->setGeometry(QRect(0, 0, 500, 500));
-
- container.reset(gv);
- } else
- QVERIFY2(false, "Unknown view type");
-
- page->settings()->setFontFamily(QWebEngineSettings::SerifFont, page->settings()->fontFamily(QWebEngineSettings::FixedFont));
- page->setHtml("<html><body>" \
- "<input type='text' id='input1' style='font-family: serif' value='' maxlength='20'/><br>" \
- "<input type='password'/>" \
- "</body></html>");
- page->mainFrame()->setFocus();
-
- TestInputContext testContext;
-
- QWebEngineElementCollection inputs = page->mainFrame()->documentElement().findAll("input");
- QPoint textInputCenter = inputs.at(0).geometry().center();
-
- clickOnPage(page, textInputCenter);
-
- //ImMicroFocus
- QVariant variant = page->inputMethodQuery(Qt::ImMicroFocus);
- QVERIFY(inputs.at(0).geometry().contains(variant.toRect().topLeft()));
-
- // We assigned the serif font famility to be the same as the fixef font family.
- // Then test ImFont on a serif styled element, we should get our fixef font family.
- variant = page->inputMethodQuery(Qt::ImFont);
- QFont font = variant.value<QFont>();
- QCOMPARE(page->settings()->fontFamily(QWebEngineSettings::FixedFont), font.family());
-
- QList<QInputMethodEvent::Attribute> inputAttributes;
-
- //Insert text.
- {
- QInputMethodEvent eventText("QtWebEngine", inputAttributes);
- QSignalSpy signalSpy(page, SIGNAL(microFocusChanged()));
- page->event(&eventText);
- QCOMPARE(signalSpy.count(), 0);
- }
-
- {
- QInputMethodEvent eventText("", inputAttributes);
- eventText.setCommitString(QString("QtWebEngine"), 0, 0);
- page->event(&eventText);
- }
-
- //ImMaximumTextLength
- variant = page->inputMethodQuery(Qt::ImMaximumTextLength);
- QCOMPARE(20, variant.toInt());
-
- //Set selection
- inputAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 3, 2, QVariant());
- QInputMethodEvent eventSelection("",inputAttributes);
- page->event(&eventSelection);
-
- //ImAnchorPosition
- variant = page->inputMethodQuery(Qt::ImAnchorPosition);
- int anchorPosition = variant.toInt();
- QCOMPARE(anchorPosition, 3);
-
- //ImCursorPosition
- variant = page->inputMethodQuery(Qt::ImCursorPosition);
- int cursorPosition = variant.toInt();
- QCOMPARE(cursorPosition, 5);
-
- //ImCurrentSelection
- variant = page->inputMethodQuery(Qt::ImCurrentSelection);
- QString selectionValue = variant.value<QString>();
- QCOMPARE(selectionValue, QString("eb"));
-
- //Set selection with negative length
- inputAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 6, -5, QVariant());
- QInputMethodEvent eventSelection3("",inputAttributes);
- page->event(&eventSelection3);
-
- //ImAnchorPosition
- variant = page->inputMethodQuery(Qt::ImAnchorPosition);
- anchorPosition = variant.toInt();
- QCOMPARE(anchorPosition, 1);
-
- //ImCursorPosition
- variant = page->inputMethodQuery(Qt::ImCursorPosition);
- cursorPosition = variant.toInt();
- QCOMPARE(cursorPosition, 6);
-
- //ImCurrentSelection
- variant = page->inputMethodQuery(Qt::ImCurrentSelection);
- selectionValue = variant.value<QString>();
- QCOMPARE(selectionValue, QString("tWebK"));
-
- //ImSurroundingText
- variant = page->inputMethodQuery(Qt::ImSurroundingText);
- QString value = variant.value<QString>();
- QCOMPARE(value, QString("QtWebEngine"));
-
- {
- QList<QInputMethodEvent::Attribute> attributes;
- // Clear the selection, so the next test does not clear any contents.
- QInputMethodEvent::Attribute newSelection(QInputMethodEvent::Selection, 0, 0, QVariant());
- attributes.append(newSelection);
- QInputMethodEvent event("composition", attributes);
- page->event(&event);
- }
-
- // A ongoing composition should not change the surrounding text before it is committed.
- variant = page->inputMethodQuery(Qt::ImSurroundingText);
- value = variant.value<QString>();
- QCOMPARE(value, QString("QtWebEngine"));
-
- // Cancel current composition first
- inputAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 0, 0, QVariant());
- QInputMethodEvent eventSelection4("", inputAttributes);
- page->event(&eventSelection4);
-
- // START - Tests for Selection when the Editor is NOT in Composition mode
-
- // LEFT to RIGHT selection
- // Deselect the selection by sending MouseButtonPress events
- // This moves the current cursor to the end of the text
- clickOnPage(page, textInputCenter);
-
- {
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event(QString(), attributes);
- event.setCommitString("XXX", 0, 0);
- page->event(&event);
- event.setCommitString(QString(), -2, 2); // Erase two characters.
- page->event(&event);
- event.setCommitString(QString(), -1, 1); // Erase one character.
- page->event(&event);
- variant = page->inputMethodQuery(Qt::ImSurroundingText);
- value = variant.value<QString>();
- QCOMPARE(value, QString("QtWebEngine"));
- }
-
- //Move to the start of the line
- page->triggerAction(QWebEnginePage::MoveToStartOfLine);
-
- QKeyEvent keyRightEventPress(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier);
- QKeyEvent keyRightEventRelease(QEvent::KeyRelease, Qt::Key_Right, Qt::NoModifier);
-
- //Move 2 characters RIGHT
- for (int j = 0; j < 2; ++j) {
- page->event(&keyRightEventPress);
- page->event(&keyRightEventRelease);
- }
-
- //Select to the end of the line
- page->triggerAction(QWebEnginePage::SelectEndOfLine);
-
- //ImAnchorPosition QtWebEngine
- variant = page->inputMethodQuery(Qt::ImAnchorPosition);
- anchorPosition = variant.toInt();
- QCOMPARE(anchorPosition, 2);
-
- //ImCursorPosition
- variant = page->inputMethodQuery(Qt::ImCursorPosition);
- cursorPosition = variant.toInt();
- QCOMPARE(cursorPosition, 8);
-
- //ImCurrentSelection
- variant = page->inputMethodQuery(Qt::ImCurrentSelection);
- selectionValue = variant.value<QString>();
- QCOMPARE(selectionValue, QString("WebKit"));
-
- //RIGHT to LEFT selection
- //Deselect the selection (this moves the current cursor to the end of the text)
- clickOnPage(page, textInputCenter);
-
- //ImAnchorPosition
- variant = page->inputMethodQuery(Qt::ImAnchorPosition);
- anchorPosition = variant.toInt();
- QCOMPARE(anchorPosition, 8);
-
- //ImCursorPosition
- variant = page->inputMethodQuery(Qt::ImCursorPosition);
- cursorPosition = variant.toInt();
- QCOMPARE(cursorPosition, 8);
-
- //ImCurrentSelection
- variant = page->inputMethodQuery(Qt::ImCurrentSelection);
- selectionValue = variant.value<QString>();
- QCOMPARE(selectionValue, QString(""));
-
- QKeyEvent keyLeftEventPress(QEvent::KeyPress, Qt::Key_Left, Qt::NoModifier);
- QKeyEvent keyLeftEventRelease(QEvent::KeyRelease, Qt::Key_Left, Qt::NoModifier);
-
- //Move 2 characters LEFT
- for (int i = 0; i < 2; ++i) {
- page->event(&keyLeftEventPress);
- page->event(&keyLeftEventRelease);
- }
-
- //Select to the start of the line
- page->triggerAction(QWebEnginePage::SelectStartOfLine);
-
- //ImAnchorPosition
- variant = page->inputMethodQuery(Qt::ImAnchorPosition);
- anchorPosition = variant.toInt();
- QCOMPARE(anchorPosition, 6);
-
- //ImCursorPosition
- variant = page->inputMethodQuery(Qt::ImCursorPosition);
- cursorPosition = variant.toInt();
- QCOMPARE(cursorPosition, 0);
-
- //ImCurrentSelection
- variant = page->inputMethodQuery(Qt::ImCurrentSelection);
- selectionValue = variant.value<QString>();
- QCOMPARE(selectionValue, QString("QtWebK"));
-
- //END - Tests for Selection when the Editor is not in Composition mode
-
- page->setHtml("<html><body>" \
- "<input type='text' id='input4' value='QtWebEngine inputMethod'/>" \
- "</body></html>");
- evaluateJavaScriptSync(page, "var inputEle = document.getElementById('input4'); inputEle.focus(); inputEle.select();");
-
- // Clear the selection, also cancel the ongoing composition if there is one.
- {
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent::Attribute newSelection(QInputMethodEvent::Selection, 0, 0, QVariant());
- attributes.append(newSelection);
- QInputMethodEvent event("", attributes);
- page->event(&event);
- }
-
- // ImCurrentSelection
- variant = page->inputMethodQuery(Qt::ImCurrentSelection);
- selectionValue = variant.value<QString>();
- QCOMPARE(selectionValue, QString(""));
-
- variant = page->inputMethodQuery(Qt::ImSurroundingText);
- QString surroundingValue = variant.value<QString>();
- QCOMPARE(surroundingValue, QString("QtWebEngine inputMethod"));
-
- // ImAnchorPosition
- variant = page->inputMethodQuery(Qt::ImAnchorPosition);
- anchorPosition = variant.toInt();
- QCOMPARE(anchorPosition, 0);
-
- // ImCursorPosition
- variant = page->inputMethodQuery(Qt::ImCursorPosition);
- cursorPosition = variant.toInt();
- QCOMPARE(cursorPosition, 0);
-
- // 1. Insert a character to the beginning of the line.
- // Send temporary text, which makes the editor has composition 'm'.
- {
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event("m", attributes);
- page->event(&event);
- }
-
- // ImCurrentSelection
- variant = page->inputMethodQuery(Qt::ImCurrentSelection);
- selectionValue = variant.value<QString>();
- QCOMPARE(selectionValue, QString(""));
-
- // ImSurroundingText
- variant = page->inputMethodQuery(Qt::ImSurroundingText);
- surroundingValue = variant.value<QString>();
- QCOMPARE(surroundingValue, QString("QtWebEngine inputMethod"));
-
- // ImCursorPosition
- variant = page->inputMethodQuery(Qt::ImCursorPosition);
- cursorPosition = variant.toInt();
- QCOMPARE(cursorPosition, 0);
-
- // ImAnchorPosition
- variant = page->inputMethodQuery(Qt::ImAnchorPosition);
- anchorPosition = variant.toInt();
- QCOMPARE(anchorPosition, 0);
-
- // Send temporary text, which makes the editor has composition 'n'.
- {
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event("n", attributes);
- page->event(&event);
- }
-
- // ImCurrentSelection
- variant = page->inputMethodQuery(Qt::ImCurrentSelection);
- selectionValue = variant.value<QString>();
- QCOMPARE(selectionValue, QString(""));
-
- // ImSurroundingText
- variant = page->inputMethodQuery(Qt::ImSurroundingText);
- surroundingValue = variant.value<QString>();
- QCOMPARE(surroundingValue, QString("QtWebEngine inputMethod"));
-
- // ImCursorPosition
- variant = page->inputMethodQuery(Qt::ImCursorPosition);
- cursorPosition = variant.toInt();
- QCOMPARE(cursorPosition, 0);
-
- // ImAnchorPosition
- variant = page->inputMethodQuery(Qt::ImAnchorPosition);
- anchorPosition = variant.toInt();
- QCOMPARE(anchorPosition, 0);
-
- // Send commit text, which makes the editor conforms composition.
- {
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event("", attributes);
- event.setCommitString("o");
- page->event(&event);
- }
-
- // ImCurrentSelection
- variant = page->inputMethodQuery(Qt::ImCurrentSelection);
- selectionValue = variant.value<QString>();
- QCOMPARE(selectionValue, QString(""));
-
- // ImSurroundingText
- variant = page->inputMethodQuery(Qt::ImSurroundingText);
- surroundingValue = variant.value<QString>();
- QCOMPARE(surroundingValue, QString("oQtWebEngine inputMethod"));
-
- // ImCursorPosition
- variant = page->inputMethodQuery(Qt::ImCursorPosition);
- cursorPosition = variant.toInt();
- QCOMPARE(cursorPosition, 1);
-
- // ImAnchorPosition
- variant = page->inputMethodQuery(Qt::ImAnchorPosition);
- anchorPosition = variant.toInt();
- QCOMPARE(anchorPosition, 1);
-
- // 2. insert a character to the middle of the line.
- // Send temporary text, which makes the editor has composition 'd'.
- {
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event("d", attributes);
- page->event(&event);
- }
-
- // ImCurrentSelection
- variant = page->inputMethodQuery(Qt::ImCurrentSelection);
- selectionValue = variant.value<QString>();
- QCOMPARE(selectionValue, QString(""));
-
- // ImSurroundingText
- variant = page->inputMethodQuery(Qt::ImSurroundingText);
- surroundingValue = variant.value<QString>();
- QCOMPARE(surroundingValue, QString("oQtWebEngine inputMethod"));
-
- // ImCursorPosition
- variant = page->inputMethodQuery(Qt::ImCursorPosition);
- cursorPosition = variant.toInt();
- QCOMPARE(cursorPosition, 1);
-
- // ImAnchorPosition
- variant = page->inputMethodQuery(Qt::ImAnchorPosition);
- anchorPosition = variant.toInt();
- QCOMPARE(anchorPosition, 1);
-
- // Send commit text, which makes the editor conforms composition.
- {
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event("", attributes);
- event.setCommitString("e");
- page->event(&event);
- }
-
- // ImCurrentSelection
- variant = page->inputMethodQuery(Qt::ImCurrentSelection);
- selectionValue = variant.value<QString>();
- QCOMPARE(selectionValue, QString(""));
-
- // ImSurroundingText
- variant = page->inputMethodQuery(Qt::ImSurroundingText);
- surroundingValue = variant.value<QString>();
- QCOMPARE(surroundingValue, QString("oeQtWebEngine inputMethod"));
-
- // ImCursorPosition
- variant = page->inputMethodQuery(Qt::ImCursorPosition);
- cursorPosition = variant.toInt();
- QCOMPARE(cursorPosition, 2);
-
- // ImAnchorPosition
- variant = page->inputMethodQuery(Qt::ImAnchorPosition);
- anchorPosition = variant.toInt();
- QCOMPARE(anchorPosition, 2);
-
- // 3. Insert a character to the end of the line.
- page->triggerAction(QWebEnginePage::MoveToEndOfLine);
-
- // Send temporary text, which makes the editor has composition 't'.
- {
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event("t", attributes);
- page->event(&event);
- }
-
- // ImCurrentSelection
- variant = page->inputMethodQuery(Qt::ImCurrentSelection);
- selectionValue = variant.value<QString>();
- QCOMPARE(selectionValue, QString(""));
-
- // ImSurroundingText
- variant = page->inputMethodQuery(Qt::ImSurroundingText);
- surroundingValue = variant.value<QString>();
- QCOMPARE(surroundingValue, QString("oeQtWebEngine inputMethod"));
-
- // ImCursorPosition
- variant = page->inputMethodQuery(Qt::ImCursorPosition);
- cursorPosition = variant.toInt();
- QCOMPARE(cursorPosition, 22);
-
- // ImAnchorPosition
- variant = page->inputMethodQuery(Qt::ImAnchorPosition);
- anchorPosition = variant.toInt();
- QCOMPARE(anchorPosition, 22);
-
- // Send commit text, which makes the editor conforms composition.
- {
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event("", attributes);
- event.setCommitString("t");
- page->event(&event);
- }
-
- // ImCurrentSelection
- variant = page->inputMethodQuery(Qt::ImCurrentSelection);
- selectionValue = variant.value<QString>();
- QCOMPARE(selectionValue, QString(""));
-
- // ImSurroundingText
- variant = page->inputMethodQuery(Qt::ImSurroundingText);
- surroundingValue = variant.value<QString>();
- QCOMPARE(surroundingValue, QString("oeQtWebEngine inputMethodt"));
-
- // ImCursorPosition
- variant = page->inputMethodQuery(Qt::ImCursorPosition);
- cursorPosition = variant.toInt();
- QCOMPARE(cursorPosition, 23);
-
- // ImAnchorPosition
- variant = page->inputMethodQuery(Qt::ImAnchorPosition);
- anchorPosition = variant.toInt();
- QCOMPARE(anchorPosition, 23);
-
- // 4. Replace the selection.
- page->triggerAction(QWebEnginePage::SelectPreviousWord);
-
- // ImCurrentSelection
- variant = page->inputMethodQuery(Qt::ImCurrentSelection);
- selectionValue = variant.value<QString>();
- QCOMPARE(selectionValue, QString("inputMethodt"));
-
- // ImSurroundingText
- variant = page->inputMethodQuery(Qt::ImSurroundingText);
- surroundingValue = variant.value<QString>();
- QCOMPARE(surroundingValue, QString("oeQtWebEngine inputMethodt"));
-
- // ImCursorPosition
- variant = page->inputMethodQuery(Qt::ImCursorPosition);
- cursorPosition = variant.toInt();
- QCOMPARE(cursorPosition, 11);
-
- // ImAnchorPosition
- variant = page->inputMethodQuery(Qt::ImAnchorPosition);
- anchorPosition = variant.toInt();
- QCOMPARE(anchorPosition, 23);
-
- // Send temporary text, which makes the editor has composition 'w'.
- {
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event("w", attributes);
- page->event(&event);
- }
-
- // ImCurrentSelection
- variant = page->inputMethodQuery(Qt::ImCurrentSelection);
- selectionValue = variant.value<QString>();
- QCOMPARE(selectionValue, QString(""));
-
- // ImSurroundingText
- variant = page->inputMethodQuery(Qt::ImSurroundingText);
- surroundingValue = variant.value<QString>();
- QCOMPARE(surroundingValue, QString("oeQtWebEngine "));
-
- // ImCursorPosition
- variant = page->inputMethodQuery(Qt::ImCursorPosition);
- cursorPosition = variant.toInt();
- QCOMPARE(cursorPosition, 11);
-
- // ImAnchorPosition
- variant = page->inputMethodQuery(Qt::ImAnchorPosition);
- anchorPosition = variant.toInt();
- QCOMPARE(anchorPosition, 11);
-
- // Send commit text, which makes the editor conforms composition.
- {
- QList<QInputMethodEvent::Attribute> attributes;
- QInputMethodEvent event("", attributes);
- event.setCommitString("2");
- page->event(&event);
- }
-
- // ImCurrentSelection
- variant = page->inputMethodQuery(Qt::ImCurrentSelection);
- selectionValue = variant.value<QString>();
- QCOMPARE(selectionValue, QString(""));
-
- // ImSurroundingText
- variant = page->inputMethodQuery(Qt::ImSurroundingText);
- surroundingValue = variant.value<QString>();
- QCOMPARE(surroundingValue, QString("oeQtWebEngine 2"));
-
- // ImCursorPosition
- variant = page->inputMethodQuery(Qt::ImCursorPosition);
- cursorPosition = variant.toInt();
- QCOMPARE(cursorPosition, 12);
-
- // ImAnchorPosition
- variant = page->inputMethodQuery(Qt::ImAnchorPosition);
- anchorPosition = variant.toInt();
- QCOMPARE(anchorPosition, 12);
-#endif
-}
-
void tst_QWebEnginePage::protectBindingsRuntimeObjectsFromCollector()
{
#if !defined(QWEBENGINEPAGE_CREATEPLUGIN)
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index a6138c59d..82e50409d 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -97,8 +97,11 @@ private Q_SLOTS:
void postData();
void softwareInputPanel();
+ void inputMethods();
+ void textSelection();
void hiddenText();
void emptyInputMethodEvent();
+ void imeComposition();
void newlineInTextarea();
};
@@ -1341,6 +1344,24 @@ static QPoint elementCenter(QWebEnginePage *page, const QString &id)
return QPoint(rectList.at(0).toInt(), rectList.at(1).toInt());
}
+static QRect elementGeometry(QWebEnginePage *page, const QString &id)
+{
+ const QString jsCode(
+ "(function() {"
+ " var elem = document.getElementById('" + id + "');"
+ " var rect = elem.getBoundingClientRect();"
+ " return [rect.left, rect.top, rect.right, rect.bottom];"
+ "})()");
+ QVariantList coords = evaluateJavaScriptSync(page, jsCode).toList();
+
+ if (coords.count() != 4) {
+ qWarning("elementGeometry faield.");
+ return QRect();
+ }
+
+ return QRect(coords[0].toInt(), coords[1].toInt(), coords[2].toInt(), coords[3].toInt());
+}
+
void tst_QWebEngineView::softwareInputPanel()
{
TestInputContext testContext;
@@ -1398,6 +1419,183 @@ void tst_QWebEngineView::softwareInputPanel()
QVERIFY(!testContext.isInputPanelVisible());
}
+void tst_QWebEngineView::inputMethods()
+{
+ QWebEngineView view;
+ view.show();
+
+ QSignalSpy selectionChangedSpy(&view, SIGNAL(selectionChanged()));
+ QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
+ view.settings()->setFontFamily(QWebEngineSettings::SerifFont, view.settings()->fontFamily(QWebEngineSettings::FixedFont));
+ view.setHtml("<html><body>"
+ " <input type='text' id='input1' style='font-family: serif' value='' maxlength='20' size='50'/>"
+ "</body></html>");
+ QVERIFY(loadFinishedSpy.wait());
+
+ QPoint textInputCenter = elementCenter(view.page(), "input1");
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input1"));
+
+ // ImCursorRectangle
+ QVariant variant = view.focusProxy()->inputMethodQuery(Qt::ImCursorRectangle);
+ QVERIFY(elementGeometry(view.page(), "input1").contains(variant.toRect().topLeft()));
+
+ // We assigned the serif font family to be the same as the fixed font family.
+ // Then test ImFont on a serif styled element, we should get our fixed font family.
+ variant = view.focusProxy()->inputMethodQuery(Qt::ImFont);
+ QFont font = variant.value<QFont>();
+ QEXPECT_FAIL("", "UNIMPLEMENTED: RenderWidgetHostViewQt::inputMethodQuery(Qt::ImFont)", Continue);
+ QCOMPARE(view.settings()->fontFamily(QWebEngineSettings::FixedFont), font.family());
+
+ QList<QInputMethodEvent::Attribute> inputAttributes;
+
+ // Insert text
+ {
+ QString text = QStringLiteral("QtWebEngine");
+ QInputMethodEvent eventText(text, inputAttributes);
+ QApplication::sendEvent(view.focusProxy(), &eventText);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), text);
+ QCOMPARE(selectionChangedSpy.count(), 0);
+ }
+
+ {
+ QString text = QStringLiteral("QtWebEngine");
+ QInputMethodEvent eventText("", inputAttributes);
+ eventText.setCommitString(text, 0, 0);
+ QApplication::sendEvent(view.focusProxy(), &eventText);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), text);
+ QCOMPARE(selectionChangedSpy.count(), 0);
+ }
+
+ // ImMaximumTextLength
+ QEXPECT_FAIL("", "UNIMPLEMENTED: RenderWidgetHostViewQt::inputMethodQuery(Qt::ImMaximumTextLength)", Continue);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImMaximumTextLength).toInt(), 20);
+
+ // Set selection
+ inputAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 3, 2, QVariant());
+ QInputMethodEvent eventSelection1("", inputAttributes);
+
+ QApplication::sendEvent(view.focusProxy(), &eventSelection1);
+ QVERIFY(selectionChangedSpy.wait());
+ QCOMPARE(selectionChangedSpy.count(), 1);
+
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 3);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 5);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString("eb"));
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("QtWebEngine"));
+
+ // Set selection with negative length
+ inputAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 6, -5, QVariant());
+ QInputMethodEvent eventSelection2("", inputAttributes);
+ QApplication::sendEvent(view.focusProxy(), &eventSelection2);
+ QVERIFY(selectionChangedSpy.wait());
+ QCOMPARE(selectionChangedSpy.count(), 2);
+
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 1);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 6);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString("tWebE"));
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("QtWebEngine"));
+
+ QList<QInputMethodEvent::Attribute> attributes;
+ // Clear the selection, so the next test does not clear any contents.
+ QInputMethodEvent::Attribute newSelection(QInputMethodEvent::Selection, 0, 0, QVariant());
+ attributes.append(newSelection);
+ QInputMethodEvent eventComposition("composition", attributes);
+ QApplication::sendEvent(view.focusProxy(), &eventComposition);
+ QVERIFY(selectionChangedSpy.wait());
+ QCOMPARE(selectionChangedSpy.count(), 3);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
+
+ // An ongoing composition should not change the surrounding text before it is committed.
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("QtWebEngine"));
+
+ // Cancel current composition first
+ inputAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, 0, 0, QVariant());
+ QInputMethodEvent eventSelection3("", inputAttributes);
+ QApplication::sendEvent(view.focusProxy(), &eventSelection3);
+
+ // Cancelling composition should not clear the surrounding text
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("QtWebEngine"));
+}
+
+void tst_QWebEngineView::textSelection()
+{
+ QWebEngineView view;
+ view.show();
+
+ QSignalSpy selectionChangedSpy(&view, SIGNAL(selectionChanged()));
+ QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
+ view.setHtml("<html><body>"
+ " <input type='text' id='input1' value='QtWebEngine' size='50'/>"
+ "</body></html>");
+ QVERIFY(loadFinishedSpy.wait());
+
+ // Tests for Selection when the Editor is NOT in Composition mode
+
+ // LEFT to RIGHT selection
+ // Mouse click event moves the current cursor to the end of the text
+ QPoint textInputCenter = elementCenter(view.page(), "input1");
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input1"));
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 11);
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 11);
+ // There was no selection to be changed by the click
+ QCOMPARE(selectionChangedSpy.count(), 0);
+
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent event(QString(), attributes);
+ event.setCommitString("XXX", 0, 0);
+ QApplication::sendEvent(view.focusProxy(), &event);
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("QtWebEngineXXX"));
+
+ event.setCommitString(QString(), -2, 2); // Erase two characters.
+ QApplication::sendEvent(view.focusProxy(), &event);
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("QtWebEngineX"));
+
+ event.setCommitString(QString(), -1, 1); // Erase one character.
+ QApplication::sendEvent(view.focusProxy(), &event);
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("QtWebEngine"));
+
+ // Move to the start of the line
+ QTest::keyClick(view.focusProxy(), Qt::Key_Home);
+
+ // Move 2 characters RIGHT
+ for (int j = 0; j < 2; ++j)
+ QTest::keyClick(view.focusProxy(), Qt::Key_Right);
+
+ // Select to the end of the line
+ QTest::keyClick(view.focusProxy(), Qt::Key_End, Qt::ShiftModifier);
+ QVERIFY(selectionChangedSpy.wait());
+ QCOMPARE(selectionChangedSpy.count(), 1);
+
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 2);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 11);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString("WebEngine"));
+
+ // RIGHT to LEFT selection
+ // Deselect the selection (this moves the current cursor to the end of the text)
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QVERIFY(selectionChangedSpy.wait());
+ QCOMPARE(selectionChangedSpy.count(), 2);
+
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 11);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 11);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
+
+ // Move 2 characters LEFT
+ for (int i = 0; i < 2; ++i)
+ QTest::keyClick(view.focusProxy(), Qt::Key_Left);
+
+ // Select to the start of the line
+ QTest::keyClick(view.focusProxy(), Qt::Key_Home, Qt::ShiftModifier);
+ QVERIFY(selectionChangedSpy.wait());
+ QCOMPARE(selectionChangedSpy.count(), 3);
+
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 9);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 0);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString("QtWebEngi"));
+}
+
void tst_QWebEngineView::hiddenText()
{
QWebEngineView view;
@@ -1451,6 +1649,193 @@ void tst_QWebEngineView::emptyInputMethodEvent()
QCOMPARE(inputValue, QString("QtWebEngine"));
}
+void tst_QWebEngineView::imeComposition()
+{
+ QWebEngineView view;
+ view.show();
+
+ QSignalSpy selectionChangedSpy(&view, SIGNAL(selectionChanged()));
+ QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
+ view.setHtml("<html><body>"
+ " <input type='text' id='input1' value='QtWebEngine inputMethod'/>"
+ "</body></html>");
+ QVERIFY(loadFinishedSpy.wait());
+
+ evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1'); inputEle.focus(); inputEle.select();");
+ QTRY_VERIFY(!evaluateJavaScriptSync(view.page(), "window.getSelection().toString()").toString().isEmpty());
+
+ QEXPECT_FAIL("", "https://bugreports.qt.io/browse/QTBUG-53134", Continue);
+ QVERIFY(selectionChangedSpy.wait(100));
+ QEXPECT_FAIL("", "https://bugreports.qt.io/browse/QTBUG-53134", Continue);
+ QCOMPARE(selectionChangedSpy.count(), 1);
+
+ // Clear the selection, also cancel the ongoing composition if there is one.
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent::Attribute newSelection(QInputMethodEvent::Selection, 0, 0, QVariant());
+ attributes.append(newSelection);
+ QInputMethodEvent event("", attributes);
+ QApplication::sendEvent(view.focusProxy(), &event);
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "window.getSelection().toString()").toString().isEmpty());
+
+ QEXPECT_FAIL("", "https://bugreports.qt.io/browse/QTBUG-53134", Continue);
+ QVERIFY(selectionChangedSpy.wait(100));
+ QEXPECT_FAIL("", "https://bugreports.qt.io/browse/QTBUG-53134", Continue);
+ QCOMPARE(selectionChangedSpy.count(), 2);
+ }
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("QtWebEngine inputMethod"));
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 0);
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 0);
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
+
+ selectionChangedSpy.clear();
+
+
+ // 1. Insert a character to the beginning of the line.
+ // Send temporary text, which makes the editor has composition 'm'.
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent event("m", attributes);
+ QApplication::sendEvent(view.focusProxy(), &event);
+ }
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("QtWebEngine inputMethod"));
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 0);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 0);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
+ QCOMPARE(selectionChangedSpy.count(), 0);
+
+ // Send temporary text, which makes the editor has composition 'n'.
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent event("n", attributes);
+ QApplication::sendEvent(view.focusProxy(), &event);
+ }
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("QtWebEngine inputMethod"));
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 0);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 0);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
+ QCOMPARE(selectionChangedSpy.count(), 0);
+
+ // Send commit text, which makes the editor conforms composition.
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent event("", attributes);
+ event.setCommitString("o");
+ QApplication::sendEvent(view.focusProxy(), &event);
+ }
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("oQtWebEngine inputMethod"));
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 1);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 1);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
+ QCOMPARE(selectionChangedSpy.count(), 0);
+
+
+ // 2. insert a character to the middle of the line.
+ // Send temporary text, which makes the editor has composition 'd'.
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent event("d", attributes);
+ QApplication::sendEvent(view.focusProxy(), &event);
+ }
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("oQtWebEngine inputMethod"));
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 1);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 1);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
+ QCOMPARE(selectionChangedSpy.count(), 0);
+
+ // Send commit text, which makes the editor conforms composition.
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent event("", attributes);
+ event.setCommitString("e");
+ QApplication::sendEvent(view.focusProxy(), &event);
+ }
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("oeQtWebEngine inputMethod"));
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 2);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 2);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
+ QCOMPARE(selectionChangedSpy.count(), 0);
+
+
+ // 3. Insert a character to the end of the line.
+ QTest::keyClick(view.focusProxy(), Qt::Key_End);
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 25);
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 25);
+
+ // Send temporary text, which makes the editor has composition 't'.
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent event("t", attributes);
+ QApplication::sendEvent(view.focusProxy(), &event);
+ }
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("oeQtWebEngine inputMethod"));
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 25);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 25);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
+ QCOMPARE(selectionChangedSpy.count(), 0);
+
+ // Send commit text, which makes the editor conforms composition.
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent event("", attributes);
+ event.setCommitString("t");
+ QApplication::sendEvent(view.focusProxy(), &event);
+ }
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("oeQtWebEngine inputMethodt"));
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 26);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 26);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
+ QCOMPARE(selectionChangedSpy.count(), 0);
+
+
+ // 4. Replace the selection.
+#ifndef Q_OS_MACOS
+ QTest::keyClick(view.focusProxy(), Qt::Key_Left, Qt::ShiftModifier | Qt::ControlModifier);
+#else
+ QTest::keyClick(view.focusProxy(), Qt::Key_Left, Qt::ShiftModifier | Qt::AltModifier);
+#endif
+ QVERIFY(selectionChangedSpy.wait());
+ QCOMPARE(selectionChangedSpy.count(), 1);
+
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("oeQtWebEngine inputMethodt"));
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 14);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 26);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString("inputMethodt"));
+
+ // Send temporary text, which makes the editor has composition 'w'.
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent event("w", attributes);
+ QApplication::sendEvent(view.focusProxy(), &event);
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "window.getSelection().toString()").toString().isEmpty());
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), QString("oeQtWebEngine w"));
+
+ QEXPECT_FAIL("", "https://bugreports.qt.io/browse/QTBUG-53134", Continue);
+ QVERIFY(selectionChangedSpy.wait(100));
+ QEXPECT_FAIL("", "https://bugreports.qt.io/browse/QTBUG-53134", Continue);
+ QCOMPARE(selectionChangedSpy.count(), 2);
+ }
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("oeQtWebEngine "));
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 14);
+ QEXPECT_FAIL("", "https://bugreports.qt.io/browse/QTBUG-53134", Continue);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 14);
+ QEXPECT_FAIL("", "https://bugreports.qt.io/browse/QTBUG-53134", Continue);
+ QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
+
+ // Send commit text, which makes the editor conforms composition.
+ {
+ QList<QInputMethodEvent::Attribute> attributes;
+ QInputMethodEvent event("", attributes);
+ event.setCommitString("2");
+ QApplication::sendEvent(view.focusProxy(), &event);
+ }
+ // There is no text selection to be changed at this point thus we can't wait for selectionChanged signal.
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("oeQtWebEngine 2"));
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 15);
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 15);
+ QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString(""));
+}
+
void tst_QWebEngineView::newlineInTextarea()
{
QWebEngineView view;