To display the requested web page again, "
"the browser needs to resend information you have "
"previously submitted.
"
"If you were shopping online and made a purchase, "
"click the Cancel button to prevent a duplicate purchase."
"Otherwise, click the Continue button to display the web"
"page again.
"),
i18n("Resubmit Information")) == KMessageBox::Cancel) {
return false;
}
break;
#endif
case QWebEnginePage::NavigationTypeBackForward:
// If history navigation is locked, ignore all such requests...
if (property("HistoryNavigationLocked").toBool()) {
setProperty("HistoryNavigationLocked", QVariant());
qDebug() << "Rejected history navigation because 'HistoryNavigationLocked' property is set!";
return false;
}
//kDebug() << "Navigating to item (" << history()->currentItemIndex()
// << "of" << history()->count() << "):" << history()->currentItem().url();
inPageRequest = false;
break;
case QWebEnginePage::NavigationTypeReload:
// setRequestMetaData(QL1S("cache"), QL1S("reload"));
inPageRequest = false;
break;
case QWebEnginePage::NavigationTypeOther: // triggered by javascript
qDebug() << "Triggered by javascript";
inPageRequest = !isTypedUrl;
break;
default:
break;
}
if (inPageRequest) {
// if (!checkLinkSecurity(request, type))
// return false;
// if (m_sslInfo.isValid())
// setRequestMetaData(QL1S("ssl_was_in_use"), QL1S("TRUE"));
}
// Honor the enabling/disabling of plugins per host.
settings()->setAttribute(QWebEngineSettings::PluginsEnabled, WebEngineSettings::self()->isPluginsEnabled(reqUrl.host()));
emit navigationRequested(this, url);
return QWebEnginePage::acceptNavigationRequest(url, type, isMainFrame);
}
#if 0
static int errorCodeFromReply(QNetworkReply* reply)
{
// First check if there is a KIO error code sent back and use that,
// if not attempt to convert QNetworkReply's NetworkError to KIO::Error.
QVariant attr = reply->attribute(static_cast(KIO::AccessManager::KioError));
if (attr.isValid() && attr.type() == QVariant::Int)
return attr.toInt();
switch (reply->error()) {
case QNetworkReply::ConnectionRefusedError:
return KIO::ERR_COULD_NOT_CONNECT;
case QNetworkReply::HostNotFoundError:
return KIO::ERR_UNKNOWN_HOST;
case QNetworkReply::TimeoutError:
return KIO::ERR_SERVER_TIMEOUT;
case QNetworkReply::OperationCanceledError:
return KIO::ERR_USER_CANCELED;
case QNetworkReply::ProxyNotFoundError:
return KIO::ERR_UNKNOWN_PROXY_HOST;
case QNetworkReply::ContentAccessDenied:
return KIO::ERR_ACCESS_DENIED;
case QNetworkReply::ContentOperationNotPermittedError:
return KIO::ERR_WRITE_ACCESS_DENIED;
case QNetworkReply::ContentNotFoundError:
return KIO::ERR_NO_CONTENT;
case QNetworkReply::AuthenticationRequiredError:
return KIO::ERR_COULD_NOT_AUTHENTICATE;
case QNetworkReply::ProtocolUnknownError:
return KIO::ERR_UNSUPPORTED_PROTOCOL;
case QNetworkReply::ProtocolInvalidOperationError:
return KIO::ERR_UNSUPPORTED_ACTION;
case QNetworkReply::UnknownNetworkError:
return KIO::ERR_UNKNOWN;
case QNetworkReply::NoError:
default:
break;
}
return 0;
}
#endif
WebEnginePart* WebEnginePage::part() const
{
return m_part.data();
}
void WebEnginePage::setPart(WebEnginePart* part)
{
m_part = part;
}
void WebEnginePage::slotLoadFinished(bool ok)
{
QUrl requestUrl = url();
requestUrl.setUserInfo(QString());
const bool shouldResetSslInfo = (m_sslInfo.isValid() && !domainSchemeMatch(requestUrl, m_sslInfo.url()));
#if 0
QWebFrame* frame = qobject_cast(reply->request().originatingObject());
if (!frame)
return;
const bool isMainFrameRequest = (frame == mainFrame());
#else
// PORTING_TODO
const bool isMainFrameRequest = true;
#endif
#if 0
// Only deal with non-redirect responses...
const QVariant redirectVar = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (isMainFrameRequest && redirectVar.isValid()) {
m_sslInfo.restoreFrom(reply->attribute(static_cast(KIO::AccessManager::MetaData)),
reply->url(), shouldResetSslInfo);
return;
}
const int errCode = errorCodeFromReply(reply);
kDebug() << frame << "is main frame request?" << isMainFrameRequest << requestUrl;
#endif
if (ok) {
if (isMainFrameRequest) {
#if 0
m_sslInfo.restoreFrom(reply->attribute(static_cast(KIO::AccessManager::MetaData)),
reply->url(), shouldResetSslInfo);
#endif
setPageJScriptPolicy(url());
}
} else {
// Handle any error...
#if 0
switch (errCode) {
case 0:
case KIO::ERR_NO_CONTENT:
break;
case KIO::ERR_ABORTED:
case KIO::ERR_USER_CANCELED: // Do nothing if request is cancelled/aborted
//kDebug() << "User aborted request!";
m_ignoreError = true;
emit loadAborted(QUrl());
return;
// Handle the user clicking on a link that refers to a directory
// Since KIO cannot automatically convert a GET request to a LISTDIR one.
case KIO::ERR_IS_DIRECTORY:
m_ignoreError = true;
emit loadAborted(reply->url());
return;
default:
// Make sure the saveFrameStateRequested signal is emitted so
// the page can restored properly.
if (isMainFrameRequest)
emit saveFrameStateRequested(frame, 0);
m_ignoreError = (reply->attribute(QNetworkRequest::User).toInt() == QNetworkReply::ContentAccessDenied);
m_kioErrorCode = errCode;
break;
#endif
}
if (isMainFrameRequest) {
const WebEnginePageSecurity security = (m_sslInfo.isValid() ? PageEncrypted : PageUnencrypted);
emit m_part->browserExtension()->setPageSecurity(security);
}
}
void WebEnginePage::slotUnsupportedContent(QNetworkReply* reply)
{
#if 0
//kDebug() << reply->url();
QString mimeType;
KIO::MetaData metaData;
KIO::AccessManager::putReplyOnHold(reply);
QString downloadCmd;
checkForDownloadManager(view(), downloadCmd);
if (!downloadCmd.isEmpty()) {
reply->setProperty("DownloadManagerExe", downloadCmd);
}
if (QWePage::handleReply(reply, &mimeType, &metaData)) {
reply->deleteLater();
if (qobject_cast(this) && isBlankUrl(m_part->url())) {
m_part->closeUrl();
if (m_part->arguments().metaData().contains(QL1S("new-window"))) {
m_part->widget()->topLevelWidget()->close();
} else {
delete m_part;
}
}
return;
}
//kDebug() << "mimetype=" << mimeType << "metadata:" << metaData;
if (reply->request().originatingObject() == this->mainFrame()) {
KParts::OpenUrlArguments args;
args.setMimeType(mimeType);
args.metaData() = metaData;
emit m_part->browserExtension()->openUrlRequest(reply->url(), args, KParts::BrowserArguments());
return;
}
#endif
reply->deleteLater();
}
void WebEnginePage::slotFeaturePermissionRequested(const QUrl& url, QWebEnginePage::Feature feature)
{
if (url == this->url()) {
part()->slotShowFeaturePermissionBar(feature);
return;
}
switch(feature) {
case QWebEnginePage::Notifications:
// FIXME: We should have a setting to tell if this is enabled, but so far it is always enabled.
setFeaturePermission(url, feature, QWebEnginePage::PermissionGrantedByUser);
break;
case QWebEnginePage::Geolocation:
if (KMessageBox::warningContinueCancel(0, i18n("This site is attempting to "
"access information about your "
"physical location.\n"
"Do you want to allow it access?"),
i18n("Network Transmission"),
KGuiItem(i18n("Allow access")),
KStandardGuiItem::cancel(),
QStringLiteral("WarnGeolocation")) == KMessageBox::Cancel) {
setFeaturePermission(url, feature, QWebEnginePage::PermissionDeniedByUser);
} else {
setFeaturePermission(url, feature, QWebEnginePage::PermissionGrantedByUser);
}
break;
default:
setFeaturePermission(url, feature, QWebEnginePage::PermissionUnknown);
break;
}
}
void WebEnginePage::slotGeometryChangeRequested(const QRect & rect)
{
const QString host = url().host();
// NOTE: If a new window was created from another window which is in
// maximized mode and its width and/or height were not specified at the
// time of its creation, which is always the case in QWebEnginePage::createWindow,
// then any move operation will seem not to work. That is because the new
// window will be in maximized mode where moving it will not be possible...
if (WebEngineSettings::self()->windowMovePolicy(host) == KParts::HtmlSettingsInterface::JSWindowMoveAllow &&
(view()->x() != rect.x() || view()->y() != rect.y()))
emit m_part->browserExtension()->moveTopLevelWidget(rect.x(), rect.y());
const int height = rect.height();
const int width = rect.width();
// parts of following code are based on kjs_window.cpp
// Security check: within desktop limits and bigger than 100x100 (per spec)
if (width < 100 || height < 100) {
qWarning() << "Window resize refused, window would be too small (" << width << "," << height << ")";
return;
}
QRect sg = QApplication::desktop()->screenGeometry(view());
if (width > sg.width() || height > sg.height()) {
qWarning() << "Window resize refused, window would be too big (" << width << "," << height << ")";
return;
}
if (WebEngineSettings::self()->windowResizePolicy(host) == KParts::HtmlSettingsInterface::JSWindowResizeAllow) {
//kDebug() << "resizing to " << width << "x" << height;
emit m_part->browserExtension()->resizeTopLevelWidget(width, height);
}
// If the window is out of the desktop, move it up/left
// (maybe we should use workarea instead of sg, otherwise the window ends up below kicker)
const int right = view()->x() + view()->frameGeometry().width();
const int bottom = view()->y() + view()->frameGeometry().height();
int moveByX = 0, moveByY = 0;
if (right > sg.right())
moveByX = - right + sg.right(); // always <0
if (bottom > sg.bottom())
moveByY = - bottom + sg.bottom(); // always <0
if ((moveByX || moveByY) && WebEngineSettings::self()->windowMovePolicy(host) == KParts::HtmlSettingsInterface::JSWindowMoveAllow)
emit m_part->browserExtension()->moveTopLevelWidget(view()->x() + moveByX, view()->y() + moveByY);
}
bool WebEnginePage::checkLinkSecurity(const QNetworkRequest &req, NavigationType type) const
{
// Check whether the request is authorized or not...
if (!KUrlAuthorized::authorizeUrlAction(QStringLiteral("redirect"), url(), req.url())) {
//kDebug() << "*** Failed security check: base-url=" << mainFrame()->url() << ", dest-url=" << req.url();
QString buttonText, title, message;
int response = KMessageBox::Cancel;
QUrl linkUrl (req.url());
if (type == QWebEnginePage::NavigationTypeLinkClicked) {
message = i18n("This untrusted page links to
%1."
"
Do you want to follow the link?", linkUrl.url());
title = i18n("Security Warning");
buttonText = i18nc("follow link despite of security warning", "Follow");
} else {
title = i18n("Security Alert");
message = i18n("Access by untrusted page to
%1
denied.",
linkUrl.toDisplayString().toHtmlEscaped());
}
if (buttonText.isEmpty()) {
KMessageBox::error( 0, message, title);
} else {
// Dangerous flag makes the Cancel button the default
response = KMessageBox::warningContinueCancel(0, message, title,
KGuiItem(buttonText),
KStandardGuiItem::cancel(),
QString(), // no don't ask again info
KMessageBox::Notify | KMessageBox::Dangerous);
}
return (response == KMessageBox::Continue);
}
return true;
}
-bool WebEnginePage::checkFormData(const QNetworkRequest &req) const
+bool WebEnginePage::checkFormData(const QUrl &url) const
{
- const QString scheme (req.url().scheme());
+ const QString scheme (url.scheme());
if (m_sslInfo.isValid() &&
!scheme.compare(QL1S("https")) && !scheme.compare(QL1S("mailto")) &&
(KMessageBox::warningContinueCancel(0,
i18n("Warning: This is a secure form "
"but it is attempting to send "
"your data back unencrypted.\n"
"A third party may be able to "
"intercept and view this "
"information.\nAre you sure you "
"want to send the data unencrypted?"),
i18n("Network Transmission"),
KGuiItem(i18n("&Send Unencrypted"))) == KMessageBox::Cancel)) {
return false;
}
if (scheme.compare(QL1S("mailto")) == 0 &&
(KMessageBox::warningContinueCancel(0, i18n("This site is attempting to "
"submit form data via email.\n"
"Do you want to continue?"),
i18n("Network Transmission"),
KGuiItem(i18n("&Send Email")),
KStandardGuiItem::cancel(),
QStringLiteral("WarnTriedEmailSubmit")) == KMessageBox::Cancel)) {
return false;
}
return true;
}
// Sanitizes the "mailto:" url, e.g. strips out any "attach" parameters.
static QUrl sanitizeMailToUrl(const QUrl &url, QStringList& files) {
QUrl sanitizedUrl;
// NOTE: This is necessary to ensure we can properly use QUrl's query
// related APIs to process 'mailto:' urls of form 'mailto:foo@bar.com'.
if (url.hasQuery())
sanitizedUrl = url;
else
sanitizedUrl = QUrl(url.scheme() + QL1S(":?") + url.path());
QUrlQuery query(sanitizedUrl);
const QList > items (query.queryItems());
QUrlQuery sanitizedQuery;
for(auto queryItem : items) {
if (queryItem.first.contains(QL1C('@')) && queryItem.second.isEmpty()) {
// ### DF: this hack breaks mailto:faure@kde.org, kmail doesn't expect mailto:?to=faure@kde.org
queryItem.second = queryItem.first;
queryItem.first = QStringLiteral("to");
} else if (QString::compare(queryItem.first, QL1S("attach"), Qt::CaseInsensitive) == 0) {
files << queryItem.second;
continue;
}
sanitizedQuery.addQueryItem(queryItem.first, queryItem.second);
}
sanitizedUrl.setQuery(sanitizedQuery);
return sanitizedUrl;
}
bool WebEnginePage::handleMailToUrl (const QUrl &url, NavigationType type) const
{
if (url.scheme() == QL1S("mailto")) {
QStringList files;
QUrl mailtoUrl (sanitizeMailToUrl(url, files));
switch (type) {
case QWebEnginePage::NavigationTypeLinkClicked:
if (!files.isEmpty() && KMessageBox::warningContinueCancelList(0,
i18n("Do you want to allow this site to attach "
"the following files to the email message?"),
files, i18n("Email Attachment Confirmation"),
KGuiItem(i18n("&Allow attachments")),
KGuiItem(i18n("&Ignore attachments")), QL1S("WarnEmailAttachment")) == KMessageBox::Continue) {
// Re-add the attachments...
QStringListIterator filesIt (files);
QUrlQuery query(mailtoUrl);
while (filesIt.hasNext()) {
query.addQueryItem(QL1S("attach"), filesIt.next());
}
mailtoUrl.setQuery(query);
}
break;
case QWebEnginePage::NavigationTypeFormSubmitted:
//case QWebEnginePage::NavigationTypeFormResubmitted:
if (!files.isEmpty()) {
KMessageBox::information(0, i18n("This site attempted to attach a file from your "
"computer in the form submission. The attachment "
"was removed for your protection."),
i18n("Attachment Removed"), QStringLiteral("InfoTriedAttach"));
}
break;
default:
break;
}
//kDebug() << "Emitting openUrlRequest with " << mailtoUrl;
emit m_part->browserExtension()->openUrlRequest(mailtoUrl);
return true;
}
return false;
}
void WebEnginePage::setPageJScriptPolicy(const QUrl &url)
{
const QString hostname (url.host());
settings()->setAttribute(QWebEngineSettings::JavascriptEnabled,
WebEngineSettings::self()->isJavaScriptEnabled(hostname));
const KParts::HtmlSettingsInterface::JSWindowOpenPolicy policy = WebEngineSettings::self()->windowOpenPolicy(hostname);
settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows,
(policy != KParts::HtmlSettingsInterface::JSWindowOpenDeny &&
policy != KParts::HtmlSettingsInterface::JSWindowOpenSmart));
}
void WebEnginePage::slotAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *auth)
{
KIO::AuthInfo info;
info.url = requestUrl;
info.username = auth->user();
info.realmValue = auth->realm();
// If no realm metadata, then make sure path matching is turned on.
info.verifyPath = info.realmValue.isEmpty();
const QString errorMsg = QString();
#if KIO_VERSION >= QT_VERSION_CHECK(5, 30, 0)
const int ret = m_passwdServerClient->queryAuthInfo(&info, errorMsg, view()->window()->winId(), KUserTimestamp::userTimestamp());
#else
const int ret = 1; // no KPasswdServerClient until 5.30
#endif
if (ret == KJob::NoError) {
auth->setUser(info.username);
auth->setPassword(info.password);
} else {
// Set authenticator null if dialog is cancelled
// or if we couldn't communicate with kpasswdserver
*auth = QAuthenticator();
}
}
/************************************* Begin NewWindowPage ******************************************/
NewWindowPage::NewWindowPage(WebWindowType type, WebEnginePart* part, QWidget* parent)
:WebEnginePage(part, parent) , m_type(type) , m_createNewWindow(true)
{
Q_ASSERT_X (part, "NewWindowPage", "Must specify a valid KPart");
connect(this, SIGNAL(menuBarVisibilityChangeRequested(bool)),
this, SLOT(slotMenuBarVisibilityChangeRequested(bool)));
connect(this, SIGNAL(toolBarVisibilityChangeRequested(bool)),
this, SLOT(slotToolBarVisibilityChangeRequested(bool)));
connect(this, SIGNAL(statusBarVisibilityChangeRequested(bool)),
this, SLOT(slotStatusBarVisibilityChangeRequested(bool)));
connect(this, SIGNAL(loadFinished(bool)), this, SLOT(slotLoadFinished(bool)));
#if QTWEBENGINE_VERSION >= QT_VERSION_CHECK(5, 7, 0)
if (m_type == WebBrowserBackgroundTab) {
m_windowArgs.setLowerWindow(true);
}
#endif
}
NewWindowPage::~NewWindowPage()
{
}
static KParts::BrowserArguments browserArgs(WebEnginePage::WebWindowType type)
{
KParts::BrowserArguments bargs;
switch (type) {
case WebEnginePage::WebDialog:
case WebEnginePage::WebBrowserWindow:
bargs.setForcesNewWindow(true);
break;
case WebEnginePage::WebBrowserTab:
#if QTWEBENGINE_VERSION >= QT_VERSION_CHECK(5, 7, 0)
case WebEnginePage::WebBrowserBackgroundTab:
#endif
// let konq decide, based on user configuration
//bargs.setNewTab(true);
break;
}
return bargs;
}
bool NewWindowPage::acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame)
{
//qDebug() << "url:" << url << ", type:" << type << ", isMainFrame:" << isMainFrame << "m_createNewWindow=" << m_createNewWindow;
if (m_createNewWindow) {
const QUrl reqUrl (url);
const bool actionRequestedByUser = type != QWebEnginePage::NavigationTypeOther;
if (actionRequestedByUser) {
if (!part() && !isMainFrame) {
return false;
}
const KParts::HtmlSettingsInterface::JSWindowOpenPolicy policy = WebEngineSettings::self()->windowOpenPolicy(reqUrl.host());
switch (policy) {
case KParts::HtmlSettingsInterface::JSWindowOpenDeny:
// TODO: Implement support for dealing with blocked pop up windows.
this->deleteLater();
return false;
case KParts::HtmlSettingsInterface::JSWindowOpenAsk: {
const QString message = (reqUrl.isEmpty() ?
i18n("This site is requesting to open a new popup window.\n"
"Do you want to allow this?") :
i18n("This site is requesting to open a popup window to"
"%1
Do you want to allow this?",
KStringHandler::rsqueeze(reqUrl.toDisplayString().toHtmlEscaped(), 100)));
if (KMessageBox::questionYesNo(view(), message,
i18n("Javascript Popup Confirmation"),
KGuiItem(i18n("Allow")),
KGuiItem(i18n("Do Not Allow"))) == KMessageBox::No) {
// TODO: Implement support for dealing with blocked pop up windows.
this->deleteLater();
return false;
}
break;
}
default:
break;
}
}
// Browser args...
KParts::BrowserArguments bargs = browserArgs(m_type);
// OpenUrl args...
KParts::OpenUrlArguments uargs;
uargs.setMimeType(QL1S("text/html"));
uargs.setActionRequestedByUser(actionRequestedByUser);
// Window args...
KParts::WindowArgs wargs (m_windowArgs);
KParts::ReadOnlyPart* newWindowPart =0;
part()->browserExtension()->createNewWindow(QUrl(), uargs, bargs, wargs, &newWindowPart);
qDebug() << "Created new window" << newWindowPart;
if (!newWindowPart) {
return false;
} else if (newWindowPart->widget()->topLevelWidget() != part()->widget()->topLevelWidget()) {
KParts::OpenUrlArguments args;
args.metaData().insert(QL1S("new-window"), QL1S("true"));
newWindowPart->setArguments(args);
}
// Get the webview...
WebEnginePart* webenginePart = qobject_cast(newWindowPart);
WebEngineView* webView = webenginePart ? qobject_cast(webenginePart->view()) : 0;
// If the newly created window is NOT a webenginepart...
if (!webView) {
qDebug() << "Opening URL on" << newWindowPart;
newWindowPart->openUrl(reqUrl);
this->deleteLater();
return false;
}
// Reparent this page to the new webview to prevent memory leaks.
setParent(webView);
// Replace the webpage of the new webview with this one. Nice trick...
webView->setPage(this);
// Set the new part as the one this page will use going forward.
setPart(webenginePart);
// Connect all the signals from this page to the slots in the new part.
webenginePart->connectWebEnginePageSignals(this);
//Set the create new window flag to false...
m_createNewWindow = false;
}
emit navigationRequested(this, url);
return WebEnginePage::acceptNavigationRequest(url, type, isMainFrame);
}
void NewWindowPage::slotGeometryChangeRequested(const QRect & rect)
{
if (!rect.isValid())
return;
if (!m_createNewWindow) {
WebEnginePage::slotGeometryChangeRequested(rect);
return;
}
m_windowArgs.setX(rect.x());
m_windowArgs.setY(rect.y());
m_windowArgs.setWidth(qMax(rect.width(), 100));
m_windowArgs.setHeight(qMax(rect.height(), 100));
}
void NewWindowPage::slotMenuBarVisibilityChangeRequested(bool visible)
{
//kDebug() << visible;
m_windowArgs.setMenuBarVisible(visible);
}
void NewWindowPage::slotStatusBarVisibilityChangeRequested(bool visible)
{
//kDebug() << visible;
m_windowArgs.setStatusBarVisible(visible);
}
void NewWindowPage::slotToolBarVisibilityChangeRequested(bool visible)
{
//kDebug() << visible;
m_windowArgs.setToolBarsVisible(visible);
}
// When is this called? (and acceptNavigationRequest is not called?)
// The only case I found is Ctrl+click on link to data URL (like in konqviewmgrtest), that's quite specific...
// Everything else seems to work with this method being commented out...
void NewWindowPage::slotLoadFinished(bool ok)
{
Q_UNUSED(ok)
qDebug() << ok;
if (!m_createNewWindow)
return;
const bool actionRequestedByUser = true; // ### we don't have the information here, unlike in acceptNavigationRequest
// Browser args...
KParts::BrowserArguments bargs = browserArgs(m_type);
//bargs.frameName = mainFrame()->frameName();
// OpenUrl args...
KParts::OpenUrlArguments uargs;
uargs.setMimeType(QL1S("text/html"));
uargs.setActionRequestedByUser(actionRequestedByUser);
// Window args...
KParts::WindowArgs wargs (m_windowArgs);
KParts::ReadOnlyPart* newWindowPart =0;
part()->browserExtension()->createNewWindow(QUrl(), uargs, bargs, wargs, &newWindowPart);
qDebug() << "Created new window or tab" << newWindowPart;
// Get the webview...
WebEnginePart* webenginePart = newWindowPart ? qobject_cast(newWindowPart) : 0;
WebEngineView* webView = webenginePart ? qobject_cast(webenginePart->view()) : 0;
if (webView) {
// if a new window is created, set a new window meta-data flag.
if (newWindowPart->widget()->topLevelWidget() != part()->widget()->topLevelWidget()) {
KParts::OpenUrlArguments args;
args.metaData().insert(QL1S("new-window"), QL1S("true"));
newWindowPart->setArguments(args);
}
// Reparent this page to the new webview to prevent memory leaks.
setParent(webView);
// Replace the webpage of the new webview with this one. Nice trick...
webView->setPage(this);
// Set the new part as the one this page will use going forward.
setPart(webenginePart);
// Connect all the signals from this page to the slots in the new part.
webenginePart->connectWebEnginePageSignals(this);
}
//Set the create new window flag to false...
m_createNewWindow = false;
}
/****************************** End NewWindowPage *************************************************/
diff --git a/webenginepart/src/webenginepage.h b/webenginepart/src/webenginepage.h
index 8fa038665..cb3d5ed71 100644
--- a/webenginepart/src/webenginepage.h
+++ b/webenginepart/src/webenginepage.h
@@ -1,163 +1,168 @@
/*
* This file is part of the KDE project.
*
* Copyright (C) 2008 Dirk Mueller
* Copyright (C) 2008 Urs Wolfer
* Copyright (C) 2009 Dawit Alemayehu
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
*
*/
#ifndef WEBENGINEPAGE_H
#define WEBENGINEPAGE_H
#include "websslinfo.h"
#include
#include
#include
#include
#include
#include
#include
class QAuthenticator;
class QUrl;
class WebSslInfo;
class WebEnginePart;
class QWebEngineDownloadItem;
class KPasswdServerClient;
+class WebEngineWallet;
class WebEnginePage : public QWebEnginePage
{
Q_OBJECT
public:
explicit WebEnginePage(WebEnginePart *wpart, QWidget *parent = Q_NULLPTR);
~WebEnginePage();
/**
* Returns the SSL information for the current page.
*
* @see WebSslInfo.
*/
const WebSslInfo& sslInfo() const;
/**
* Sets the page's SSL information to @p other.
*
* @see WebSslInfo
*/
void setSslInfo (const WebSslInfo &other);
void download(const QUrl &url, bool newWindow = false);
+ WebEngineWallet* wallet() const {return m_wallet;}
+
Q_SIGNALS:
/**
* This signal is emitted whenever a user cancels/aborts a load resource
* request.
*/
void loadAborted(const QUrl &url);
void navigationRequested(WebEnginePage* page, const QUrl& url);
protected:
/**
* Returns the webengine part in use by this object.
* @internal
*/
WebEnginePart* part() const;
/**
* Sets the webengine part to be used by this object.
* @internal
*/
void setPart(WebEnginePart*);
/**
* Reimplemented for internal reasons, the API is not affected.
* @internal
*/
QWebEnginePage* createWindow(WebWindowType type) Q_DECL_OVERRIDE;
/**
* Reimplemented for internal reasons, the API is not affected.
* @internal
*/
bool acceptNavigationRequest(const QUrl& request, NavigationType type, bool isMainFrame) Q_DECL_OVERRIDE;
protected Q_SLOTS:
void slotLoadFinished(bool ok);
void slotUnsupportedContent(QNetworkReply* reply);
virtual void slotGeometryChangeRequested(const QRect& rect);
void slotFeaturePermissionRequested(const QUrl& url, QWebEnginePage::Feature feature);
void slotAuthenticationRequired(const QUrl &requestUrl, QAuthenticator *auth);
private:
bool checkLinkSecurity(const QNetworkRequest& req, NavigationType type) const;
- bool checkFormData(const QNetworkRequest& req) const;
+ bool checkFormData(const QUrl& url) const;
bool handleMailToUrl (const QUrl& , NavigationType type) const;
void setPageJScriptPolicy(const QUrl& url);
private:
enum WebEnginePageSecurity { PageUnencrypted, PageEncrypted, PageMixed };
int m_kioErrorCode;
bool m_ignoreError;
WebSslInfo m_sslInfo;
QPointer m_part;
QScopedPointer m_passwdServerClient;
+ WebEngineWallet *m_wallet;
};
/**
* This is a fake implementation of WebEnginePage to workaround the ugly API used
* to request for the creation of a new window from javascript in QtWebEngine. PORTING_TODO
*
* The KPart API for creating new windows requires all the information about the
* new window up front. Unfortunately QWebEnginePage::createWindow function does not
* provide any of these necessary information except for the window type. All
* the other necessary information is emitted as signals instead! Hence, the
* need for this class to collect all of the necessary information, such as
* window name, size and position, before calling KPart's createNewWindow
* function.
*/
class NewWindowPage : public WebEnginePage
{
Q_OBJECT
public:
NewWindowPage(WebWindowType windowType, WebEnginePart* part,
QWidget* parent = Q_NULLPTR);
virtual ~NewWindowPage();
protected:
bool acceptNavigationRequest(const QUrl& request, NavigationType type, bool isMainFrame) Q_DECL_OVERRIDE;
private Q_SLOTS:
void slotGeometryChangeRequested(const QRect& rect) override;
void slotMenuBarVisibilityChangeRequested(bool visible);
void slotStatusBarVisibilityChangeRequested(bool visible);
void slotToolBarVisibilityChangeRequested(bool visible);
void slotLoadFinished(bool);
private:
KParts::WindowArgs m_windowArgs;
WebWindowType m_type;
bool m_createNewWindow;
+ WebEngineWallet* m_wallet;
};
#endif // WEBENGINEPAGE_H
diff --git a/webenginepart/src/webenginepart.cpp b/webenginepart/src/webenginepart.cpp
index 10bbffc15..66edce7f0 100644
--- a/webenginepart/src/webenginepart.cpp
+++ b/webenginepart/src/webenginepart.cpp
@@ -1,926 +1,934 @@
/*
* This file is part of the KDE project.
*
* Copyright (C) 2007 Trolltech ASA
* Copyright (C) 2008 - 2010 Urs Wolfer
* Copyright (C) 2008 Laurent Montel
* Copyright (C) 2009 Dawit Alemayehu
* Copyright (C) 2013 Allan Sandfeld Jensen
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
*
*/
#include "webenginepart.h"
//#include
#include
#include
#include
#include "webenginepart_ext.h"
#include "webengineview.h"
#include "webenginepage.h"
#include "websslinfo.h"
#include "webhistoryinterface.h"
+#include "webenginewallet.h"
#include "ui/searchbar.h"
#include "ui/passwordbar.h"
#include "ui/featurepermissionbar.h"
#include "settings/webenginesettings.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "utils.h"
WebEnginePart::WebEnginePart(QWidget *parentWidget, QObject *parent,
const QByteArray& cachedHistory, const QStringList& /*args*/)
:KParts::ReadOnlyPart(parent),
m_emitOpenUrlNotify(true),
m_hasCachedFormData(false),
m_doLoadFinishedActions(false),
m_statusBarWalletLabel(0),
m_searchBar(0),
m_passwordBar(0),
- m_featurePermissionBar(0)
+ m_featurePermissionBar(0),
+ m_wallet(Q_NULLPTR)
{
KAboutData about = KAboutData(QStringLiteral("webenginepart"),
i18nc("Program Name", "WebEnginePart"),
/*version*/ QStringLiteral("1.3.0"),
i18nc("Short Description", "QtWebEngine Browser Engine Component"),
KAboutLicense::LGPL,
i18n("(C) 2009-2010 Dawit Alemayehu\n"
"(C) 2008-2010 Urs Wolfer\n"
"(C) 2007 Trolltech ASA"));
about.addAuthor(i18n("Sune Vuorela"), i18n("Maintainer, Developer"), QStringLiteral("sune@kde.org"));
about.addAuthor(i18n("Dawit Alemayehu"), i18n("Developer"), QStringLiteral("adawit@kde.org"));
about.addAuthor(i18n("Urs Wolfer"), i18n("Maintainer, Developer"), QStringLiteral("uwolfer@kde.org"));
about.addAuthor(i18n("Michael Howell"), i18n("Developer"), QStringLiteral("mhowell123@gmail.com"));
about.addAuthor(i18n("Laurent Montel"), i18n("Developer"), QStringLiteral("montel@kde.org"));
about.addAuthor(i18n("Dirk Mueller"), i18n("Developer"), QStringLiteral("mueller@kde.org"));
about.setProductName("webenginepart/general");
// KComponentData componentData(&about);
setComponentData(about, false /*don't load plugins yet*/);
#if 0
// NOTE: If the application does not set its version number, we automatically
// set it to KDE's version number so that the default user-agent string contains
// proper application version number information. See QWebEnginePage::userAgentForUrl...
if (QCoreApplication::applicationVersion().isEmpty())
QCoreApplication::setApplicationVersion(QString("%1.%2.%3")
.arg(KDE::versionMajor())
.arg(KDE::versionMinor())
.arg(KDE::versionRelease()));
#endif
setXMLFile(QL1S("webenginepart.rc"));
// Create this KPart's widget
QWidget *mainWidget = new QWidget (parentWidget);
mainWidget->setObjectName(QStringLiteral("webenginepart"));
// Create the WebEngineView...
m_webView = new WebEngineView (this, parentWidget);
// Create the browser extension.
m_browserExtension = new WebEngineBrowserExtension(this, cachedHistory);
// Add status bar extension...
m_statusBarExtension = new KParts::StatusBarExtension(this);
// Add a web history interface for storing visited links.
// if (!QWebEngineHistoryInterface::defaultInterface())
// QWebHistoryInterface::setDefaultInterface(new WebHistoryInterface(this));
// Add text and html extensions...
new WebEngineTextExtension(this);
new WebEngineHtmlExtension(this);
new WebEngineScriptableExtension(this);
// Layout the GUI...
QVBoxLayout* l = new QVBoxLayout(mainWidget);
l->setContentsMargins(0, 0, 0, 0);
l->setSpacing(0);
l->addWidget(m_webView);
// Set the part's widget
setWidget(mainWidget);
// Set the web view as the the focus object
mainWidget->setFocusProxy(m_webView);
// Connect the signals from the webview
connect(m_webView, &QWebEngineView::titleChanged,
this, &Part::setWindowCaption);
connect(m_webView, &QWebEngineView::urlChanged,
this, &WebEnginePart::slotUrlChanged);
// connect(m_webView, SIGNAL(linkMiddleOrCtrlClicked(QUrl)),
// this, SLOT(slotLinkMiddleOrCtrlClicked(QUrl)));
// connect(m_webView, SIGNAL(selectionClipboardUrlPasted(QUrl,QString)),
// this, SLOT(slotSelectionClipboardUrlPasted(QUrl,QString)));
connect(m_webView, &QWebEngineView::loadFinished,
this, &WebEnginePart::slotLoadFinished);
// Connect the signals from the page...
connectWebEnginePageSignals(page());
// Init the QAction we are going to use...
initActions();
// Load plugins once we are fully ready
loadPlugins();
+ setWallet(page()->wallet());
}
WebEnginePart::~WebEnginePart()
{
}
WebEnginePage* WebEnginePart::page()
{
if (m_webView)
return qobject_cast(m_webView->page());
return Q_NULLPTR;
}
const WebEnginePage* WebEnginePart::page() const
{
if (m_webView)
return qobject_cast(m_webView->page());
return Q_NULLPTR;
}
void WebEnginePart::initActions()
{
actionCollection()->addAction(KStandardAction::SaveAs, QStringLiteral("saveDocument"),
m_browserExtension, SLOT(slotSaveDocument()));
QAction* action = new QAction(i18n("Save &Frame As..."), this);
actionCollection()->addAction(QStringLiteral("saveFrame"), action);
connect(action, &QAction::triggered, m_browserExtension, &WebEngineBrowserExtension::slotSaveFrame);
action = new QAction(QIcon::fromTheme(QStringLiteral("document-print-preview")), i18n("Print Preview"), this);
actionCollection()->addAction(QStringLiteral("printPreview"), action);
connect(action, &QAction::triggered, m_browserExtension, &WebEngineBrowserExtension::slotPrintPreview);
action = new QAction(QIcon::fromTheme(QStringLiteral("zoom-in")), i18nc("zoom in action", "Zoom In"), this);
actionCollection()->addAction(QStringLiteral("zoomIn"), action);
actionCollection()->setDefaultShortcuts(action, QList () << QKeySequence(QStringLiteral("CTRL++")) << QKeySequence(QStringLiteral("CTRL+=")));
connect(action, &QAction::triggered, m_browserExtension, &WebEngineBrowserExtension::zoomIn);
action = new QAction(QIcon::fromTheme(QStringLiteral("zoom-out")), i18nc("zoom out action", "Zoom Out"), this);
actionCollection()->addAction(QStringLiteral("zoomOut"), action);
actionCollection()->setDefaultShortcuts(action, QList () << QKeySequence(QStringLiteral("CTRL+-")) << QKeySequence(QStringLiteral("CTRL+_")));
connect(action, &QAction::triggered, m_browserExtension, &WebEngineBrowserExtension::zoomOut);
action = new QAction(QIcon::fromTheme(QStringLiteral("zoom-original")), i18nc("reset zoom action", "Actual Size"), this);
actionCollection()->addAction(QStringLiteral("zoomNormal"), action);
actionCollection()->setDefaultShortcut(action, QKeySequence(QStringLiteral("CTRL+0")));
connect(action, &QAction::triggered, m_browserExtension, &WebEngineBrowserExtension::zoomNormal);
action = new QAction(i18n("Zoom Text Only"), this);
action->setCheckable(true);
KConfigGroup cgHtml(KSharedConfig::openConfig(), "HTML Settings");
bool zoomTextOnly = cgHtml.readEntry("ZoomTextOnly", false);
action->setChecked(zoomTextOnly);
actionCollection()->addAction(QStringLiteral("zoomTextOnly"), action);
connect(action, &QAction::triggered, m_browserExtension, &WebEngineBrowserExtension::toogleZoomTextOnly);
action = new QAction(i18n("Zoom To DPI"), this);
action->setCheckable(true);
bool zoomToDPI = cgHtml.readEntry("ZoomToDPI", false);
action->setChecked(zoomToDPI);
actionCollection()->addAction(QStringLiteral("zoomToDPI"), action);
connect(action, &QAction::triggered, m_browserExtension, &WebEngineBrowserExtension::toogleZoomToDPI);
action = actionCollection()->addAction(KStandardAction::SelectAll, QStringLiteral("selectAll"),
m_browserExtension, SLOT(slotSelectAll()));
action->setShortcutContext(Qt::WidgetShortcut);
m_webView->addAction(action);
KCodecAction *codecAction = new KCodecAction( QIcon::fromTheme(QStringLiteral("character-set")), i18n( "Set &Encoding" ), this, true );
actionCollection()->addAction( QStringLiteral("setEncoding"), codecAction );
connect(codecAction, SIGNAL(triggered(QTextCodec*)), SLOT(slotSetTextEncoding(QTextCodec*)));
action = new QAction(i18n("View Do&cument Source"), this);
actionCollection()->addAction(QStringLiteral("viewDocumentSource"), action);
actionCollection()->setDefaultShortcut(action, QKeySequence(Qt::CTRL + Qt::Key_U));
connect(action, &QAction::triggered, m_browserExtension, &WebEngineBrowserExtension::slotViewDocumentSource);
action = new QAction(i18nc("Secure Sockets Layer", "SSL"), this);
actionCollection()->addAction(QStringLiteral("security"), action);
connect(action, &QAction::triggered, this, &WebEnginePart::slotShowSecurity);
action = actionCollection()->addAction(KStandardAction::Find, QStringLiteral("find"), this, SLOT(slotShowSearchBar()));
action->setWhatsThis(i18nc("find action \"whats this\" text", "Find text
"
"Shows a dialog that allows you to find text on the displayed page."));
}
void WebEnginePart::updateActions()
{
m_browserExtension->updateActions();
QAction* action = actionCollection()->action(QL1S("saveDocument"));
if (action) {
const QString protocol (url().scheme());
action->setEnabled(protocol != QL1S("about") && protocol != QL1S("error"));
}
action = actionCollection()->action(QL1S("printPreview"));
if (action) {
action->setEnabled(m_browserExtension->isActionEnabled("print"));
}
}
void WebEnginePart::connectWebEnginePageSignals(WebEnginePage* page)
{
if (!page)
return;
connect(page, SIGNAL(loadStarted()),
this, SLOT(slotLoadStarted()));
connect(page, SIGNAL(loadAborted(QUrl)),
this, SLOT(slotLoadAborted(QUrl)));
connect(page, &QWebEnginePage::linkHovered,
this, &WebEnginePart::slotLinkHovered);
// connect(page, SIGNAL(saveFrameStateRequested(QWebFrame*,QWebHistoryItem*)),
// this, SLOT(slotSaveFrameState(QWebFrame*,QWebHistoryItem*)));
// connect(page, SIGNAL(restoreFrameStateRequested(QWebFrame*)),
// this, SLOT(slotRestoreFrameState(QWebFrame*)));
// connect(page, SIGNAL(statusBarMessage(QString)),
// this, SLOT(slotSetStatusBarText(QString)));
connect(page, SIGNAL(windowCloseRequested()),
this, SLOT(slotWindowCloseRequested()));
// connect(page, SIGNAL(printRequested(QWebFrame*)),
// m_browserExtension, SLOT(slotPrintRequested(QWebFrame*)));
// connect(page, SIGNAL(frameCreated(QWebFrame*)),
// this, SLOT(slotFrameCreated(QWebFrame*)));
// connect(m_webView, SIGNAL(linkShiftClicked(QUrl)),
// page, SLOT(downloadUrl(QUrl)));
connect(page, SIGNAL(loadProgress(int)),
m_browserExtension, SIGNAL(loadingProgress(int)));
connect(page, SIGNAL(selectionChanged()),
m_browserExtension, SLOT(updateEditActions()));
// connect(m_browserExtension, SIGNAL(saveUrl(QUrl)),
// page, SLOT(downloadUrl(QUrl)));
connect(page, &QWebEnginePage::iconUrlChanged, [page, this](const QUrl& url) {
if (WebEngineSettings::self()->favIconsEnabled()
&& !page->profile()->isOffTheRecord()){
m_browserExtension->setIconUrl(url);
}
});
+}
-#if 0
- KWebWallet *wallet = page->wallet();
- if (wallet) {
- connect(wallet, SIGNAL(saveFormDataRequested(QString,QUrl)),
- this, SLOT(slotSaveFormDataRequested(QString,QUrl)));
- connect(wallet, SIGNAL(fillFormRequestCompleted(bool)),
- this, SLOT(slotFillFormRequestCompleted(bool)));
- connect(wallet, SIGNAL(walletClosed()), this, SLOT(slotWalletClosed()));
+void WebEnginePart::setWallet(WebEngineWallet* wallet)
+{
+ if(m_wallet){
+ disconnect(m_wallet, &WebEngineWallet::saveFormDataRequested,
+ this, &WebEnginePart::slotSaveFormDataRequested);
+ disconnect(m_wallet, &WebEngineWallet::fillFormRequestCompleted,
+ this, &WebEnginePart::slotFillFormRequestCompleted);
+ disconnect(m_wallet, &WebEngineWallet::walletClosed, this, &WebEnginePart::slotWalletClosed);
+ }
+ m_wallet = wallet;
+ if (m_wallet) {
+ connect(m_wallet, &WebEngineWallet::saveFormDataRequested,
+ this, &WebEnginePart::slotSaveFormDataRequested);
+ connect(m_wallet, &WebEngineWallet::fillFormRequestCompleted,
+ this, &WebEnginePart::slotFillFormRequestCompleted);
+ connect(m_wallet, &WebEngineWallet::walletClosed, this, &WebEnginePart::slotWalletClosed);
}
-#endif
}
bool WebEnginePart::openUrl(const QUrl &_u)
{
QUrl u (_u);
qDebug() << u;
// Ignore empty requests...
if (u.isEmpty())
return false;
// If the URL given is a supported local protocol, e.g. "bookmark" but lacks
// a path component, we set the path to "/" here so that the security context
// will properly allow access to local resources.
if (u.host().isEmpty() && u.path().isEmpty()
&& KProtocolInfo::protocolClass(u.scheme()) == QL1S(":local")) {
u.setPath(QL1S("/"));
}
// Do not emit update history when url is typed in since the host
// should handle that automatically itself.
m_emitOpenUrlNotify = false;
// Pointer to the page object...
WebEnginePage* p = page();
Q_ASSERT(p);
KParts::BrowserArguments bargs (m_browserExtension->browserArguments());
KParts::OpenUrlArguments args (arguments());
if (!Utils::isBlankUrl(u)) {
// Get the SSL information sent, if any...
if (args.metaData().contains(QL1S("ssl_in_use"))) {
WebSslInfo sslInfo;
sslInfo.restoreFrom(KIO::MetaData(args.metaData()).toVariant());
sslInfo.setUrl(u);
p->setSslInfo(sslInfo);
}
}
// Set URL in KParts before emitting started; konq plugins rely on that.
setUrl(u);
m_doLoadFinishedActions = true;
m_webView->loadUrl(u, args, bargs);
return true;
}
bool WebEnginePart::closeUrl()
{
m_webView->triggerPageAction(QWebEnginePage::Stop);
m_webView->stop();
return true;
}
QWebEngineView* WebEnginePart::view()
{
return m_webView;
}
bool WebEnginePart::isModified() const
{
//return m_webView->isModified();
return false;
}
void WebEnginePart::guiActivateEvent(KParts::GUIActivateEvent *event)
{
if (event && event->activated() && m_webView) {
emit setWindowCaption(m_webView->title());
}
}
bool WebEnginePart::openFile()
{
// never reached
return false;
}
/// slots...
void WebEnginePart::slotLoadStarted()
{
if(!Utils::isBlankUrl(url()))
{
emit started(0);
}
updateActions();
// If "NoEmitOpenUrlNotification" property is set to true, do not
// emit the open url notification. Property is set by this part's
// extension to prevent openUrl notification being sent when
// handling history navigation requests (back/forward).
const bool doNotEmitOpenUrl = property("NoEmitOpenUrlNotification").toBool();
if (doNotEmitOpenUrl) {
setProperty("NoEmitOpenUrlNotification", QVariant());
} else {
if (m_emitOpenUrlNotify) {
emit m_browserExtension->openUrlNotify();
}
}
// Unless we go via openUrl again, the next time we are here we emit (e.g. after clicking on a link)
m_emitOpenUrlNotify = true;
}
void WebEnginePart::slotLoadFinished (bool ok)
{
if (!ok || !m_doLoadFinishedActions)
return;
slotWalletClosed();
m_doLoadFinishedActions = false;
// If the document contains no tag, then set it to the current url.
if (m_webView->title().trimmed().isEmpty()) {
// If the document title is empty, then set it to the current url
const QUrl url (m_webView->url());
const QString caption (url.toString((QUrl::RemoveQuery|QUrl::RemoveFragment)));
emit setWindowCaption(caption);
// The urlChanged signal is emitted if and only if the main frame
// receives the title of the page so we manually invoke the slot as a
// work around here for pages that do not contain it, such as text
// documents...
slotUrlChanged(url);
}
if (!Utils::isBlankUrl(url())) {
m_hasCachedFormData = false;
-
if (WebEngineSettings::self()->isNonPasswordStorableSite(url().host())) {
addWalletStatusBarIcon();
- } else {
+ }
+ else {
// Attempt to fill the web form...
-// KWebWallet *webWallet = page() ? page()->wallet() : 0;
-// if (webWallet) {
-// webWallet->fillFormData(frame, false);
-// }
+ WebEngineWallet *wallet = page() ? page()->wallet() : 0;
+ if (wallet){
+ wallet->fillFormData(page());
+ }
}
}
bool pending = false;
// QWebFrame* frame = (page() ? page()->currentFrame() : 0);
// if (ok &&
// frame == page()->mainFrame() &&
// !frame->findFirstElement(QL1S("head>meta[http-equiv=refresh]")).isNull()) {
// if (WebEngineSettings::self()->autoPageRefresh()) {
// pending = true;
// } else {
// frame->page()->triggerAction(QWebEnginePage::Stop);
// }
// }
emit completed ((ok && pending));
updateActions();
}
void WebEnginePart::slotLoadAborted(const QUrl & url)
{
closeUrl();
m_doLoadFinishedActions = false;
if (url.isValid())
emit m_browserExtension->openUrlRequest(url);
else
setUrl(m_webView->url());
}
void WebEnginePart::slotUrlChanged(const QUrl& url)
{
// Ignore if empty
if (url.isEmpty())
return;
// Ignore if error url
if (url.scheme() == QL1S("error"))
return;
const QUrl u (url);
// Ignore if url has not changed!
if (this->url() == u)
return;
m_doLoadFinishedActions = true;
setUrl(u);
// Do not update the location bar with about:blank
if (!Utils::isBlankUrl(url)) {
//kDebug() << "Setting location bar to" << u.prettyUrl() << "current URL:" << this->url();
emit m_browserExtension->setLocationBarUrl(u.toDisplayString());
}
}
void WebEnginePart::slotShowSecurity()
{
if (!page())
return;
const WebSslInfo& sslInfo = page()->sslInfo();
if (!sslInfo.isValid()) {
KMessageBox::information(0, i18n("The SSL information for this site "
"appears to be corrupt."),
i18nc("Secure Sockets Layer", "SSL"));
return;
}
KSslInfoDialog *dlg = new KSslInfoDialog (widget());
dlg->setSslInfo(sslInfo.certificateChain(),
sslInfo.peerAddress().toString(),
url().host(),
sslInfo.protocol(),
sslInfo.ciphers(),
sslInfo.usedChiperBits(),
sslInfo.supportedChiperBits(),
KSslInfoDialog::errorsFromString(sslInfo.certificateErrors()));
dlg->open();
}
#if 0
void WebEnginePart::slotSaveFrameState(QWebFrame *frame, QWebHistoryItem *item)
{
if (!frame || !item) {
return;
}
// Handle actions that apply only to the mainframe...
if (frame == view()->page()->mainFrame()) {
}
// For some reason, QtWebEngine PORTING_TODO does not restore scroll position when
// QWebHistory is restored from persistent storage. Therefore, we
// preserve that information and restore it as needed. See
// slotRestoreFrameState.
const QPoint scrollPos (frame->scrollPosition());
if (!scrollPos.isNull()) {
// kDebug() << "Saving scroll position:" << scrollPos;
item->setUserData(scrollPos);
}
}
#endif
#if 0
void WebEnginePart::slotRestoreFrameState(QWebFrame *frame)
{
QWebEnginePage* page = (frame ? frame->page() : 0);
QWebHistory* history = (page ? page->history() : 0);
// No history item...
if (!history || history->count() < 1)
return;
QWebHistoryItem currentHistoryItem (history->currentItem());
// Update the scroll position if needed. See comment in slotSaveFrameState above.
if (frame->baseUrl().resolved(frame->url()) == currentHistoryItem.url()) {
const QPoint currentPos (frame->scrollPosition());
const QPoint desiredPos (currentHistoryItem.userData().toPoint());
if (currentPos.isNull() && !desiredPos.isNull()) {
frame->setScrollPosition(desiredPos);
}
}
}
#endif
void WebEnginePart::slotLinkHovered(const QString& _link)
{
QString message;
if (_link.isEmpty()) {
message = QL1S("");
emit m_browserExtension->mouseOverInfo(KFileItem());
} else {
QUrl linkUrl (_link);
const QString scheme = linkUrl.scheme();
// Protect the user against URL spoofing!
linkUrl.setUserName(QString());
const QString link (linkUrl.toString());
if (QString::compare(scheme, QL1S("mailto"), Qt::CaseInsensitive) == 0) {
message += i18nc("status bar text when hovering email links; looks like \"Email: xy@kde.org - CC: z@kde.org -BCC: x@kde.org - Subject: Hi translator\"", "Email: ");
// Workaround: for QUrl's parsing deficiencies of "mailto:foo@bar.com".
if (!linkUrl.hasQuery())
linkUrl = QUrl(scheme + '?' + linkUrl.path());
QMap fields;
QUrlQuery query(linkUrl);
QList > queryItems = query.queryItems();
const int count = queryItems.count();
for(int i = 0; i < count; ++i) {
const QPair queryItem (queryItems.at(i));
//kDebug() << "query: " << queryItem.first << queryItem.second;
if (queryItem.first.contains(QL1C('@')) && queryItem.second.isEmpty())
fields[QStringLiteral("to")] << queryItem.first;
if (QString::compare(queryItem.first, QL1S("to"), Qt::CaseInsensitive) == 0)
fields[QStringLiteral("to")] << queryItem.second;
if (QString::compare(queryItem.first, QL1S("cc"), Qt::CaseInsensitive) == 0)
fields[QStringLiteral("cc")] << queryItem.second;
if (QString::compare(queryItem.first, QL1S("bcc"), Qt::CaseInsensitive) == 0)
fields[QStringLiteral("bcc")] << queryItem.second;
if (QString::compare(queryItem.first, QL1S("subject"), Qt::CaseInsensitive) == 0)
fields[QStringLiteral("subject")] << queryItem.second;
}
if (fields.contains(QL1S("to")))
message += fields.value(QL1S("to")).join(QL1S(", "));
if (fields.contains(QL1S("cc")))
message += i18nc("status bar text when hovering email links; looks like \"Email: xy@kde.org - CC: z@kde.org -BCC: x@kde.org - Subject: Hi translator\"", " - CC: ") + fields.value(QL1S("cc")).join(QL1S(", "));
if (fields.contains(QL1S("bcc")))
message += i18nc("status bar text when hovering email links; looks like \"Email: xy@kde.org - CC: z@kde.org -BCC: x@kde.org - Subject: Hi translator\"", " - BCC: ") + fields.value(QL1S("bcc")).join(QL1S(", "));
if (fields.contains(QL1S("subject")))
message += i18nc("status bar text when hovering email links; looks like \"Email: xy@kde.org - CC: z@kde.org -BCC: x@kde.org - Subject: Hi translator\"", " - Subject: ") + fields.value(QL1S("subject")).join(QL1S(" "));
} else if (scheme == QL1S("javascript")) {
message = KStringHandler::rsqueeze(link, 150);
if (link.startsWith(QL1S("javascript:window.open")))
message += i18n(" (In new window)");
} else {
message = link;
#if 0
QWebFrame* frame = page() ? page()->currentFrame() : 0;
if (frame) {
QWebHitTestResult result = frame->hitTestContent(page()->view()->mapFromGlobal(QCursor::pos()));
QWebFrame* target = result.linkTargetFrame();
if (frame->parentFrame() && target == frame->parentFrame()) {
message += i18n(" (In parent frame)");
} else if (!target || target != frame) {
message += i18n(" (In new window)");
}
}
#endif
KFileItem item (linkUrl, QString(), KFileItem::Unknown);
emit m_browserExtension->mouseOverInfo(item);
}
}
emit setStatusBarText(message);
}
void WebEnginePart::slotSearchForText(const QString &text, bool backward)
{
QWebEnginePage::FindFlags flags; // = QWebEnginePage::FindWrapsAroundDocument;
if (backward)
flags |= QWebEnginePage::FindBackward;
if (m_searchBar->caseSensitive())
flags |= QWebEnginePage::FindCaseSensitively;
//kDebug() << "search for text:" << text << ", backward ?" << backward;
page()->findText(text, flags, [this](bool found) {
m_searchBar->setFoundMatch(found);
});
}
void WebEnginePart::slotShowSearchBar()
{
if (!m_searchBar) {
// Create the search bar...
m_searchBar = new SearchBar(widget());
connect(m_searchBar, SIGNAL(searchTextChanged(QString,bool)),
this, SLOT(slotSearchForText(QString,bool)));
actionCollection()->addAction(KStandardAction::FindNext, QStringLiteral("findnext"),
m_searchBar, SLOT(findNext()));
actionCollection()->addAction(KStandardAction::FindPrev, QStringLiteral("findprev"),
m_searchBar, SLOT(findPrevious()));
QBoxLayout* lay = qobject_cast(widget()->layout());
if (lay) {
lay->addWidget(m_searchBar);
}
}
const QString text = m_webView->selectedText();
m_searchBar->setSearchText(text.left(150));
}
void WebEnginePart::slotLinkMiddleOrCtrlClicked(const QUrl& linkUrl)
{
emit m_browserExtension->createNewWindow(linkUrl);
}
void WebEnginePart::slotSelectionClipboardUrlPasted(const QUrl& selectedUrl, const QString& searchText)
{
if (!WebEngineSettings::self()->isOpenMiddleClickEnabled())
return;
if (!searchText.isEmpty() &&
KMessageBox::questionYesNo(m_webView,
i18n("Do you want to search for %1?", searchText),
i18n("Internet Search"), KGuiItem(i18n("&Search"), QStringLiteral("edit-find")),
KStandardGuiItem::cancel(), QStringLiteral("MiddleClickSearch")) != KMessageBox::Yes)
return;
emit m_browserExtension->openUrlRequest(selectedUrl);
}
void WebEnginePart::slotWalletClosed()
{
if (!m_statusBarWalletLabel)
return;
m_statusBarExtension->removeStatusBarItem(m_statusBarWalletLabel);
delete m_statusBarWalletLabel;
m_statusBarWalletLabel = 0;
m_hasCachedFormData = false;
}
void WebEnginePart::slotShowWalletMenu()
{
QMenu *menu = new QMenu(0);
if (m_webView && WebEngineSettings::self()->isNonPasswordStorableSite(m_webView->url().host()))
menu->addAction(i18n("&Allow password caching for this site"), this, SLOT(slotDeleteNonPasswordStorableSite()));
if (m_hasCachedFormData)
menu->addAction(i18n("Remove all cached passwords for this site"), this, SLOT(slotRemoveCachedPasswords()));
menu->addSeparator();
menu->addAction(i18n("&Close Wallet"), this, SLOT(slotWalletClosed()));
KAcceleratorManager::manage(menu);
menu->popup(QCursor::pos());
}
void WebEnginePart::slotLaunchWalletManager()
{
QDBusInterface r(QStringLiteral("org.kde.kwalletmanager"), QStringLiteral("/kwalletmanager/MainWindow_1"));
if (r.isValid())
r.call(QDBus::NoBlock, QStringLiteral("show"));
else
KToolInvocation::startServiceByDesktopName(QStringLiteral("kwalletmanager_show"));
}
void WebEnginePart::slotDeleteNonPasswordStorableSite()
{
if (m_webView)
WebEngineSettings::self()->removeNonPasswordStorableSite(m_webView->url().host());
}
void WebEnginePart::slotRemoveCachedPasswords()
{
- if (!page()) // || !page()->wallet())
+ if (!page() || !page()->wallet())
return;
-// page()->wallet()->removeFormData(page()->mainFrame(), true);
+ page()->wallet()->removeFormData(page());
m_hasCachedFormData = false;
}
void WebEnginePart::slotSetTextEncoding(QTextCodec * codec)
{
// FIXME: The code below that sets the text encoding has been reported not to work.
if (!page())
return;
QWebEngineSettings *localSettings = page()->settings();
if (!localSettings)
return;
qDebug() << "Encoding: new=>" << localSettings->defaultTextEncoding() << ", old=>" << codec->name();
localSettings->setDefaultTextEncoding(codec->name());
page()->triggerAction(QWebEnginePage::Reload);
}
void WebEnginePart::slotSetStatusBarText(const QString& text)
{
const QString host (page() ? page()->url().host() : QString());
if (WebEngineSettings::self()->windowStatusPolicy(host) == KParts::HtmlSettingsInterface::JSWindowStatusAllow)
emit setStatusBarText(text);
}
void WebEnginePart::slotWindowCloseRequested()
{
emit m_browserExtension->requestFocus(this);
#if 0
if (KMessageBox::questionYesNo(m_webView,
i18n("Close window?"), i18n("Confirmation Required"),
KStandardGuiItem::close(), KStandardGuiItem::cancel())
!= KMessageBox::Yes)
return;
#endif
this->deleteLater();
}
void WebEnginePart::slotShowFeaturePermissionBar(QWebEnginePage::Feature feature)
{
// FIXME: Allow multiple concurrent feature permission requests.
if (m_featurePermissionBar && m_featurePermissionBar->isVisible())
return;
if (!m_featurePermissionBar) {
m_featurePermissionBar = new FeaturePermissionBar(widget());
connect(m_featurePermissionBar, SIGNAL(permissionGranted(QWebEnginePage::Feature)),
this, SLOT(slotFeaturePermissionGranted(QWebEnginePage::Feature)));
connect(m_featurePermissionBar, SIGNAL(permissionDenied(QWebEnginePage::Feature)),
this, SLOT(slotFeaturePermissionDenied(QWebEnginePage::Feature)));
-// connect(m_passwordBar, SIGNAL(done()),
-// this, SLOT(slotSaveFormDataDone()));
+ connect(m_passwordBar, SIGNAL(done()),
+ this, SLOT(slotSaveFormDataDone()));
QBoxLayout* lay = qobject_cast(widget()->layout());
if (lay)
lay->insertWidget(0, m_featurePermissionBar);
}
m_featurePermissionBar->setFeature(feature);
// m_featurePermissionBar->setText(i18n("Do you want to grant the site %1 "
// "access to information about your current physical location?",
// url.host()));
m_featurePermissionBar->setText(i18n("Do you want to grant the site "
"access to information about your current physical location?"));
m_featurePermissionBar->animatedShow();
}
void WebEnginePart::slotFeaturePermissionGranted(QWebEnginePage::Feature feature)
{
Q_ASSERT(m_featurePermissionBar && m_featurePermissionBar->feature() == feature);
page()->setFeaturePermission(page()->url(), feature, QWebEnginePage::PermissionGrantedByUser);
}
void WebEnginePart::slotFeaturePermissionDenied(QWebEnginePage::Feature feature)
{
Q_ASSERT(m_featurePermissionBar && m_featurePermissionBar->feature() == feature);
page()->setFeaturePermission(page()->url(), feature, QWebEnginePage::PermissionDeniedByUser);
}
void WebEnginePart::slotSaveFormDataRequested (const QString& key, const QUrl& url)
{
if (WebEngineSettings::self()->isNonPasswordStorableSite(url.host()))
return;
if (!WebEngineSettings::self()->askToSaveSitePassword())
return;
if (m_passwordBar && m_passwordBar->isVisible())
return;
if (!m_passwordBar) {
m_passwordBar = new PasswordBar(widget());
-#if 0
- KWebWallet* wallet = page()->wallet();
- if (!wallet) {
- kWarning() << "No wallet instance found! This should never happen!";
+ if (!m_wallet) {
+ qDebug() << "No m_wallet instance found! This should never happen!";
return;
}
connect(m_passwordBar, SIGNAL(saveFormDataAccepted(QString)),
- wallet, SLOT(acceptSaveFormDataRequest(QString)));
+ m_wallet, SLOT(acceptSaveFormDataRequest(QString)));
connect(m_passwordBar, SIGNAL(saveFormDataRejected(QString)),
- wallet, SLOT(rejectSaveFormDataRequest(QString)));
+ m_wallet, SLOT(rejectSaveFormDataRequest(QString)));
connect(m_passwordBar, SIGNAL(done()),
this, SLOT(slotSaveFormDataDone()));
-#endif
}
Q_ASSERT(m_passwordBar);
m_passwordBar->setUrl(url);
m_passwordBar->setRequestKey(key);
m_passwordBar->setText(i18n("Do you want %1 to remember the login "
"information for %2?",
QCoreApplication::applicationName(),
url.host()));
QBoxLayout* lay = qobject_cast(widget()->layout());
if (lay)
lay->insertWidget(0, m_passwordBar);
m_passwordBar->animatedShow();
}
void WebEnginePart::slotSaveFormDataDone()
{
if (!m_passwordBar)
return;
QBoxLayout* lay = qobject_cast(widget()->layout());
if (lay)
lay->removeWidget(m_passwordBar);
}
void WebEnginePart::addWalletStatusBarIcon ()
{
if (m_statusBarWalletLabel) {
m_statusBarExtension->removeStatusBarItem(m_statusBarWalletLabel);
} else {
m_statusBarWalletLabel = new KUrlLabel(m_statusBarExtension->statusBar());
m_statusBarWalletLabel->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum));
m_statusBarWalletLabel->setUseCursor(false);
m_statusBarWalletLabel->setPixmap(QIcon::fromTheme(QStringLiteral("wallet-open")).pixmap(QSize(16,16)));
connect(m_statusBarWalletLabel, SIGNAL(leftClickedUrl()), SLOT(slotLaunchWalletManager()));
connect(m_statusBarWalletLabel, SIGNAL(rightClickedUrl()), SLOT(slotShowWalletMenu()));
}
m_statusBarExtension->addStatusBarItem(m_statusBarWalletLabel, 0, false);
}
void WebEnginePart::slotFillFormRequestCompleted (bool ok)
{
if ((m_hasCachedFormData = ok))
addWalletStatusBarIcon();
}
diff --git a/webenginepart/src/webenginepart.h b/webenginepart/src/webenginepart.h
index 6889e6d7f..91afa426f 100644
--- a/webenginepart/src/webenginepart.h
+++ b/webenginepart/src/webenginepart.h
@@ -1,165 +1,170 @@
/*
* This file is part of the KDE project.
*
* Copyright (C) 2007 Trolltech ASA
* Copyright (C) 2008 Urs Wolfer
* Copyright (C) 2009 Dawit Alemayehu
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
*
*/
#ifndef WEBENGINEPART_H
#define WEBENGINEPART_H
#include "kwebenginepartlib_export.h"
#include
#include
#include
namespace KParts {
class BrowserExtension;
class StatusBarExtension;
}
class QWebEngineView;
class WebEngineView;
class WebEnginePage;
class SearchBar;
class PasswordBar;
class FeaturePermissionBar;
class KUrlLabel;
class WebEngineBrowserExtension;
+class WebEngineWallet;
/**
* A KPart wrapper for the QtWebEngine's browser rendering engine.
*
* This class attempts to provide the same type of integration into KPart
* plugin applications, such as Konqueror, in much the same way as KHTML.
*
* Unlink the KHTML part however, access into the internals of the rendering
* engine are provided through existing QtWebEngine class ; @see QWebEngineView.
*
*/
class KWEBENGINEPARTLIB_EXPORT WebEnginePart : public KParts::ReadOnlyPart
{
Q_OBJECT
Q_PROPERTY( bool modified READ isModified )
public:
explicit WebEnginePart(QWidget* parentWidget = 0, QObject* parent = Q_NULLPTR,
const QByteArray& cachedHistory = QByteArray(),
const QStringList& = QStringList());
~WebEnginePart();
/**
* Re-implemented for internal reasons. API remains unaffected.
*
* @see KParts::ReadOnlyPart::openUrl
*/
bool openUrl(const QUrl &) Q_DECL_OVERRIDE;
/**
* Re-implemented for internal reasons. API remains unaffected.
*
* @see KParts::ReadOnlyPart::closeUrl
*/
bool closeUrl() Q_DECL_OVERRIDE;
/**
* Returns a pointer to the render widget used to display a web page.
*
* @see QWebEngineView.
*/
virtual QWebEngineView *view();
/**
* Checks whether the page contains unsubmitted form changes.
*
* @return @p true if form changes exist.
*/
bool isModified() const;
/**
* Connects the appropriate signals from the given page to the slots
* in this class.
*/
void connectWebEnginePageSignals(WebEnginePage* page);
void slotShowFeaturePermissionBar(QWebEnginePage::Feature);
+
+ void setWallet(WebEngineWallet* wallet);
+
protected:
/**
* Re-implemented for internal reasons. API remains unaffected.
*
* @see KParts::ReadOnlyPart::guiActivateEvent
*/
void guiActivateEvent(KParts::GUIActivateEvent *) Q_DECL_OVERRIDE;
/**
* Re-implemented for internal reasons. API remains unaffected.
*
* @see KParts::ReadOnlyPart::openFile
*/
bool openFile() Q_DECL_OVERRIDE;
private Q_SLOTS:
void slotShowSecurity();
void slotShowSearchBar();
void slotLoadStarted();
void slotLoadAborted(const QUrl &);
void slotLoadFinished(bool);
void slotSearchForText(const QString &text, bool backward);
void slotLinkHovered(const QString &);
//void slotSaveFrameState(QWebFrame *frame, QWebHistoryItem *item);
//void slotRestoreFrameState(QWebFrame *frame);
void slotLinkMiddleOrCtrlClicked(const QUrl&);
void slotSelectionClipboardUrlPasted(const QUrl&, const QString&);
void slotUrlChanged(const QUrl &);
void slotWalletClosed();
void slotShowWalletMenu();
void slotLaunchWalletManager();
void slotDeleteNonPasswordStorableSite();
void slotRemoveCachedPasswords();
void slotSetTextEncoding(QTextCodec*);
void slotSetStatusBarText(const QString& text);
void slotWindowCloseRequested();
void slotSaveFormDataRequested(const QString &, const QUrl &);
void slotSaveFormDataDone();
void slotFillFormRequestCompleted(bool);
void slotFeaturePermissionGranted(QWebEnginePage::Feature);
void slotFeaturePermissionDenied(QWebEnginePage::Feature);
private:
WebEnginePage* page();
const WebEnginePage* page() const;
void initActions();
void updateActions();
void addWalletStatusBarIcon();
bool m_emitOpenUrlNotify;
bool m_hasCachedFormData;
bool m_doLoadFinishedActions;
KUrlLabel* m_statusBarWalletLabel;
SearchBar* m_searchBar;
PasswordBar* m_passwordBar;
FeaturePermissionBar* m_featurePermissionBar;
WebEngineBrowserExtension* m_browserExtension;
KParts::StatusBarExtension* m_statusBarExtension;
WebEngineView* m_webView;
+ WebEngineWallet* m_wallet;
};
#endif // WEBENGINEPART_H
diff --git a/webenginepart/src/webenginepartfactory.cpp b/webenginepart/src/webenginepartfactory.cpp
index 04853bd27..7a877b422 100644
--- a/webenginepart/src/webenginepartfactory.cpp
+++ b/webenginepart/src/webenginepartfactory.cpp
@@ -1,65 +1,66 @@
/*
* This file is part of the KDE project.
*
* Copyright (C) 2008 Laurent Montel
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see .
*
*/
#include "webenginepartfactory.h"
#include "webenginepart_ext.h"
#include "webenginepart.h"
#include
+
WebEngineFactory::~WebEngineFactory()
{
// kDebug() << this;
}
QObject *WebEngineFactory::create(const char* iface, QWidget *parentWidget, QObject *parent, const QVariantList &args, const QString& keyword)
{
Q_UNUSED(iface);
Q_UNUSED(keyword);
Q_UNUSED(args);
qDebug() << parentWidget << parent;
connect(parentWidget, SIGNAL(destroyed(QObject*)), this, SLOT(slotDestroyed(QObject*)));
// NOTE: The code below is what makes it possible to properly integrate QtWebEngine's PORTING_TODO
// history management with any KParts based application.
QByteArray histData (m_historyBufContainer.value(parentWidget));
if (!histData.isEmpty()) histData = qUncompress(histData);
WebEnginePart* part = new WebEnginePart(parentWidget, parent, histData);
WebEngineBrowserExtension* ext = qobject_cast(part->browserExtension());
if (ext) {
connect(ext, SIGNAL(saveHistory(QObject*,QByteArray)), this, SLOT(slotSaveHistory(QObject*,QByteArray)));
}
return part;
}
void WebEngineFactory::slotSaveHistory(QObject* widget, const QByteArray& buffer)
{
// kDebug() << "Caching history data from" << widget;
m_historyBufContainer.insert(widget, buffer);
}
void WebEngineFactory::slotDestroyed(QObject* object)
{
// kDebug() << "Removing cached history data of" << object;
m_historyBufContainer.remove(object);
}
K_EXPORT_PLUGIN(WebEngineFactory)
diff --git a/webenginepart/src/webenginewallet.cpp b/webenginepart/src/webenginewallet.cpp
new file mode 100644
index 000000000..f501b273b
--- /dev/null
+++ b/webenginepart/src/webenginewallet.cpp
@@ -0,0 +1,599 @@
+/*
+ * This file is part of the KDE project.
+ *
+ * Copyright (C) 2009 Dawit Alemayehu
+ * Copyright (C) 2018 Stefano Crocco
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "webenginewallet.h"
+#include "webenginepage.h"
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define QL1S(x) QLatin1String(x)
+#define QL1C(x) QLatin1Char(x)
+
+// Javascript used to extract/set data from