1
mirror of https://invent.kde.org/network/falkon.git synced 2024-09-23 02:32:10 +02:00
falkonOfficial/src/webview/webpage.cpp

443 lines
16 KiB
C++
Raw Normal View History

2011-03-03 18:29:20 +01:00
/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2010-2011 nowrep
*
* 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"
#include "webview.h"
#include "tabwidget.h"
#include "qupzilla.h"
#include "downloadmanager.h"
#include "webpluginfactory.h"
#include "mainapplication.h"
#include "ui_jsconfirm.h"
#include "ui_jsalert.h"
#include "ui_jsprompt.h"
#include "widget.h"
2011-03-02 16:57:41 +01:00
2011-03-17 17:03:04 +01:00
WebPage::WebPage(WebView* parent, QupZilla* mainClass)
2011-03-02 16:57:41 +01:00
: QWebPage(parent)
,p_QupZilla(mainClass)
,m_view(parent)
,m_blockAlerts(false)
,m_lastUploadLocation(QDir::homePath())
,m_secureStatus(false)
2011-03-27 21:59:40 +02:00
// ,m_isOpeningNextWindowAsNewTab(false)
2011-03-02 16:57:41 +01:00
{
setForwardUnsupportedContent(true);
setPluginFactory(new WebPluginFactory(this));
history()->setMaximumItemCount(20);
2011-03-02 16:57:41 +01:00
connect(this, SIGNAL(unsupportedContent(QNetworkReply*)), SLOT(handleUnsupportedContent(QNetworkReply*)));
connect(this, SIGNAL(loadStarted()), this, SLOT(loadingStarted()));
connect(this, SIGNAL(loadProgress(int)), this, SLOT(progress(int)));
connect(this, SIGNAL(loadFinished(bool)), this, SLOT(finished()));
}
void WebPage::progress(int prog)
{
Q_UNUSED(prog)
bool secStatus = sslCertificate().isValid();
if (secStatus != m_secureStatus) {
m_secureStatus = secStatus;
emit privacyChanged(sslCertificate().isValid());
}
2011-03-02 16:57:41 +01:00
}
void WebPage::finished()
{
progress(100);
}
void WebPage::loadingStarted()
{
m_adBlockedEntries.clear();
m_blockAlerts = false;
//m_SslCert.clear();
}
2011-03-02 16:57:41 +01:00
void WebPage::handleUnsupportedContent(QNetworkReply* reply)
{
if (!reply)
return;
QUrl url = reply->url();
switch(reply->error()) {
case QNetworkReply::NoError:
if (reply->header(QNetworkRequest::ContentTypeHeader).isValid()) {
2011-03-04 13:59:07 +01:00
DownloadManager* dManager = mApp->downManager();
2011-03-02 16:57:41 +01:00
dManager->handleUnsupportedContent(reply);
return;
}
break;
case QNetworkReply::ProtocolUnknownError:
qDebug() << url << "ProtocolUnknowError";
QDesktopServices::openUrl(url);
return;
break;
default:
break;
}
2011-03-24 16:51:19 +01:00
qDebug() << "WebPage::UnsupportedContent error" << reply->errorString();
2011-03-02 16:57:41 +01:00
}
2011-04-24 09:08:53 +02:00
void WebPage::setSSLCertificate(const QSslCertificate &cert)
{
// if (cert != m_SslCert) -- crashing on linux :-|
m_SslCert = cert;
}
QSslCertificate WebPage::sslCertificate()
{
if (mainFrame()->url().scheme() == "https" && m_SslCert.subjectInfo(QSslCertificate::CommonName).remove("*").contains(QRegExp(mainFrame()->url().host())))
return m_SslCert;
else
return QSslCertificate();
}
2011-03-17 17:03:04 +01:00
bool WebPage::acceptNavigationRequest(QWebFrame* frame, const QNetworkRequest &request, NavigationType type)
2011-03-02 16:57:41 +01:00
{
m_lastRequest = request;
m_lastRequestType = type;
QString scheme = request.url().scheme();
if (scheme == "mailto" || scheme == "ftp") {
QDesktopServices::openUrl(request.url());
return false;
}
if (type == QWebPage::NavigationTypeFormResubmitted) {
bool result = javaScriptConfirm(frame, tr("To show this page, QupZilla must resend request which do it again \n"
"(like searching on making an shoping, witch has been already done.)"));
if (!result)
2011-03-02 16:57:41 +01:00
return false;
}
TabWidget::OpenUrlIn openIn= frame ? TabWidget::CurrentTab: TabWidget::NewTab;
bool accept = QWebPage::acceptNavigationRequest(frame, request, type);
if (accept && openIn == TabWidget::NewTab) {
2011-03-27 21:59:40 +02:00
// m_isOpeningNextWindowAsNewTab = true;
// p_QupZilla->tabWidget()->addView(request.url(),tr("New tab"), openIn);
2011-03-02 16:57:41 +01:00
}
return accept;
}
QString WebPage::userAgentForUrl(const QUrl &url) const
{
return QWebPage::userAgentForUrl(url);
}
void WebPage::populateNetworkRequest(QNetworkRequest &request)
{
QVariant variant = qVariantFromValue((void *) this);
request.setAttribute((QNetworkRequest::Attribute)(QNetworkRequest::User + 100), variant);
request.setAttribute((QNetworkRequest::Attribute)(QNetworkRequest::User + 101), m_lastRequestType);
variant = qVariantFromValue((void *) m_view);
request.setAttribute((QNetworkRequest::Attribute)(QNetworkRequest::User + 102), variant);
}
QWebPage* WebPage::createWindow(QWebPage::WebWindowType type)
{
2011-03-27 21:59:40 +02:00
// if (m_isOpeningNextWindowAsNewTab)
// return 0;
// m_isOpeningNextWindowAsNewTab = false;
// qDebug() << type;
// QWebView* view = new QWebView();
// view->show();
// return view->page();
2011-03-02 16:57:41 +01:00
Q_UNUSED(type);
int index = p_QupZilla->tabWidget()->addView();
return p_QupZilla->weView(index)->page();
}
void WebPage::addAdBlockRule(const QString &filter, const QUrl &url)
{
AdBlockedEntry entry;
entry.rule = filter;
entry.url = url;
m_adBlockedEntries.append(entry);
}
bool WebPage::extension(Extension extension, const ExtensionOption* option, ExtensionReturn* output)
2011-03-02 16:57:41 +01:00
{
if (extension == ChooseMultipleFilesExtension)
return QWebPage::extension(extension, option, output);
const ErrorPageExtensionOption* exOption = static_cast<const QWebPage::ErrorPageExtensionOption*>(option);
ErrorPageExtensionReturn* exReturn = static_cast<QWebPage::ErrorPageExtensionReturn*>(output);
QString errorString;
if (exOption->domain == QWebPage::QtNetwork) {
switch (exOption->error) {
case QNetworkReply::ConnectionRefusedError:
errorString = tr("Server refused the connection");
break;
case QNetworkReply::RemoteHostClosedError:
errorString = tr("Server closed the connection");
break;
case QNetworkReply::HostNotFoundError:
errorString = tr("Server not found");
break;
case QNetworkReply::TimeoutError:
errorString = tr("Connection timed out");
break;
case QNetworkReply::SslHandshakeFailedError:
errorString = tr("Untrusted connection");
break;
case QNetworkReply::ContentAccessDenied:
if (exOption->errorString.startsWith("AdBlockRule")) {
if (exOption->frame != exOption->frame->page()->mainFrame()) { //Content in <iframe>
QWebElement docElement = exOption->frame->page()->mainFrame()->documentElement();
QWebElementCollection elements;
elements.append(docElement.findAll("iframe"));
foreach (QWebElement element, elements) {
QString src = element.attribute("src");
if (exOption->url.toString().contains(src))
element.setAttribute("style", "display:none;");
}
return false;
} else { //The whole page is blocked
QString rule = exOption->errorString;
rule.remove("AdBlockRule:");
QFile file(":/html/adblockPage.html");
file.open(QFile::ReadOnly);
QString errString = file.readAll();
errString.replace("%TITLE%", tr("AdBlocked Content"));
//QPixmap pixmap = QIcon::fromTheme("dialog-warning").pixmap(45,45);
QPixmap pixmap(":/html/adblock_big.png");
QByteArray bytes;
QBuffer buffer(&bytes);
buffer.open(QIODevice::WriteOnly);
if (pixmap.save(&buffer, "PNG")) {
errString.replace("%IMAGE%", buffer.buffer().toBase64());
errString.replace("%FAVICON%", buffer.buffer().toBase64());
}
errString.replace("%RULE%", tr("Blocked by rule <i>%1</i>").arg(rule));
exReturn->baseUrl = exOption->url.toString();
exReturn->content = errString.toUtf8();
return true;
}
}
errorString = tr("Content Access Denied");
break;
2011-03-02 16:57:41 +01:00
default:
qDebug() << "Content error: " << exOption->errorString;
return false;
// if (errorString.isEmpty())
// errorString = tr("Unknown error");
2011-03-02 16:57:41 +01:00
}
}
else if (exOption->domain == QWebPage::Http) {
errorString = tr("Error code %1").arg(exOption->error);
}
else if (exOption->domain == QWebPage::WebKit)
return false; // Downloads
QString loadedUrl = exOption->url.toString();
exReturn->baseUrl = loadedUrl;
QFile file(":/html/errorPage.html");
file.open(QFile::ReadOnly);
QString errString = file.readAll();
errString.replace("%TITLE%", tr("Failed loading page"));
//QPixmap pixmap = QIcon::fromTheme("dialog-warning").pixmap(45,45);
QPixmap pixmap = MainApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning).pixmap(45,45);
QByteArray bytes;
QBuffer buffer(&bytes);
buffer.open(QIODevice::WriteOnly);
if (pixmap.save(&buffer, "PNG"))
errString.replace("%IMAGE%", buffer.buffer().toBase64());
//pixmap = QIcon::fromTheme("dialog-warning").pixmap(16,16);
pixmap = MainApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning).pixmap(16,16);
bytes.clear();
QBuffer buffer2(&bytes);
buffer2.open(QIODevice::WriteOnly);
if (pixmap.save(&buffer2, "PNG"))
errString.replace("%FAVICON%", buffer.buffer().toBase64());
errString.replace("%HEADING%", errorString);
errString.replace("%HEADING2%", tr("QupZilla can't load page from %1.").arg(QUrl(loadedUrl).host()));
2011-03-02 16:57:41 +01:00
errString.replace("%LI-1%", tr("Check the address for typing errors such as <b>ww.</b>example.com instead of <b>www.</b>example.com"));
errString.replace("%LI-2%", tr("If you are unable to load any pages, check your computer's network connection."));
errString.replace("%LI-3%", tr("If your computer or network is protected by a firewall or proxy, make sure that QupZilla is permitted to access the Web."));
errString.replace("%TRY-AGAIN%", tr("Try Again"));
exReturn->content = errString.toUtf8();
return true;
}
void WebPage::adBlockCleanup()
{
QWebElement docElement = mainFrame()->documentElement();
foreach (AdBlockedEntry entry, m_adBlockedEntries) {
QWebElementCollection elements;
elements.append(docElement.findAll("*[src=\"" + entry.url.toString() + "\"]"));
foreach (QWebElement element, elements)
// element.setAttribute("style", "display:none;");
element.removeFromDocument();
}
}
bool WebPage::javaScriptPrompt(QWebFrame* originatingFrame, const QString &msg, const QString &defaultValue, QString* result)
{
WebView* _view = (WebView*)originatingFrame->page()->view();
Widget* widget = new Widget(_view->webTab());
Ui_jsPrompt* ui = new Ui_jsPrompt();
ui->setupUi(widget);
ui->message->setText(msg);
ui->lineEdit->setText(defaultValue);
ui->lineEdit->setFocus();
widget->resize(originatingFrame->page()->viewportSize());
widget->show();
connect(_view, SIGNAL(viewportResized(QSize)), widget, SLOT(slotResize(QSize)));
connect(ui->lineEdit, SIGNAL(returnPressed()), ui->buttonBox->button(QDialogButtonBox::Ok), SLOT(animateClick()));
QWebElement bodyElement = originatingFrame->findFirstElement("body");
if (!bodyElement.isNull()) {
QString height = QString::number(originatingFrame->contentsSize().height());
QString width = QString::number(originatingFrame->contentsSize().width());
bodyElement.prependInside("<span id='qupzilla-background-content' style='display: block;background: #6b6b6b;"
"position: absolute;opacity: .9;filter: alpha(opacity=90);top: 0px;"
"left: 0px;z-index: 998;overflow: hidden;width:"+width+"px; height:"+height+"px;'> </span>");
} else {
widget->setAutoFillBackground(true);
}
QEventLoop eLoop;
connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), &eLoop, SLOT(quit()) );
eLoop.exec();
QString x = ui->lineEdit->text();
bool _result = ui->buttonBox->clickedButtonRole() == QDialogButtonBox::AcceptRole;
*result = x;
delete widget;
originatingFrame->findFirstElement("span[id=\"qupzilla-background-content\"]").removeFromDocument();
_view->setFocus();
return _result;
}
bool WebPage::javaScriptConfirm(QWebFrame* originatingFrame, const QString &msg)
{
WebView* _view = (WebView*)originatingFrame->page()->view();
Widget* widget = new Widget(_view->webTab());
Ui_jsConfirm* ui = new Ui_jsConfirm();
ui->setupUi(widget);
ui->message->setText(msg);
ui->buttonBox->button(QDialogButtonBox::Ok)->setFocus();
widget->resize(originatingFrame->page()->viewportSize());
widget->show();
connect(_view, SIGNAL(viewportResized(QSize)), widget, SLOT(slotResize(QSize)));
QWebElement bodyElement = originatingFrame->findFirstElement("body");
if (!bodyElement.isNull()) {
QString height = QString::number(originatingFrame->contentsSize().height());
QString width = QString::number(originatingFrame->contentsSize().width());
bodyElement.prependInside("<span id='qupzilla-background-content' style='display: block;background: #6b6b6b;"
"position: absolute;opacity: .9;filter: alpha(opacity=90);top: 0px;"
"left: 0px;z-index: 998;overflow: hidden;width:"+width+"px; height:"+height+"px;'> </span>");
} else {
widget->setAutoFillBackground(true);
}
QEventLoop eLoop;
connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), &eLoop, SLOT(quit()) );
eLoop.exec();
bool result = ui->buttonBox->clickedButtonRole() == QDialogButtonBox::AcceptRole;
delete widget;
originatingFrame->findFirstElement("span[id=\"qupzilla-background-content\"]").removeFromDocument();
_view->setFocus();
return result;
}
void WebPage::javaScriptAlert(QWebFrame* originatingFrame, const QString &msg)
{
if (m_blockAlerts)
return;
WebView* _view = (WebView*)originatingFrame->page()->view();
Widget* widget = new Widget(_view->webTab());
Ui_jsAlert* ui = new Ui_jsAlert();
ui->setupUi(widget);
ui->message->setText(msg);
ui->buttonBox->button(QDialogButtonBox::Ok)->setFocus();
widget->resize(originatingFrame->page()->viewportSize());
widget->show();
connect(_view, SIGNAL(viewportResized(QSize)), widget, SLOT(slotResize(QSize)));
QWebElement bodyElement = originatingFrame->findFirstElement("body");
if (!bodyElement.isNull()) {
QString height = QString::number(originatingFrame->contentsSize().height());
QString width = QString::number(originatingFrame->contentsSize().width());
bodyElement.prependInside("<span id='qupzilla-background-content' style='display: block;background: #6b6b6b;"
"position: absolute;opacity: .9;filter: alpha(opacity=90);top: 0px;"
"left: 0px;z-index: 998;overflow: hidden;width:"+width+"px; height:"+height+"px;'> </span>");
} else {
widget->setAutoFillBackground(true);
}
QEventLoop eLoop;
connect(ui->buttonBox, SIGNAL(clicked(QAbstractButton*)), &eLoop, SLOT(quit()) );
eLoop.exec();
m_blockAlerts = ui->preventAlerts->isChecked();
delete widget;
originatingFrame->findFirstElement("span[id=\"qupzilla-background-content\"]").removeFromDocument();
_view->setFocus();
}
QString WebPage::chooseFile(QWebFrame *originatingFrame, const QString &oldFile)
{
QString suggFileName;
if (oldFile.isEmpty())
suggFileName = m_lastUploadLocation;
else
suggFileName = oldFile;
QString fileName = QFileDialog::getOpenFileName(originatingFrame->page()->view(), tr("Choose file..."), suggFileName);
if (!fileName.isEmpty())
m_lastUploadLocation = fileName;
return fileName;
}
2011-03-02 16:57:41 +01:00
WebPage::~WebPage()
{
setNetworkAccessManager(0);
mainFrame()->deleteLater();
}