2011-03-03 18:29:20 +01:00
|
|
|
/* ============================================================
|
2017-08-25 17:11:29 +02:00
|
|
|
* Falkon - Qt web browser
|
2017-01-22 10:23:14 +01:00
|
|
|
* Copyright (C) 2010-2017 David Rosca <nowrep@gmail.com>
|
2011-03-03 18:29:20 +01:00
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program 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 General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
* ============================================================ */
|
2011-03-02 16:57:41 +01:00
|
|
|
#include "webpage.h"
|
2012-01-21 20:20:48 +01:00
|
|
|
#include "tabbedwebview.h"
|
2014-02-19 22:07:21 +01:00
|
|
|
#include "browserwindow.h"
|
2013-01-17 15:24:30 +01:00
|
|
|
#include "pluginproxy.h"
|
2011-03-02 16:57:41 +01:00
|
|
|
#include "downloadmanager.h"
|
|
|
|
#include "mainapplication.h"
|
2012-03-15 19:35:37 +01:00
|
|
|
#include "checkboxdialog.h"
|
2011-05-22 10:47:03 +02:00
|
|
|
#include "widget.h"
|
2013-01-22 19:04:22 +01:00
|
|
|
#include "qztools.h"
|
2011-12-09 21:56:01 +01:00
|
|
|
#include "speeddial.h"
|
2013-05-14 17:25:55 +02:00
|
|
|
#include "autofill.h"
|
2012-01-21 20:20:48 +01:00
|
|
|
#include "popupwebview.h"
|
2015-05-22 23:57:24 +02:00
|
|
|
#include "popupwindow.h"
|
2012-06-25 16:07:25 +02:00
|
|
|
#include "adblockmanager.h"
|
2012-03-28 16:42:50 +02:00
|
|
|
#include "iconprovider.h"
|
2012-08-10 21:16:43 +02:00
|
|
|
#include "qzsettings.h"
|
2012-08-16 23:15:31 +02:00
|
|
|
#include "useragentmanager.h"
|
2013-04-02 13:14:19 +02:00
|
|
|
#include "delayedfilewatcher.h"
|
2014-06-06 23:29:49 +02:00
|
|
|
#include "searchenginesmanager.h"
|
2013-01-19 17:28:12 +01:00
|
|
|
#include "html5permissions/html5permissionsmanager.h"
|
2014-02-03 23:50:18 +01:00
|
|
|
#include "javascript/externaljsobject.h"
|
2015-05-22 23:57:24 +02:00
|
|
|
#include "tabwidget.h"
|
2015-05-27 19:16:19 +02:00
|
|
|
#include "scripts.h"
|
2015-09-29 16:18:21 +02:00
|
|
|
#include "networkmanager.h"
|
2015-09-29 21:53:56 +02:00
|
|
|
#include "webhittestresult.h"
|
2011-03-02 16:57:41 +01:00
|
|
|
|
2012-03-16 23:28:23 +01:00
|
|
|
#ifdef NONBLOCK_JS_DIALOGS
|
|
|
|
#include "ui_jsconfirm.h"
|
|
|
|
#include "ui_jsalert.h"
|
|
|
|
#include "ui_jsprompt.h"
|
|
|
|
|
|
|
|
#include <QPushButton>
|
|
|
|
#endif
|
|
|
|
|
2012-02-29 18:33:50 +01:00
|
|
|
#include <QDir>
|
2012-08-31 15:19:07 +02:00
|
|
|
#include <QMouseEvent>
|
2015-09-29 16:18:21 +02:00
|
|
|
#include <QWebChannel>
|
2015-01-27 11:01:52 +01:00
|
|
|
#include <QWebEngineHistory>
|
2015-08-30 15:52:15 +02:00
|
|
|
#include <QWebEngineSettings>
|
2012-02-29 18:33:50 +01:00
|
|
|
#include <QTimer>
|
|
|
|
#include <QDesktopServices>
|
|
|
|
#include <QMessageBox>
|
|
|
|
#include <QFileDialog>
|
2015-09-29 16:18:21 +02:00
|
|
|
#include <QAuthenticator>
|
2015-08-28 19:25:45 +02:00
|
|
|
|
2012-04-17 18:26:01 +02:00
|
|
|
QString WebPage::s_lastUploadLocation = QDir::homePath();
|
|
|
|
QUrl WebPage::s_lastUnsupportedUrl;
|
2012-08-09 19:09:52 +02:00
|
|
|
QTime WebPage::s_lastUnsupportedUrlTime;
|
2011-10-26 19:23:50 +02:00
|
|
|
|
2013-05-12 22:55:53 +02:00
|
|
|
WebPage::WebPage(QObject* parent)
|
2015-05-24 17:29:41 +02:00
|
|
|
: QWebEnginePage(mApp->webProfile(), parent)
|
2011-12-15 19:08:33 +01:00
|
|
|
, m_fileWatcher(0)
|
2011-12-13 15:38:09 +01:00
|
|
|
, m_runningLoop(0)
|
2012-07-03 15:22:42 +02:00
|
|
|
, m_loadProgress(-1)
|
2011-10-26 19:23:50 +02:00
|
|
|
, m_blockAlerts(false)
|
|
|
|
, m_secureStatus(false)
|
2011-03-02 16:57:41 +01:00
|
|
|
{
|
2017-02-06 20:45:28 +01:00
|
|
|
QWebChannel *channel = new QWebChannel(this);
|
|
|
|
channel->registerObject(QSL("qz_object"), new ExternalJsObject(this));
|
|
|
|
setWebChannel(channel);
|
2015-08-30 17:42:58 +02:00
|
|
|
|
2015-05-27 19:16:19 +02:00
|
|
|
connect(this, &QWebEnginePage::loadProgress, this, &WebPage::progress);
|
|
|
|
connect(this, &QWebEnginePage::loadFinished, this, &WebPage::finished);
|
2015-08-30 16:53:51 +02:00
|
|
|
connect(this, &QWebEnginePage::urlChanged, this, &WebPage::urlChanged);
|
2015-05-22 23:18:25 +02:00
|
|
|
connect(this, &QWebEnginePage::featurePermissionRequested, this, &WebPage::featurePermissionRequested);
|
2015-05-22 23:19:39 +02:00
|
|
|
connect(this, &QWebEnginePage::windowCloseRequested, this, &WebPage::windowCloseRequested);
|
2015-10-05 17:39:52 +02:00
|
|
|
connect(this, &QWebEnginePage::fullScreenRequested, this, &WebPage::fullScreenRequested);
|
2015-10-14 16:19:54 +02:00
|
|
|
connect(this, &QWebEnginePage::renderProcessTerminated, this, &WebPage::renderProcessTerminated);
|
2015-09-29 16:18:21 +02:00
|
|
|
|
|
|
|
connect(this, &QWebEnginePage::authenticationRequired, this, [this](const QUrl &url, QAuthenticator *auth) {
|
|
|
|
mApp->networkManager()->authentication(url, auth, view());
|
|
|
|
});
|
|
|
|
|
|
|
|
connect(this, &QWebEnginePage::proxyAuthenticationRequired, this, [this](const QUrl &, QAuthenticator *auth, const QString &proxyHost) {
|
|
|
|
mApp->networkManager()->proxyAuthentication(proxyHost, auth, view());
|
|
|
|
});
|
2017-03-15 13:11:27 +01:00
|
|
|
|
|
|
|
// Workaround QWebEnginePage not scrolling to anchors when opened in background tab
|
|
|
|
m_contentsResizedConnection = connect(this, &QWebEnginePage::contentsSizeChanged, this, [this]() {
|
|
|
|
const QString fragment = url().fragment();
|
|
|
|
if (!fragment.isEmpty()) {
|
|
|
|
const QString src = QSL("var els = document.querySelectorAll(\"[name='%1']\"); if (els.length) els[0].scrollIntoView();");
|
|
|
|
runJavaScript(src.arg(fragment));
|
|
|
|
}
|
|
|
|
disconnect(m_contentsResizedConnection);
|
|
|
|
});
|
2012-01-21 20:20:48 +01:00
|
|
|
}
|
2011-12-13 15:38:09 +01:00
|
|
|
|
2014-03-13 11:24:19 +01:00
|
|
|
WebPage::~WebPage()
|
|
|
|
{
|
|
|
|
mApp->plugins()->emitWebPageDeleted(this);
|
|
|
|
|
|
|
|
if (m_runningLoop) {
|
|
|
|
m_runningLoop->exit(1);
|
|
|
|
m_runningLoop = 0;
|
|
|
|
}
|
2012-01-21 20:20:48 +01:00
|
|
|
}
|
|
|
|
|
2015-09-24 23:00:27 +02:00
|
|
|
WebView *WebPage::view() const
|
2011-11-12 09:45:32 +01:00
|
|
|
{
|
2015-09-24 23:00:27 +02:00
|
|
|
return static_cast<WebView*>(QWebEnginePage::view());
|
|
|
|
}
|
2012-03-04 14:25:52 +01:00
|
|
|
|
2017-02-06 20:39:57 +01:00
|
|
|
bool WebPage::execPrintPage(QPrinter *printer, int timeout)
|
|
|
|
{
|
|
|
|
QPointer<QEventLoop> loop = new QEventLoop;
|
|
|
|
bool result = false;
|
|
|
|
QTimer::singleShot(timeout, loop.data(), &QEventLoop::quit);
|
|
|
|
|
|
|
|
print(printer, [loop, &result](bool res) {
|
|
|
|
if (loop && loop->isRunning()) {
|
|
|
|
result = res;
|
|
|
|
loop->quit();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
loop->exec();
|
|
|
|
delete loop;
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2016-05-10 10:47:35 +02:00
|
|
|
QVariant WebPage::execJavaScript(const QString &scriptSource, quint32 worldId, int timeout)
|
2015-09-29 21:53:56 +02:00
|
|
|
{
|
2015-09-30 11:01:10 +02:00
|
|
|
QPointer<QEventLoop> loop = new QEventLoop;
|
2015-09-29 21:53:56 +02:00
|
|
|
QVariant result;
|
2015-12-06 16:09:04 +01:00
|
|
|
QTimer::singleShot(timeout, loop.data(), &QEventLoop::quit);
|
2015-09-30 11:01:10 +02:00
|
|
|
|
2016-05-10 10:47:35 +02:00
|
|
|
runJavaScript(scriptSource, worldId, [loop, &result](const QVariant &res) {
|
2015-09-30 11:01:10 +02:00
|
|
|
if (loop && loop->isRunning()) {
|
|
|
|
result = res;
|
|
|
|
loop->quit();
|
|
|
|
}
|
2015-09-29 21:53:56 +02:00
|
|
|
});
|
2015-09-30 11:01:10 +02:00
|
|
|
|
2017-03-12 17:57:19 +01:00
|
|
|
loop->exec(QEventLoop::ExcludeUserInputEvents);
|
2015-09-30 11:01:10 +02:00
|
|
|
delete loop;
|
|
|
|
|
2015-09-29 21:53:56 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2016-12-27 11:58:10 +01:00
|
|
|
QPointF WebPage::mapToViewport(const QPointF &pos) const
|
2016-04-06 17:22:44 +02:00
|
|
|
{
|
2016-12-27 11:58:10 +01:00
|
|
|
return QPointF(pos.x() / zoomFactor(), pos.y() / zoomFactor());
|
2016-04-06 17:22:44 +02:00
|
|
|
}
|
|
|
|
|
2015-09-29 21:53:56 +02:00
|
|
|
WebHitTestResult WebPage::hitTestContent(const QPoint &pos) const
|
|
|
|
{
|
|
|
|
return WebHitTestResult(this, pos);
|
|
|
|
}
|
|
|
|
|
2015-10-02 15:23:59 +02:00
|
|
|
void WebPage::scroll(int x, int y)
|
|
|
|
{
|
2016-05-10 10:47:35 +02:00
|
|
|
runJavaScript(QSL("window.scrollTo(window.scrollX + %1, window.scrollY + %2)").arg(x).arg(y), WebPage::SafeJsWorld);
|
2016-12-26 12:38:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void WebPage::setScrollPosition(const QPointF &pos)
|
|
|
|
{
|
2016-12-27 11:58:10 +01:00
|
|
|
const QPointF v = mapToViewport(pos.toPoint());
|
|
|
|
runJavaScript(QSL("window.scrollTo(%1, %2)").arg(v.x()).arg(v.y()), WebPage::SafeJsWorld);
|
2015-10-02 15:23:59 +02:00
|
|
|
}
|
|
|
|
|
2012-01-21 20:20:48 +01:00
|
|
|
bool WebPage::isRunningLoop()
|
|
|
|
{
|
|
|
|
return m_runningLoop;
|
2011-11-12 09:45:32 +01:00
|
|
|
}
|
|
|
|
|
2012-07-03 15:22:42 +02:00
|
|
|
bool WebPage::isLoading() const
|
|
|
|
{
|
|
|
|
return m_loadProgress < 100;
|
|
|
|
}
|
|
|
|
|
2011-10-09 14:51:25 +02:00
|
|
|
void WebPage::urlChanged(const QUrl &url)
|
|
|
|
{
|
2015-08-30 17:42:58 +02:00
|
|
|
Q_UNUSED(url)
|
2012-02-04 19:43:43 +01:00
|
|
|
|
2012-07-03 15:22:42 +02:00
|
|
|
if (isLoading()) {
|
|
|
|
m_blockAlerts = false;
|
|
|
|
}
|
2011-07-11 20:30:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void WebPage::progress(int prog)
|
|
|
|
{
|
2012-07-03 15:22:42 +02:00
|
|
|
m_loadProgress = prog;
|
2012-02-04 19:43:43 +01:00
|
|
|
|
2015-09-29 11:37:17 +02:00
|
|
|
bool secStatus = url().scheme() == QL1S("https");
|
2011-07-11 20:30:49 +02:00
|
|
|
|
|
|
|
if (secStatus != m_secureStatus) {
|
|
|
|
m_secureStatus = secStatus;
|
2015-09-29 11:37:17 +02:00
|
|
|
emit privacyChanged(secStatus);
|
2011-07-11 20:30:49 +02:00
|
|
|
}
|
2011-03-02 16:57:41 +01:00
|
|
|
}
|
|
|
|
|
2011-07-11 22:53:32 +02:00
|
|
|
void WebPage::finished()
|
|
|
|
{
|
|
|
|
progress(100);
|
2011-10-30 16:32:36 +01:00
|
|
|
|
2013-02-08 18:44:26 +01:00
|
|
|
// File scheme watcher
|
2012-09-04 12:42:45 +02:00
|
|
|
if (url().scheme() == QLatin1String("file")) {
|
2012-08-23 16:17:56 +02:00
|
|
|
QFileInfo info(url().toLocalFile());
|
|
|
|
if (info.isFile()) {
|
|
|
|
if (!m_fileWatcher) {
|
2013-04-02 13:14:19 +02:00
|
|
|
m_fileWatcher = new DelayedFileWatcher(this);
|
|
|
|
connect(m_fileWatcher, SIGNAL(delayedFileChanged(QString)), this, SLOT(watchedFileChanged(QString)));
|
2012-08-23 16:17:56 +02:00
|
|
|
}
|
2011-12-15 19:08:33 +01:00
|
|
|
|
2013-12-30 13:43:48 +01:00
|
|
|
const QString filePath = url().toLocalFile();
|
2011-12-15 19:08:33 +01:00
|
|
|
|
2012-08-23 16:17:56 +02:00
|
|
|
if (QFile::exists(filePath) && !m_fileWatcher->files().contains(filePath)) {
|
|
|
|
m_fileWatcher->addPath(filePath);
|
|
|
|
}
|
2011-12-15 19:08:33 +01:00
|
|
|
}
|
|
|
|
}
|
2012-01-21 20:20:48 +01:00
|
|
|
else if (m_fileWatcher && !m_fileWatcher->files().isEmpty()) {
|
2011-12-15 19:08:33 +01:00
|
|
|
m_fileWatcher->removePaths(m_fileWatcher->files());
|
|
|
|
}
|
|
|
|
|
2013-02-08 18:44:26 +01:00
|
|
|
// AdBlock
|
2012-07-15 23:18:08 +02:00
|
|
|
cleanBlockedObjects();
|
2015-08-31 18:56:52 +02:00
|
|
|
|
|
|
|
// AutoFill
|
|
|
|
m_passwordEntries = mApp->autoFill()->completePage(this, url());
|
2011-07-11 22:53:32 +02:00
|
|
|
}
|
|
|
|
|
2011-12-15 19:08:33 +01:00
|
|
|
void WebPage::watchedFileChanged(const QString &file)
|
|
|
|
{
|
2012-01-21 20:20:48 +01:00
|
|
|
if (url().toLocalFile() == file) {
|
2015-01-27 11:01:52 +01:00
|
|
|
triggerAction(QWebEnginePage::Reload);
|
2011-12-15 19:08:33 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-13 13:26:32 +02:00
|
|
|
void WebPage::handleUnknownProtocol(const QUrl &url)
|
|
|
|
{
|
2013-12-30 13:43:48 +01:00
|
|
|
const QString protocol = url.scheme();
|
2012-04-13 13:26:32 +02:00
|
|
|
|
2013-04-12 17:52:51 +02:00
|
|
|
if (protocol == QLatin1String("mailto")) {
|
|
|
|
desktopServicesOpen(url);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-08-10 21:16:43 +02:00
|
|
|
if (qzSettings->blockedProtocols.contains(protocol)) {
|
2012-04-13 13:26:32 +02:00
|
|
|
qDebug() << "WebPage::handleUnknownProtocol Protocol" << protocol << "is blocked!";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-08-10 21:16:43 +02:00
|
|
|
if (qzSettings->autoOpenProtocols.contains(protocol)) {
|
2012-08-09 19:09:52 +02:00
|
|
|
desktopServicesOpen(url);
|
2012-04-13 13:26:32 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-04-05 10:27:03 +02:00
|
|
|
CheckBoxDialog dialog(QMessageBox::Yes | QMessageBox::No, view());
|
2012-05-13 17:01:35 +02:00
|
|
|
|
2013-12-30 13:43:48 +01:00
|
|
|
const QString wrappedUrl = QzTools::alignTextToWidth(url.toString(), "<br/>", dialog.fontMetrics(), 450);
|
2017-08-25 17:11:29 +02:00
|
|
|
const QString text = tr("Falkon cannot handle <b>%1:</b> links. The requested link "
|
|
|
|
"is <ul><li>%2</li></ul>Do you want Falkon to try "
|
2013-12-30 13:43:48 +01:00
|
|
|
"open this link in system application?").arg(protocol, wrappedUrl);
|
2012-05-13 17:01:35 +02:00
|
|
|
|
2012-04-13 13:26:32 +02:00
|
|
|
dialog.setText(text);
|
|
|
|
dialog.setCheckBoxText(tr("Remember my choice for this protocol"));
|
|
|
|
dialog.setWindowTitle(tr("External Protocol Request"));
|
2017-04-05 10:27:03 +02:00
|
|
|
dialog.setIcon(QMessageBox::Question);
|
2012-04-13 13:26:32 +02:00
|
|
|
|
|
|
|
switch (dialog.exec()) {
|
2017-04-05 10:27:03 +02:00
|
|
|
case QMessageBox::Yes:
|
2012-04-13 13:26:32 +02:00
|
|
|
if (dialog.isChecked()) {
|
2012-08-10 21:16:43 +02:00
|
|
|
qzSettings->autoOpenProtocols.append(protocol);
|
|
|
|
qzSettings->saveSettings();
|
2012-04-13 13:26:32 +02:00
|
|
|
}
|
|
|
|
|
2014-03-03 12:55:35 +01:00
|
|
|
|
2012-04-13 13:26:32 +02:00
|
|
|
QDesktopServices::openUrl(url);
|
|
|
|
break;
|
|
|
|
|
2017-04-05 10:27:03 +02:00
|
|
|
case QMessageBox::No:
|
2012-04-13 13:26:32 +02:00
|
|
|
if (dialog.isChecked()) {
|
2012-08-10 21:16:43 +02:00
|
|
|
qzSettings->blockedProtocols.append(protocol);
|
|
|
|
qzSettings->saveSettings();
|
2012-04-13 13:26:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-09 19:09:52 +02:00
|
|
|
void WebPage::desktopServicesOpen(const QUrl &url)
|
|
|
|
{
|
|
|
|
// Open same url only once in 2 secs
|
2014-03-03 12:55:35 +01:00
|
|
|
const int sameUrlTimeout = 2 * 1000;
|
2012-08-09 19:09:52 +02:00
|
|
|
|
2014-03-03 12:55:35 +01:00
|
|
|
if (s_lastUnsupportedUrl != url || s_lastUnsupportedUrlTime.isNull() || s_lastUnsupportedUrlTime.elapsed() > sameUrlTimeout) {
|
2012-08-09 19:09:52 +02:00
|
|
|
s_lastUnsupportedUrl = url;
|
2014-03-03 12:55:35 +01:00
|
|
|
s_lastUnsupportedUrlTime.restart();
|
2012-08-09 19:09:52 +02:00
|
|
|
QDesktopServices::openUrl(url);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
qWarning() << "WebPage::desktopServicesOpen Url" << url << "has already been opened!\n"
|
|
|
|
"Ignoring it to prevent infinite loop!";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-04 14:25:52 +01:00
|
|
|
void WebPage::windowCloseRequested()
|
|
|
|
{
|
2016-04-14 17:22:33 +02:00
|
|
|
if (!view())
|
|
|
|
return;
|
2015-09-24 23:00:27 +02:00
|
|
|
view()->closeView();
|
2012-03-04 14:25:52 +01:00
|
|
|
}
|
|
|
|
|
2015-12-08 11:27:06 +01:00
|
|
|
void WebPage::fullScreenRequested(QWebEngineFullScreenRequest fullScreenRequest)
|
2015-10-05 17:39:52 +02:00
|
|
|
{
|
2015-10-22 14:44:41 +02:00
|
|
|
view()->requestFullScreen(fullScreenRequest.toggleOn());
|
|
|
|
|
|
|
|
const bool accepted = fullScreenRequest.toggleOn() == view()->isFullScreen();
|
|
|
|
|
|
|
|
if (accepted)
|
|
|
|
fullScreenRequest.accept();
|
|
|
|
else
|
|
|
|
fullScreenRequest.reject();
|
2015-10-05 17:39:52 +02:00
|
|
|
}
|
|
|
|
|
2015-05-22 23:18:25 +02:00
|
|
|
void WebPage::featurePermissionRequested(const QUrl &origin, const QWebEnginePage::Feature &feature)
|
|
|
|
{
|
2015-10-06 10:58:17 +02:00
|
|
|
if (feature == MouseLock && view()->isFullScreen())
|
|
|
|
setFeaturePermission(origin, feature, PermissionGrantedByUser);
|
|
|
|
else
|
|
|
|
mApp->html5PermissionsManager()->requestPermissions(this, origin, feature);
|
2015-05-22 23:18:25 +02:00
|
|
|
}
|
|
|
|
|
2015-10-14 16:19:54 +02:00
|
|
|
void WebPage::renderProcessTerminated(QWebEnginePage::RenderProcessTerminationStatus terminationStatus, int exitCode)
|
|
|
|
{
|
|
|
|
Q_UNUSED(exitCode)
|
|
|
|
|
|
|
|
if (terminationStatus == NormalTerminationStatus)
|
|
|
|
return;
|
|
|
|
|
|
|
|
QTimer::singleShot(0, this, [this]() {
|
|
|
|
QString page = QzTools::readAllFileContents(":html/tabcrash.html");
|
|
|
|
page.replace(QL1S("%IMAGE%"), QzTools::pixmapToDataUrl(IconProvider::standardIcon(QStyle::SP_MessageBoxWarning).pixmap(45)).toString());
|
|
|
|
page.replace(QL1S("%TITLE%"), tr("Failed loading page"));
|
|
|
|
page.replace(QL1S("%HEADING%"), tr("Failed loading page"));
|
|
|
|
page.replace(QL1S("%LI-1%"), tr("Something went wrong while loading this page."));
|
|
|
|
page.replace(QL1S("%LI-2%"), tr("Try reloading the page or closing some tabs to make more memory available."));
|
|
|
|
page.replace(QL1S("%RELOAD-PAGE%"), tr("Reload page"));
|
|
|
|
page = QzTools::applyDirectionToPage(page);
|
2017-01-22 10:23:14 +01:00
|
|
|
load(url()); // Workaround for QtWebEngine crash
|
2015-10-14 16:19:54 +02:00
|
|
|
setHtml(page.toUtf8(), url());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-06-09 18:36:57 +02:00
|
|
|
bool WebPage::acceptNavigationRequest(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame)
|
|
|
|
{
|
|
|
|
if (!mApp->plugins()->acceptNavigationRequest(this, url, type, isMainFrame))
|
|
|
|
return false;
|
|
|
|
|
2015-10-08 22:39:27 +02:00
|
|
|
// AdBlock
|
|
|
|
if (url.scheme() == QL1S("abp") && AdBlockManager::instance()->addSubscriptionFromUrl(url))
|
|
|
|
return false;
|
|
|
|
|
2015-06-09 18:36:57 +02:00
|
|
|
return QWebEnginePage::acceptNavigationRequest(url, type, isMainFrame);
|
|
|
|
}
|
|
|
|
|
2015-09-29 11:37:17 +02:00
|
|
|
bool WebPage::certificateError(const QWebEngineCertificateError &error)
|
2015-06-09 18:36:57 +02:00
|
|
|
{
|
2015-09-29 16:18:21 +02:00
|
|
|
return mApp->networkManager()->certificateError(error, view());
|
2015-06-09 18:36:57 +02:00
|
|
|
}
|
|
|
|
|
2015-06-09 18:01:17 +02:00
|
|
|
QStringList WebPage::chooseFiles(QWebEnginePage::FileSelectionMode mode, const QStringList &oldFiles, const QStringList &acceptedMimeTypes)
|
|
|
|
{
|
|
|
|
Q_UNUSED(acceptedMimeTypes);
|
|
|
|
|
|
|
|
QStringList files;
|
|
|
|
QString suggestedFileName = s_lastUploadLocation;
|
|
|
|
if (!oldFiles.isEmpty())
|
2015-10-23 11:55:14 +02:00
|
|
|
suggestedFileName = oldFiles.at(0);
|
2015-06-09 18:01:17 +02:00
|
|
|
|
|
|
|
switch (mode) {
|
|
|
|
case FileSelectOpen:
|
|
|
|
files = QStringList(QzTools::getOpenFileName("WebPage-ChooseFile", view(), tr("Choose file..."), suggestedFileName));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case FileSelectOpenMultiple:
|
|
|
|
files = QzTools::getOpenFileNames("WebPage-ChooseFile", view(), tr("Choose files..."), suggestedFileName);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
files = QWebEnginePage::chooseFiles(mode, oldFiles, acceptedMimeTypes);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!files.isEmpty())
|
2015-10-23 11:55:14 +02:00
|
|
|
s_lastUploadLocation = files.at(0);
|
2015-06-09 18:01:17 +02:00
|
|
|
|
|
|
|
return files;
|
|
|
|
}
|
|
|
|
|
2013-02-08 18:44:26 +01:00
|
|
|
bool WebPage::hasMultipleUsernames() const
|
|
|
|
{
|
2013-05-14 17:25:55 +02:00
|
|
|
return m_passwordEntries.count() > 1;
|
2013-02-08 18:44:26 +01:00
|
|
|
}
|
|
|
|
|
2013-05-14 17:25:55 +02:00
|
|
|
QVector<PasswordEntry> WebPage::autoFillData() const
|
2013-02-08 18:44:26 +01:00
|
|
|
{
|
2013-05-14 17:25:55 +02:00
|
|
|
return m_passwordEntries;
|
2013-02-08 18:44:26 +01:00
|
|
|
}
|
|
|
|
|
2011-10-09 14:51:25 +02:00
|
|
|
void WebPage::cleanBlockedObjects()
|
|
|
|
{
|
2012-07-04 10:08:55 +02:00
|
|
|
AdBlockManager* manager = AdBlockManager::instance();
|
2012-07-13 14:12:48 +02:00
|
|
|
if (!manager->isEnabled()) {
|
2012-06-25 16:07:25 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-05-27 15:55:30 +02:00
|
|
|
// Apply global element hiding rules
|
|
|
|
const QString elementHiding = manager->elementHidingRules(url());
|
|
|
|
if (!elementHiding.isEmpty())
|
|
|
|
runJavaScript(Scripts::setCss(elementHiding), WebPage::SafeJsWorld);
|
2012-07-04 16:00:53 +02:00
|
|
|
|
2016-05-27 15:55:30 +02:00
|
|
|
// Apply domain-specific element hiding rules
|
|
|
|
const QString siteElementHiding = manager->elementHidingRulesForDomain(url());
|
|
|
|
if (!siteElementHiding.isEmpty())
|
|
|
|
runJavaScript(Scripts::setCss(siteElementHiding), WebPage::SafeJsWorld);
|
2011-03-29 20:30:05 +02:00
|
|
|
}
|
|
|
|
|
2015-08-28 19:25:45 +02:00
|
|
|
bool WebPage::javaScriptPrompt(const QUrl &securityOrigin, const QString &msg, const QString &defaultValue, QString* result)
|
2011-05-22 10:47:03 +02:00
|
|
|
{
|
2015-09-29 11:30:42 +02:00
|
|
|
Q_UNUSED(securityOrigin)
|
|
|
|
|
2012-01-21 20:20:48 +01:00
|
|
|
#ifndef NONBLOCK_JS_DIALOGS
|
2015-01-27 11:01:52 +01:00
|
|
|
return QWebEnginePage::javaScriptPrompt(securityOrigin, msg, defaultValue, result);
|
2012-01-21 20:20:48 +01:00
|
|
|
#else
|
|
|
|
if (m_runningLoop) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-09-24 23:00:27 +02:00
|
|
|
ResizableFrame* widget = new ResizableFrame(view()->overlayWidget());
|
2011-05-22 10:47:03 +02:00
|
|
|
|
2011-11-24 22:18:45 +01:00
|
|
|
widget->setObjectName("jsFrame");
|
2011-05-22 10:47:03 +02:00
|
|
|
Ui_jsPrompt* ui = new Ui_jsPrompt();
|
|
|
|
ui->setupUi(widget);
|
|
|
|
ui->message->setText(msg);
|
|
|
|
ui->lineEdit->setText(defaultValue);
|
|
|
|
ui->lineEdit->setFocus();
|
2015-09-29 11:30:42 +02:00
|
|
|
widget->resize(view()->size());
|
2011-05-22 10:47:03 +02:00
|
|
|
widget->show();
|
|
|
|
|
2015-09-29 11:30:42 +02:00
|
|
|
connect(view(), SIGNAL(viewportResized(QSize)), widget, SLOT(slotResize(QSize)));
|
2011-05-22 10:47:03 +02:00
|
|
|
connect(ui->lineEdit, SIGNAL(returnPressed()), ui->buttonBox->button(QDialogButtonBox::Ok), SLOT(animateClick()));
|
|
|
|
|
|
|
|
QEventLoop eLoop;
|
2011-12-13 15:38:09 +01:00
|
|
|
m_runningLoop = &eLoop;
|
2011-11-06 17:01:23 +01:00
|
|
|
connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), &eLoop, SLOT(quit()));
|
2011-12-13 15:38:09 +01:00
|
|
|
|
2012-04-04 14:45:45 +02:00
|
|
|
if (eLoop.exec() == 1) {
|
2011-12-13 15:38:09 +01:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
m_runningLoop = 0;
|
2011-05-22 10:47:03 +02:00
|
|
|
|
|
|
|
QString x = ui->lineEdit->text();
|
|
|
|
bool _result = ui->buttonBox->clickedButtonRole() == QDialogButtonBox::AcceptRole;
|
|
|
|
*result = x;
|
|
|
|
|
2011-12-13 15:38:09 +01:00
|
|
|
delete widget;
|
2015-09-24 23:00:27 +02:00
|
|
|
view()->setFocus();
|
2011-05-22 10:47:03 +02:00
|
|
|
|
|
|
|
return _result;
|
2012-01-21 20:20:48 +01:00
|
|
|
#endif
|
2011-05-22 10:47:03 +02:00
|
|
|
}
|
|
|
|
|
2015-08-28 19:25:45 +02:00
|
|
|
bool WebPage::javaScriptConfirm(const QUrl &securityOrigin, const QString &msg)
|
2011-05-22 10:47:03 +02:00
|
|
|
{
|
2015-09-29 11:30:42 +02:00
|
|
|
Q_UNUSED(securityOrigin)
|
|
|
|
|
2012-01-21 20:20:48 +01:00
|
|
|
#ifndef NONBLOCK_JS_DIALOGS
|
2015-01-27 11:01:52 +01:00
|
|
|
return QWebEnginePage::javaScriptConfirm(securityOrigin, msg);
|
2012-01-21 20:20:48 +01:00
|
|
|
#else
|
|
|
|
if (m_runningLoop) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-09-24 23:00:27 +02:00
|
|
|
ResizableFrame* widget = new ResizableFrame(view()->overlayWidget());
|
2011-05-22 10:47:03 +02:00
|
|
|
|
2011-11-24 22:18:45 +01:00
|
|
|
widget->setObjectName("jsFrame");
|
2011-05-22 10:47:03 +02:00
|
|
|
Ui_jsConfirm* ui = new Ui_jsConfirm();
|
|
|
|
ui->setupUi(widget);
|
|
|
|
ui->message->setText(msg);
|
|
|
|
ui->buttonBox->button(QDialogButtonBox::Ok)->setFocus();
|
2015-09-29 11:30:42 +02:00
|
|
|
widget->resize(view()->size());
|
2011-05-22 10:47:03 +02:00
|
|
|
widget->show();
|
|
|
|
|
2015-09-29 11:30:42 +02:00
|
|
|
connect(view(), SIGNAL(viewportResized(QSize)), widget, SLOT(slotResize(QSize)));
|
2011-05-22 10:47:03 +02:00
|
|
|
|
|
|
|
QEventLoop eLoop;
|
2011-12-13 15:38:09 +01:00
|
|
|
m_runningLoop = &eLoop;
|
2011-11-06 17:01:23 +01:00
|
|
|
connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), &eLoop, SLOT(quit()));
|
2011-12-13 15:38:09 +01:00
|
|
|
|
2012-04-04 14:45:45 +02:00
|
|
|
if (eLoop.exec() == 1) {
|
2011-12-13 15:38:09 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
m_runningLoop = 0;
|
2011-05-22 10:47:03 +02:00
|
|
|
|
|
|
|
bool result = ui->buttonBox->clickedButtonRole() == QDialogButtonBox::AcceptRole;
|
|
|
|
|
2011-12-13 15:38:09 +01:00
|
|
|
delete widget;
|
2015-09-24 23:00:27 +02:00
|
|
|
view()->setFocus();
|
2011-05-22 10:47:03 +02:00
|
|
|
|
|
|
|
return result;
|
2012-01-21 20:20:48 +01:00
|
|
|
#endif
|
2011-05-22 10:47:03 +02:00
|
|
|
}
|
|
|
|
|
2015-08-28 19:25:45 +02:00
|
|
|
void WebPage::javaScriptAlert(const QUrl &securityOrigin, const QString &msg)
|
2011-05-22 10:47:03 +02:00
|
|
|
{
|
2015-01-27 11:01:52 +01:00
|
|
|
Q_UNUSED(securityOrigin)
|
2012-02-05 17:13:08 +01:00
|
|
|
|
2012-01-21 20:20:48 +01:00
|
|
|
if (m_blockAlerts || m_runningLoop) {
|
2011-05-22 10:47:03 +02:00
|
|
|
return;
|
2011-11-06 17:01:23 +01:00
|
|
|
}
|
2011-05-22 10:47:03 +02:00
|
|
|
|
2012-01-21 20:20:48 +01:00
|
|
|
#ifndef NONBLOCK_JS_DIALOGS
|
2012-03-15 19:35:37 +01:00
|
|
|
QString title = tr("JavaScript alert");
|
|
|
|
if (!url().host().isEmpty()) {
|
|
|
|
title.append(QString(" - %1").arg(url().host()));
|
|
|
|
}
|
|
|
|
|
2017-04-05 10:27:03 +02:00
|
|
|
CheckBoxDialog dialog(QMessageBox::Ok, view());
|
2012-03-15 19:35:37 +01:00
|
|
|
dialog.setWindowTitle(title);
|
|
|
|
dialog.setText(msg);
|
|
|
|
dialog.setCheckBoxText(tr("Prevent this page from creating additional dialogs"));
|
2017-04-05 10:27:03 +02:00
|
|
|
dialog.setIcon(QMessageBox::Information);
|
2012-03-15 19:35:37 +01:00
|
|
|
dialog.exec();
|
|
|
|
|
|
|
|
m_blockAlerts = dialog.isChecked();
|
2012-01-21 20:20:48 +01:00
|
|
|
#else
|
2015-09-24 23:00:27 +02:00
|
|
|
ResizableFrame* widget = new ResizableFrame(view()->overlayWidget());
|
2011-05-22 10:47:03 +02:00
|
|
|
|
2011-11-24 22:18:45 +01:00
|
|
|
widget->setObjectName("jsFrame");
|
2011-05-22 10:47:03 +02:00
|
|
|
Ui_jsAlert* ui = new Ui_jsAlert();
|
|
|
|
ui->setupUi(widget);
|
|
|
|
ui->message->setText(msg);
|
|
|
|
ui->buttonBox->button(QDialogButtonBox::Ok)->setFocus();
|
2015-09-24 23:00:27 +02:00
|
|
|
widget->resize(view()->size());
|
2011-05-22 10:47:03 +02:00
|
|
|
widget->show();
|
|
|
|
|
2015-09-24 23:00:27 +02:00
|
|
|
connect(view(), SIGNAL(viewportResized(QSize)), widget, SLOT(slotResize(QSize)));
|
2011-05-22 10:47:03 +02:00
|
|
|
|
|
|
|
QEventLoop eLoop;
|
2011-12-13 15:38:09 +01:00
|
|
|
m_runningLoop = &eLoop;
|
2011-11-06 17:01:23 +01:00
|
|
|
connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), &eLoop, SLOT(quit()));
|
2011-12-13 15:38:09 +01:00
|
|
|
|
2012-04-04 14:45:45 +02:00
|
|
|
if (eLoop.exec() == 1) {
|
2011-12-13 15:38:09 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
m_runningLoop = 0;
|
2011-05-22 10:47:03 +02:00
|
|
|
|
|
|
|
m_blockAlerts = ui->preventAlerts->isChecked();
|
|
|
|
|
|
|
|
delete widget;
|
|
|
|
|
2015-09-24 23:00:27 +02:00
|
|
|
view()->setFocus();
|
2012-01-21 20:20:48 +01:00
|
|
|
#endif
|
2011-05-22 10:47:03 +02:00
|
|
|
}
|
|
|
|
|
2014-01-25 17:48:30 +01:00
|
|
|
void WebPage::setJavaScriptEnabled(bool enabled)
|
|
|
|
{
|
2015-01-27 11:01:52 +01:00
|
|
|
settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, enabled);
|
2014-01-25 17:48:30 +01:00
|
|
|
}
|
|
|
|
|
2015-06-09 18:01:17 +02:00
|
|
|
QWebEnginePage* WebPage::createWindow(QWebEnginePage::WebWindowType type)
|
2011-05-22 11:05:36 +02:00
|
|
|
{
|
2015-08-30 16:53:51 +02:00
|
|
|
TabbedWebView *tView = qobject_cast<TabbedWebView*>(view());
|
|
|
|
BrowserWindow *window = tView ? tView->browserWindow() : mApp->getWindow();
|
|
|
|
|
2016-10-24 21:31:24 +02:00
|
|
|
auto createTab = [=](Qz::NewTabPositionFlags pos) {
|
|
|
|
int index = window->tabWidget()->addView(QUrl(), pos);
|
|
|
|
TabbedWebView* view = window->weView(index);
|
|
|
|
view->setPage(new WebPage);
|
2017-07-19 13:57:37 +02:00
|
|
|
// Workaround focus issue when creating tab
|
|
|
|
if (pos.testFlag(Qz::NT_SelectedTab)) {
|
|
|
|
QPointer<TabbedWebView> pview = view;
|
|
|
|
QTimer::singleShot(0, this, [pview]() {
|
|
|
|
if (pview && pview->webTab()->isCurrentTab()) {
|
|
|
|
pview->setFocus();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2016-10-24 21:31:24 +02:00
|
|
|
return view->page();
|
|
|
|
};
|
|
|
|
|
2015-06-09 18:01:17 +02:00
|
|
|
switch (type) {
|
2016-03-30 09:10:57 +02:00
|
|
|
case QWebEnginePage::WebBrowserWindow: {
|
|
|
|
BrowserWindow *window = mApp->createWindow(Qz::BW_NewWindow);
|
|
|
|
WebPage *page = new WebPage;
|
|
|
|
window->setStartPage(page);
|
|
|
|
return page;
|
|
|
|
}
|
2015-10-04 19:51:39 +02:00
|
|
|
|
2016-02-14 10:37:28 +01:00
|
|
|
case QWebEnginePage::WebDialog:
|
|
|
|
if (!qzSettings->openPopupsInTabs) {
|
|
|
|
PopupWebView* view = new PopupWebView;
|
|
|
|
view->setPage(new WebPage);
|
|
|
|
PopupWindow* popup = new PopupWindow(view);
|
|
|
|
popup->show();
|
|
|
|
window->addDeleteOnCloseWidget(popup);
|
|
|
|
return view->page();
|
|
|
|
}
|
|
|
|
// else fallthrough
|
|
|
|
|
2016-10-24 21:31:24 +02:00
|
|
|
case QWebEnginePage::WebBrowserTab:
|
|
|
|
return createTab(Qz::NT_CleanSelectedTab);
|
|
|
|
|
|
|
|
case QWebEnginePage::WebBrowserBackgroundTab:
|
|
|
|
return createTab(Qz::NT_CleanNotSelectedTab);
|
2012-02-04 19:43:43 +01:00
|
|
|
|
2015-06-09 18:01:17 +02:00
|
|
|
default:
|
2015-12-07 12:41:07 +01:00
|
|
|
break;
|
2015-06-09 18:01:17 +02:00
|
|
|
}
|
2015-12-07 12:41:07 +01:00
|
|
|
|
|
|
|
return Q_NULLPTR;
|
2011-05-22 11:05:36 +02:00
|
|
|
}
|