summaryrefslogtreecommitdiffstats
path: root/src/core/web_contents_adapter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/web_contents_adapter.cpp')
-rw-r--r--src/core/web_contents_adapter.cpp179
1 files changed, 119 insertions, 60 deletions
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 53bb55b6a..0592e36fb 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -50,7 +50,6 @@
#include "browser_context_qt.h"
#include "download_manager_delegate_qt.h"
#include "media_capture_devices_dispatcher.h"
-#include "pdfium_document_wrapper_qt.h"
#include "print_view_manager_qt.h"
#include "qwebenginecallback_p.h"
#include "renderer_host/web_channel_ipc_transport_host.h"
@@ -83,6 +82,8 @@
#include "content/public/common/web_preferences.h"
#include "third_party/WebKit/public/web/WebFindOptions.h"
#include "printing/features/features.h"
+#include "ui/base/clipboard/clipboard.h"
+#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/gfx/font_render_params.h"
#include <QDir>
@@ -90,6 +91,7 @@
#include <QPageLayout>
#include <QStringList>
#include <QStyleHints>
+#include <QTimer>
#include <QVariant>
#include <QtCore/qelapsedtimer.h>
#include <QtCore/qmimedata.h>
@@ -101,6 +103,12 @@
namespace QtWebEngineCore {
+#define CHECK_VALID_RENDER_WIDGET_HOST_VIEW(render_view_host) \
+ if (!render_view_host->IsRenderViewLive() && render_view_host->GetWidget()->GetView()) { \
+ qWarning("Ignore navigation due to terminated render process with invalid RenderWidgetHostView."); \
+ return; \
+ }
+
static const int kTestWindowWidth = 800;
static const int kTestWindowHeight = 600;
static const int kHistoryStreamVersion = 3;
@@ -109,37 +117,37 @@ static QVariant fromJSValue(const base::Value *result)
{
QVariant ret;
switch (result->GetType()) {
- case base::Value::TYPE_NULL:
+ case base::Value::Type::NONE:
break;
- case base::Value::TYPE_BOOLEAN:
+ case base::Value::Type::BOOLEAN:
{
bool out;
if (result->GetAsBoolean(&out))
ret.setValue(out);
break;
}
- case base::Value::TYPE_INTEGER:
+ case base::Value::Type::INTEGER:
{
int out;
if (result->GetAsInteger(&out))
ret.setValue(out);
break;
}
- case base::Value::TYPE_DOUBLE:
+ case base::Value::Type::DOUBLE:
{
double out;
if (result->GetAsDouble(&out))
ret.setValue(out);
break;
}
- case base::Value::TYPE_STRING:
+ case base::Value::Type::STRING:
{
base::string16 out;
if (result->GetAsString(&out))
ret.setValue(toQt(out));
break;
}
- case base::Value::TYPE_LIST:
+ case base::Value::Type::LIST:
{
const base::ListValue *out;
if (result->GetAsList(&out)) {
@@ -154,7 +162,7 @@ static QVariant fromJSValue(const base::Value *result)
}
break;
}
- case base::Value::TYPE_DICTIONARY:
+ case base::Value::Type::DICTIONARY:
{
const base::DictionaryValue *out;
if (result->GetAsDictionary(&out)) {
@@ -168,10 +176,9 @@ static QVariant fromJSValue(const base::Value *result)
}
break;
}
- case base::Value::TYPE_BINARY:
+ case base::Value::Type::BINARY:
{
- const base::BinaryValue *out = static_cast<const base::BinaryValue*>(result);
- QByteArray data(out->GetBuffer(), out->GetSize());
+ QByteArray data(result->GetBlob().data(), result->GetBlob().size());
ret.setValue(data);
break;
}
@@ -350,7 +357,7 @@ WebContentsAdapterPrivate::WebContentsAdapterPrivate()
, adapterClient(0)
, nextRequestId(CallbackDirectory::ReservedCallbackIdsEnd)
, lastFindRequestId(0)
- , currentDropAction(blink::WebDragOperationNone)
+ , currentDropAction(blink::kWebDragOperationNone)
{
}
@@ -501,14 +508,16 @@ void WebContentsAdapter::stop()
void WebContentsAdapter::reload()
{
Q_D(WebContentsAdapter);
- d->webContents->GetController().Reload(/*checkRepost = */false);
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(d->webContents->GetRenderViewHost());
+ d->webContents->GetController().Reload(content::ReloadType::NORMAL, /*checkRepost = */false);
focusIfNecessary();
}
void WebContentsAdapter::reloadAndBypassCache()
{
Q_D(WebContentsAdapter);
- d->webContents->GetController().ReloadBypassingCache(/*checkRepost = */false);
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(d->webContents->GetRenderViewHost());
+ d->webContents->GetController().Reload(content::ReloadType::BYPASSING_CACHE, /*checkRepost = */false);
focusIfNecessary();
}
@@ -520,6 +529,9 @@ void WebContentsAdapter::load(const QUrl &url)
void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
{
+ Q_D(WebContentsAdapter);
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(d->webContents->GetRenderViewHost());
+
// The situation can occur when relying on the editingFinished signal in QML to set the url
// of the WebView.
// When enter is pressed, onEditingFinished fires and the url of the webview is set, which
@@ -533,7 +545,6 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
LoadRecursionGuard guard(this);
Q_UNUSED(guard);
- Q_D(WebContentsAdapter);
GURL gurl = toGurl(request.url());
// Add URL scheme if missing from view-source URL.
@@ -583,13 +594,35 @@ void WebContentsAdapter::load(const QWebEngineHttpRequest &request)
params.extra_headers += (*it).toStdString() + ": " + request.header(*it).toStdString();
}
- d->webContents->GetController().LoadURLWithParams(params);
- focusIfNecessary();
+ bool resizeNeeded = false;
+ if (request.url().hasFragment()) {
+ if (content::RenderWidgetHostView *rwhv = webContents()->GetRenderWidgetHostView()) {
+ const gfx::Size &viewportSize = rwhv->GetVisibleViewportSize();
+ resizeNeeded = (viewportSize.width() == 0 || viewportSize.height() == 0);
+ }
+ }
+
+ auto navigate = [this, params]() {
+ Q_D(WebContentsAdapter);
+ webContents()->GetController().LoadURLWithParams(params);
+ // Follow chrome::Navigate and invalidate the URL immediately.
+ d->webContentsDelegate->NavigationStateChanged(webContents(), content::INVALIDATE_TYPE_URL);
+ focusIfNecessary();
+ };
+
+ if (resizeNeeded) {
+ // Schedule navigation on the event loop.
+ QTimer::singleShot(0, navigate);
+ } else {
+ navigate();
+ }
}
void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl)
{
Q_D(WebContentsAdapter);
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(d->webContents->GetRenderViewHost());
+
QByteArray encodedData = data.toPercentEncoding();
std::string urlString;
if (!mimeType.isEmpty())
@@ -612,7 +645,7 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT
params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE;
d->webContents->GetController().LoadURLWithParams(params);
focusIfNecessary();
- d->webContents->Unselect();
+ d->webContents->CollapseSelection();
}
void WebContentsAdapter::save(const QString &filePath, int savePageFormat)
@@ -625,7 +658,7 @@ void WebContentsAdapter::save(const QString &filePath, int savePageFormat)
QUrl WebContentsAdapter::activeUrl() const
{
Q_D(const WebContentsAdapter);
- return toQt(d->webContents->GetLastCommittedURL());
+ return d->webContentsDelegate->url();
}
QUrl WebContentsAdapter::requestedUrl() const
@@ -660,7 +693,7 @@ QUrl WebContentsAdapter::iconUrl() const
QString WebContentsAdapter::pageTitle() const
{
Q_D(const WebContentsAdapter);
- return toQt(d->webContents->GetTitle());
+ return d->webContentsDelegate->title();
}
QString WebContentsAdapter::selectedText() const
@@ -720,12 +753,13 @@ void WebContentsAdapter::requestClose()
void WebContentsAdapter::unselect()
{
Q_D(const WebContentsAdapter);
- d->webContents->Unselect();
+ d->webContents->CollapseSelection();
}
void WebContentsAdapter::navigateToIndex(int offset)
{
Q_D(WebContentsAdapter);
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(d->webContents->GetRenderViewHost());
d->webContents->GetController().GoToIndex(offset);
focusIfNecessary();
}
@@ -733,6 +767,7 @@ void WebContentsAdapter::navigateToIndex(int offset)
void WebContentsAdapter::navigateToOffset(int offset)
{
Q_D(WebContentsAdapter);
+ CHECK_VALID_RENDER_WIDGET_HOST_VIEW(d->webContents->GetRenderViewHost());
d->webContents->GetController().GoToOffset(offset);
focusIfNecessary();
}
@@ -902,8 +937,8 @@ quint64 WebContentsAdapter::findText(const QString &subString, bool caseSensitiv
blink::WebFindOptions options;
options.forward = !findBackward;
- options.matchCase = caseSensitively;
- options.findNext = subString == d->webContentsDelegate->lastSearchedString();
+ options.match_case = caseSensitively;
+ options.find_next = subString == d->webContentsDelegate->lastSearchedString();
d->webContentsDelegate->setLastSearchedString(subString);
// Find already allows a request ID as input, but only as an int.
@@ -918,9 +953,6 @@ void WebContentsAdapter::stopFinding()
{
Q_D(WebContentsAdapter);
d->webContentsDelegate->setLastSearchedString(QString());
- // Clear any previous selection,
- // but keep the renderer blue rectangle selection just like Chromium does.
- d->webContents->Unselect();
d->webContents->StopFinding(content::STOP_FIND_ACTION_KEEP_SELECTION);
}
@@ -945,9 +977,26 @@ void WebContentsAdapter::download(const QUrl &url, const QString &suggestedFileN
dlmd->setDownloadType(BrowserContextAdapterClient::UserRequested);
dlm->SetDelegate(dlmd);
+ net::NetworkTrafficAnnotationTag traffic_annotation =
+ net::DefineNetworkTrafficAnnotation(
+ "WebContentsAdapter::download", R"(
+ semantics {
+ sender: "User"
+ description:
+ "User requested download"
+ trigger: "User."
+ data: "Anything."
+ destination: OTHER
+ }
+ policy {
+ cookies_allowed: YES
+ cookies_store: "user"
+ setting:
+ "It's possible not to use this feature."
+ })");
GURL gurl = toGurl(url);
std::unique_ptr<content::DownloadUrlParameters> params(
- content::DownloadUrlParameters::CreateForWebContentsMainFrame(webContents(), gurl));
+ content::DownloadUrlParameters::CreateForWebContentsMainFrame(webContents(), gurl, traffic_annotation));
params->set_suggested_name(toString16(suggestedFileName));
@@ -985,11 +1034,11 @@ void WebContentsAdapter::copyImageAt(const QPoint &location)
d->webContents->GetRenderViewHost()->GetMainFrame()->CopyImageAt(location.x(), location.y());
}
-ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerNoAction, blink::WebMediaPlayerAction::Unknown)
-ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerPlay, blink::WebMediaPlayerAction::Play)
-ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerMute, blink::WebMediaPlayerAction::Mute)
-ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerLoop, blink::WebMediaPlayerAction::Loop)
-ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerControls, blink::WebMediaPlayerAction::Controls)
+ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerNoAction, blink::WebMediaPlayerAction::kUnknown)
+ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerPlay, blink::WebMediaPlayerAction::kPlay)
+ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerMute, blink::WebMediaPlayerAction::kMute)
+ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerLoop, blink::WebMediaPlayerAction::kLoop)
+ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerControls, blink::WebMediaPlayerAction::kControls)
void WebContentsAdapter::executeMediaPlayerActionAt(const QPoint &location, MediaPlayerAction action, bool enable)
{
@@ -1180,18 +1229,23 @@ static QMimeData *mimeDataFromDropData(const content::DropData &dropData)
mimeData->setHtml(toQt(dropData.html.string()));
if (dropData.url.is_valid())
mimeData->setUrls(QList<QUrl>() << toQt(dropData.url));
+ if (!dropData.custom_data.empty()) {
+ base::Pickle pickle;
+ ui::WriteCustomDataToPickle(dropData.custom_data, &pickle);
+ mimeData->setData(toQt(ui::Clipboard::GetWebCustomDataFormatType().ToString()), QByteArray((const char*)pickle.data(), pickle.size()));
+ }
return mimeData;
}
static blink::WebDragOperationsMask toWeb(const Qt::DropActions action)
{
- int result = blink::WebDragOperationNone;
+ int result = blink::kWebDragOperationNone;
if (action & Qt::CopyAction)
- result |= blink::WebDragOperationCopy;
+ result |= blink::kWebDragOperationCopy;
if (action & Qt::LinkAction)
- result |= blink::WebDragOperationLink;
+ result |= blink::kWebDragOperationLink;
if (action & Qt::MoveAction)
- result |= blink::WebDragOperationMove;
+ result |= blink::kWebDragOperationMove;
return static_cast<blink::WebDragOperationsMask>(result);
}
@@ -1209,16 +1263,14 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD
d->currentDropData.reset(new content::DropData(dropData));
d->currentDropData->download_metadata.clear();
d->currentDropData->file_contents.clear();
- d->currentDropData->file_description_filename.clear();
+ d->currentDropData->file_contents_content_disposition.clear();
- d->currentDropAction = blink::WebDragOperationNone;
+ d->currentDropAction = blink::kWebDragOperationNone;
QDrag *drag = new QDrag(dragSource); // will be deleted by Qt's DnD implementation
bool dValid = true;
QMetaObject::Connection onDestroyed = QObject::connect(dragSource, &QObject::destroyed, [&dValid](){
dValid = false;
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0))
QDrag::cancel();
-#endif
});
QMimeData *mimeData = mimeDataFromDropData(*d->currentDropData);
@@ -1266,7 +1318,8 @@ bool WebContentsAdapter::handleDropDataFileContents(const content::DropData &dro
}
}
- const QString &fileName = toQt(dropData.file_description_filename);
+ const auto maybeFilename = dropData.GetSafeFilenameForImageFileContents();
+ const QString fileName = maybeFilename ? toQt(maybeFilename->AsUTF16Unsafe()) : QString();
const QString &filePath = d->dndTmpDir->filePath(fileName);
QFile file(filePath);
if (!file.open(QIODevice::WriteOnly)) {
@@ -1296,6 +1349,10 @@ static void fillDropDataFromMimeData(content::DropData *dropData, const QMimeDat
dropData->html = toNullableString16(mimeData->html());
if (mimeData->hasText())
dropData->text = toNullableString16(mimeData->text());
+ if (mimeData->hasFormat(toQt(ui::Clipboard::GetWebCustomDataFormatType().ToString()))) {
+ QByteArray customData = mimeData->data(toQt(ui::Clipboard::GetWebCustomDataFormatType().ToString()));
+ ui::ReadCustomDataIntoMap(customData.constData(), customData.length(), &dropData->custom_data);
+ }
}
void WebContentsAdapter::enterDrag(QDragEnterEvent *e, const QPoint &screenPos)
@@ -1317,11 +1374,11 @@ void WebContentsAdapter::enterDrag(QDragEnterEvent *e, const QPoint &screenPos)
Qt::DropAction toQt(blink::WebDragOperation op)
{
- if (op & blink::WebDragOperationCopy)
+ if (op & blink::kWebDragOperationCopy)
return Qt::CopyAction;
- if (op & blink::WebDragOperationLink)
+ if (op & blink::kWebDragOperationLink)
return Qt::LinkAction;
- if (op & blink::WebDragOperationMove || op & blink::WebDragOperationDelete)
+ if (op & blink::kWebDragOperationMove || op & blink::kWebDragOperationDelete)
return Qt::MoveAction;
return Qt::IgnoreAction;
}
@@ -1330,11 +1387,11 @@ static int toWeb(Qt::MouseButtons buttons)
{
int result = 0;
if (buttons & Qt::LeftButton)
- result |= blink::WebInputEvent::LeftButtonDown;
+ result |= blink::WebInputEvent::kLeftButtonDown;
if (buttons & Qt::RightButton)
- result |= blink::WebInputEvent::RightButtonDown;
+ result |= blink::WebInputEvent::kRightButtonDown;
if (buttons & Qt::MiddleButton)
- result |= blink::WebInputEvent::MiddleButtonDown;
+ result |= blink::WebInputEvent::kMiddleButtonDown;
return result;
}
@@ -1342,13 +1399,13 @@ static int toWeb(Qt::KeyboardModifiers modifiers)
{
int result = 0;
if (modifiers & Qt::ShiftModifier)
- result |= blink::WebInputEvent::ShiftKey;
+ result |= blink::WebInputEvent::kShiftKey;
if (modifiers & Qt::ControlModifier)
- result |= blink::WebInputEvent::ControlKey;
+ result |= blink::WebInputEvent::kControlKey;
if (modifiers & Qt::AltModifier)
- result |= blink::WebInputEvent::AltKey;
+ result |= blink::WebInputEvent::kAltKey;
if (modifiers & Qt::MetaModifier)
- result |= blink::WebInputEvent::MetaKey;
+ result |= blink::WebInputEvent::kMetaKey;
return result;
}
@@ -1408,7 +1465,7 @@ void WebContentsAdapter::leaveDrag()
{
Q_D(WebContentsAdapter);
content::RenderViewHost *rvh = d->webContents->GetRenderViewHost();
- rvh->GetWidget()->DragTargetDragLeave();
+ rvh->GetWidget()->DragTargetDragLeave(d->lastDragClientPos, d->lastDragScreenPos);
d->currentDropData.reset();
}
@@ -1496,13 +1553,15 @@ ASSERT_ENUMS_MATCH(WebContentsAdapterClient::SaveToDiskDisposition, WindowOpenDi
ASSERT_ENUMS_MATCH(WebContentsAdapterClient::OffTheRecordDisposition, WindowOpenDisposition::OFF_THE_RECORD)
ASSERT_ENUMS_MATCH(WebContentsAdapterClient::IgnoreActionDisposition, WindowOpenDisposition::IGNORE_ACTION)
-ASSERT_ENUMS_MATCH(ReferrerPolicy::Always, blink::WebReferrerPolicyAlways)
-ASSERT_ENUMS_MATCH(ReferrerPolicy::Default, blink::WebReferrerPolicyDefault)
-ASSERT_ENUMS_MATCH(ReferrerPolicy::NoReferrerWhenDowngrade, blink::WebReferrerPolicyNoReferrerWhenDowngrade)
-ASSERT_ENUMS_MATCH(ReferrerPolicy::Never, blink::WebReferrerPolicyNever)
-ASSERT_ENUMS_MATCH(ReferrerPolicy::Origin, blink::WebReferrerPolicyOrigin)
-ASSERT_ENUMS_MATCH(ReferrerPolicy::OriginWhenCrossOrigin, blink::WebReferrerPolicyOriginWhenCrossOrigin)
-ASSERT_ENUMS_MATCH(ReferrerPolicy::NoReferrerWhenDowngradeOriginWhenCrossOrigin, blink::WebReferrerPolicyNoReferrerWhenDowngradeOriginWhenCrossOrigin)
-ASSERT_ENUMS_MATCH(ReferrerPolicy::Last, blink::WebReferrerPolicyLast)
+ASSERT_ENUMS_MATCH(ReferrerPolicy::Always, blink::kWebReferrerPolicyAlways)
+ASSERT_ENUMS_MATCH(ReferrerPolicy::Default, blink::kWebReferrerPolicyDefault)
+ASSERT_ENUMS_MATCH(ReferrerPolicy::NoReferrerWhenDowngrade, blink::kWebReferrerPolicyNoReferrerWhenDowngrade)
+ASSERT_ENUMS_MATCH(ReferrerPolicy::Never, blink::kWebReferrerPolicyNever)
+ASSERT_ENUMS_MATCH(ReferrerPolicy::Origin, blink::kWebReferrerPolicyOrigin)
+ASSERT_ENUMS_MATCH(ReferrerPolicy::OriginWhenCrossOrigin, blink::kWebReferrerPolicyOriginWhenCrossOrigin)
+ASSERT_ENUMS_MATCH(ReferrerPolicy::NoReferrerWhenDowngradeOriginWhenCrossOrigin, blink::kWebReferrerPolicyNoReferrerWhenDowngradeOriginWhenCrossOrigin)
+ASSERT_ENUMS_MATCH(ReferrerPolicy::SameOrigin, blink::kWebReferrerPolicySameOrigin)
+ASSERT_ENUMS_MATCH(ReferrerPolicy::StrictOrigin, blink::kWebReferrerPolicyStrictOrigin)
+ASSERT_ENUMS_MATCH(ReferrerPolicy::Last, blink::kWebReferrerPolicyLast)
} // namespace QtWebEngineCore