summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/widgets/browser/browsermainwindow.cpp17
-rw-r--r--examples/widgets/browser/browsermainwindow.h1
-rw-r--r--src/core/web_contents_adapter.cpp25
-rw-r--r--src/core/web_contents_adapter.h2
-rw-r--r--src/core/web_contents_adapter_client.h1
-rw-r--r--src/core/web_contents_delegate_qt.cpp9
-rw-r--r--src/core/web_contents_delegate_qt.h1
-rw-r--r--src/webengine/api/qquickwebengineview_p_p.h1
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp43
-rw-r--r--src/webenginewidgets/api/qwebenginepage.h5
-rw-r--r--src/webenginewidgets/api/qwebenginepage_p.h10
-rw-r--r--src/webenginewidgets/api/qwebengineview.cpp5
-rw-r--r--src/webenginewidgets/api/qwebengineview.h2
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp38
-rw-r--r--tests/auto/widgets/util.h7
15 files changed, 146 insertions, 21 deletions
diff --git a/examples/widgets/browser/browsermainwindow.cpp b/examples/widgets/browser/browsermainwindow.cpp
index 319e2d4c2..3cee14e9e 100644
--- a/examples/widgets/browser/browsermainwindow.cpp
+++ b/examples/widgets/browser/browsermainwindow.cpp
@@ -325,7 +325,6 @@ void BrowserMainWindow::setupMenu()
m_tabWidget->addWebAction(m_paste, QWebEnginePage::Paste);
editMenu->addSeparator();
-#if defined(QWEBENGINEPAGE_FINDTEXT)
QAction *m_find = editMenu->addAction(tr("&Find"));
m_find->setShortcuts(QKeySequence::Find);
connect(m_find, SIGNAL(triggered()), this, SLOT(slotEditFind()));
@@ -339,7 +338,6 @@ void BrowserMainWindow::setupMenu()
m_findPrevious->setShortcuts(QKeySequence::FindPrevious);
connect(m_findPrevious, SIGNAL(triggered()), this, SLOT(slotEditFindPrevious()));
editMenu->addSeparator();
-#endif
editMenu->addAction(tr("&Preferences"), this, SLOT(slotPreferences()), tr("Ctrl+,"));
@@ -557,6 +555,12 @@ void BrowserMainWindow::updateStatusbarActionText(bool visible)
m_viewStatusbar->setText(!visible ? tr("Show Status Bar") : tr("Hide Status Bar"));
}
+void BrowserMainWindow::handleFindTextResult(bool found)
+{
+ if (!found)
+ slotUpdateStatusbar(tr("\"%1\" not found.").arg(m_lastSearch));
+}
+
void BrowserMainWindow::updateToolbarActionText(bool visible)
{
m_viewToolbar->setText(!visible ? tr("Show Toolbar") : tr("Hide Toolbar"));
@@ -746,7 +750,6 @@ void BrowserMainWindow::closeEvent(QCloseEvent *event)
void BrowserMainWindow::slotEditFind()
{
-#if defined(QWEBENGINEPAGE_FINDTEXT)
if (!currentTab())
return;
bool ok;
@@ -755,28 +758,22 @@ void BrowserMainWindow::slotEditFind()
m_lastSearch, &ok);
if (ok && !search.isEmpty()) {
m_lastSearch = search;
- if (!currentTab()->findText(m_lastSearch))
- slotUpdateStatusbar(tr("\"%1\" not found.").arg(m_lastSearch));
+ currentTab()->findText(m_lastSearch, 0, invoke(this, &BrowserMainWindow::handleFindTextResult));
}
-#endif
}
void BrowserMainWindow::slotEditFindNext()
{
-#if defined(QWEBENGINEPAGE_FINDTEXT)
if (!currentTab() && !m_lastSearch.isEmpty())
return;
currentTab()->findText(m_lastSearch);
-#endif
}
void BrowserMainWindow::slotEditFindPrevious()
{
-#if defined(QWEBENGINEPAGE_FINDTEXT)
if (!currentTab() && !m_lastSearch.isEmpty())
return;
currentTab()->findText(m_lastSearch, QWebEnginePage::FindBackward);
-#endif
}
void BrowserMainWindow::slotViewZoomIn()
diff --git a/examples/widgets/browser/browsermainwindow.h b/examples/widgets/browser/browsermainwindow.h
index 2ad5ab62e..3c3df9117 100644
--- a/examples/widgets/browser/browsermainwindow.h
+++ b/examples/widgets/browser/browsermainwindow.h
@@ -137,6 +137,7 @@ private:
void setupMenu();
void setupToolBar();
void updateStatusbarActionText(bool visible);
+ void handleFindTextResult(bool found);
private:
QToolBar *m_navigationBar;
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 82d6ed26f..be68e6ef4 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -59,6 +59,7 @@
#include "content/public/common/renderer_preferences.h"
#include "content/public/common/url_constants.h"
#include "ui/shell_dialogs/selected_file_info.h"
+#include "third_party/WebKit/public/web/WebFindOptions.h"
#include <QDir>
#include <QGuiApplication>
@@ -173,6 +174,7 @@ public:
scoped_ptr<QtRenderViewObserverHost> renderViewObserverHost;
WebContentsAdapterClient *adapterClient;
quint64 lastRequestId;
+ QString lastSearchedString;
};
WebContentsAdapterPrivate::WebContentsAdapterPrivate(WebContentsAdapterClient::RenderingMode renderingMode)
@@ -429,6 +431,29 @@ quint64 WebContentsAdapter::fetchDocumentInnerText()
return d->lastRequestId;
}
+quint64 WebContentsAdapter::findText(const QString &subString, bool caseSensitively, bool findBackward)
+{
+ Q_D(WebContentsAdapter);
+ WebKit::WebFindOptions options;
+ options.forward = !findBackward;
+ options.matchCase = caseSensitively;
+ options.findNext = subString == d->lastSearchedString;
+ d->lastSearchedString = subString;
+
+ // Find already allows a request ID as input, but only as an int.
+ // Use the same counter but mod it to MAX_INT, this keeps the same likeliness of request ID clashing.
+ int shrunkRequestId = ++d->lastRequestId & 0x7fffffff;
+ d->webContents->GetRenderViewHost()->Find(shrunkRequestId, toString16(subString), options);
+ return shrunkRequestId;
+}
+
+void WebContentsAdapter::stopFinding()
+{
+ Q_D(WebContentsAdapter);
+ d->lastSearchedString = QString();
+ d->webContents->GetRenderViewHost()->StopFinding(content::STOP_FIND_ACTION_CLEAR_SELECTION);
+}
+
void WebContentsAdapter::wasShown()
{
Q_D(WebContentsAdapter);
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 56e39ba32..4cef56103 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -89,6 +89,8 @@ public:
quint64 runJavaScriptCallbackResult(const QString &javaScript, const QString &xPath);
quint64 fetchDocumentMarkup();
quint64 fetchDocumentInnerText();
+ quint64 findText(const QString &subString, bool caseSensitively, bool findBackward);
+ void stopFinding();
void wasShown();
void wasHidden();
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 778446a12..f56e31a71 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -136,6 +136,7 @@ public:
virtual void didRunJavaScript(quint64 requestId, const QVariant& result) = 0;
virtual void didFetchDocumentMarkup(quint64 requestId, const QString& result) = 0;
virtual void didFetchDocumentInnerText(quint64 requestId, const QString& result) = 0;
+ virtual void didFindText(quint64 requestId, int matchCount) = 0;
virtual void passOnFocus(bool reverse) = 0;
virtual void javaScriptConsoleMessage(int level, const QString& message, int lineNumber, const QString& sourceID) = 0;
};
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 16ec54afd..c0b050de6 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -166,3 +166,12 @@ bool WebContentsDelegateQt::AddMessageToConsole(content::WebContents *source, in
m_viewClient->javaScriptConsoleMessage(static_cast<int>(level), toQt(message), static_cast<int>(line_no), toQt(source_id));
return false;
}
+
+void WebContentsDelegateQt::FindReply(content::WebContents *source, int request_id, int number_of_matches, const gfx::Rect& selection_rect, int active_match_ordinal, bool final_update)
+{
+ Q_UNUSED(source)
+ Q_UNUSED(selection_rect)
+ Q_UNUSED(active_match_ordinal)
+ if (final_update)
+ m_viewClient->didFindText(request_id, number_of_matches);
+}
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index 460bb9ec2..4c8701945 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -77,6 +77,7 @@ public:
virtual bool IsFullscreenForTabOrPending(const content::WebContents* web_contents) const Q_DECL_OVERRIDE;
virtual void RunFileChooser(content::WebContents *, const content::FileChooserParams &params) Q_DECL_OVERRIDE;
virtual bool AddMessageToConsole(content::WebContents* source, int32 level, const string16& message, int32 line_no, const string16& source_id) Q_DECL_OVERRIDE;
+ virtual void FindReply(content::WebContents *source, int request_id, int number_of_matches, const gfx::Rect& selection_rect, int active_match_ordinal, bool final_update) Q_DECL_OVERRIDE;
private:
WebContentsAdapterClient *m_viewClient;
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index a36eb327c..ce8b64001 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -141,6 +141,7 @@ public:
virtual void didRunJavaScript(quint64, const QVariant&) Q_DECL_OVERRIDE { }
virtual void didFetchDocumentMarkup(quint64, const QString&) Q_DECL_OVERRIDE { }
virtual void didFetchDocumentInnerText(quint64, const QString&) Q_DECL_OVERRIDE { }
+ virtual void didFindText(quint64, int) Q_DECL_OVERRIDE { }
virtual void passOnFocus(bool reverse) Q_DECL_OVERRIDE;
virtual void javaScriptConsoleMessage(int level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE;
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 760a8eff7..ca1c203dd 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -57,6 +57,9 @@ CallbackDirectory::~CallbackDirectory()
case CallbackSharedDataPointer::String:
(*sharedPtr.stringCallback)(QString());
break;
+ case CallbackSharedDataPointer::Bool:
+ (*sharedPtr.boolCallback)(false);
+ break;
default:
Q_UNREACHABLE();
}
@@ -73,6 +76,11 @@ void CallbackDirectory::registerCallback(quint64 requestId, const QExplicitlySha
m_callbackMap.insert(requestId, CallbackSharedDataPointer(callback.data()));
}
+void CallbackDirectory::registerCallback(quint64 requestId, const QExplicitlySharedDataPointer<BoolCallback> &callback)
+{
+ m_callbackMap.insert(requestId, CallbackSharedDataPointer(callback.data()));
+}
+
void CallbackDirectory::invoke(quint64 requestId, const QVariant &result)
{
CallbackSharedDataPointer sharedPtr = m_callbackMap.take(requestId);
@@ -91,6 +99,15 @@ void CallbackDirectory::invoke(quint64 requestId, const QString &result)
}
}
+void CallbackDirectory::invoke(quint64 requestId, bool result)
+{
+ CallbackSharedDataPointer sharedPtr = m_callbackMap.take(requestId);
+ if (sharedPtr) {
+ Q_ASSERT(sharedPtr.type == CallbackSharedDataPointer::Bool);
+ (*sharedPtr.boolCallback)(result);
+ }
+}
+
void CallbackDirectory::CallbackSharedDataPointer::doRef()
{
switch (type) {
@@ -102,6 +119,9 @@ void CallbackDirectory::CallbackSharedDataPointer::doRef()
case String:
stringCallback->ref.ref();
break;
+ case Bool:
+ boolCallback->ref.ref();
+ break;
}
}
@@ -118,6 +138,10 @@ void CallbackDirectory::CallbackSharedDataPointer::doDeref()
if (!stringCallback->ref.deref())
delete stringCallback;
break;
+ case Bool:
+ if (!boolCallback->ref.deref())
+ delete boolCallback;
+ break;
}
}
@@ -251,6 +275,11 @@ void QWebEnginePagePrivate::didFetchDocumentInnerText(quint64 requestId, const Q
m_callbacks.invoke(requestId, result);
}
+void QWebEnginePagePrivate::didFindText(quint64 requestId, int matchCount)
+{
+ m_callbacks.invoke(requestId, matchCount > 0);
+}
+
void QWebEnginePagePrivate::updateAction(QWebEnginePage::WebAction action) const
{
#ifdef QT_NO_ACTION
@@ -414,6 +443,20 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
}
}
+void QWebEnginePage::findText(const QString &subString, FindFlags options, const QWebEngineCallback<bool> &resultCallback)
+{
+ Q_D(QWebEnginePage);
+ if (subString.isEmpty()) {
+ d->adapter->stopFinding();
+ if (resultCallback.d)
+ (*resultCallback.d)(false);
+ } else {
+ quint64 requestId = d->adapter->findText(subString, options & FindCaseSensitively, options & FindBackward);
+ if (resultCallback.d)
+ d->m_callbacks.registerCallback(requestId, resultCallback.d);
+ }
+}
+
void QWebEnginePage::setViewportSize(const QSize &size) const
{
Q_UNUSED(size)
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index f89115579..aac37bc99 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -76,6 +76,7 @@ class QWebEngineCallback {
public:
template <typename F>
QWebEngineCallback(F f) : d(new QtWebEnginePrivate::QWebEngineCallbackPrivate<T, F>(f)) { }
+ QWebEngineCallback() { }
private:
QExplicitlySharedDataPointer<QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> > d;
friend class QWebEnginePage;
@@ -249,8 +250,6 @@ public:
enum FindFlag {
FindBackward = 1,
FindCaseSensitively = 2,
- FindWrapsAroundDocument = 4,
- HighlightAllOccurrences = 8
};
Q_DECLARE_FLAGS(FindFlags, FindFlag)
@@ -368,7 +367,7 @@ public:
QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
- bool findText(const QString &subString, FindFlags options = 0);
+ void findText(const QString &subString, FindFlags options = 0, const QWebEngineCallback<bool> &resultCallback = QWebEngineCallback<bool>());
void setForwardUnsupportedContent(bool forward);
bool forwardUnsupportedContent() const;
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index e6113b795..ed21c3816 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -62,27 +62,33 @@ class CallbackDirectory {
public:
typedef QtWebEnginePrivate::QWebEngineCallbackPrivateBase<const QVariant&> VariantCallback;
typedef QtWebEnginePrivate::QWebEngineCallbackPrivateBase<const QString&> StringCallback;
+ typedef QtWebEnginePrivate::QWebEngineCallbackPrivateBase<bool> BoolCallback;
~CallbackDirectory();
void registerCallback(quint64 requestId, const QExplicitlySharedDataPointer<VariantCallback> &callback);
void registerCallback(quint64 requestId, const QExplicitlySharedDataPointer<StringCallback> &callback);
+ void registerCallback(quint64 requestId, const QExplicitlySharedDataPointer<BoolCallback> &callback);
void invoke(quint64 requestId, const QVariant &result);
void invoke(quint64 requestId, const QString &result);
+ void invoke(quint64 requestId, bool result);
private:
struct CallbackSharedDataPointer {
enum {
None,
Variant,
- String
+ String,
+ Bool
} type;
union {
VariantCallback *variantCallback;
StringCallback *stringCallback;
+ BoolCallback *boolCallback;
};
CallbackSharedDataPointer() : type(None) { }
CallbackSharedDataPointer(VariantCallback *callback) : type(Variant), variantCallback(callback) { callback->ref.ref(); }
CallbackSharedDataPointer(StringCallback *callback) : type(String), stringCallback(callback) { callback->ref.ref(); }
+ CallbackSharedDataPointer(BoolCallback *callback) : type(Bool), boolCallback(callback) { callback->ref.ref(); }
CallbackSharedDataPointer(const CallbackSharedDataPointer &other) : type(other.type), variantCallback(other.variantCallback) { doRef(); }
~CallbackSharedDataPointer() { doDeref(); }
operator bool () const { return type != None; }
@@ -125,8 +131,8 @@ public:
virtual void didRunJavaScript(quint64 requestId, const QVariant& result) Q_DECL_OVERRIDE;
virtual void didFetchDocumentMarkup(quint64 requestId, const QString& result) Q_DECL_OVERRIDE;
virtual void didFetchDocumentInnerText(quint64 requestId, const QString& result) Q_DECL_OVERRIDE;
+ virtual void didFindText(quint64 requestId, int matchCount) Q_DECL_OVERRIDE;
virtual void passOnFocus(bool reverse) Q_DECL_OVERRIDE { Q_UNUSED(reverse); };
-
virtual void javaScriptConsoleMessage(int level, const QString& message, int lineNumber, const QString& sourceID) Q_DECL_OVERRIDE;
void updateAction(QWebEnginePage::WebAction) const;
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index e5237bc72..3d884f464 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -177,6 +177,11 @@ void QWebEngineView::triggerPageAction(QWebEnginePage::WebAction action, bool ch
page()->triggerAction(action, checked);
}
+void QWebEngineView::findText(const QString &subString, QWebEnginePage::FindFlags options, const QWebEngineCallback<bool> &resultCallback)
+{
+ page()->findText(subString, options, resultCallback);
+}
+
void QWebEngineView::stop()
{
page()->triggerAction(QWebEnginePage::Stop);
diff --git a/src/webenginewidgets/api/qwebengineview.h b/src/webenginewidgets/api/qwebengineview.h
index 46b144d14..836e61be3 100644
--- a/src/webenginewidgets/api/qwebengineview.h
+++ b/src/webenginewidgets/api/qwebengineview.h
@@ -105,7 +105,7 @@ public:
void setRenderHints(QPainter::RenderHints hints);
void setRenderHint(QPainter::RenderHint hint, bool enabled = true);
- bool findText(const QString& subString, QWebEnginePage::FindFlags options = 0);
+ void findText(const QString &subString, QWebEnginePage::FindFlags options = 0, const QWebEngineCallback<bool> &resultCallback = QWebEngineCallback<bool>());
virtual QSize sizeHint() const { return QSize(800, 600); }
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index d6f154e5e..bb07e2e00 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -173,6 +173,7 @@ private Q_SLOTS:
void showModalDialog();
void testStopScheduledPageRefresh();
void findText();
+ void findTextResult();
void supportedContentType();
// [Qt] tst_QWebEnginePage::infiniteLoopJS() timeouts with DFG JIT
// https://bugs.webkit.org/show_bug.cgi?id=79040
@@ -3187,26 +3188,53 @@ void tst_QWebEnginePage::testStopScheduledPageRefresh()
void tst_QWebEnginePage::findText()
{
-#if !defined(QWEBENGINEPAGE_FINDTEXT)
- QSKIP("QWEBENGINEPAGE_FINDTEXT");
-#else
m_view->setHtml(QString("<html><head></head><body><div>foo bar</div></body></html>"));
+#if defined(QWEBENGINEPAGE_TRIGGERACTION_SELECTALL)
m_page->triggerAction(QWebEnginePage::SelectAll);
QVERIFY(!m_page->selectedText().isEmpty());
QVERIFY(!m_page->selectedHtml().isEmpty());
+#endif
m_page->findText("");
QVERIFY(m_page->selectedText().isEmpty());
+#if defined(QWEBENGINEPAGE_SELECTEDHTML)
QVERIFY(m_page->selectedHtml().isEmpty());
+#endif
QStringList words = (QStringList() << "foo" << "bar");
foreach (QString subString, words) {
- m_page->findText(subString, QWebEnginePage::FindWrapsAroundDocument);
+ m_page->findText(subString);
+ QEXPECT_FAIL("", "Unsupported: findText only highlights and doesn't update the selection.", Continue);
QCOMPARE(m_page->selectedText(), subString);
+#if defined(QWEBENGINEPAGE_SELECTEDHTML)
QVERIFY(m_page->selectedHtml().contains(subString));
+#endif
m_page->findText("");
QVERIFY(m_page->selectedText().isEmpty());
+#if defined(QWEBENGINEPAGE_SELECTEDHTML)
QVERIFY(m_page->selectedHtml().isEmpty());
- }
#endif
+ }
+}
+
+void tst_QWebEnginePage::findTextResult()
+{
+ // findText will abort in blink if the view has an empty size.
+ m_view->resize(800, 600);
+ m_view->show();
+
+ QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool)));
+ m_view->setHtml(QString("<html><head></head><body><div>foo bar</div></body></html>"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+
+ QCOMPARE(findTextSync(m_page, ""), false);
+
+ QStringList words = (QStringList() << "foo" << "bar");
+ foreach (QString subString, words) {
+ QCOMPARE(findTextSync(m_page, subString), true);
+ QCOMPARE(findTextSync(m_page, ""), false);
+ }
+
+ QCOMPARE(findTextSync(m_page, "blahhh"), false);
+ QCOMPARE(findTextSync(m_page, ""), false);
}
static QString getMimeTypeForExtension(const QString &ext)
diff --git a/tests/auto/widgets/util.h b/tests/auto/widgets/util.h
index 0b146aedc..035578358 100644
--- a/tests/auto/widgets/util.h
+++ b/tests/auto/widgets/util.h
@@ -142,6 +142,13 @@ static inline QString toHtmlSync(QWebEnginePage *page)
return spy.waitForResult();
}
+static inline bool findTextSync(QWebEnginePage *page, const QString &subString)
+{
+ CallbackSpy<bool> spy;
+ page->findText(subString, 0, spy.ref());
+ return spy.waitForResult();
+}
+
static inline QVariant evaluateJavaScriptSync(QWebEnginePage *page, const QString &script)
{
CallbackSpy<QVariant> spy;