summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKirill Burtsev <kirill.burtsev@qt.io>2020-02-12 16:15:34 +0100
committerKirill Burtsev <kirill.burtsev@qt.io>2020-02-26 12:13:40 +0000
commitdf5d831bae99662fab43ed2628187113c18aac2c (patch)
tree62e24e3c05d6d9c1f90834523b476651536b712d
parent08d1d866107b82525f5c1ec83f179c58ee7e6b97 (diff)
Clear previous page text selection on new navigation unconditionally
Remove code duplication on triggering new url load, and use direct code to clear SelectedText instead of CollapseSelection as it assumes focused frame and might be ignored. Fixes: QTBUG-81574 Change-Id: I01cf02967e118f407c8a3997e176d5b258478a5a Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
-rw-r--r--src/core/web_contents_adapter.cpp46
-rw-r--r--src/core/web_contents_adapter.h1
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp46
3 files changed, 61 insertions, 32 deletions
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 8cc8179cf..a7579f916 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -67,6 +67,7 @@
#include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"
#include "base/values.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/renderer_host/text_input_manager.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/child_process_security_policy.h"
@@ -369,6 +370,23 @@ static void deserializeNavigationHistory(QDataStream &input, int *currentIndex,
}
}
+static void Navigate(WebContentsAdapter *adapter, const content::NavigationController::LoadURLParams &params)
+{
+ Q_ASSERT(adapter);
+ adapter->webContents()->GetController().LoadURLWithParams(params);
+ adapter->focusIfNecessary();
+ adapter->resetSelection();
+}
+
+static void NavigateTask(QWeakPointer<WebContentsAdapter> weakAdapter, const content::NavigationController::LoadURLParams &params)
+{
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ const auto adapter = weakAdapter.toStrongRef();
+ if (!adapter)
+ return;
+ Navigate(adapter.get(), params);
+}
+
namespace {
static QList<WebContentsAdapter *> recursive_guard_loading_adapters;
@@ -705,21 +723,12 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
}
}
- auto navigate = [](QWeakPointer<WebContentsAdapter> weakAdapter, const content::NavigationController::LoadURLParams &params) {
- const auto adapter = weakAdapter.toStrongRef();
- if (!adapter)
- return;
- adapter->webContents()->GetController().LoadURLWithParams(params);
- adapter->focusIfNecessary();
- };
-
- QWeakPointer<WebContentsAdapter> weakThis(sharedFromThis());
if (resizeNeeded) {
// Schedule navigation on the event loop.
base::PostTaskWithTraits(FROM_HERE, {content::BrowserThread::UI},
- base::BindOnce(navigate, std::move(weakThis), std::move(params)));
+ base::BindOnce(&NavigateTask, sharedFromThis().toWeakRef(), std::move(params)));
} else {
- navigate(std::move(weakThis), params);
+ Navigate(this, params);
}
}
@@ -752,9 +761,7 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT
params.can_load_local_resources = true;
params.transition_type = ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_API);
params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
- m_webContents->GetController().LoadURLWithParams(params);
- focusIfNecessary();
- m_webContents->CollapseSelection();
+ Navigate(this, params);
}
void WebContentsAdapter::save(const QString &filePath, int savePageFormat)
@@ -1676,6 +1683,17 @@ bool WebContentsAdapter::hasFocusedFrame() const
return m_webContents->GetFocusedFrame() != nullptr;
}
+void WebContentsAdapter::resetSelection()
+{
+ CHECK_INITIALIZED();
+ // unconditionally clears the selection in contrast to CollapseSelection, which checks focus state first
+ if (auto rwhv = static_cast<RenderWidgetHostViewQt *>(m_webContents->GetRenderWidgetHostView())) {
+ if (auto mgr = rwhv->GetTextInputManager())
+ if (auto selection = const_cast<content::TextInputManager::TextSelection *>(mgr->GetTextSelection(rwhv)))
+ selection->SetSelection(base::string16(), 0, gfx::Range(), false);
+ }
+}
+
WebContentsAdapterClient::RenderProcessTerminationStatus
WebContentsAdapterClient::renderProcessExitStatus(int terminationStatus) {
auto status = WebContentsAdapterClient::RenderProcessTerminationStatus(-1);
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 11f8f9cb1..f8f147f9a 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -229,6 +229,7 @@ public:
void focusIfNecessary();
bool isFindTextInProgress() const;
bool hasFocusedFrame() const;
+ void resetSelection();
// meant to be used within WebEngineCore only
void initialize(content::SiteInstance *site);
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 8cdcc9f46..94b3f16c1 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -700,7 +700,7 @@ public:
CursorTrackedPage(QWidget *parent = 0): QWebEnginePage(parent) {
}
- QString selectedText() {
+ QString jsSelectedText() {
return evaluateJavaScriptSync(this, "window.getSelection().toString()").toString();
}
@@ -716,42 +716,52 @@ public:
int isSelectionCollapsed() {
return evaluateJavaScriptSync(this, "window.getSelection().getRangeAt(0).collapsed").toBool();
}
- bool hasSelection()
- {
- return !selectedText().isEmpty();
- }
};
void tst_QWebEnginePage::textSelection()
{
- QWebEngineView view;
- CursorTrackedPage *page = new CursorTrackedPage(&view);
- QString content("<html><body><p id=one>The quick brown fox</p>" \
+ CursorTrackedPage page;
+
+ QString textToSelect("The quick brown fox");
+ QString content = QString("<html><body><p id=one>%1</p>" \
"<p id=two>jumps over the lazy dog</p>" \
- "<p>May the source<br/>be with you!</p></body></html>");
- page->setView(&view);
- QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
- page->setHtml(content);
+ "<p>May the source<br/>be with you!</p></body></html>").arg(textToSelect);
+
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+ page.setHtml(content);
QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
// these actions must exist
- QVERIFY(page->action(QWebEnginePage::SelectAll) != 0);
+ QVERIFY(page.action(QWebEnginePage::SelectAll) != 0);
// ..but SelectAll is disabled because the page has no focus due to disabled FocusOnNavigationEnabled.
- QCOMPARE(page->action(QWebEnginePage::SelectAll)->isEnabled(), false);
+ QCOMPARE(page.action(QWebEnginePage::SelectAll)->isEnabled(), false);
// Verify hasSelection returns false since there is no selection yet...
- QCOMPARE(page->hasSelection(), false);
+ QVERIFY(!page.hasSelection());
+ QVERIFY(page.jsSelectedText().isEmpty());
// this will select the first paragraph
QString selectScript = "var range = document.createRange(); " \
"var node = document.getElementById(\"one\"); " \
"range.selectNode(node); " \
"getSelection().addRange(range);";
- evaluateJavaScriptSync(page, selectScript);
- QCOMPARE(page->selectedText().trimmed(), QString::fromLatin1("The quick brown fox"));
+ evaluateJavaScriptSync(&page, selectScript);
+
// Make sure hasSelection returns true, since there is selected text now...
- QCOMPARE(page->hasSelection(), true);
+ QTRY_VERIFY(page.hasSelection());
+ QCOMPARE(page.selectedText().trimmed(), textToSelect);
+
+ QCOMPARE(page.jsSelectedText().trimmed(), textToSelect);
+
+ // navigate away and check that selection is cleared
+ page.load(QUrl("about:blank"));
+ QTRY_COMPARE(loadSpy.count(), 2);
+
+ QVERIFY(!page.hasSelection());
+ QVERIFY(page.selectedText().isEmpty());
+
+ QVERIFY(page.jsSelectedText().isEmpty());
}