summaryrefslogtreecommitdiff
path: root/libre/konqueror
diff options
context:
space:
mode:
authorcoadde [Márcio Alexandre Silva Delgado] <coadde@parabola.nu>2017-03-21 12:49:20 -0300
committercoadde [Márcio Alexandre Silva Delgado] <coadde@parabola.nu>2017-03-21 21:11:45 -0300
commit7b81bd6f911a1c778f1eacc57faa0a4e94c5079b (patch)
tree072e6a18ff2cd5e1ec2f9b041a44fc676de3fc12 /libre/konqueror
parent3ebbdf800de63622d855c30bd09582720f9b9627 (diff)
downloadabslibre-7b81bd6f911a1c778f1eacc57faa0a4e94c5079b.tar.gz
abslibre-7b81bd6f911a1c778f1eacc57faa0a4e94c5079b.tar.bz2
abslibre-7b81bd6f911a1c778f1eacc57faa0a4e94c5079b.zip
konqueror: minor fix
Diffstat (limited to 'libre/konqueror')
-rw-r--r--libre/konqueror/PKGBUILD6
-rw-r--r--libre/konqueror/libre.patch14
-rw-r--r--libre/konqueror/webkit.patch19659
3 files changed, 19668 insertions, 11 deletions
diff --git a/libre/konqueror/PKGBUILD b/libre/konqueror/PKGBUILD
index e9be3590a..504995ec9 100644
--- a/libre/konqueror/PKGBUILD
+++ b/libre/konqueror/PKGBUILD
@@ -5,12 +5,12 @@
pkgname=konqueror
pkgver=16.12.3
-pkgrel=1.parabola1
+pkgrel=2.parabola1
pkgdesc="KDE File Manager & Web Browser, without Google, nonfree software recommendation and nonfree qt5-webengine support"
arch=(i686 x86_64 armv7h)
url="https://konqueror.org/"
license=(LGPL)
-depends=(dolphin keditbookmarks)
+depends=(dolphin keditbookmarks mesa)
makedepends=(extra-cmake-modules kdoctools python tidy kdesignerplugin kdesu)
optdepends=('tidy: tidy HTML plugin' 'kdesu: shell command plugin')
conflicts=(kdebase-konqueror kdebase-konq-plugins)
@@ -20,7 +20,7 @@ source=("https://download.kde.org/stable/applications/$pkgver/src/$pkgname-$pkgv
'libre.patch')
sha256sums=('e52654a1bb2c0be317f8ed80dba3147bc4d2126abce209ab57c6e69e64159bdf'
'SKIP'
- 'af6595efd698e61b69297207918c8fc4679c42226656d5a31725d870bb436a87')
+ 'a7a19439e211cd96f63273c9cf5a8dbfa7385b02e4143e67a0992551c1297a73')
validpgpkeys=(CA262C6C83DE4D2FB28A332A3A6A4DB839EAA6D7) # Albert Astals Cid <aacid@kde.org>
prepare() {
diff --git a/libre/konqueror/libre.patch b/libre/konqueror/libre.patch
index 81251960d..f772c625a 100644
--- a/libre/konqueror/libre.patch
+++ b/libre/konqueror/libre.patch
@@ -20,28 +20,26 @@ index 0b1c8782c..8a822fcf8 100644
add_subdirectory( about )
add_subdirectory( pics )
diff --git a/about/konq_aboutpage.cpp b/about/konq_aboutpage.cpp
-index 017875809..fc95efa89 100644
+index 017875809..86d8f0d4c 100644
--- a/about/konq_aboutpage.cpp
+++ b/about/konq_aboutpage.cpp
-@@ -219,14 +219,11 @@ QString KonqAboutPageSingleton::specs()
+@@ -219,13 +219,10 @@ QString KonqAboutPageSingleton::specs()
QStringLiteral("http://www.ecma-international.org/publications/standards/ECMA-262.HTM")))
.arg(i18n("JavaScript disabled (globally). Enable JavaScript <A HREF=\"%1\">here</A>.", QStringLiteral("exec:/kcmshell5 khtml_java_js")))
.arg(i18n("JavaScript enabled (globally). Configure JavaScript <A HREF=\\\"%1\\\">here</A>.", QStringLiteral("exec:/kcmshell5 khtml_java_js"))) // leave the double backslashes here, they are necessary for javascript !
- .arg(i18n("Secure <A HREF=\"%1\">Java</A><SUP>&reg;</SUP> support", QStringLiteral("http://www.oracle.com/technetwork/java/index.html")))
- .arg(i18n("JDK 1.2.0 (Java 2) compatible VM (<A HREF=\"%1\">IBM</A> or <A HREF=\"%2\">Sun/Oracle</A>)",
- QStringLiteral("http://www.ibm.com"), QStringLiteral("http://www.oracle.com/technetwork/java/index.html")))
-+ .arg(i18n("Secure Java<SUP>&reg;</SUP> support"),
-+ QStringLiteral("about:plugins"))
++ .arg(i18n("Secure Java support"))
++ .arg(i18n("JDK 1.2.0 (Java 2) compatible VM"))
.arg(i18n("Enable Java (globally) <A HREF=\"%1\">here</A>.", QStringLiteral("exec:/kcmshell5 khtml_java_js"))) // TODO Maybe test if Java is enabled ?
- .arg(i18n("Netscape Communicator<SUP>&reg;</SUP> <A HREF=\"%4\">plugins</A> (for viewing <A HREF=\"%1\">Flash<SUP>&reg;</SUP></A>, <A HREF=\"%2\">Real<SUP>&reg;</SUP></A>Audio, <A HREF=\"%3\">Real<SUP>&reg;</SUP></A>Video, etc.)",
- QStringLiteral("http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash"),
- QStringLiteral("http://www.real.com"), QStringLiteral("http://www.real.com"),
-- QStringLiteral("about:plugins")))
-+ .arg(i18n("Netscape Communicator<SUP>&reg;</SUP> <A HREF=\"%1\">plugins</A>"),
-+ QStringLiteral("about:plugins"))
++ .arg(i18n("NPAPI<SUP>&reg;</SUP> <A HREF=\"%1\">plugins</A>",
+ QStringLiteral("about:plugins")))
.arg(i18n("built-in"))
.arg(i18n("Secure Sockets Layer"))
- .arg(i18n("(TLS/SSL v2/3) for secure communications up to 168bit"))
@@ -301,8 +298,8 @@ QString KonqAboutPageSingleton::tips()
.arg(i18n("Tips"))
.arg(i18n("Specifications"))
diff --git a/libre/konqueror/webkit.patch b/libre/konqueror/webkit.patch
new file mode 100644
index 000000000..5bf669235
--- /dev/null
+++ b/libre/konqueror/webkit.patch
@@ -0,0 +1,19659 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 0b1c8782c..8f1da02d1 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -20,7 +20,7 @@ include(ECMSetupVersion)
+ set(KONQUEROR_LIB_VERSION "5.0.97")
+ set(KONQUEROR_VERSION "${KONQUEROR_LIB_VERSION}")
+
+-find_package(Qt5 ${QT_MIN_VERSION} REQUIRED COMPONENTS Core Widgets WebEngineWidgets)
++find_package(Qt5 ${QT_MIN_VERSION} REQUIRED COMPONENTS Core Widgets WebKitWidgets)
+ find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS Parts KCMUtils KHtml KDELibs4Support Archive Crash)
+
+ find_package(KF5 ${KF5_MIN_VERSION} COMPONENTS Activities DocTools) # Optional
+@@ -52,7 +52,7 @@ add_subdirectory( libkonq )
+ add_subdirectory( src )
+ add_subdirectory( client )
+ add_subdirectory( autotests )
+-add_subdirectory( webenginepart )
++add_subdirectory( webkitpart )
+
+ add_subdirectory( about )
+ add_subdirectory( pics )
+diff --git a/about/konq_aboutpage.cpp b/about/konq_aboutpage.cpp
+index 017875809..edfab3b64 100644
+--- a/about/konq_aboutpage.cpp
++++ b/about/konq_aboutpage.cpp
+@@ -219,13 +219,10 @@ QString KonqAboutPageSingleton::specs()
+ QStringLiteral("http://www.ecma-international.org/publications/standards/ECMA-262.HTM")))
+ .arg(i18n("JavaScript disabled (globally). Enable JavaScript <A HREF=\"%1\">here</A>.", QStringLiteral("exec:/kcmshell5 khtml_java_js")))
+ .arg(i18n("JavaScript enabled (globally). Configure JavaScript <A HREF=\\\"%1\\\">here</A>.", QStringLiteral("exec:/kcmshell5 khtml_java_js"))) // leave the double backslashes here, they are necessary for javascript !
+- .arg(i18n("Secure <A HREF=\"%1\">Java</A><SUP>&reg;</SUP> support", QStringLiteral("http://www.oracle.com/technetwork/java/index.html")))
+- .arg(i18n("JDK 1.2.0 (Java 2) compatible VM (<A HREF=\"%1\">IBM</A> or <A HREF=\"%2\">Sun/Oracle</A>)",
+- QStringLiteral("http://www.ibm.com"), QStringLiteral("http://www.oracle.com/technetwork/java/index.html")))
++ .arg(i18n("Secure <A HREF=\"%1\">Java</A><SUP>&reg;</SUP> support"))
++ .arg(i18n("JDK 1.2.0 (Java 2) compatible VM"))
+ .arg(i18n("Enable Java (globally) <A HREF=\"%1\">here</A>.", QStringLiteral("exec:/kcmshell5 khtml_java_js"))) // TODO Maybe test if Java is enabled ?
+- .arg(i18n("Netscape Communicator<SUP>&reg;</SUP> <A HREF=\"%4\">plugins</A> (for viewing <A HREF=\"%1\">Flash<SUP>&reg;</SUP></A>, <A HREF=\"%2\">Real<SUP>&reg;</SUP></A>Audio, <A HREF=\"%3\">Real<SUP>&reg;</SUP></A>Video, etc.)",
+- QStringLiteral("http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash"),
+- QStringLiteral("http://www.real.com"), QStringLiteral("http://www.real.com"),
++ .arg(i18n("NPAPI<SUP>&reg;</SUP> <A HREF=\"%4\">plugins</A>",
+ QStringLiteral("about:plugins")))
+ .arg(i18n("built-in"))
+ .arg(i18n("Secure Sockets Layer"))
+@@ -301,8 +298,8 @@ QString KonqAboutPageSingleton::tips()
+ .arg(i18n("Tips"))
+ .arg(i18n("Specifications"))
+ .arg(i18n("Tips & Tricks"))
+- .arg(i18n("Use Web-Shortcuts: by typing \"gg: KDE\" one can search the Internet, "
+- "using Google, for the search phrase \"KDE\". There are a lot of "
++ .arg(i18n("Use Web-Shortcuts: by typing \"dd: KDE\" one can search the Internet, "
++ "using DuckDuckGo HTML, for the search phrase \"KDE\". There are a lot of "
+ "Web-Shortcuts predefined to make searching for software or looking "
+ "up certain words in an encyclopedia a breeze. You can even "
+ "<a href=\"%1\">create your own</a> Web-Shortcuts.", QStringLiteral("exec:/kcmshell5 webshortcuts")))
+diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt
+index 09c1a28e9..590aea85d 100644
+--- a/autotests/CMakeLists.txt
++++ b/autotests/CMakeLists.txt
+@@ -12,7 +12,7 @@ add_test(konqviewmgrtest konqviewmgrtest)
+ ecm_mark_as_test(konqviewmgrtest)
+ target_link_libraries(konqviewmgrtest kdeinit_konqueror Qt5::Core Qt5::Gui
+ # KF5::KHtml
+- kwebenginepartlib Qt5::WebEngineWidgets Qt5::Test)
++ kwebkitpartlib Qt5::WebKitWidgets Qt5::Test)
+
+ ########### historymanagertest ###############
+
+@@ -33,7 +33,7 @@ target_link_libraries(undomanagertest kdeinit_konqueror Qt5::Core Qt5::Test)
+ add_executable(konqhtmltest konqhtmltest.cpp)
+ add_test(konqhtmltest konqhtmltest)
+ ecm_mark_as_test(konqhtmltest)
+-target_link_libraries(konqhtmltest kdeinit_konqueror kwebenginepartlib Qt5::Core Qt5::Test)
++target_link_libraries(konqhtmltest kdeinit_konqueror kwebkitpartlib Qt5::Core Qt5::Test)
+
+ ########### konqviewtest ###############
+
+diff --git a/autotests/konqhtmltest.cpp b/autotests/konqhtmltest.cpp
+index b893e704e..e43b735d2 100644
+--- a/autotests/konqhtmltest.cpp
++++ b/autotests/konqhtmltest.cpp
+@@ -23,8 +23,8 @@
+ #include <konqview.h>
+ #include <konqsessionmanager.h>
+
+-#include <webenginepart.h>
+-#include <webengineview.h>
++#include <webkitpart.h>
++#include <webkitview.h>
+
+ #include <KSharedConfig>
+ #include <kstandarddirs.h>
+@@ -50,14 +50,14 @@ private Q_SLOTS:
+ KonqSessionManager::self()->disableAutosave();
+ //qRegisterMetaType<KonqView *>("KonqView*");
+
+- // Ensure the tests use webenginepart, not KHTML or kwebkitpart
++ // Ensure the tests use webkitpart, not KHTML or kwebkitpart
+ // This code is inspired by settings/konqhtml/generalopts.cpp
+ bool needsUpdate = false;
+ KSharedConfig::Ptr profile = KSharedConfig::openConfig(QStringLiteral("mimeapps.list"), KConfig::NoGlobals, QStandardPaths::ApplicationsLocation);
+ KConfigGroup addedServices(profile, "Added KDE Service Associations");
+ Q_FOREACH (const QString &mimeType, QStringList() << "text/html" << "application/xhtml+xml" << "application/xml") {
+ QStringList services = addedServices.readXdgListEntry(mimeType);
+- const QString wanted = QStringLiteral("webenginepart.desktop");
++ const QString wanted = QStringLiteral("webkitpart.desktop");
+ if (services.isEmpty() || services.at(0) != wanted) {
+ services.removeAll(wanted);
+ services.prepend(wanted); // make it the preferred one
+@@ -87,7 +87,7 @@ private Q_SLOTS:
+ QSignalSpy spyCompleted(view, SIGNAL(viewCompleted(KonqView*)));
+ QVERIFY(spyCompleted.wait(20000));
+ QCOMPARE(view->serviceType(), QString("text/html"));
+- WebEnginePart* part = qobject_cast<WebEnginePart *>(view->part());
++ WebKitPart* part = qobject_cast<WebKitPart *>(view->part());
+ QVERIFY(part);
+ }
+
+@@ -105,7 +105,7 @@ private Q_SLOTS:
+ QVERIFY(spyCompleted.wait(20000)); // which then opens the right part
+ QCOMPARE(view->serviceType(), QString("inode/directory"));
+ } else {
+- // WebEngine can actually list directories, no error.
++ // WebKit can actually list directories, no error.
+ // To test this: konqueror --mimetype text/html $HOME
+ QCOMPARE(view->url().adjusted(QUrl::StripTrailingSlash), url);
+ }
+@@ -181,9 +181,9 @@ private Q_SLOTS:
+ KonqFrame *frame = newWindow->currentView()->frame();
+ QVERIFY(frame);
+ QVERIFY(!frame->childView()->isLoading());
+- WebEnginePart *part = qobject_cast<WebEnginePart *>(frame->part());
++ WebKitPart *part = qobject_cast<WebKitPart *>(frame->part());
+ QVERIFY(part);
+- QTRY_VERIFY(!part->view()->url().isEmpty()); // hack to wait for webengine to load the page
++ QTRY_VERIFY(!part->view()->url().isEmpty()); // hack to wait for webkit to load the page
+ QTRY_COMPARE(part->view()->title(), QString("Opener=[object Window]"));
+ deleteAllMainWindows();
+ }
+@@ -210,14 +210,14 @@ private:
+ static QWidget *partWidget(KonqView *view)
+ {
+ QWidget *widget = view->part()->widget();
+- WebEnginePart *htmlPart = qobject_cast<WebEnginePart *>(view->part());
++ WebKitPart *htmlPart = qobject_cast<WebKitPart *>(view->part());
+ if (htmlPart) {
+ widget = htmlPart->view(); // khtmlview != widget() nowadays, due to find bar
+ }
+ if (QScrollArea *scrollArea = qobject_cast<QScrollArea *>(widget)) {
+ widget = scrollArea->widget();
+ }
+- if (widget && widget->focusProxy()) { // for WebEngine's RenderWidgetHostViewQtDelegateWidget
++ if (widget && widget->focusProxy()) { // for WebKit's RenderWidgetHostViewQtDelegateWidget
+ return widget->focusProxy();
+ }
+ return widget;
+diff --git a/autotests/konqviewmgrtest.cpp b/autotests/konqviewmgrtest.cpp
+index c1ac0fc05..b68c21190 100644
+--- a/autotests/konqviewmgrtest.cpp
++++ b/autotests/konqviewmgrtest.cpp
+@@ -45,9 +45,9 @@
+ #include <khtml_part.h>
+ #include <khtmlview.h>
+ #else
+-#include <webenginepart.h>
+-#include <webengineview.h>
+-#include "../webenginepart/autotests/webengine_testutils.h"
++#include <webkitpart.h>
++#include <webkitview.h>
++#include "../webkitpart/autotests/webkit_testutils.h"
+ #endif
+
+ #include <QStandardPaths>
+@@ -81,7 +81,7 @@ static QWidget *partWidget(KonqView *view)
+ #ifdef TEST_KHTML
+ KHTMLPart *htmlPart = qobject_cast<KHTMLPart *>(view->part());
+ #else
+- WebEnginePart *htmlPart = qobject_cast<WebEnginePart *>(view->part());
++ WebKitPart *htmlPart = qobject_cast<WebKitPart *>(view->part());
+ #endif
+ if (htmlPart) {
+ widget = htmlPart->view(); // khtmlview != widget() nowadays, due to find bar
+@@ -89,7 +89,7 @@ static QWidget *partWidget(KonqView *view)
+ if (QScrollArea *scrollArea = qobject_cast<QScrollArea *>(widget)) {
+ widget = scrollArea->widget();
+ }
+- if (widget && widget->focusProxy()) { // for WebEngine's RenderWidgetHostViewQtDelegateWidget
++ if (widget && widget->focusProxy()) { // for WebKit's RenderWidgetHostViewQtDelegateWidget
+ return widget->focusProxy();
+ }
+ return widget;
+@@ -192,7 +192,7 @@ void ViewMgrTest::initTestCase()
+ QCOMPARE(KonqSettings::mmbOpensTab(), true);
+ QCOMPARE(KonqSettings::popupsWithinTabs(), false);
+
+- // Ensure the tests use webenginepart (not khtml or webkit)
++ // Ensure the tests use webkitpart (not khtml or webkit)
+ // This code is inspired by settings/konqhtml/generalopts.cpp
+ KSharedConfig::Ptr profile = KSharedConfig::openConfig(QStringLiteral("mimeapps.list"), KConfig::NoGlobals, QStandardPaths::ApplicationsLocation);
+ KConfigGroup addedServices(profile, "Added KDE Service Associations");
+@@ -202,7 +202,7 @@ void ViewMgrTest::initTestCase()
+ #ifdef TEST_KHTML
+ const QString wanted = "khtml.desktop";
+ #else
+- const QString wanted = QStringLiteral("webenginepart.desktop");
++ const QString wanted = QStringLiteral("webkitpart.desktop");
+ #endif
+ if (services.isEmpty() || services.at(0) != wanted) {
+ services.removeAll(wanted);
+@@ -434,7 +434,7 @@ void ViewMgrTest::testLinkedViews()
+ MyKonqMainWindow mainWindow;
+ openHtmlWithLink(mainWindow);
+ KonqView *view = mainWindow.currentView();
+- WebEnginePart *part = qobject_cast<WebEnginePart *>(view->part());
++ WebKitPart *part = qobject_cast<WebKitPart *>(view->part());
+ QVERIFY(part);
+ // Split it
+ qDebug() << "SPLITTING";
+diff --git a/doc/konqueror/index.docbook b/doc/konqueror/index.docbook
+index 05bed1fc0..4f9313758 100644
+--- a/doc/konqueror/index.docbook
++++ b/doc/konqueror/index.docbook
+@@ -2244,7 +2244,7 @@ playground/utils
+ Extensions...</guimenuitem></menuchoice> to open a dialog with all installed plugins and select
+ the ones you need. All plugins are accessible in the <guimenu>Tools</guimenu> menu.</para>
+
+-<para>Only plugins appropriate for the current mode (file manager or browser in KHTML/WebEngine view)
++<para>Only plugins appropriate for the current mode (file manager or browser in KHTML/WebKit view)
+ are listed in the dialog.</para>
+
+ <variablelist>
+@@ -2254,7 +2254,7 @@ FIXME 16.12
+ KHTML: Auto Refresh, HTML Settings, Minitools-Bookmarklets, Translate (disabled), DOM Tree Viewer, Document Relations, Web Archiver, Website Validators, Search Bar
+ kwebkitpart for kf5 in extragear/base in branch frameworks
+ WebKit only HTML Settings and Translate (disabled)
+-WebEngine -> no extensions
++WebKit -> no extensions
+ -->
+ <varlistentry> <!-- disabled here, why?-->
+ <term>Web Page Translation</term>
+@@ -3406,7 +3406,7 @@ in the text or &HTML; page.</para></listitem>
+ <guisubmenu>View Mode</guisubmenu>
+ </menuchoice></term>
+ <listitem><para>In browser mode this submenu holds items to select embedded
+-views like <guimenuitem>KHTML</guimenuitem>, <guimenuitem>WebEngine</guimenuitem>, <guimenuitem>Embedded Advanced
++views like <guimenuitem>KHTML</guimenuitem>, <guimenuitem>WebKit</guimenuitem>, <guimenuitem>Embedded Advanced
+ Text Editor</guimenuitem> and more embedded views.</para>
+ <para>In file manager mode this submenu holds items to select <guimenuitem>Icon</guimenuitem>,
+ <guimenuitem>Details</guimenuitem>, <guimenuitem>Compact</guimenuitem>,
+@@ -3495,7 +3495,7 @@ page.</para>
+ <guimenu>View</guimenu>
+ <guimenuitem>Zoom In</guimenuitem> <guimenuitem>Zoom Out</guimenuitem>
+ <guimenuitem>Actual Size</guimenuitem> <guimenuitem>Zoom Text Only</guimenuitem>
+-<guimenuitem>Zoom To DPI</guimenuitem></menuchoice> (Browser mode - WebEngine view)</term>
++<guimenuitem>Zoom To DPI</guimenuitem></menuchoice> (Browser mode - WebKit view)</term>
+ <listitem><para>These menuitems offer different actions to modify the size of the items
+ in the page.</para>
+ </listitem>
+diff --git a/settings/konqhtml/generalopts.cpp b/settings/konqhtml/generalopts.cpp
+index 36cb14388..3298adc3d 100644
+--- a/settings/konqhtml/generalopts.cpp
++++ b/settings/konqhtml/generalopts.cpp
+@@ -126,12 +126,12 @@ void KKonqGeneralOptions::addHomeUrlWidgets(QVBoxLayout *lay)
+
+ QLabel *webLabel = new QLabel(i18n("Default web browser engine:"), this);
+
+- m_webEngineCombo = new QComboBox(this);
+- m_webEngineCombo->setEditable(false);
+- m_webEngineCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents);
+- formLayout->addRow(webLabel, m_webEngineCombo);
+- webLabel->setBuddy(m_webEngineCombo);
+- connect(m_webEngineCombo, SIGNAL(currentIndexChanged(int)), SLOT(slotChanged()));
++ m_webCombo = new QComboBox(this);
++ m_webCombo->setEditable(false);
++ m_webCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents);
++ formLayout->addRow(webLabel, m_webCombo);
++ webLabel->setBuddy(m_webCombo);
++ connect(m_webCombo, SIGNAL(currentIndexChanged(int)), SLOT(slotChanged()));
+ }
+
+ KKonqGeneralOptions::~KKonqGeneralOptions()
+@@ -180,7 +180,7 @@ void KKonqGeneralOptions::load()
+ Q_ASSERT(startComboIndex != -1);
+ m_startCombo->setCurrentIndex(startComboIndex);
+
+- m_webEngineCombo->clear();
++ m_webCombo->clear();
+ // ## Well, the problem with using the trader to find the available parts, is that if a user
+ // removed a part in keditfiletype text/html, it won't be in the list anymore. Oh well.
+ const KService::List partOfferList = KMimeTypeTrader::self()->query(QStringLiteral("text/html"), QStringLiteral("KParts/ReadOnlyPart"), QStringLiteral("not ('KParts/ReadWritePart' in ServiceTypes)"));
+@@ -189,7 +189,7 @@ void KKonqGeneralOptions::load()
+ // We want only the HTML-capable parts, not any text/plain part (via inheritance)
+ // This is a small "private inheritance" hack, pending a more general solution
+ if (!partService->hasMimeType(QStringLiteral("text/plain"))) {
+- m_webEngineCombo->addItem(QIcon::fromTheme(partService->icon()), partService->name(),
++ m_webCombo->addItem(QIcon::fromTheme(partService->icon()), partService->name(),
+ QVariant(partService->storageId()));
+ }
+ }
+@@ -234,17 +234,17 @@ void KKonqGeneralOptions::save()
+ userSettings.writeEntry("StartURL", startUrl);
+ userSettings.writeEntry("HomeURL", homeURL->text());
+
+- if (m_webEngineCombo->currentIndex() > 0) {
++ if (m_webCombo->currentIndex() > 0) {
+ // The user changed the preferred web engine, save into mimeapps.list.
+- const QString preferredWebEngine = m_webEngineCombo->itemData(m_webEngineCombo->currentIndex()).toString();
+- //qDebug() << "preferredWebEngine=" << preferredWebEngine;
++ const QString preferredWebKit = m_webCombo->itemData(m_webCombo->currentIndex()).toString();
++ //qDebug() << "preferredWebKit=" << preferredWebKit;
+
+ KSharedConfig::Ptr profile = KSharedConfig::openConfig("mimeapps.list", KConfig::NoGlobals, QStandardPaths::ConfigLocation);
+ KConfigGroup addedServices(profile, "Added KDE Service Associations");
+ Q_FOREACH (const QString &mimeType, QStringList() << "text/html" << "application/xhtml+xml" << "application/xml") {
+ QStringList services = addedServices.readXdgListEntry(mimeType);
+- services.removeAll(preferredWebEngine);
+- services.prepend(preferredWebEngine); // make it the preferred one
++ services.removeAll(preferredWebKit);
++ services.prepend(preferredWebKit); // make it the preferred one
+ addedServices.writeXdgListEntry(mimeType, services);
+ }
+ profile->sync();
+diff --git a/settings/konqhtml/generalopts.h b/settings/konqhtml/generalopts.h
+index 066d02c81..838483c54 100644
+--- a/settings/konqhtml/generalopts.h
++++ b/settings/konqhtml/generalopts.h
+@@ -41,7 +41,7 @@ private:
+ QComboBox *m_startCombo;
+ QLineEdit *homeURL;
+ QLineEdit *startURL;
+- QComboBox *m_webEngineCombo;
++ QComboBox *m_webCombo;
+ Ui_advancedTabOptions *tabOptions;
+ };
+
+diff --git a/src/konqmain.cpp b/src/konqmain.cpp
+index 73c6a2f88..413bf5061 100644
+--- a/src/konqmain.cpp
++++ b/src/konqmain.cpp
+@@ -58,7 +58,7 @@ static KonqPreloadingHandler s_preloadingHandler;
+
+ extern "C" Q_DECL_EXPORT int kdemain(int argc, char **argv)
+ {
+- QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); // says QtWebEngine
++ QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); // says QtWebKit
+ KonquerorApplication app(argc, argv);
+ KLocalizedString::setApplicationDomain("konqueror");
+
+diff --git a/webenginepart/CMakeLists.txt a/webenginepart/CMakeLists.txt
+deleted file mode 100644
+index b62735e8b..000000000
+--- a/webenginepart/CMakeLists.txt
++++ /dev/null
+@@ -1,4 +0,0 @@
+-add_subdirectory(icons)
+-add_subdirectory(src)
+-add_subdirectory(tests)
+-add_subdirectory(autotests)
+diff --git a/webenginepart/COPYING.LIB a/webenginepart/COPYING.LIB
+deleted file mode 100644
+index 01148ab6f..000000000
+--- a/webenginepart/COPYING.LIB
++++ /dev/null
+@@ -1,486 +0,0 @@
+-NOTE! The LGPL below is copyrighted by the Free Software Foundation, but
+-the instance of code that it refers to (the kde libraries) are copyrighted
+-by the authors who actually wrote it.
+-
+----------------------------------------------------------------------------
+- GNU LIBRARY GENERAL PUBLIC LICENSE
+- Version 2, June 1991
+-
+- Copyright (C) 1991 Free Software Foundation, Inc.
+- 51 Franklin Street, Fifth Floor
+- Boston, MA 02110-1301, USA.
+- Everyone is permitted to copy and distribute verbatim copies
+- of this license document, but changing it is not allowed.
+-
+-[This is the first released version of the library GPL. It is
+- numbered 2 because it goes with version 2 of the ordinary GPL.]
+-
+- Preamble
+-
+- The licenses for most software are designed to take away your
+-freedom to share and change it. By contrast, the GNU General Public
+-Licenses are intended to guarantee your freedom to share and change
+-free software--to make sure the software is free for all its users.
+-
+- This license, the Library General Public License, applies to some
+-specially designated Free Software Foundation software, and to any
+-other libraries whose authors decide to use it. You can use it for
+-your libraries, too.
+-
+- When we speak of free software, we are referring to freedom, not
+-price. Our General Public Licenses are designed to make sure that you
+-have the freedom to distribute copies of free software (and charge for
+-this service if you wish), that you receive source code or can get it
+-if you want it, that you can change the software or use pieces of it
+-in new free programs; and that you know you can do these things.
+-
+- To protect your rights, we need to make restrictions that forbid
+-anyone to deny you these rights or to ask you to surrender the rights.
+-These restrictions translate to certain responsibilities for you if
+-you distribute copies of the library, or if you modify it.
+-
+- For example, if you distribute copies of the library, whether gratis
+-or for a fee, you must give the recipients all the rights that we gave
+-you. You must make sure that they, too, receive or can get the source
+-code. If you link a program with the library, you must provide
+-complete object files to the recipients so that they can relink them
+-with the library, after making changes to the library and recompiling
+-it. And you must show them these terms so they know their rights.
+-
+- Our method of protecting your rights has two steps: (1) copyright
+-the library, and (2) offer you this license which gives you legal
+-permission to copy, distribute and/or modify the library.
+-
+- Also, for each distributor's protection, we want to make certain
+-that everyone understands that there is no warranty for this free
+-library. If the library is modified by someone else and passed on, we
+-want its recipients to know that what they have is not the original
+-version, so that any problems introduced by others will not reflect on
+-the original authors' reputations.
+-
+- Finally, any free program is threatened constantly by software
+-patents. We wish to avoid the danger that companies distributing free
+-software will individually obtain patent licenses, thus in effect
+-transforming the program into proprietary software. To prevent this,
+-we have made it clear that any patent must be licensed for everyone's
+-free use or not licensed at all.
+-
+- Most GNU software, including some libraries, is covered by the ordinary
+-GNU General Public License, which was designed for utility programs. This
+-license, the GNU Library General Public License, applies to certain
+-designated libraries. This license is quite different from the ordinary
+-one; be sure to read it in full, and don't assume that anything in it is
+-the same as in the ordinary license.
+-
+- The reason we have a separate public license for some libraries is that
+-they blur the distinction we usually make between modifying or adding to a
+-program and simply using it. Linking a program with a library, without
+-changing the library, is in some sense simply using the library, and is
+-analogous to running a utility program or application program. However, in
+-a textual and legal sense, the linked executable is a combined work, a
+-derivative of the original library, and the ordinary General Public License
+-treats it as such.
+-
+- Because of this blurred distinction, using the ordinary General
+-Public License for libraries did not effectively promote software
+-sharing, because most developers did not use the libraries. We
+-concluded that weaker conditions might promote sharing better.
+-
+- However, unrestricted linking of non-free programs would deprive the
+-users of those programs of all benefit from the free status of the
+-libraries themselves. This Library General Public License is intended to
+-permit developers of non-free programs to use free libraries, while
+-preserving your freedom as a user of such programs to change the free
+-libraries that are incorporated in them. (We have not seen how to achieve
+-this as regards changes in header files, but we have achieved it as regards
+-changes in the actual functions of the Library.) The hope is that this
+-will lead to faster development of free libraries.
+-
+- The precise terms and conditions for copying, distribution and
+-modification follow. Pay close attention to the difference between a
+-"work based on the library" and a "work that uses the library". The
+-former contains code derived from the library, while the latter only
+-works together with the library.
+-
+- Note that it is possible for a library to be covered by the ordinary
+-General Public License rather than by this special one.
+-
+- GNU LIBRARY GENERAL PUBLIC LICENSE
+- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+-
+- 0. This License Agreement applies to any software library which
+-contains a notice placed by the copyright holder or other authorized
+-party saying it may be distributed under the terms of this Library
+-General Public License (also called "this License"). Each licensee is
+-addressed as "you".
+-
+- A "library" means a collection of software functions and/or data
+-prepared so as to be conveniently linked with application programs
+-(which use some of those functions and data) to form executables.
+-
+- The "Library", below, refers to any such software library or work
+-which has been distributed under these terms. A "work based on the
+-Library" means either the Library or any derivative work under
+-copyright law: that is to say, a work containing the Library or a
+-portion of it, either verbatim or with modifications and/or translated
+-straightforwardly into another language. (Hereinafter, translation is
+-included without limitation in the term "modification".)
+-
+- "Source code" for a work means the preferred form of the work for
+-making modifications to it. For a library, complete source code means
+-all the source code for all modules it contains, plus any associated
+-interface definition files, plus the scripts used to control compilation
+-and installation of the library.
+-
+- Activities other than copying, distribution and modification are not
+-covered by this License; they are outside its scope. The act of
+-running a program using the Library is not restricted, and output from
+-such a program is covered only if its contents constitute a work based
+-on the Library (independent of the use of the Library in a tool for
+-writing it). Whether that is true depends on what the Library does
+-and what the program that uses the Library does.
+-
+- 1. You may copy and distribute verbatim copies of the Library's
+-complete source code as you receive it, in any medium, provided that
+-you conspicuously and appropriately publish on each copy an
+-appropriate copyright notice and disclaimer of warranty; keep intact
+-all the notices that refer to this License and to the absence of any
+-warranty; and distribute a copy of this License along with the
+-Library.
+-
+- You may charge a fee for the physical act of transferring a copy,
+-and you may at your option offer warranty protection in exchange for a
+-fee.
+-
+- 2. You may modify your copy or copies of the Library or any portion
+-of it, thus forming a work based on the Library, and copy and
+-distribute such modifications or work under the terms of Section 1
+-above, provided that you also meet all of these conditions:
+-
+- a) The modified work must itself be a software library.
+-
+- b) You must cause the files modified to carry prominent notices
+- stating that you changed the files and the date of any change.
+-
+- c) You must cause the whole of the work to be licensed at no
+- charge to all third parties under the terms of this License.
+-
+- d) If a facility in the modified Library refers to a function or a
+- table of data to be supplied by an application program that uses
+- the facility, other than as an argument passed when the facility
+- is invoked, then you must make a good faith effort to ensure that,
+- in the event an application does not supply such function or
+- table, the facility still operates, and performs whatever part of
+- its purpose remains meaningful.
+-
+- (For example, a function in a library to compute square roots has
+- a purpose that is entirely well-defined independent of the
+- application. Therefore, Subsection 2d requires that any
+- application-supplied function or table used by this function must
+- be optional: if the application does not supply it, the square
+- root function must still compute square roots.)
+-
+-These requirements apply to the modified work as a whole. If
+-identifiable sections of that work are not derived from the Library,
+-and can be reasonably considered independent and separate works in
+-themselves, then this License, and its terms, do not apply to those
+-sections when you distribute them as separate works. But when you
+-distribute the same sections as part of a whole which is a work based
+-on the Library, the distribution of the whole must be on the terms of
+-this License, whose permissions for other licensees extend to the
+-entire whole, and thus to each and every part regardless of who wrote
+-it.
+-
+-Thus, it is not the intent of this section to claim rights or contest
+-your rights to work written entirely by you; rather, the intent is to
+-exercise the right to control the distribution of derivative or
+-collective works based on the Library.
+-
+-In addition, mere aggregation of another work not based on the Library
+-with the Library (or with a work based on the Library) on a volume of
+-a storage or distribution medium does not bring the other work under
+-the scope of this License.
+-
+- 3. You may opt to apply the terms of the ordinary GNU General Public
+-License instead of this License to a given copy of the Library. To do
+-this, you must alter all the notices that refer to this License, so
+-that they refer to the ordinary GNU General Public License, version 2,
+-instead of to this License. (If a newer version than version 2 of the
+-ordinary GNU General Public License has appeared, then you can specify
+-that version instead if you wish.) Do not make any other change in
+-these notices.
+-
+- Once this change is made in a given copy, it is irreversible for
+-that copy, so the ordinary GNU General Public License applies to all
+-subsequent copies and derivative works made from that copy.
+-
+- This option is useful when you wish to copy part of the code of
+-the Library into a program that is not a library.
+-
+- 4. You may copy and distribute the Library (or a portion or
+-derivative of it, under Section 2) in object code or executable form
+-under the terms of Sections 1 and 2 above provided that you accompany
+-it with the complete corresponding machine-readable source code, which
+-must be distributed under the terms of Sections 1 and 2 above on a
+-medium customarily used for software interchange.
+-
+- If distribution of object code is made by offering access to copy
+-from a designated place, then offering equivalent access to copy the
+-source code from the same place satisfies the requirement to
+-distribute the source code, even though third parties are not
+-compelled to copy the source along with the object code.
+-
+- 5. A program that contains no derivative of any portion of the
+-Library, but is designed to work with the Library by being compiled or
+-linked with it, is called a "work that uses the Library". Such a
+-work, in isolation, is not a derivative work of the Library, and
+-therefore falls outside the scope of this License.
+-
+- However, linking a "work that uses the Library" with the Library
+-creates an executable that is a derivative of the Library (because it
+-contains portions of the Library), rather than a "work that uses the
+-library". The executable is therefore covered by this License.
+-Section 6 states terms for distribution of such executables.
+-
+- When a "work that uses the Library" uses material from a header file
+-that is part of the Library, the object code for the work may be a
+-derivative work of the Library even though the source code is not.
+-Whether this is true is especially significant if the work can be
+-linked without the Library, or if the work is itself a library. The
+-threshold for this to be true is not precisely defined by law.
+-
+- If such an object file uses only numerical parameters, data
+-structure layouts and accessors, and small macros and small inline
+-functions (ten lines or less in length), then the use of the object
+-file is unrestricted, regardless of whether it is legally a derivative
+-work. (Executables containing this object code plus portions of the
+-Library will still fall under Section 6.)
+-
+- Otherwise, if the work is a derivative of the Library, you may
+-distribute the object code for the work under the terms of Section 6.
+-Any executables containing that work also fall under Section 6,
+-whether or not they are linked directly with the Library itself.
+-
+- 6. As an exception to the Sections above, you may also compile or
+-link a "work that uses the Library" with the Library to produce a
+-work containing portions of the Library, and distribute that work
+-under terms of your choice, provided that the terms permit
+-modification of the work for the customer's own use and reverse
+-engineering for debugging such modifications.
+-
+- You must give prominent notice with each copy of the work that the
+-Library is used in it and that the Library and its use are covered by
+-this License. You must supply a copy of this License. If the work
+-during execution displays copyright notices, you must include the
+-copyright notice for the Library among them, as well as a reference
+-directing the user to the copy of this License. Also, you must do one
+-of these things:
+-
+- a) Accompany the work with the complete corresponding
+- machine-readable source code for the Library including whatever
+- changes were used in the work (which must be distributed under
+- Sections 1 and 2 above); and, if the work is an executable linked
+- with the Library, with the complete machine-readable "work that
+- uses the Library", as object code and/or source code, so that the
+- user can modify the Library and then relink to produce a modified
+- executable containing the modified Library. (It is understood
+- that the user who changes the contents of definitions files in the
+- Library will not necessarily be able to recompile the application
+- to use the modified definitions.)
+-
+- b) Accompany the work with a written offer, valid for at
+- least three years, to give the same user the materials
+- specified in Subsection 6a, above, for a charge no more
+- than the cost of performing this distribution.
+-
+- c) If distribution of the work is made by offering access to copy
+- from a designated place, offer equivalent access to copy the above
+- specified materials from the same place.
+-
+- d) Verify that the user has already received a copy of these
+- materials or that you have already sent this user a copy.
+-
+- For an executable, the required form of the "work that uses the
+-Library" must include any data and utility programs needed for
+-reproducing the executable from it. However, as a special exception,
+-the source code distributed need not include anything that is normally
+-distributed (in either source or binary form) with the major
+-components (compiler, kernel, and so on) of the operating system on
+-which the executable runs, unless that component itself accompanies
+-the executable.
+-
+- It may happen that this requirement contradicts the license
+-restrictions of other proprietary libraries that do not normally
+-accompany the operating system. Such a contradiction means you cannot
+-use both them and the Library together in an executable that you
+-distribute.
+-
+- 7. You may place library facilities that are a work based on the
+-Library side-by-side in a single library together with other library
+-facilities not covered by this License, and distribute such a combined
+-library, provided that the separate distribution of the work based on
+-the Library and of the other library facilities is otherwise
+-permitted, and provided that you do these two things:
+-
+- a) Accompany the combined library with a copy of the same work
+- based on the Library, uncombined with any other library
+- facilities. This must be distributed under the terms of the
+- Sections above.
+-
+- b) Give prominent notice with the combined library of the fact
+- that part of it is a work based on the Library, and explaining
+- where to find the accompanying uncombined form of the same work.
+-
+- 8. You may not copy, modify, sublicense, link with, or distribute
+-the Library except as expressly provided under this License. Any
+-attempt otherwise to copy, modify, sublicense, link with, or
+-distribute the Library is void, and will automatically terminate your
+-rights under this License. However, parties who have received copies,
+-or rights, from you under this License will not have their licenses
+-terminated so long as such parties remain in full compliance.
+-
+- 9. You are not required to accept this License, since you have not
+-signed it. However, nothing else grants you permission to modify or
+-distribute the Library or its derivative works. These actions are
+-prohibited by law if you do not accept this License. Therefore, by
+-modifying or distributing the Library (or any work based on the
+-Library), you indicate your acceptance of this License to do so, and
+-all its terms and conditions for copying, distributing or modifying
+-the Library or works based on it.
+-
+- 10. Each time you redistribute the Library (or any work based on the
+-Library), the recipient automatically receives a license from the
+-original licensor to copy, distribute, link with or modify the Library
+-subject to these terms and conditions. You may not impose any further
+-restrictions on the recipients' exercise of the rights granted herein.
+-You are not responsible for enforcing compliance by third parties to
+-this License.
+-
+- 11. If, as a consequence of a court judgment or allegation of patent
+-infringement or for any other reason (not limited to patent issues),
+-conditions are imposed on you (whether by court order, agreement or
+-otherwise) that contradict the conditions of this License, they do not
+-excuse you from the conditions of this License. If you cannot
+-distribute so as to satisfy simultaneously your obligations under this
+-License and any other pertinent obligations, then as a consequence you
+-may not distribute the Library at all. For example, if a patent
+-license would not permit royalty-free redistribution of the Library by
+-all those who receive copies directly or indirectly through you, then
+-the only way you could satisfy both it and this License would be to
+-refrain entirely from distribution of the Library.
+-
+-If any portion of this section is held invalid or unenforceable under any
+-particular circumstance, the balance of the section is intended to apply,
+-and the section as a whole is intended to apply in other circumstances.
+-
+-It is not the purpose of this section to induce you to infringe any
+-patents or other property right claims or to contest validity of any
+-such claims; this section has the sole purpose of protecting the
+-integrity of the free software distribution system which is
+-implemented by public license practices. Many people have made
+-generous contributions to the wide range of software distributed
+-through that system in reliance on consistent application of that
+-system; it is up to the author/donor to decide if he or she is willing
+-to distribute software through any other system and a licensee cannot
+-impose that choice.
+-
+-This section is intended to make thoroughly clear what is believed to
+-be a consequence of the rest of this License.
+-
+- 12. If the distribution and/or use of the Library is restricted in
+-certain countries either by patents or by copyrighted interfaces, the
+-original copyright holder who places the Library under this License may add
+-an explicit geographical distribution limitation excluding those countries,
+-so that distribution is permitted only in or among countries not thus
+-excluded. In such case, this License incorporates the limitation as if
+-written in the body of this License.
+-
+- 13. The Free Software Foundation may publish revised and/or new
+-versions of the Library General Public License from time to time.
+-Such new versions will be similar in spirit to the present version,
+-but may differ in detail to address new problems or concerns.
+-
+-Each version is given a distinguishing version number. If the Library
+-specifies a version number of this License which applies to it and
+-"any later version", you have the option of following the terms and
+-conditions either of that version or of any later version published by
+-the Free Software Foundation. If the Library does not specify a
+-license version number, you may choose any version ever published by
+-the Free Software Foundation.
+-
+- 14. If you wish to incorporate parts of the Library into other free
+-programs whose distribution conditions are incompatible with these,
+-write to the author to ask for permission. For software which is
+-copyrighted by the Free Software Foundation, write to the Free
+-Software Foundation; we sometimes make exceptions for this. Our
+-decision will be guided by the two goals of preserving the free status
+-of all derivatives of our free software and of promoting the sharing
+-and reuse of software generally.
+-
+- NO WARRANTY
+-
+- 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+-LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+-
+- 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+-DAMAGES.
+-
+- END OF TERMS AND CONDITIONS
+- How to Apply These Terms to Your New Libraries
+-
+- If you develop a new library, and you want it to be of the greatest
+-possible use to the public, we recommend making it free software that
+-everyone can redistribute and change. You can do so by permitting
+-redistribution under these terms (or, alternatively, under the terms of the
+-ordinary General Public License).
+-
+- To apply these terms, attach the following notices to the library. It is
+-safest to attach them to the start of each source file to most effectively
+-convey the exclusion of warranty; and each file should have at least the
+-"copyright" line and a pointer to where the full notice is found.
+-
+- <one line to give the library's name and a brief idea of what it does.>
+- Copyright (C) <year> <name of author>
+-
+- 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 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, write to the Free Software
+- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+-
+-Also add information on how to contact you by electronic and paper mail.
+-
+-You should also get your employer (if you work as a programmer) or your
+-school, if any, to sign a "copyright disclaimer" for the library, if
+-necessary. Here is a sample; alter the names:
+-
+- Yoyodyne, Inc., hereby disclaims all copyright interest in the
+- library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+-
+- <signature of Ty Coon>, 1 April 1990
+- Ty Coon, President of Vice
+-
+-That's all there is to it!
+diff --git a/webenginepart/Mainpage.dox a/webenginepart/Mainpage.dox
+deleted file mode 100644
+index 832196aef..000000000
+--- a/webenginepart/Mainpage.dox
++++ /dev/null
+@@ -1,4 +0,0 @@
+-/** @mainpage
+-*
+-* Main Doxygen page for KWebKitPart.
+-*/
+diff --git a/webenginepart/Messages.sh a/webenginepart/Messages.sh
+deleted file mode 100644
+index 1fea7c2bb..000000000
+--- a/webenginepart/Messages.sh
++++ /dev/null
+@@ -1,4 +0,0 @@
+-#! /usr/bin/env bash
+-$EXTRACTRC `find . -name '*.rc' -or -name '*.ui'` >> rc.cpp || exit 11
+-$XGETTEXT `find . -name '*.cpp' | grep -v '/tests/'` -o $podir/webenginepart.pot
+-rm -f rc.cpp
+diff --git a/webenginepart/README a/webenginepart/README
+deleted file mode 100644
+index f73bfc864..000000000
+--- a/webenginepart/README
++++ /dev/null
+@@ -1,40 +0,0 @@
+-KWebKitPart
+-===========
+-
+-KWebKitPart is a KDE component (KPart) wrapper for QtWebKit. It is intended to
+-allow KPart based KDE applications such as Konqueror to use it in place of other
+-browser engine, such as KHTML, to browse the web in Konqueror.
+-
+-Known limitations and unimplemented features are listed in the following
+-documents:
+-
+-* https://projects.kde.org/projects/kde/kdelibs/repository/revisions/master/entry/kdewebkit/ISSUES
+-* https://projects.kde.org/projects/extragear/base/kwebkitpart/repository/revisions/master/entry/TODO
+-
+-Please report any issues to: https://bugs.kde.org
+-IMPORTANT NOTE: Do not select "konqueror" as product, but "kwebkitpart"!
+-
+-There is also a public mailing list available for support:
+-
+- webkit-devel @ kde.org
+-
+-How to use KWebKitPart in Konqueror
+-===================================
+-
+-You can switch between the different rendering engines:
+-View -> View Mode -> {KHTML, WebKit} (website needs to be open)
+-If WebKit does not show up in Konqueror, run 'kbuildsycoca4' and
+-restart Konqueror. Note that this change does not persist. If you
+-press the reload button or open a new website, it will fall back
+-to the default rendering engine.
+-
+-If you want to set KWebKitPart as default for any website, run:
+-'keditfiletype text/html'
+-and move "WebKit (kwebkitpart)" in the "Embedding" tab to the top.
+-
+-In KDE 4.6 and higher you can choose the default rendering engine
+-in Konqueror's configuration dialog under the "General" section.
+-
+-For more information about this project please see also:
+-http://techbase.kde.org/Projects/WebKit
+-
+diff --git a/webenginepart/TODO a/webenginepart/TODO
+deleted file mode 100644
+index f6ba03459..000000000
+--- a/webenginepart/TODO
++++ /dev/null
+@@ -1,23 +0,0 @@
+-* Proper support for KWebKitPart in the following Konqueror plugins:
+- - adblock This plugin's GUI needs to be changed to use the KPart plugin
+- extensions so that it is not khtml specific. Other than that
+- kwebkitpart supports the ad filtering functionalities supported
+- by khtml.
+-
+-* Add KPartStatusBarExtension support for the following plugins/features:
+- - Popup blocker (non-plugin)
+-
+-* Implement some means of showing information about the webkit rendering engine:
+- - KWebKitPart's version #
+- - QtWebKit's version #
+- - UserAgent string ???
+-
+-* Look through all of Konqueror's web configuration options and make sure we
+- honor all those we possibly can. Here is a non-complete list of features
+- that are either partially implemented or not implemented at all:
+- - Change cursor over links (TODO, QtWebKit ???).
+- - Smooth scrolling support (TODO, QtWebKit ???).
+- - Underline links support (Partial, does not work as intended).
+- - Enable access key navigation with Ctrl key (TODO, QtWebKit ???).
+- - Animations (TODO, QtWebKit ???).
+- - Draw frames around not completely loaded images (TODO, QtWebKit ???).
+diff --git a/webenginepart/autotests/CMakeLists.txt a/webenginepart/autotests/CMakeLists.txt
+deleted file mode 100644
+index 6c9f3b14f..000000000
+--- a/webenginepart/autotests/CMakeLists.txt
++++ /dev/null
+@@ -1,14 +0,0 @@
+-include(ECMAddTests)
+-
+-find_package(Qt5Test ${QT_MIN_VERSION} CONFIG REQUIRED)
+-
+-macro(webenginepart_unit_tests)
+- foreach(_testname ${ARGN})
+- ecm_add_test(${_testname}.cpp TEST_NAME ${_testname}
+- LINK_LIBRARIES kwebenginepartlib Qt5::Test)
+- endforeach()
+-endmacro(webenginepart_unit_tests)
+-
+-webenginepart_unit_tests(
+- webengine_partapi_test
+-)
+diff --git a/webenginepart/autotests/data/hello.html a/webenginepart/autotests/data/hello.html
+deleted file mode 100644
+index e965047ad..000000000
+--- a/webenginepart/autotests/data/hello.html
++++ /dev/null
+@@ -1 +0,0 @@
+-Hello
+diff --git a/webenginepart/autotests/data/page-with-link.html a/webenginepart/autotests/data/page-with-link.html
+deleted file mode 100644
+index df85219d6..000000000
+--- a/webenginepart/autotests/data/page-with-link.html
++++ /dev/null
+@@ -1 +0,0 @@
+-<a href="hello.html" id="linkid">click me</a>
+diff --git a/webenginepart/autotests/webengine_partapi_test.cpp a/webenginepart/autotests/webengine_partapi_test.cpp
+deleted file mode 100644
+index c246536bf..000000000
+--- a/webenginepart/autotests/webengine_partapi_test.cpp
++++ /dev/null
+@@ -1,133 +0,0 @@
+-/*
+- Copyright (c) 2016 David Faure <faure@kde.org>
+-
+- 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 of the License or ( at
+- your option ) version 3 or, at the discretion of KDE e.V. ( which shall
+- act as a proxy as in section 14 of the GPLv3 ), 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 Lesser 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 <webenginepart.h>
+-#include "webengine_testutils.h"
+-
+-#include <KIO/Job>
+-#include <KParts/BrowserExtension>
+-
+-#include <QTest>
+-#include <QObject>
+-#include <QSignalSpy>
+-#include <QWebEngineView>
+-
+-class WebEnginePartApiTest : public QObject
+-{
+- Q_OBJECT
+-private Q_SLOTS:
+- void initTestCase();
+- void shouldHaveBrowserExtension();
+- void shouldEmitStartedAndCompleted();
+- void shouldEmitSetWindowCaption();
+- void shouldEmitOpenUrlNotifyOnClick();
+-
+-};
+-
+-void WebEnginePartApiTest::initTestCase()
+-{
+- qRegisterMetaType<KIO::Job *>(); // for the KParts started signal
+-}
+-
+-void WebEnginePartApiTest::shouldHaveBrowserExtension()
+-{
+- // GIVEN
+- WebEnginePart part;
+-
+- // WHEN
+- KParts::BrowserExtension *ext = KParts::BrowserExtension::childObject(&part);
+-
+- // THEN
+- QVERIFY(ext);
+-}
+-
+-void WebEnginePartApiTest::shouldEmitStartedAndCompleted()
+-{
+- // GIVEN
+- WebEnginePart part;
+- QSignalSpy spyStarted(&part, &KParts::ReadOnlyPart::started);
+- QSignalSpy spyCompleted(&part, SIGNAL(completed(bool)));
+- QSignalSpy spySetWindowCaption(&part, &KParts::ReadOnlyPart::setWindowCaption);
+- KParts::BrowserExtension *ext = KParts::BrowserExtension::childObject(&part);
+- QSignalSpy spyOpenUrlNotify(ext, &KParts::BrowserExtension::openUrlNotify);
+- const QUrl url(QStringLiteral("data:text/html, <p>Hello World</p>"));
+-
+- // WHEN
+- part.openUrl(url);
+-
+- // THEN
+- QVERIFY(spyStarted.wait());
+- QVERIFY(spySetWindowCaption.wait());
+- QCOMPARE(spySetWindowCaption.at(0).at(0).toUrl().toString(), url.toString());
+- QVERIFY(spyCompleted.wait());
+- QVERIFY(!spyCompleted.at(0).at(0).toBool());
+- QVERIFY(spyOpenUrlNotify.isEmpty());
+-}
+-
+-void WebEnginePartApiTest::shouldEmitSetWindowCaption()
+-{
+- // GIVEN
+- WebEnginePart part;
+- QSignalSpy spyStarted(&part, &KParts::ReadOnlyPart::started);
+- QSignalSpy spyCompleted(&part, SIGNAL(completed(bool)));
+- QSignalSpy spySetWindowCaption(&part, &KParts::ReadOnlyPart::setWindowCaption);
+-
+- // WHEN opening a URL with a title tag
+- part.openUrl(QUrl(QStringLiteral("data:text/html, <title>Custom Title</title><p>Hello World</p>")));
+-
+- // THEN
+- QVERIFY(spyStarted.wait());
+- QVERIFY(spyCompleted.wait());
+- QVERIFY(!spyCompleted.at(0).at(0).toBool());
+- QCOMPARE(spySetWindowCaption.count(), 2);
+- QCOMPARE(spySetWindowCaption.at(1).at(0).toUrl().toString(), QStringLiteral("Custom Title"));
+-}
+-
+-void WebEnginePartApiTest::shouldEmitOpenUrlNotifyOnClick()
+-{
+- // GIVEN
+- WebEnginePart part;
+- QSignalSpy spyStarted(&part, &KParts::ReadOnlyPart::started);
+- QSignalSpy spyCompleted(&part, SIGNAL(completed(bool)));
+- QSignalSpy spySetWindowCaption(&part, &KParts::ReadOnlyPart::setWindowCaption);
+- KParts::BrowserExtension *ext = KParts::BrowserExtension::childObject(&part);
+- QSignalSpy spyOpenUrlNotify(ext, &KParts::BrowserExtension::openUrlNotify);
+- const QString file = QFINDTESTDATA("data/page-with-link.html");
+- QVERIFY(!file.isEmpty());
+- const QUrl url = QUrl::fromLocalFile(file);
+- part.openUrl(url);
+- QVERIFY(spyCompleted.wait());
+- QVERIFY(spyOpenUrlNotify.isEmpty());
+- QWebEnginePage *page = part.view()->page();
+- const QPoint pos = elementCenter(page, QStringLiteral("linkid")); // doesn't seem fully correct...
+- part.widget()->show();
+- spyCompleted.clear();
+-
+- // WHEN clicking on the link
+- QTest::mouseClick(part.view()->focusProxy(), Qt::LeftButton, Qt::KeyboardModifiers(), pos);
+-
+- // THEN
+- QVERIFY(spyCompleted.wait());
+- QCOMPARE(spyOpenUrlNotify.count(), 1);
+- QCOMPARE(part.url().fileName(), QStringLiteral("hello.html"));
+-}
+-
+-QTEST_MAIN(WebEnginePartApiTest)
+-#include "webengine_partapi_test.moc"
+diff --git a/webenginepart/autotests/webengine_testutils.h a/webenginepart/autotests/webengine_testutils.h
+deleted file mode 100644
+index 37489847b..000000000
+--- a/webenginepart/autotests/webengine_testutils.h
++++ /dev/null
+@@ -1,108 +0,0 @@
+-/****************************************************************************
+- **
+- ** Copyright (C) 2016 The Qt Company Ltd.
+- ** Contact: https://www.qt.io/licensing/
+- **
+- ** This file is part of the QtWebEngine module of the Qt Toolkit.
+- **
+- ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+- ** Commercial License Usage
+- ** Licensees holding valid commercial Qt licenses may use this file in
+- ** accordance with the commercial license agreement provided with the
+- ** Software or, alternatively, in accordance with the terms contained in
+- ** a written agreement between you and The Qt Company. For licensing terms
+- ** and conditions see https://www.qt.io/terms-conditions. For further
+- ** information use the contact form at https://www.qt.io/contact-us.
+- **
+- ** GNU General Public License Usage
+- ** Alternatively, this file may be used under the terms of the GNU
+- ** General Public License version 3 as published by the Free Software
+- ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+- ** included in the packaging of this file. Please review the following
+- ** information to ensure the GNU General Public License requirements will
+- ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+- **
+- ** $QT_END_LICENSE$
+- **
+- ****************************************************************************/
+-
+-#include <QEventLoop>
+-#include <QTimer>
+-#include <QWebEnginePage>
+-
+-template<typename T, typename R>
+-struct RefWrapper {
+- R &ref;
+- void operator()(const T& result) {
+- ref(result);
+- }
+-};
+-
+-template<typename T>
+-class CallbackSpy {
+-public:
+- CallbackSpy() : called(false) {
+- timeoutTimer.setSingleShot(true);
+- QObject::connect(&timeoutTimer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
+- }
+-
+- T waitForResult() {
+- if (!called) {
+- timeoutTimer.start(10000);
+- eventLoop.exec();
+- }
+- return result;
+- }
+-
+- bool wasCalled() const {
+- return called;
+- }
+-
+- void operator()(const T &result) {
+- this->result = result;
+- called = true;
+- eventLoop.quit();
+- }
+-
+- // Cheap rip-off of boost/std::ref
+- RefWrapper<T, CallbackSpy<T> > ref()
+- {
+- RefWrapper<T, CallbackSpy<T> > wrapper = {*this};
+- return wrapper;
+- }
+-
+-private:
+- Q_DISABLE_COPY(CallbackSpy)
+- bool called;
+- QTimer timeoutTimer;
+- QEventLoop eventLoop;
+- T result;
+-};
+-
+-// taken from the qwebengine unittests
+-static inline QVariant evaluateJavaScriptSync(QWebEnginePage *page, const QString &script)
+-{
+- CallbackSpy<QVariant> spy;
+- page->runJavaScript(script, spy.ref());
+- return spy.waitForResult();
+-}
+-
+-// Taken from QtWebEngine's tst_qwebenginepage.cpp
+-static QPoint elementCenter(QWebEnginePage *page, const QString &id)
+-{
+- QVariantList rectList = evaluateJavaScriptSync(page,
+- "(function(){"
+- "var elem = document.getElementById('" + id + "');"
+- "var rect = elem.getBoundingClientRect();"
+- "return [rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top];"
+- "})()").toList();
+-
+- if (rectList.count() != 4) {
+- qWarning("elementCenter failed.");
+- return QPoint();
+- }
+- const QRect rect(rectList.at(0).toInt(), rectList.at(1).toInt(),
+- rectList.at(2).toInt(), rectList.at(3).toInt());
+- return rect.center();
+-}
+-
+diff --git a/webenginepart/icons/CMakeLists.txt a/webenginepart/icons/CMakeLists.txt
+deleted file mode 100644
+index 4b820aeb3..000000000
+--- a/webenginepart/icons/CMakeLists.txt
++++ /dev/null
+@@ -1,2 +0,0 @@
+-include(ECMInstallIcons)
+-ecm_install_icons(${ICON_INSTALL_DIR})
+diff --git a/webenginepart/icons/webengine.svg a/webenginepart/icons/webengine.svg
+deleted file mode 100644
+index 148d955f9..000000000
+--- a/webenginepart/icons/webengine.svg
++++ /dev/null
+@@ -1,104 +0,0 @@
+-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+-<!-- Created with Inkscape (http://www.inkscape.org/) -->
+-
+-<svg
+- xmlns:dc="http://purl.org/dc/elements/1.1/"
+- xmlns:cc="http://creativecommons.org/ns#"
+- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+- xmlns:svg="http://www.w3.org/2000/svg"
+- xmlns="http://www.w3.org/2000/svg"
+- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+- width="64"
+- height="64"
+- id="svg3360"
+- version="1.1"
+- inkscape:version="0.91 r13725"
+- viewBox="0 0 64 64"
+- sodipodi:docname="webengine.svg"
+- inkscape:export-filename="/home/sune/git/kwebkitpart/icons/hi128-app-webengine.png"
+- inkscape:export-xdpi="180"
+- inkscape:export-ydpi="180">
+- <defs
+- id="defs3362" />
+- <sodipodi:namedview
+- id="base"
+- pagecolor="#ffffff"
+- bordercolor="#666666"
+- borderopacity="1.0"
+- inkscape:pageopacity="0.0"
+- inkscape:pageshadow="2"
+- inkscape:zoom="5.5"
+- inkscape:cx="-5.0909091"
+- inkscape:cy="24.727273"
+- inkscape:current-layer="layer1"
+- showgrid="true"
+- inkscape:document-units="px"
+- inkscape:grid-bbox="true"
+- inkscape:window-width="3200"
+- inkscape:window-height="1685"
+- inkscape:window-x="0"
+- inkscape:window-y="0"
+- inkscape:window-maximized="1" />
+- <metadata
+- id="metadata3365">
+- <rdf:RDF>
+- <cc:Work
+- rdf:about="">
+- <dc:format>image/svg+xml</dc:format>
+- <dc:type
+- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+- <dc:title></dc:title>
+- </cc:Work>
+- </rdf:RDF>
+- </metadata>
+- <g
+- id="layer1"
+- inkscape:label="Layer 1"
+- inkscape:groupmode="layer">
+- <text
+- xml:space="preserve"
+- style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0079b1;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+- x="1.6363635"
+- y="32.545456"
+- id="text3368"
+- sodipodi:linespacing="125%"><tspan
+- sodipodi:role="line"
+- id="tspan3370"
+- x="1.6363635"
+- y="32.545456">W</tspan></text>
+- <text
+- xml:space="preserve"
+- style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#b0009d;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+- x="14.545453"
+- y="46"
+- id="text4172"
+- sodipodi:linespacing="125%"><tspan
+- sodipodi:role="line"
+- id="tspan4174"
+- x="14.545453"
+- y="46">E</tspan></text>
+- <text
+- xml:space="preserve"
+- style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#b0009d;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+- x="39.40696"
+- y="32.398262"
+- id="text4172-3"
+- sodipodi:linespacing="125%"><tspan
+- sodipodi:role="line"
+- id="tspan4174-6"
+- x="39.40696"
+- y="32.398262">E</tspan></text>
+- <text
+- xml:space="preserve"
+- style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#848400;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+- x="28"
+- y="59.818184"
+- id="text4194"
+- sodipodi:linespacing="125%"><tspan
+- sodipodi:role="line"
+- id="tspan4196"
+- x="28"
+- y="59.818184">B</tspan></text>
+- </g>
+-</svg>
+diff --git a/webenginepart/scripts/codingstyle.sh a/webenginepart/scripts/codingstyle.sh
+deleted file mode 100755
+index 1761942d6..000000000
+--- a/webenginepart/scripts/codingstyle.sh
++++ /dev/null
+@@ -1,19 +0,0 @@
+-#!/bin/sh
+-#
+-# Kdelibs coding style is defined in http://techbase.kde.org/Policies/Kdelibs_Coding_Style
+-#
+-
+-PWD=$(pwd)
+-cd $PWD
+-
+-echo "Applying astyle rules..."
+-astyle -v --indent=spaces=4 \
+- --brackets=linux \
+- --indent-labels \
+- --pad=oper --unpad=paren \
+- --one-line=keep-statements \
+- --convert-tabs --indent-preprocessor \
+- `find -type f -name '*.cpp' -or -name '*.h' -or -name '*.cc' | grep -Ev "\./.+/settings/"`
+-
+-echo "Done!"
+-
+diff --git a/webenginepart/scripts/create_release_package.sh a/webenginepart/scripts/create_release_package.sh
+deleted file mode 100755
+index a8694c897..000000000
+--- a/webenginepart/scripts/create_release_package.sh
++++ /dev/null
+@@ -1,16 +0,0 @@
+-#!/bin/sh
+-
+-VERSION=${1}
+-GITREPO=${2}
+-OUTPUTDIR=${3}
+-
+-if [ -z ${VERSION} ] || [ -z {GITREPO} ]; then
+- echo "Usage: `basename ${0}` <VERSION> <GITREPO> [<OUTPUTDIR>]"
+- exit 1
+-fi
+-
+-if [ -z $OUTPUTDIR ] || [ ! -d $OUTPUTDIR ]; then
+- OUTPUTDIR="${PWD}"
+-fi
+-
+-git archive --format=tar --prefix=kwebkitpart-${VERSION}/ ${GITREPO} | bzip2 -9 > ${OUTPUTDIR}/kwebkitpart-${VERSION}.tar.bz2
+diff --git a/webenginepart/src/CMakeLists.txt a/webenginepart/src/CMakeLists.txt
+deleted file mode 100644
+index 1672c6038..000000000
+--- a/webenginepart/src/CMakeLists.txt
++++ /dev/null
+@@ -1,41 +0,0 @@
+-include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_BINARY_DIR})
+-
+-set(kwebenginepartlib_LIB_SRCS
+- webenginepart.cpp
+- webenginepart_ext.cpp
+- webengineview.cpp
+- webenginepage.cpp
+- websslinfo.cpp
+- webhistoryinterface.cpp
+- settings/webenginesettings.cpp
+- settings/webengine_filter.cpp
+- ui/searchbar.cpp
+- ui/passwordbar.cpp
+- ui/featurepermissionbar.cpp
+-)
+-
+-qt5_wrap_ui(kwebenginepartlib_LIB_SRCS
+- ui/searchbar.ui
+-)
+-
+-add_library(kwebenginepartlib ${kwebenginepartlib_LIB_SRCS})
+-
+-generate_export_header(kwebenginepartlib)
+-
+-target_link_libraries(kwebenginepartlib Qt5::Core Qt5::DBus Qt5::Gui Qt5::Widgets Qt5::WebEngineWidgets Qt5::PrintSupport KF5::Parts KF5::SonnetCore)
+-
+-target_include_directories(kwebenginepartlib PUBLIC
+- "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/>"
+-)
+-
+-install(TARGETS kwebenginepartlib ${KF5_INSTALL_TARGETS_DEFAULT_ARGS})
+-
+-add_library(webenginepart MODULE webenginepartfactory.cpp)
+-
+-target_link_libraries(webenginepart kwebenginepartlib)
+-
+-install(TARGETS webenginepart DESTINATION ${KDE_INSTALL_PLUGINDIR}/kf5/parts)
+-
+-install(FILES webenginepart.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
+-
+-install(FILES webenginepart.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/webenginepart)
+diff --git a/webenginepart/src/settings/webengine_filter.cpp a/webenginepart/src/settings/webengine_filter.cpp
+deleted file mode 100644
+index 98f505d60..000000000
+--- a/webenginepart/src/settings/webengine_filter.cpp
++++ /dev/null
+@@ -1,344 +0,0 @@
+-/* This file is part of the KDE project
+-
+- Copyright (C) 2005 Ivor Hewitt <ivor@kde.org>
+- Copyright (C) 2008 Maksim Orlovich <maksim@kde.org>
+- Copyright (C) 2008 Vyacheslav Tokarev <tsjoker@gmail.com>
+-
+- 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 "webengine_filter.h"
+-
+-#include <QHash>
+-#include <QBitArray>
+-
+-// rolling hash parameters
+-#define HASH_P (1997)
+-#define HASH_Q (17509)
+-// HASH_MOD = (HASH_P^7) % HASH_Q
+-#define HASH_MOD (523)
+-
+-
+-using namespace KDEPrivate;
+-
+-// Updateable Multi-String Matcher based on Rabin-Karp's algorithm
+-class StringsMatcher {
+-public:
+- // add filter to matching set
+- void addString(const QString& pattern)
+- {
+- if (pattern.length() < 8) {
+- // handle short string differently
+- shortStringFilters.append(pattern);
+- } else {
+- // use modified Rabin-Karp's algorithm with 8-length string hash
+- // i.e. store hash of first 8 chars in the HashMap for fast look-up
+- stringFilters.append(pattern);
+- int ind = stringFilters.size() - 1;
+- int current = 0;
+-
+- // compute hash using rolling hash
+- // hash for string: x0,x1,x2...xn-1 will be:
+- // (p^(n-1)*x0 + p^(n-2)*x1 + ... + p * xn-2 + xn-1) % q
+- // where p and q some wisely-chosen integers
+- /*for (int k = 0; k < 8; ++k)*/
+- int len = pattern.length();
+- for (int k = len - 8; k < len; ++k)
+- current = (current * HASH_P + pattern[k].unicode()) % HASH_Q;
+-
+- // insert computed hash value into HashMap
+- QHash<int, QVector<int> >::iterator it = stringFiltersHash.find(current + 1);
+- if (it == stringFiltersHash.end()) {
+- QVector<int> list;
+- list.append(ind);
+- stringFiltersHash.insert(current + 1, list);
+- fastLookUp.setBit(current);
+- } else {
+- it->append(ind);
+- }
+- }
+- }
+-
+-
+- // check if string match at least one string from matching set
+- bool isMatched(const QString& str, QString *by = 0) const
+- {
+- // check short strings first
+- for (int i = 0; i < shortStringFilters.size(); ++i) {
+- if (str.contains(shortStringFilters[i]))
+- {
+- if (by != 0) *by = shortStringFilters[i];
+- return true;
+- }
+- }
+-
+- int len = str.length();
+- int k;
+-
+- int current = 0;
+- int next = 0;
+- // compute hash for first 8 characters
+- for (k = 0; k < 8 && k < len; ++k)
+- current = (current * HASH_P + str[k].unicode()) % HASH_Q;
+-
+- QHash<int, QVector<int> >::const_iterator hashEnd = stringFiltersHash.end();
+- // main Rabin-Karp's algorithm loop
+- for (k = 7; k < len; ++k, current = next) {
+- // roll the hash if not at the end
+- // (calculate hash for the next iteration)
+- if (k + 1 < len)
+- next = (HASH_P * ((current + HASH_Q - ((HASH_MOD * str[k - 7].unicode()) % HASH_Q)) % HASH_Q) + str[k + 1].unicode()) % HASH_Q;
+-
+- if (!fastLookUp.testBit(current))
+- continue;
+-
+- // look-up the hash in the HashMap and check all strings
+- QHash<int, QVector<int> >::const_iterator it = stringFiltersHash.find(current + 1);
+-
+- // check possible strings
+- if (it != hashEnd) {
+- for (int j = 0; j < it->size(); ++j) {
+- int index = it->value(j);
+- // check if we got simple string or REs prefix
+- if (index >= 0) {
+- int flen = stringFilters[index].length();
+- if (k - flen + 1 >= 0 && stringFilters[index] == str.midRef(k - flen + 1 , flen))
+- {
+- if (by != 0) *by = stringFilters[index];
+- return true;
+- }
+- } else {
+- index = -index - 1;
+- int flen = rePrefixes[index].length();
+- if (k - 8 + flen < len && rePrefixes[index] == str.midRef(k - 7, flen))
+- {
+- int remStart = k - 7 + flen;
+- QString remainder = QString::fromRawData(str.unicode() + remStart,
+- str.length() - remStart);
+- if (reFilters[index].exactMatch(remainder)) {
+- if (by != 0) *by = rePrefixes[index]+reFilters[index].pattern();
+- return true;
+- }
+- }
+- }
+- }
+- }
+- }
+-
+- return false;
+- }
+-
+- // add filter to matching set with wildcards (*,?) in it
+- void addWildedString(const QString& prefix, const QRegExp& rx)
+- {
+- rePrefixes.append(prefix);
+- reFilters.append(rx);
+- int index = -rePrefixes.size();
+-
+- int current = 0;
+- for (int k = 0; k < 8; ++k)
+- current = (current * HASH_P + prefix[k].unicode()) % HASH_Q;
+-
+- // insert computed hash value into HashMap
+- QHash<int, QVector<int> >::iterator it = stringFiltersHash.find(current + 1);
+- if (it == stringFiltersHash.end()) {
+- QVector<int> list;
+- list.append(index);
+- stringFiltersHash.insert(current + 1, list);
+- fastLookUp.setBit(current);
+- } else {
+- it->append(index);
+- }
+- }
+-
+- void clear()
+- {
+- stringFilters.clear();
+- shortStringFilters.clear();
+- reFilters.clear();
+- rePrefixes.clear();
+- stringFiltersHash.clear();
+- fastLookUp.resize(HASH_Q);
+- fastLookUp.fill(0, 0, HASH_Q);
+- }
+-
+-private:
+- QVector<QString> stringFilters;
+- QVector<QString> shortStringFilters;
+- QVector<QRegExp> reFilters;
+- QVector<QString> rePrefixes;
+- QBitArray fastLookUp;
+-
+- QHash<int, QVector<int> > stringFiltersHash;
+-};
+-
+-
+-// We only want a subset of features of wildcards -- just the
+-// star, so we escape the rest before passing to QRegExp.
+-// The \ is escaped due to a QRegExp bug.
+-// ### we really should rather parse it ourselves, in order to
+-// handle adblock-special things like | and ^ properly.
+-static QRegExp fromAdBlockWildcard(const QString& wcStr) {
+- QRegExp rx;
+- rx.setPatternSyntax(QRegExp::Wildcard);
+-
+- QString out;
+- for (int p = 0; p < wcStr.length(); ++p) {
+- QChar c = wcStr[p];
+- if (c == QLatin1Char('?'))
+- out += QLatin1String("[?]");
+- else if (c == QLatin1Char('['))
+- out += QLatin1String("[[]");
+- else if (c == QLatin1Char('\\'))
+- out += QLatin1String("[\\]");
+- else
+- out += c;
+- }
+-
+- rx.setPattern(out);
+- return rx;
+-}
+-
+-FilterSet::FilterSet()
+- :stringFiltersMatcher(new StringsMatcher)
+-{
+-}
+-
+-FilterSet::~FilterSet()
+-{
+- delete stringFiltersMatcher;
+-}
+-
+-void FilterSet::addFilter(const QString& filterStr)
+-{
+- QString filter = filterStr;
+-
+- /** ignore special lines starting with "[", "!", "&", or "#" or contain "#" (comments or features are not supported by KHTML's AdBlock */
+- QChar firstChar = filter.at(0);
+- if (firstChar == QLatin1Char('[') || firstChar == QLatin1Char('!') || firstChar == QLatin1Char('&') || firstChar == QLatin1Char('#') || filter.contains(QLatin1Char('#')))
+- return;
+-
+- // Strip leading @@
+- int first = 0;
+- int last = filter.length() - 1;
+- if (filter.startsWith(QLatin1String("@@")))
+- first = 2;
+-
+- // Strip options, we ignore them for now.
+- // TODO: Add support for filters with options. See #310230.
+- int dollar = filter.lastIndexOf(QLatin1Char('$'));
+- if (dollar != -1) {
+- return;
+- }
+-
+- // Perhaps nothing left?
+- if (first > last)
+- return;
+-
+- filter = filter.mid(first, last - first + 1);
+-
+- // Is it a regexp filter?
+- if (filter.length()>2 && filter.startsWith(QLatin1Char('/')) && filter.endsWith(QLatin1Char('/')))
+- {
+- QString inside = filter.mid(1, filter.length()-2);
+- QRegExp rx(inside);
+- reFilters.append(rx);
+-// qDebug() << "R:" << inside;
+- }
+- else
+- {
+- // Nope, a wildcard one.
+- // Note: For these, we also need to handle |.
+-
+- // Strip wildcards at the ends
+- first = 0;
+- last = filter.length() - 1;
+-
+- while (first < filter.length() && filter[first] == QLatin1Char('*'))
+- ++first;
+-
+- while (last >= 0 && filter[last] == QLatin1Char('*'))
+- --last;
+-
+- if (first > last)
+- filter = QStringLiteral("*"); // erm... Well, they asked for it.
+- else
+- filter = filter.mid(first, last - first + 1);
+-
+- // Now, do we still have any wildcard stuff left?
+- if (filter.contains(QLatin1String("*")))
+- {
+- // check if we can use RK first (and then check full RE for the rest) for better performance
+- int aPos = filter.indexOf('*');
+- if (aPos < 0)
+- aPos = filter.length();
+- if (aPos > 7) {
+- QRegExp rx = fromAdBlockWildcard(filter.mid(aPos) + QLatin1Char('*'));
+- // We pad the final r.e. with * so we can check for an exact match
+- stringFiltersMatcher->addWildedString(filter.mid(0, aPos), rx);
+- } else {
+- QRegExp rx = fromAdBlockWildcard(filter);
+- reFilters.append(rx);
+- }
+- }
+- else
+- {
+- // Fast path
+- stringFiltersMatcher->addString(filter);
+- }
+- }
+-}
+-
+-bool FilterSet::isUrlMatched(const QString& url)
+-{
+- if (stringFiltersMatcher->isMatched(url))
+- return true;
+-
+- for (int c = 0; c < reFilters.size(); ++c)
+- {
+- if (url.contains(reFilters[c]))
+- return true;
+- }
+-
+- return false;
+-}
+-
+-QString FilterSet::urlMatchedBy(const QString& url)
+-{
+- QString by;
+-
+- if (stringFiltersMatcher->isMatched(url, &by))
+- return by;
+-
+- for (int c = 0; c < reFilters.size(); ++c)
+- {
+- if (url.contains(reFilters[c]))
+- {
+- by = reFilters[c].pattern();
+- break;
+- }
+- }
+-
+- return by;
+-}
+-
+-void FilterSet::clear()
+-{
+- reFilters.clear();
+- stringFiltersMatcher->clear();
+-}
+-
+-// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;
+diff --git a/webenginepart/src/settings/webengine_filter.h a/webenginepart/src/settings/webengine_filter.h
+deleted file mode 100644
+index 2c908a478..000000000
+--- a/webenginepart/src/settings/webengine_filter.h
++++ /dev/null
+@@ -1,60 +0,0 @@
+-/* This file is part of the KDE project
+-
+- Copyright (C) 2005 Ivor Hewitt <ivor@kde.org>
+- Copyright (C) 2008 Maksim Orlovich <maksim@kde.org>
+- Copyright (C) 2008 Vyacheslav Tokarev <tsjoker@gmail.com>
+-
+- 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.
+-*/
+-
+-#ifndef WEBENGNINE_FILTER_P_H
+-#define WEBENGNINE_FILTER_P_H
+-
+-#include <QString>
+-#include <QRegExp>
+-#include <QVector>
+-#include <webenginepart.h>
+-
+-class StringsMatcher;
+-
+-namespace KDEPrivate
+-{
+-// This represents a set of filters that may match URLs.
+-// Currently it supports a subset of AddBlock Plus functionality.
+-class FilterSet {
+-public:
+- FilterSet();
+- ~FilterSet();
+-
+- // Parses and registers a filter. This will also strip @@ for exclusion rules, skip comments, etc.
+- // The user does have to split black and white lists into separate sets, however
+- void addFilter(const QString& filter);
+-
+- bool isUrlMatched(const QString& url);
+- QString urlMatchedBy(const QString& url);
+-
+- void clear();
+-
+-private:
+- QVector<QRegExp> reFilters;
+- StringsMatcher* stringFiltersMatcher;
+-};
+-
+-}
+-
+-#endif // WEBENGINE_FILTER_P_H
+-
+-// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;
+diff --git a/webenginepart/src/settings/webenginesettings.cpp a/webenginepart/src/settings/webenginesettings.cpp
+deleted file mode 100644
+index d159d29c0..000000000
+--- a/webenginepart/src/settings/webenginesettings.cpp
++++ /dev/null
+@@ -1,1276 +0,0 @@
+-/* This file is part of the KDE project
+- Copyright (C) 1999 David Faure <faure@kde.org>
+-
+- 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 "webenginesettings.h"
+-
+-#include "webengine_filter.h"
+-
+-#include <KConfig>
+-#include <KSharedConfig>
+-#include <KLocalizedString>
+-#include <KConfigGroup>
+-#include <KJob>
+-#include <KIO/Job>
+-#include <KMessageBox>
+-
+-#include <QtWebEngineWidgets/QWebEngineSettings>
+-#include <QFontDatabase>
+-#include <QFileInfo>
+-
+-// browser window color defaults -- Bernd
+-#define HTML_DEFAULT_LNK_COLOR Qt::blue
+-#define HTML_DEFAULT_TXT_COLOR Qt::black
+-#define HTML_DEFAULT_VLNK_COLOR Qt::magenta
+-#define HTML_DEFAULT_BASE_COLOR Qt::white
+-
+-#define HTML_DEFAULT_VIEW_FONT "Sans Serif"
+-#define HTML_DEFAULT_VIEW_FIXED_FONT "Monospace"
+-#define HTML_DEFAULT_VIEW_SERIF_FONT "Serif"
+-#define HTML_DEFAULT_VIEW_SANSSERIF_FONT "Sans Serif"
+-#define HTML_DEFAULT_VIEW_CURSIVE_FONT "Sans Serif"
+-#define HTML_DEFAULT_VIEW_FANTASY_FONT "Sans Serif"
+-#define HTML_DEFAULT_MIN_FONT_SIZE 7 // everything smaller is usually unreadable.
+-
+-/**
+- * @internal
+- * Contains all settings which are both available globally and per-domain
+- */
+-struct KPerDomainSettings {
+- bool m_bEnableJava : 1;
+- bool m_bEnableJavaScript : 1;
+- bool m_bEnablePlugins : 1;
+- // don't forget to maintain the bitfields as the enums grow
+- KParts::HtmlSettingsInterface::JSWindowOpenPolicy m_windowOpenPolicy : 2;
+- KParts::HtmlSettingsInterface::JSWindowStatusPolicy m_windowStatusPolicy : 1;
+- KParts::HtmlSettingsInterface::JSWindowFocusPolicy m_windowFocusPolicy : 1;
+- KParts::HtmlSettingsInterface::JSWindowMovePolicy m_windowMovePolicy : 1;
+- KParts::HtmlSettingsInterface::JSWindowResizePolicy m_windowResizePolicy : 1;
+-
+-#ifdef DEBUG_SETTINGS
+- void dump(const QString &infix = QString()) const {
+- kDebug() << "KPerDomainSettings " << infix << " @" << this << ":";
+- kDebug() << " m_bEnableJava: " << m_bEnableJava;
+- kDebug() << " m_bEnableJavaScript: " << m_bEnableJavaScript;
+- kDebug() << " m_bEnablePlugins: " << m_bEnablePlugins;
+- kDebug() << " m_windowOpenPolicy: " << m_windowOpenPolicy;
+- kDebug() << " m_windowStatusPolicy: " << m_windowStatusPolicy;
+- kDebug() << " m_windowFocusPolicy: " << m_windowFocusPolicy;
+- kDebug() << " m_windowMovePolicy: " << m_windowMovePolicy;
+- kDebug() << " m_windowResizePolicy: " << m_windowResizePolicy;
+- }
+-#endif
+-};
+-
+-typedef QMap<QString,KPerDomainSettings> PolicyMap;
+-
+-class WebEngineSettingsData
+-{
+-public:
+- bool m_bChangeCursor : 1;
+- bool m_bOpenMiddleClick : 1;
+- bool m_underlineLink : 1;
+- bool m_hoverLink : 1;
+- bool m_bEnableJavaScriptDebug : 1;
+- bool m_bEnableJavaScriptErrorReporting : 1;
+- bool enforceCharset : 1;
+- bool m_bAutoLoadImages : 1;
+- bool m_bUnfinishedImageFrame : 1;
+- bool m_formCompletionEnabled : 1;
+- bool m_autoDelayedActionsEnabled : 1;
+- bool m_jsErrorsEnabled : 1;
+- bool m_follow_system_colors : 1;
+- bool m_allowTabulation : 1;
+- bool m_autoSpellCheck : 1;
+- bool m_adFilterEnabled : 1;
+- bool m_hideAdsEnabled : 1;
+- bool m_jsPopupBlockerPassivePopup : 1;
+- bool m_accessKeysEnabled : 1;
+- bool m_zoomTextOnly : 1;
+- bool m_useCookieJar : 1;
+- bool m_bAutoRefreshPage: 1;
+- bool m_bEnableFavicon:1;
+- bool m_disableInternalPluginHandling:1;
+- bool m_offerToSaveWebSitePassword:1;
+- bool m_loadPluginsOnDemand:1;
+- bool m_enableLocalStorage:1;
+- bool m_enableOfflineStorageDb:1;
+- bool m_enableOfflineWebAppCache:1;
+- bool m_enableWebGL:1;
+- bool m_zoomToDPI:1;
+- bool m_allowActiveMixedContent:1;
+- bool m_allowMixedContentDisplay:1;
+-
+- // the virtual global "domain"
+- KPerDomainSettings global;
+-
+- int m_fontSize;
+- int m_minFontSize;
+- int m_maxFormCompletionItems;
+- WebEngineSettings::KAnimationAdvice m_showAnimations;
+- WebEngineSettings::KSmoothScrollingMode m_smoothScrolling;
+-
+- QString m_encoding;
+- QString m_userSheet;
+-
+- QColor m_textColor;
+- QColor m_baseColor;
+- QColor m_linkColor;
+- QColor m_vLinkColor;
+-
+- PolicyMap domainPolicy;
+- QStringList fonts;
+- QStringList defaultFonts;
+-
+- KDEPrivate::FilterSet adBlackList;
+- KDEPrivate::FilterSet adWhiteList;
+- QList< QPair< QString, QChar > > m_fallbackAccessKeysAssignments;
+-
+- KSharedConfig::Ptr nonPasswordStorableSites;
+-};
+-
+-class WebEngineSettingsPrivate : public QObject, public WebEngineSettingsData
+-{
+- Q_OBJECT
+-public:
+- void adblockFilterLoadList(const QString& filename)
+- {
+- /** load list file and process each line */
+- QFile file(filename);
+- if (file.open(QIODevice::ReadOnly)) {
+- QTextStream ts(&file);
+- QString line = ts.readLine();
+- while (!line.isEmpty()) {
+- //kDebug() << "Adding filter:" << line;
+- /** white list lines start with "@@" */
+- if (line.startsWith(QLatin1String("@@")))
+- adWhiteList.addFilter(line);
+- else
+- adBlackList.addFilter(line);
+- line = ts.readLine();
+- }
+- file.close();
+- }
+- }
+-
+-public Q_SLOTS:
+- void adblockFilterResult(KJob *job)
+- {
+- KIO::StoredTransferJob *tJob = qobject_cast<KIO::StoredTransferJob*>(job);
+- Q_ASSERT(tJob);
+-
+- if ( job->error() == KJob::NoError )
+- {
+- const QByteArray byteArray = tJob->data();
+- const QString localFileName = tJob->property( "webenginesettings_adBlock_filename" ).toString();
+-
+- QFile file(localFileName);
+- if ( file.open(QFile::WriteOnly) )
+- {
+- const bool success = (file.write(byteArray) == byteArray.size());
+- if ( success )
+- adblockFilterLoadList(localFileName);
+- else
+- qWarning() << "Could not write" << byteArray.size() << "to file" << localFileName;
+- file.close();
+- }
+- else
+- qDebug() << "Cannot open file" << localFileName << "for filter list";
+- }
+- else
+- qDebug() << "Downloading" << tJob->url() << "failed with message:" << job->errorText();
+- }
+-};
+-
+-
+-/** Returns a writeable per-domains settings instance for the given domain
+- * or a deep copy of the global settings if not existent.
+- */
+-static KPerDomainSettings &setup_per_domain_policy(WebEngineSettingsPrivate* const d, const QString &domain)
+-{
+- if (domain.isEmpty())
+- qWarning() << "setup_per_domain_policy: domain is empty";
+-
+- const QString ldomain = domain.toLower();
+- PolicyMap::iterator it = d->domainPolicy.find(ldomain);
+- if (it == d->domainPolicy.end()) {
+- // simply copy global domain settings (they should have been initialized
+- // by this time)
+- it = d->domainPolicy.insert(ldomain,d->global);
+- }
+- return *it;
+-}
+-
+-template<typename T>
+-static T readEntry(const KConfigGroup& config, const QString& key, int defaultValue)
+-{
+- return static_cast<T>(config.readEntry(key, defaultValue));
+-}
+-
+-void WebEngineSettings::readDomainSettings(const KConfigGroup &config, bool reset,
+- bool global, KPerDomainSettings &pd_settings)
+-{
+- const QString javaPrefix ((global ? QString() : QStringLiteral("java.")));
+- const QString jsPrefix ((global ? QString() : QStringLiteral("javascript.")));
+- const QString pluginsPrefix (global ? QString() : QStringLiteral("plugins."));
+-
+- // The setting for Java
+- QString key = javaPrefix + QLatin1String("EnableJava");
+- if ( (global && reset) || config.hasKey( key ) )
+- pd_settings.m_bEnableJava = config.readEntry( key, false );
+- else if ( !global )
+- pd_settings.m_bEnableJava = d->global.m_bEnableJava;
+-
+- // The setting for Plugins
+- key = pluginsPrefix + QLatin1String("EnablePlugins");
+- if ( (global && reset) || config.hasKey( key ) )
+- pd_settings.m_bEnablePlugins = config.readEntry( key, true );
+- else if ( !global )
+- pd_settings.m_bEnablePlugins = d->global.m_bEnablePlugins;
+-
+- // The setting for JavaScript
+- key = jsPrefix + QLatin1String("EnableJavaScript");
+- if ( (global && reset) || config.hasKey( key ) )
+- pd_settings.m_bEnableJavaScript = config.readEntry( key, true );
+- else if ( !global )
+- pd_settings.m_bEnableJavaScript = d->global.m_bEnableJavaScript;
+-
+- // window property policies
+- key = jsPrefix + QLatin1String("WindowOpenPolicy");
+- if ( (global && reset) || config.hasKey( key ) )
+- pd_settings.m_windowOpenPolicy = readEntry<KParts::HtmlSettingsInterface::JSWindowOpenPolicy>(config, key, KParts::HtmlSettingsInterface::JSWindowOpenSmart);
+- else if ( !global )
+- pd_settings.m_windowOpenPolicy = d->global.m_windowOpenPolicy;
+-
+- key = jsPrefix + QLatin1String("WindowMovePolicy");
+- if ( (global && reset) || config.hasKey( key ) )
+- pd_settings.m_windowMovePolicy = readEntry<KParts::HtmlSettingsInterface::JSWindowMovePolicy>(config, key, KParts::HtmlSettingsInterface::JSWindowMoveAllow);
+- else if ( !global )
+- pd_settings.m_windowMovePolicy = d->global.m_windowMovePolicy;
+-
+- key = jsPrefix + QLatin1String("WindowResizePolicy");
+- if ( (global && reset) || config.hasKey( key ) )
+- pd_settings.m_windowResizePolicy = readEntry<KParts::HtmlSettingsInterface::JSWindowResizePolicy>(config, key, KParts::HtmlSettingsInterface::JSWindowResizeAllow);
+- else if ( !global )
+- pd_settings.m_windowResizePolicy = d->global.m_windowResizePolicy;
+-
+- key = jsPrefix + QLatin1String("WindowStatusPolicy");
+- if ( (global && reset) || config.hasKey( key ) )
+- pd_settings.m_windowStatusPolicy = readEntry<KParts::HtmlSettingsInterface::JSWindowStatusPolicy>(config, key, KParts::HtmlSettingsInterface::JSWindowStatusAllow);
+- else if ( !global )
+- pd_settings.m_windowStatusPolicy = d->global.m_windowStatusPolicy;
+-
+- key = jsPrefix + QLatin1String("WindowFocusPolicy");
+- if ( (global && reset) || config.hasKey( key ) )
+- pd_settings.m_windowFocusPolicy = readEntry<KParts::HtmlSettingsInterface::JSWindowFocusPolicy>(config, key, KParts::HtmlSettingsInterface::JSWindowFocusAllow);
+- else if ( !global )
+- pd_settings.m_windowFocusPolicy = d->global.m_windowFocusPolicy;
+-}
+-
+-
+-WebEngineSettings::WebEngineSettings()
+- :d (new WebEngineSettingsPrivate)
+-{
+- init();
+-}
+-
+-WebEngineSettings::~WebEngineSettings()
+-{
+- delete d;
+-}
+-
+-bool WebEngineSettings::changeCursor() const
+-{
+- return d->m_bChangeCursor;
+-}
+-
+-bool WebEngineSettings::underlineLink() const
+-{
+- return d->m_underlineLink;
+-}
+-
+-bool WebEngineSettings::hoverLink() const
+-{
+- return d->m_hoverLink;
+-}
+-
+-void WebEngineSettings::init()
+-{
+- initWebEngineSettings();
+-
+- KConfig global( QStringLiteral("khtmlrc"), KConfig::NoGlobals );
+- init( &global, true );
+-
+- KSharedConfig::Ptr local = KSharedConfig::openConfig();
+- if ( local ) {
+- init( local.data(), false );
+- }
+-
+- initNSPluginSettings();
+- initCookieJarSettings();
+-}
+-
+-void WebEngineSettings::init( KConfig * config, bool reset )
+-{
+- KConfigGroup cg( config, "MainView Settings" );
+- if (reset || cg.exists() )
+- {
+- if ( reset || cg.hasKey( "OpenMiddleClick" ) )
+- d->m_bOpenMiddleClick = cg.readEntry( "OpenMiddleClick", true );
+- }
+-
+- KConfigGroup cgAccess(config,"Access Keys" );
+- if (reset || cgAccess.exists() ) {
+- d->m_accessKeysEnabled = cgAccess.readEntry( "Enabled", true );
+- }
+-
+- KConfigGroup cgFilter( config, "Filter Settings" );
+-
+- if ((reset || cgFilter.exists()) && (d->m_adFilterEnabled = cgFilter.readEntry("Enabled", false)))
+- {
+- d->m_hideAdsEnabled = cgFilter.readEntry("Shrink", false);
+-
+- d->adBlackList.clear();
+- d->adWhiteList.clear();
+-
+- /** read maximum age for filter list files, minimum is one day */
+- int htmlFilterListMaxAgeDays = cgFilter.readEntry(QStringLiteral("HTMLFilterListMaxAgeDays")).toInt();
+- if (htmlFilterListMaxAgeDays < 1)
+- htmlFilterListMaxAgeDays = 1;
+-
+- QMapIterator<QString,QString> it (cgFilter.entryMap());
+- while (it.hasNext())
+- {
+- it.next();
+- int id = -1;
+- const QString name = it.key();
+- const QString url = it.value();
+-
+- if (name.startsWith(QLatin1String("Filter")))
+- {
+- if (url.startsWith(QLatin1String("@@")))
+- d->adWhiteList.addFilter(url);
+- else
+- d->adBlackList.addFilter(url);
+- }
+- else if (name.startsWith(QLatin1String("HTMLFilterListName-")) && (id = name.midRef(19).toInt()) > 0)
+- {
+- /** check if entry is enabled */
+- bool filterEnabled = cgFilter.readEntry(QStringLiteral("HTMLFilterListEnabled-").append(QString::number(id))) != QLatin1String("false");
+-
+- /** get url for HTMLFilterList */
+- QUrl url(cgFilter.readEntry(QStringLiteral("HTMLFilterListURL-").append(QString::number(id))));
+-
+- if (filterEnabled && url.isValid()) {
+- /** determine where to cache HTMLFilterList file */
+- QString localFile = cgFilter.readEntry(QStringLiteral("HTMLFilterListLocalFilename-").append(QString::number(id)));
+- localFile = QStandardPaths::locate(QStandardPaths::ConfigLocation, "khtml/" + localFile);
+-
+- /** determine existence and age of cache file */
+- QFileInfo fileInfo(localFile);
+-
+- /** load cached file if it exists, irrespective of age */
+- if (fileInfo.exists())
+- d->adblockFilterLoadList( localFile );
+-
+- /** if no cache list file exists or if it is too old ... */
+- if (!fileInfo.exists() || fileInfo.lastModified().daysTo(QDateTime::currentDateTime()) > htmlFilterListMaxAgeDays)
+- {
+- /** ... in this case, refetch list asynchronously */
+- // kDebug() << "Fetching filter list from" << url << "to" << localFile;
+- KIO::StoredTransferJob *job = KIO::storedGet( url, KIO::Reload, KIO::HideProgressInfo );
+- QObject::connect( job, SIGNAL(result(KJob*)), d, SLOT(adblockFilterResult(KJob*)) );
+- /** for later reference, store name of cache file */
+- job->setProperty("webenginesettings_adBlock_filename", localFile);
+- }
+- }
+- }
+- }
+- }
+-
+- KConfigGroup cgHtml( config, "HTML Settings" );
+- if (reset || cgHtml.exists() )
+- {
+- // Fonts and colors
+- if( reset ) {
+- d->defaultFonts = QStringList();
+- d->defaultFonts.append( cgHtml.readEntry( "StandardFont", QFontDatabase::systemFont(QFontDatabase::GeneralFont).family() ) );
+- d->defaultFonts.append( cgHtml.readEntry( "FixedFont", QFontDatabase::systemFont(QFontDatabase::FixedFont).family() ));
+- d->defaultFonts.append( cgHtml.readEntry( "SerifFont", HTML_DEFAULT_VIEW_SERIF_FONT ) );
+- d->defaultFonts.append( cgHtml.readEntry( "SansSerifFont", HTML_DEFAULT_VIEW_SANSSERIF_FONT ) );
+- d->defaultFonts.append( cgHtml.readEntry( "CursiveFont", HTML_DEFAULT_VIEW_CURSIVE_FONT ) );
+- d->defaultFonts.append( cgHtml.readEntry( "FantasyFont", HTML_DEFAULT_VIEW_FANTASY_FONT ) );
+- d->defaultFonts.append( QStringLiteral( "0" ) ); // font size adjustment
+- }
+-
+- if ( reset || cgHtml.hasKey( "MinimumFontSize" ) )
+- d->m_minFontSize = cgHtml.readEntry( "MinimumFontSize", HTML_DEFAULT_MIN_FONT_SIZE );
+-
+- if ( reset || cgHtml.hasKey( "MediumFontSize" ) )
+- d->m_fontSize = cgHtml.readEntry( "MediumFontSize", 12 );
+-
+- d->fonts = cgHtml.readEntry( "Fonts", QStringList() );
+-
+- if ( reset || cgHtml.hasKey( "DefaultEncoding" ) )
+- d->m_encoding = cgHtml.readEntry( "DefaultEncoding", "" );
+-
+- if ( reset || cgHtml.hasKey( "EnforceDefaultCharset" ) )
+- d->enforceCharset = cgHtml.readEntry( "EnforceDefaultCharset", false );
+-
+- // Behavior
+-
+- if ( reset || cgHtml.hasKey("UnderlineLinks") )
+- d->m_underlineLink = cgHtml.readEntry( "UnderlineLinks", true );
+-
+- if ( reset || cgHtml.hasKey( "HoverLinks" ) )
+- {
+- if ( (d->m_hoverLink = cgHtml.readEntry( "HoverLinks", false )))
+- d->m_underlineLink = false;
+- }
+-
+- if ( reset || cgHtml.hasKey( "AllowTabulation" ) )
+- d->m_allowTabulation = cgHtml.readEntry( "AllowTabulation", false );
+-
+- if ( reset || cgHtml.hasKey( "AutoSpellCheck" ) )
+- d->m_autoSpellCheck = cgHtml.readEntry( "AutoSpellCheck", true );
+-
+- // Other
+- if ( reset || cgHtml.hasKey( "AutoLoadImages" ) )
+- d->m_bAutoLoadImages = cgHtml.readEntry( "AutoLoadImages", true );
+-
+- if ( reset || cgHtml.hasKey( "AutoDelayedActions" ) )
+- d->m_bAutoRefreshPage = cgHtml.readEntry( "AutoDelayedActions", true );
+-
+- if ( reset || cgHtml.hasKey( "UnfinishedImageFrame" ) )
+- d->m_bUnfinishedImageFrame = cgHtml.readEntry( "UnfinishedImageFrame", true );
+-
+- if ( reset || cgHtml.hasKey( "ShowAnimations" ) )
+- {
+- QString value = cgHtml.readEntry( "ShowAnimations").toLower();
+- if (value == QLatin1String("disabled"))
+- d->m_showAnimations = KAnimationDisabled;
+- else if (value == QLatin1String("looponce"))
+- d->m_showAnimations = KAnimationLoopOnce;
+- else
+- d->m_showAnimations = KAnimationEnabled;
+- }
+-
+- if ( reset || cgHtml.hasKey( "SmoothScrolling" ) )
+- {
+- QString value = cgHtml.readEntry( "SmoothScrolling", "whenefficient" ).toLower();
+- if (value == QLatin1String("disabled"))
+- d->m_smoothScrolling = KSmoothScrollingDisabled;
+- else if (value == QLatin1String("whenefficient"))
+- d->m_smoothScrolling = KSmoothScrollingWhenEfficient;
+- else
+- d->m_smoothScrolling = KSmoothScrollingEnabled;
+- }
+-
+- if ( reset || cgHtml.hasKey( "ZoomTextOnly" ) ) {
+- d->m_zoomTextOnly = cgHtml.readEntry( "ZoomTextOnly", false );
+- }
+-
+- if ( reset || cgHtml.hasKey( "ZoomToDPI" ) ) {
+- d->m_zoomToDPI = cgHtml.readEntry( "ZoomToDPI", false );
+- }
+-
+- if (cgHtml.readEntry("UserStyleSheetEnabled", false)) {
+- if (reset || cgHtml.hasKey("UserStyleSheet"))
+- d->m_userSheet = cgHtml.readEntry("UserStyleSheet", QString());
+- } else {
+- d->m_userSheet.clear();
+- }
+-
+- d->m_formCompletionEnabled = cgHtml.readEntry("FormCompletion", true);
+- d->m_maxFormCompletionItems = cgHtml.readEntry("MaxFormCompletionItems", 10);
+- d->m_autoDelayedActionsEnabled = cgHtml.readEntry ("AutoDelayedActions", true);
+- d->m_jsErrorsEnabled = cgHtml.readEntry("ReportJSErrors", true);
+- const QStringList accesskeys = cgHtml.readEntry("FallbackAccessKeysAssignments", QStringList());
+- d->m_fallbackAccessKeysAssignments.clear();
+- for( QStringList::ConstIterator it = accesskeys.begin(); it != accesskeys.end(); ++it )
+- if( (*it).length() > 2 && (*it)[ 1 ] == ':' )
+- d->m_fallbackAccessKeysAssignments.append( qMakePair( (*it).mid( 2 ), (*it)[ 0 ] ));
+-
+- d->m_bEnableFavicon = cgHtml.readEntry("EnableFavicon", true);
+- d->m_offerToSaveWebSitePassword = cgHtml.readEntry("OfferToSaveWebsitePassword", true);
+- }
+-
+- // Colors
+- //In which group ?????
+- if ( reset || cg.hasKey( "FollowSystemColors" ) )
+- d->m_follow_system_colors = cg.readEntry( "FollowSystemColors", false );
+-
+- KConfigGroup cgGeneral( config, "General" );
+- if ( reset || cgGeneral.exists( ) )
+- {
+- if ( reset || cgGeneral.hasKey( "foreground" ) ) {
+- QColor def(HTML_DEFAULT_TXT_COLOR);
+- d->m_textColor = cgGeneral.readEntry( "foreground", def );
+- }
+-
+- if ( reset || cgGeneral.hasKey( "linkColor" ) ) {
+- QColor def(HTML_DEFAULT_LNK_COLOR);
+- d->m_linkColor = cgGeneral.readEntry( "linkColor", def );
+- }
+-
+- if ( reset || cgGeneral.hasKey( "visitedLinkColor" ) ) {
+- QColor def(HTML_DEFAULT_VLNK_COLOR);
+- d->m_vLinkColor = cgGeneral.readEntry( "visitedLinkColor", def);
+- }
+-
+- if ( reset || cgGeneral.hasKey( "background" ) ) {
+- QColor def(HTML_DEFAULT_BASE_COLOR);
+- d->m_baseColor = cgGeneral.readEntry( "background", def);
+- }
+- }
+-
+- KConfigGroup cgJava( config, "Java/JavaScript Settings" );
+- if( reset || cgJava.exists() )
+- {
+- // The global setting for JavaScript debugging
+- // This is currently always enabled by default
+- if ( reset || cgJava.hasKey( "EnableJavaScriptDebug" ) )
+- d->m_bEnableJavaScriptDebug = cgJava.readEntry( "EnableJavaScriptDebug", false );
+-
+- // The global setting for JavaScript error reporting
+- if ( reset || cgJava.hasKey( "ReportJavaScriptErrors" ) )
+- d->m_bEnableJavaScriptErrorReporting = cgJava.readEntry( "ReportJavaScriptErrors", false );
+-
+- // The global setting for popup block passive popup
+- if ( reset || cgJava.hasKey( "PopupBlockerPassivePopup" ) )
+- d->m_jsPopupBlockerPassivePopup = cgJava.readEntry("PopupBlockerPassivePopup", true );
+-
+- // Read options from the global "domain"
+- readDomainSettings(cgJava,reset,true,d->global);
+-#ifdef DEBUG_SETTINGS
+- d->global.dump("init global");
+-#endif
+-
+- // The domain-specific settings.
+-
+- static const char *const domain_keys[] = { // always keep order of keys
+- "ECMADomains", "JavaDomains", "PluginDomains"
+- };
+- bool check_old_ecma_settings = true;
+- bool check_old_java_settings = true;
+- // merge all domains into one list
+- QSet<QString> domainList;
+- for (unsigned i = 0; i < sizeof domain_keys/sizeof domain_keys[0]; ++i) {
+- if (reset || cgJava.hasKey(domain_keys[i])) {
+- if (i == 0) check_old_ecma_settings = false;
+- else if (i == 1) check_old_java_settings = false;
+- const QStringList dl = cgJava.readEntry( domain_keys[i], QStringList() );
+- const QSet<QString>::Iterator notfound = domainList.end();
+- QStringList::ConstIterator it = dl.begin();
+- const QStringList::ConstIterator itEnd = dl.end();
+- for (; it != itEnd; ++it) {
+- const QString domain = (*it).toLower();
+- QSet<QString>::Iterator pos = domainList.find(domain);
+- if (pos == notfound) domainList.insert(domain);
+- }/*next it*/
+- }
+- }/*next i*/
+-
+- if (reset)
+- d->domainPolicy.clear();
+-
+- {
+- QSet<QString>::ConstIterator it = domainList.constBegin();
+- const QSet<QString>::ConstIterator itEnd = domainList.constEnd();
+- for ( ; it != itEnd; ++it)
+- {
+- const QString domain = *it;
+- KConfigGroup cg( config, domain );
+- readDomainSettings(cg,reset,false,d->domainPolicy[domain]);
+-#ifdef DEBUG_SETTINGS
+- d->domainPolicy[domain].dump("init "+domain);
+-#endif
+- }
+- }
+-
+- bool check_old_java = true;
+- if( (reset || cgJava.hasKey("JavaDomainSettings")) && check_old_java_settings)
+- {
+- check_old_java = false;
+- const QStringList domainList = cgJava.readEntry( "JavaDomainSettings", QStringList() );
+- QStringList::ConstIterator it = domainList.constBegin();
+- const QStringList::ConstIterator itEnd = domainList.constEnd();
+- for ( ; it != itEnd; ++it)
+- {
+- QString domain;
+- KParts::HtmlSettingsInterface::JavaScriptAdvice javaAdvice;
+- KParts::HtmlSettingsInterface::JavaScriptAdvice javaScriptAdvice;
+- KParts::HtmlSettingsInterface::splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice);
+- setup_per_domain_policy(d,domain).m_bEnableJava = javaAdvice == KParts::HtmlSettingsInterface::JavaScriptAccept;
+-#ifdef DEBUG_SETTINGS
+- setup_per_domain_policy(d,domain).dump("JavaDomainSettings 4 "+domain);
+-#endif
+- }
+- }
+-
+- bool check_old_ecma = true;
+- if( ( reset || cgJava.hasKey( "ECMADomainSettings" ) ) && check_old_ecma_settings )
+- {
+- check_old_ecma = false;
+- const QStringList domainList = cgJava.readEntry( "ECMADomainSettings", QStringList() );
+- QStringList::ConstIterator it = domainList.constBegin();
+- const QStringList::ConstIterator itEnd = domainList.constEnd();
+- for ( ; it != itEnd; ++it)
+- {
+- QString domain;
+- KParts::HtmlSettingsInterface::JavaScriptAdvice javaAdvice;
+- KParts::HtmlSettingsInterface::JavaScriptAdvice javaScriptAdvice;
+- KParts::HtmlSettingsInterface::splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice);
+- setup_per_domain_policy(d,domain).m_bEnableJavaScript = javaScriptAdvice == KParts::HtmlSettingsInterface::JavaScriptAccept;
+-#ifdef DEBUG_SETTINGS
+- setup_per_domain_policy(d,domain).dump("ECMADomainSettings 4 "+domain);
+-#endif
+- }
+- }
+-
+- if( ( reset || cgJava.hasKey( "JavaScriptDomainAdvice" ) )
+- && ( check_old_java || check_old_ecma )
+- && ( check_old_ecma_settings || check_old_java_settings ) )
+- {
+- const QStringList domainList = cgJava.readEntry( "JavaScriptDomainAdvice", QStringList() );
+- QStringList::ConstIterator it = domainList.constBegin();
+- const QStringList::ConstIterator itEnd = domainList.constEnd();
+- for ( ; it != itEnd; ++it)
+- {
+- QString domain;
+- KParts::HtmlSettingsInterface::JavaScriptAdvice javaAdvice;
+- KParts::HtmlSettingsInterface::JavaScriptAdvice javaScriptAdvice;
+- KParts::HtmlSettingsInterface::splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice);
+- if( check_old_java )
+- setup_per_domain_policy(d,domain).m_bEnableJava = javaAdvice == KParts::HtmlSettingsInterface::JavaScriptAccept;
+- if( check_old_ecma )
+- setup_per_domain_policy(d,domain).m_bEnableJavaScript = javaScriptAdvice == KParts::HtmlSettingsInterface::JavaScriptAccept;
+-#ifdef DEBUG_SETTINGS
+- setup_per_domain_policy(d,domain).dump("JavaScriptDomainAdvice 4 "+domain);
+-#endif
+- }
+- }
+- }
+-
+-#if 0
+- // DNS Prefect support...
+- if ( reset || cgHtml.hasKey( "DNSPrefetch" ) )
+- {
+- // Enabled, Disabled, OnlyWWWAndSLD
+- QString value = cgHtml.readEntry( "DNSPrefetch", "Enabled" ).toLower();
+-
+- if (value == "enabled")
+- QWebEngineSettings::globalSettings()->setAttribute(QWebEngineSettings::DnsPrefetchEnabled, true);
+- else
+- QWebEngineSettings::globalSettings()->setAttribute(QWebEngineSettings::DnsPrefetchEnabled, false);
+- }
+-
+- // Sync with QWebEngineSettings.
+- if (!d->m_encoding.isEmpty())
+- QWebEngineSettings::globalSettings()->setDefaultTextEncoding(d->m_encoding);
+- QWebEngineSettings::globalSettings()->setUserStyleSheetUrl(QUrl::fromUserInput(userStyleSheet()));
+-#endif
+-
+- QWebEngineSettings::globalSettings()->setAttribute(QWebEngineSettings::AutoLoadImages, autoLoadImages());
+- QWebEngineSettings::globalSettings()->setAttribute(QWebEngineSettings::JavascriptEnabled, isJavaScriptEnabled());
+- // QWebEngineSettings::globalSettings()->setAttribute(QWebEngineSettings::JavaEnabled, isJavaEnabled());
+- QWebEngineSettings::globalSettings()->setAttribute(QWebEngineSettings::PluginsEnabled, isPluginsEnabled());
+-
+- // By default disable JS window.open when policy is deny or smart.
+- const KParts::HtmlSettingsInterface::JSWindowOpenPolicy policy = windowOpenPolicy();
+- if (policy == KParts::HtmlSettingsInterface::JSWindowOpenDeny || policy == KParts::HtmlSettingsInterface::JSWindowOpenSmart)
+- QWebEngineSettings::globalSettings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, false);
+- else
+- QWebEngineSettings::globalSettings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true);
+-
+-// QWebEngineSettings::globalSettings()->setAttribute(QWebEngineSettings::ZoomTextOnly, zoomTextOnly());
+-// QWebEngineSettings::globalSettings()->setAttribute(QWebEngineSettings::DeveloperExtrasEnabled, isJavaScriptDebugEnabled());
+- QWebEngineSettings::globalSettings()->setFontFamily(QWebEngineSettings::StandardFont, stdFontName());
+- QWebEngineSettings::globalSettings()->setFontFamily(QWebEngineSettings::FixedFont, fixedFontName());
+- QWebEngineSettings::globalSettings()->setFontFamily(QWebEngineSettings::SerifFont, serifFontName());
+- QWebEngineSettings::globalSettings()->setFontFamily(QWebEngineSettings::SansSerifFont, sansSerifFontName());
+- QWebEngineSettings::globalSettings()->setFontFamily(QWebEngineSettings::CursiveFont, cursiveFontName());
+- QWebEngineSettings::globalSettings()->setFontFamily(QWebEngineSettings::FantasyFont, fantasyFontName());
+-
+- // TODO: Create a webengine config module that gets embeded into Konqueror's kcm.
+- // Turn on WebGL support
+-// QWebEngineSettings::globalSettings()->setAttribute(QWebEngineSettings::WebGLEnabled, d->m_enableWebGL);
+- // Turn on HTML 5 local and offline storage capabilities...
+-// QWebEngineSettings::globalSettings()->setAttribute(QWebEngineSettings::OfflineStorageDatabaseEnabled, d->m_enableOfflineStorageDb);
+-// QWebEngineSettings::globalSettings()->setAttribute(QWebEngineSettings::OfflineWebApplicationCacheEnabled, d->m_enableOfflineWebAppCache);
+- QWebEngineSettings::globalSettings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, d->m_enableLocalStorage);
+-
+- QWebEngineSettings::globalSettings()->setAttribute(QWebEngineSettings::ScrollAnimatorEnabled, smoothScrolling() != KSmoothScrollingDisabled);
+-
+- // These numbers should be calculated from real "logical" DPI/72, using a default dpi of 96 for now
+- computeFontSizes(96);
+-}
+-
+-
+-void WebEngineSettings::computeFontSizes( int logicalDpi )
+-{
+- if (zoomToDPI())
+- logicalDpi = 96;
+-
+- float toPix = logicalDpi/72.0;
+-
+- if (toPix < 96.0/72.0)
+- toPix = 96.0/72.0;
+-
+- QWebEngineSettings::globalSettings()->setFontSize(QWebEngineSettings::MinimumFontSize, qRound(minFontSize() * toPix));
+- QWebEngineSettings::globalSettings()->setFontSize(QWebEngineSettings::DefaultFontSize, qRound(mediumFontSize() * toPix));
+-}
+-
+-bool WebEngineSettings::zoomToDPI() const
+-{
+- return d->m_zoomToDPI;
+-}
+-
+-void WebEngineSettings::setZoomToDPI(bool enabled)
+-{
+- d->m_zoomToDPI = enabled;
+- // save it
+- KConfigGroup cg( KSharedConfig::openConfig(), "HTML Settings");
+- cg.writeEntry("ZoomToDPI", enabled);
+- cg.sync();
+-}
+-
+-/** Local helper for retrieving per-domain settings.
+- *
+- * In case of doubt, the global domain is returned.
+- */
+-static const KPerDomainSettings& lookup_hostname_policy(const WebEngineSettingsPrivate* const d,
+- const QString& hostname)
+-{
+-#ifdef DEBUG_SETTINGS
+- kDebug() << "lookup_hostname_policy(" << hostname << ")";
+-#endif
+- if (hostname.isEmpty()) {
+-#ifdef DEBUG_SETTINGS
+- d->global.dump("global");
+-#endif
+- return d->global;
+- }
+-
+- const PolicyMap::const_iterator notfound = d->domainPolicy.constEnd();
+-
+- // First check whether there is a perfect match.
+- PolicyMap::const_iterator it = d->domainPolicy.find(hostname);
+- if( it != notfound ) {
+-#ifdef DEBUG_SETTINGS
+- kDebug() << "perfect match";
+- (*it).dump(hostname);
+-#endif
+- // yes, use it (unless dunno)
+- return *it;
+- }
+-
+- // Now, check for partial match. Chop host from the left until
+- // there's no dots left.
+- QString host_part = hostname;
+- int dot_idx = -1;
+- while( (dot_idx = host_part.indexOf(QChar('.'))) >= 0 ) {
+- host_part.remove(0,dot_idx);
+- it = d->domainPolicy.find(host_part);
+- Q_ASSERT(notfound == d->domainPolicy.end());
+- if( it != notfound ) {
+-#ifdef DEBUG_SETTINGS
+- kDebug() << "partial match";
+- (*it).dump(host_part);
+-#endif
+- return *it;
+- }
+- // assert(host_part[0] == QChar('.'));
+- host_part.remove(0,1); // Chop off the dot.
+- }
+-
+- // No domain-specific entry: use global domain
+-#ifdef DEBUG_SETTINGS
+- kDebug() << "no match";
+- d->global.dump("global");
+-#endif
+- return d->global;
+-}
+-
+-bool WebEngineSettings::isOpenMiddleClickEnabled()
+-{
+- return d->m_bOpenMiddleClick;
+-}
+-
+-bool WebEngineSettings::accessKeysEnabled() const
+-{
+- return d->m_accessKeysEnabled;
+-}
+-
+-bool WebEngineSettings::favIconsEnabled() const
+-{
+- return d->m_bEnableFavicon;
+-}
+-
+-bool WebEngineSettings::isAdFilterEnabled() const
+-{
+- return d->m_adFilterEnabled;
+-}
+-
+-bool WebEngineSettings::isHideAdsEnabled() const
+-{
+- return d->m_hideAdsEnabled;
+-}
+-
+-bool WebEngineSettings::isAdFiltered( const QString &url ) const
+-{
+- if (!d->m_adFilterEnabled)
+- return false;
+-
+- if (url.startsWith(QLatin1String("data:")))
+- return false;
+-
+- return d->adBlackList.isUrlMatched(url) && !d->adWhiteList.isUrlMatched(url);
+-}
+-
+-QString WebEngineSettings::adFilteredBy( const QString &url, bool *isWhiteListed ) const
+-{
+- QString m = d->adWhiteList.urlMatchedBy(url);
+-
+- if (!m.isEmpty()) {
+- if (isWhiteListed != 0)
+- *isWhiteListed = true;
+- return m;
+- }
+-
+- m = d->adBlackList.urlMatchedBy(url);
+- if (m.isEmpty())
+- return QString();
+-
+- if (isWhiteListed != 0)
+- *isWhiteListed = false;
+- return m;
+-}
+-
+-void WebEngineSettings::addAdFilter( const QString &url )
+-{
+- KConfigGroup config = KSharedConfig::openConfig( QStringLiteral("khtmlrc"), KConfig::NoGlobals )->group( "Filter Settings" );
+-
+- QRegExp rx;
+-
+- // Try compiling to avoid invalid stuff. Only support the basic syntax here...
+- // ### refactor somewhat
+- if (url.length()>2 && url[0]=='/' && url[url.length()-1] == '/')
+- {
+- const QString inside = url.mid(1, url.length()-2);
+- rx.setPattern(inside);
+- }
+- else
+- {
+- rx.setPatternSyntax(QRegExp::Wildcard);
+- rx.setPattern(url);
+- }
+-
+- if (rx.isValid())
+- {
+- int last=config.readEntry("Count", 0);
+- const QString key = "Filter-" + QString::number(last);
+- config.writeEntry(key, url);
+- config.writeEntry("Count",last+1);
+- config.sync();
+-
+- if (url.startsWith(QLatin1String("@@")))
+- d->adWhiteList.addFilter(url);
+- else
+- d->adBlackList.addFilter(url);
+- }
+- else
+- {
+- KMessageBox::error(0,
+- rx.errorString(),
+- i18n("Filter error"));
+- }
+-}
+-
+-bool WebEngineSettings::isJavaEnabled( const QString& hostname ) const
+-{
+- return lookup_hostname_policy(d,hostname.toLower()).m_bEnableJava;
+-}
+-
+-bool WebEngineSettings::isJavaScriptEnabled( const QString& hostname ) const
+-{
+- return lookup_hostname_policy(d,hostname.toLower()).m_bEnableJavaScript;
+-}
+-
+-bool WebEngineSettings::isJavaScriptDebugEnabled( const QString& /*hostname*/ ) const
+-{
+- // debug setting is global for now, but could change in the future
+- return d->m_bEnableJavaScriptDebug;
+-}
+-
+-bool WebEngineSettings::isJavaScriptErrorReportingEnabled( const QString& /*hostname*/ ) const
+-{
+- // error reporting setting is global for now, but could change in the future
+- return d->m_bEnableJavaScriptErrorReporting;
+-}
+-
+-bool WebEngineSettings::isPluginsEnabled( const QString& hostname ) const
+-{
+- return lookup_hostname_policy(d,hostname.toLower()).m_bEnablePlugins;
+-}
+-
+-KParts::HtmlSettingsInterface::JSWindowOpenPolicy WebEngineSettings::windowOpenPolicy(const QString& hostname) const {
+- return lookup_hostname_policy(d,hostname.toLower()).m_windowOpenPolicy;
+-}
+-
+-KParts::HtmlSettingsInterface::JSWindowMovePolicy WebEngineSettings::windowMovePolicy(const QString& hostname) const {
+- return lookup_hostname_policy(d,hostname.toLower()).m_windowMovePolicy;
+-}
+-
+-KParts::HtmlSettingsInterface::JSWindowResizePolicy WebEngineSettings::windowResizePolicy(const QString& hostname) const {
+- return lookup_hostname_policy(d,hostname.toLower()).m_windowResizePolicy;
+-}
+-
+-KParts::HtmlSettingsInterface::JSWindowStatusPolicy WebEngineSettings::windowStatusPolicy(const QString& hostname) const {
+- return lookup_hostname_policy(d,hostname.toLower()).m_windowStatusPolicy;
+-}
+-
+-KParts::HtmlSettingsInterface::JSWindowFocusPolicy WebEngineSettings::windowFocusPolicy(const QString& hostname) const {
+- return lookup_hostname_policy(d,hostname.toLower()).m_windowFocusPolicy;
+-}
+-
+-int WebEngineSettings::mediumFontSize() const
+-{
+- return d->m_fontSize;
+-}
+-
+-int WebEngineSettings::minFontSize() const
+-{
+- return d->m_minFontSize;
+-}
+-
+-QString WebEngineSettings::settingsToCSS() const
+-{
+- // lets start with the link properties
+- QString str = QStringLiteral("a:link {\ncolor: ");
+- str += d->m_linkColor.name();
+- str += ';';
+- if(d->m_underlineLink)
+- str += QLatin1String("\ntext-decoration: underline;");
+-
+- if( d->m_bChangeCursor )
+- {
+- str += QLatin1String("\ncursor: pointer;");
+- str += QLatin1String("\n}\ninput[type=image] { cursor: pointer;");
+- }
+- str += QLatin1String("\n}\n");
+- str += QLatin1String("a:visited {\ncolor: ");
+- str += d->m_vLinkColor.name();
+- str += ';';
+- if(d->m_underlineLink)
+- str += QLatin1String("\ntext-decoration: underline;");
+-
+- if( d->m_bChangeCursor )
+- str += QLatin1String("\ncursor: pointer;");
+- str += QLatin1String("\n}\n");
+-
+- if(d->m_hoverLink)
+- str += QLatin1String("a:link:hover, a:visited:hover { text-decoration: underline; }\n");
+-
+- return str;
+-}
+-
+-QString WebEngineSettings::lookupFont(int i) const
+-{
+- if (d->fonts.count() > i) {
+- return d->fonts.at(i);
+- }
+-
+- if (d->defaultFonts.count() > i) {
+- return d->defaultFonts.at(i);
+- }
+-
+- return QString();
+-}
+-
+-QString WebEngineSettings::stdFontName() const
+-{
+- return lookupFont(0);
+-}
+-
+-QString WebEngineSettings::fixedFontName() const
+-{
+- return lookupFont(1);
+-}
+-
+-QString WebEngineSettings::serifFontName() const
+-{
+- return lookupFont(2);
+-}
+-
+-QString WebEngineSettings::sansSerifFontName() const
+-{
+- return lookupFont(3);
+-}
+-
+-QString WebEngineSettings::cursiveFontName() const
+-{
+- return lookupFont(4);
+-}
+-
+-QString WebEngineSettings::fantasyFontName() const
+-{
+- return lookupFont(5);
+-}
+-
+-void WebEngineSettings::setStdFontName(const QString &n)
+-{
+- while(d->fonts.count() <= 0)
+- d->fonts.append(QString());
+- d->fonts[0] = n;
+-}
+-
+-void WebEngineSettings::setFixedFontName(const QString &n)
+-{
+- while(d->fonts.count() <= 1)
+- d->fonts.append(QString());
+- d->fonts[1] = n;
+-}
+-
+-QString WebEngineSettings::userStyleSheet() const
+-{
+- return d->m_userSheet;
+-}
+-
+-bool WebEngineSettings::isFormCompletionEnabled() const
+-{
+- return d->m_formCompletionEnabled;
+-}
+-
+-int WebEngineSettings::maxFormCompletionItems() const
+-{
+- return d->m_maxFormCompletionItems;
+-}
+-
+-const QString &WebEngineSettings::encoding() const
+-{
+- return d->m_encoding;
+-}
+-
+-bool WebEngineSettings::followSystemColors() const
+-{
+- return d->m_follow_system_colors;
+-}
+-
+-const QColor& WebEngineSettings::textColor() const
+-{
+- return d->m_textColor;
+-}
+-
+-const QColor& WebEngineSettings::baseColor() const
+-{
+- return d->m_baseColor;
+-}
+-
+-const QColor& WebEngineSettings::linkColor() const
+-{
+- return d->m_linkColor;
+-}
+-
+-const QColor& WebEngineSettings::vLinkColor() const
+-{
+- return d->m_vLinkColor;
+-}
+-
+-bool WebEngineSettings::autoPageRefresh() const
+-{
+- return d->m_bAutoRefreshPage;
+-}
+-
+-bool WebEngineSettings::autoLoadImages() const
+-{
+- return d->m_bAutoLoadImages;
+-}
+-
+-bool WebEngineSettings::unfinishedImageFrame() const
+-{
+- return d->m_bUnfinishedImageFrame;
+-}
+-
+-WebEngineSettings::KAnimationAdvice WebEngineSettings::showAnimations() const
+-{
+- return d->m_showAnimations;
+-}
+-
+-WebEngineSettings::KSmoothScrollingMode WebEngineSettings::smoothScrolling() const
+-{
+- return d->m_smoothScrolling;
+-}
+-
+-bool WebEngineSettings::zoomTextOnly() const
+-{
+- return d->m_zoomTextOnly;
+-}
+-
+-bool WebEngineSettings::isAutoDelayedActionsEnabled() const
+-{
+- return d->m_autoDelayedActionsEnabled;
+-}
+-
+-bool WebEngineSettings::jsErrorsEnabled() const
+-{
+- return d->m_jsErrorsEnabled;
+-}
+-
+-void WebEngineSettings::setJSErrorsEnabled(bool enabled)
+-{
+- d->m_jsErrorsEnabled = enabled;
+- // save it
+- KConfigGroup cg( KSharedConfig::openConfig(), "HTML Settings");
+- cg.writeEntry("ReportJSErrors", enabled);
+- cg.sync();
+-}
+-
+-bool WebEngineSettings::allowTabulation() const
+-{
+- return d->m_allowTabulation;
+-}
+-
+-bool WebEngineSettings::autoSpellCheck() const
+-{
+- return d->m_autoSpellCheck;
+-}
+-
+-QList< QPair< QString, QChar > > WebEngineSettings::fallbackAccessKeysAssignments() const
+-{
+- return d->m_fallbackAccessKeysAssignments;
+-}
+-
+-void WebEngineSettings::setJSPopupBlockerPassivePopup(bool enabled)
+-{
+- d->m_jsPopupBlockerPassivePopup = enabled;
+- // save it
+- KConfigGroup cg( KSharedConfig::openConfig(), "Java/JavaScript Settings");
+- cg.writeEntry("PopupBlockerPassivePopup", enabled);
+- cg.sync();
+-}
+-
+-bool WebEngineSettings::jsPopupBlockerPassivePopup() const
+-{
+- return d->m_jsPopupBlockerPassivePopup;
+-}
+-
+-bool WebEngineSettings::isCookieJarEnabled() const
+-{
+- return d->m_useCookieJar;
+-}
+-
+-// Password storage...
+-static KConfigGroup nonPasswordStorableSitesCg(KSharedConfig::Ptr& configPtr)
+-{
+- if (!configPtr) {
+- configPtr = KSharedConfig::openConfig(QStandardPaths::locate(QStandardPaths::DataLocation, QStringLiteral("khtml/formcompletions")), KConfig::NoGlobals);
+- }
+-
+- return KConfigGroup(configPtr, "NonPasswordStorableSites");
+-}
+-
+-bool WebEngineSettings::isNonPasswordStorableSite(const QString &host) const
+-{
+- KConfigGroup cg = nonPasswordStorableSitesCg(d->nonPasswordStorableSites);
+- const QStringList sites = cg.readEntry("Sites", QStringList());
+- return sites.contains(host);
+-}
+-
+-void WebEngineSettings::addNonPasswordStorableSite(const QString &host)
+-{
+- KConfigGroup cg = nonPasswordStorableSitesCg(d->nonPasswordStorableSites);
+- QStringList sites = cg.readEntry("Sites", QStringList());
+- sites.append(host);
+- cg.writeEntry("Sites", sites);
+- cg.sync();
+-}
+-
+-void WebEngineSettings::removeNonPasswordStorableSite(const QString &host)
+-{
+- KConfigGroup cg = nonPasswordStorableSitesCg(d->nonPasswordStorableSites);
+- QStringList sites = cg.readEntry("Sites", QStringList());
+- sites.removeOne(host);
+- cg.writeEntry("Sites", sites);
+- cg.sync();
+-}
+-
+-bool WebEngineSettings::askToSaveSitePassword() const
+-{
+- return d->m_offerToSaveWebSitePassword;
+-}
+-
+-bool WebEngineSettings::isInternalPluginHandlingDisabled() const
+-{
+- return d->m_disableInternalPluginHandling;
+-}
+-
+-bool WebEngineSettings::isLoadPluginsOnDemandEnabled() const
+-{
+- return d->m_loadPluginsOnDemand;
+-}
+-
+-bool WebEngineSettings::allowMixedContentDisplay() const
+-{
+- return d->m_allowMixedContentDisplay;
+-}
+-
+-bool WebEngineSettings::alowActiveMixedContent() const
+-{
+- return d->m_allowActiveMixedContent;
+-}
+-
+-
+-void WebEngineSettings::initWebEngineSettings()
+-{
+- KConfig cfg (QStringLiteral("webenginepartrc"), KConfig::NoGlobals);
+- KConfigGroup generalCfg (&cfg, "General");
+- d->m_disableInternalPluginHandling = generalCfg.readEntry("DisableInternalPluginHandling", false);
+- d->m_enableLocalStorage = generalCfg.readEntry("EnableLocalStorage", true);
+- d->m_enableOfflineStorageDb = generalCfg.readEntry("EnableOfflineStorageDatabase", true);
+- d->m_enableOfflineWebAppCache = generalCfg.readEntry("EnableOfflineWebApplicationCache", true);
+- d->m_enableWebGL = generalCfg.readEntry("EnableWebGL", true);
+- d->m_allowActiveMixedContent = generalCfg.readEntry("AllowActiveMixedContent", false);
+- d->m_allowMixedContentDisplay = generalCfg.readEntry("AllowMixedContentDisplay", true);
+-
+- // Force the reloading of the non password storable sites settings.
+- d->nonPasswordStorableSites.reset();
+-}
+-
+-void WebEngineSettings::initCookieJarSettings()
+-{
+- KSharedConfig::Ptr cookieCfgPtr = KSharedConfig::openConfig(QStringLiteral("kcookiejarrc"), KConfig::NoGlobals);
+- KConfigGroup cookieCfg ( cookieCfgPtr, "Cookie Policy");
+- d->m_useCookieJar = cookieCfg.readEntry("Cookies", false);
+-}
+-
+-void WebEngineSettings::initNSPluginSettings()
+-{
+- KSharedConfig::Ptr cookieCfgPtr = KSharedConfig::openConfig(QStringLiteral("kcmnspluginrc"), KConfig::NoGlobals);
+- KConfigGroup cookieCfg ( cookieCfgPtr, "Misc");
+- d->m_loadPluginsOnDemand = cookieCfg.readEntry("demandLoad", false);
+-}
+-
+-
+-WebEngineSettings* WebEngineSettings::self()
+-{
+- static WebEngineSettings s_webEngineSettings;
+- return &s_webEngineSettings;
+-}
+-
+-#include "webenginesettings.moc"
+diff --git a/webenginepart/src/settings/webenginesettings.h a/webenginepart/src/settings/webenginesettings.h
+deleted file mode 100644
+index 6b2baa101..000000000
+--- a/webenginepart/src/settings/webenginesettings.h
++++ /dev/null
+@@ -1,213 +0,0 @@
+-/* This file is part of the KDE project
+- Copyright (C) 1999 David Faure <faure@kde.org>
+-
+- 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.
+-*/
+-
+-#ifndef WEBENGINESETTINGS_H
+-#define WEBENGINESETTINGS_H
+-
+-class KConfig;
+-class KConfigGroup;
+-
+-#include <QColor>
+-#include <QStringList>
+-#include <QPair>
+-
+-#include <KParts/HtmlExtension>
+-#include <KParts/HtmlSettingsInterface>
+-
+-struct KPerDomainSettings;
+-class WebEngineSettingsPrivate;
+-
+-/**
+- * Settings for the HTML view.
+- */
+-class WebEngineSettings
+-{
+-public:
+-
+- enum KAnimationAdvice {
+- KAnimationDisabled=0,
+- KAnimationLoopOnce,
+- KAnimationEnabled
+- };
+-
+- enum KSmoothScrollingMode {
+- KSmoothScrollingDisabled=0,
+- KSmoothScrollingWhenEfficient,
+- KSmoothScrollingEnabled
+- };
+-
+- /**
+- * Called by constructor and reparseConfiguration
+- */
+- void init();
+-
+- /**
+- * Destructor. Don't delete any instance by yourself.
+- */
+- virtual ~WebEngineSettings();
+-
+- void computeFontSizes(int logicalDpi);
+- bool zoomToDPI() const;
+- void setZoomToDPI(bool b);
+-
+- // Automatic page reload/refresh...
+- bool autoPageRefresh() const;
+-
+- bool isOpenMiddleClickEnabled();
+-
+- // Java and JavaScript
+- bool isJavaEnabled( const QString& hostname = QString() ) const;
+- bool isJavaScriptEnabled( const QString& hostname = QString() ) const;
+- bool isJavaScriptDebugEnabled( const QString& hostname = QString() ) const;
+- bool isJavaScriptErrorReportingEnabled( const QString& hostname = QString() ) const;
+- bool isPluginsEnabled( const QString& hostname = QString() ) const;
+- bool isLoadPluginsOnDemandEnabled() const;
+- bool isInternalPluginHandlingDisabled() const;
+-
+- // AdBlocK Filtering
+- bool isAdFiltered( const QString &url ) const;
+- bool isAdFilterEnabled() const;
+- bool isHideAdsEnabled() const;
+- void addAdFilter( const QString &url );
+- QString adFilteredBy( const QString &url, bool *isWhiteListed = 0 ) const;
+-
+- // Access Keys
+- bool accessKeysEnabled() const;
+-
+- // Favicons
+- bool favIconsEnabled() const;
+-
+- KParts::HtmlSettingsInterface::JSWindowOpenPolicy windowOpenPolicy( const QString& hostname = QString() ) const;
+- KParts::HtmlSettingsInterface::JSWindowMovePolicy windowMovePolicy( const QString& hostname = QString() ) const;
+- KParts::HtmlSettingsInterface::JSWindowResizePolicy windowResizePolicy( const QString& hostname = QString() ) const;
+- KParts::HtmlSettingsInterface::JSWindowStatusPolicy windowStatusPolicy( const QString& hostname = QString() ) const;
+- KParts::HtmlSettingsInterface::JSWindowFocusPolicy windowFocusPolicy( const QString& hostname = QString() ) const;
+-
+- QString settingsToCSS() const;
+- QString userStyleSheet() const;
+-
+- // Form completion
+- bool isFormCompletionEnabled() const;
+- int maxFormCompletionItems() const;
+-
+- // Meta refresh/redirect (http-equiv)
+- bool isAutoDelayedActionsEnabled () const;
+-
+- // CookieJar...
+- bool isCookieJarEnabled() const;
+-
+- // Password storage...
+- bool isNonPasswordStorableSite(const QString &host) const;
+- void addNonPasswordStorableSite(const QString &host);
+- void removeNonPasswordStorableSite(const QString &host);
+- bool askToSaveSitePassword() const;
+-
+- // Mixed content
+- bool alowActiveMixedContent() const;
+- bool allowMixedContentDisplay() const;
+-
+- // Global config object stuff.
+- static WebEngineSettings* self();
+-
+-private:
+- /**
+- * Read settings from @p config.
+- * @param config is a pointer to KConfig object.
+- * @param reset if true, settings are always set; if false,
+- * settings are only set if the config file has a corresponding key.
+- */
+- void init( KConfig * config, bool reset = true );
+-
+- // Behavior settings
+- bool changeCursor() const;
+- bool underlineLink() const;
+- bool hoverLink() const;
+- bool allowTabulation() const;
+- bool autoSpellCheck() const;
+- KAnimationAdvice showAnimations() const;
+- KSmoothScrollingMode smoothScrolling() const;
+- bool zoomTextOnly() const;
+-
+- // Font settings
+- QString stdFontName() const;
+- QString fixedFontName() const;
+- QString serifFontName() const;
+- QString sansSerifFontName() const;
+- QString cursiveFontName() const;
+- QString fantasyFontName() const;
+-
+- // these two can be set. Mainly for historical reasons (the method in KHTMLPart exists...)
+- void setStdFontName(const QString &n);
+- void setFixedFontName(const QString &n);
+-
+- int minFontSize() const;
+- int mediumFontSize() const;
+-
+- bool jsErrorsEnabled() const;
+- void setJSErrorsEnabled(bool enabled);
+-
+- const QString &encoding() const;
+-
+- bool followSystemColors() const;
+-
+- // Color settings
+- const QColor& textColor() const;
+- const QColor& baseColor() const;
+- const QColor& linkColor() const;
+- const QColor& vLinkColor() const;
+-
+- // Autoload images
+- bool autoLoadImages() const;
+- bool unfinishedImageFrame() const;
+-
+- /**
+- * reads from @p config's current group, forcing initialization
+- * if @p reset is true.
+- * @param config is a pointer to KConfig object.
+- * @param reset true if initialization is to be forced.
+- * @param global true if the global domain is to be read.
+- * @param pd_settings will be initialised with the computed (inherited)
+- * settings.
+- */
+- void readDomainSettings(const KConfigGroup &config, bool reset,
+- bool global, KPerDomainSettings &pd_settings);
+-
+-
+- QList< QPair< QString, QChar > > fallbackAccessKeysAssignments() const;
+-
+- // Whether to show passive popup when windows are blocked
+- void setJSPopupBlockerPassivePopup(bool enabled);
+- bool jsPopupBlockerPassivePopup() const;
+-
+-
+- QString lookupFont(int i) const;
+-
+- void initWebEngineSettings();
+- void initCookieJarSettings();
+- void initNSPluginSettings();
+-
+- /**
+- * @internal Constructor
+- */
+- WebEngineSettings();
+-
+- WebEngineSettingsPrivate* const d;
+-};
+-
+-#endif
+diff --git a/webenginepart/src/ui/featurepermissionbar.cpp a/webenginepart/src/ui/featurepermissionbar.cpp
+deleted file mode 100644
+index e13351a16..000000000
+--- a/webenginepart/src/ui/featurepermissionbar.cpp
++++ /dev/null
+@@ -1,75 +0,0 @@
+-/*
+- * This file is part of the KDE project.
+- *
+- * Copyright (C) 2009 Dawit Alemayehu <adawit @ kde.org>
+- * Copyright (C) 2013 Allan Sandfeld Jensen <sandfeld@kde.org>
+- *
+- * 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 "featurepermissionbar.h"
+-
+-#include <KLocalizedString>
+-
+-#include <QAction>
+-
+-
+-FeaturePermissionBar::FeaturePermissionBar(QWidget *parent)
+- :KMessageWidget(parent)
+-{
+- setCloseButtonVisible(false);
+- setMessageType(KMessageWidget::Information);
+-
+- QAction* action = new QAction(i18nc("@action:deny access", "&Deny access"), this);
+- connect(action, SIGNAL(triggered()), this, SLOT(onDeniedButtonClicked()));
+- addAction(action);
+-
+- action = new QAction(i18nc("@action:grant access", "&Grant access"), this);
+- connect(action, SIGNAL(triggered()), this, SLOT(onGrantedButtonClicked()));
+- addAction(action);
+-
+- // FIXME: Add option to allow and remember for this site.
+-}
+-
+-FeaturePermissionBar::~FeaturePermissionBar()
+-{
+-}
+-
+-QWebEnginePage::Feature FeaturePermissionBar::feature() const
+-{
+- return m_feature;
+-}
+-
+-void FeaturePermissionBar::setFeature (QWebEnginePage::Feature feature)
+-{
+- m_feature = feature;
+-}
+-
+-void FeaturePermissionBar::onDeniedButtonClicked()
+-{
+- animatedHide();
+- emit permissionDenied(m_feature);
+- emit done();
+-}
+-
+-void FeaturePermissionBar::onGrantedButtonClicked()
+-{
+- animatedHide();
+- emit permissionGranted(m_feature);
+- emit done();
+-}
+-
+-#include "featurepermissionbar.moc"
+diff --git a/webenginepart/src/ui/featurepermissionbar.h a/webenginepart/src/ui/featurepermissionbar.h
+deleted file mode 100644
+index d988ad36f..000000000
+--- a/webenginepart/src/ui/featurepermissionbar.h
++++ /dev/null
+@@ -1,54 +0,0 @@
+-/*
+- * This file is part of the KDE project.
+- *
+- * Copyright (C) 2013 Allan Sandfeld Jensen <sandfeld @ kde.org>
+- *
+- * 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.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
+- * 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.
+- */
+-
+-#ifndef FEATUREPERMISSIONBAR_H
+-#define FEATUREPERMISSIONBAR_H
+-
+-#include <KMessageWidget>
+-
+-#include <QtWebEngineWidgets/QWebEnginePage>
+-
+-
+-class FeaturePermissionBar : public KMessageWidget
+-{
+- Q_OBJECT
+-public:
+- explicit FeaturePermissionBar(QWidget *parent = Q_NULLPTR);
+- ~FeaturePermissionBar();
+-
+- QWebEnginePage::Feature feature() const;
+-
+- void setFeature(QWebEnginePage::Feature);
+-
+-Q_SIGNALS:
+- void permissionGranted(QWebEnginePage::Feature);
+- void permissionDenied(QWebEnginePage::Feature);
+- void done();
+-
+-private Q_SLOTS:
+- void onDeniedButtonClicked();
+- void onGrantedButtonClicked();
+-
+-private:
+- QWebEnginePage::Feature m_feature;
+-};
+-
+-#endif // FEATUREPERMISSIONBAR_H
+diff --git a/webenginepart/src/ui/passwordbar.cpp a/webenginepart/src/ui/passwordbar.cpp
+deleted file mode 100644
+index 328d5d4b2..000000000
+--- a/webenginepart/src/ui/passwordbar.cpp
++++ /dev/null
+@@ -1,105 +0,0 @@
+-/*
+- * This file is part of the KDE project.
+- *
+- * Copyright (C) 2009 Dawit Alemayehu <adawit @ kde.org>
+- *
+- * 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 "passwordbar.h"
+-
+-#include "settings/webenginesettings.h"
+-
+-#include <KColorScheme>
+-#include <KLocalizedString>
+-
+-#include <QCoreApplication>
+-#include <QAction>
+-#include <QPalette>
+-
+-
+-PasswordBar::PasswordBar(QWidget *parent)
+- :KMessageWidget(parent)
+-{
+- setCloseButtonVisible(false);
+- setMessageType(KMessageWidget::Information);
+-
+- QAction* action = new QAction(i18nc("@action:remember password", "&Remember"), this);
+- connect(action, SIGNAL(triggered()), this, SLOT(onRememberButtonClicked()));
+- addAction(action);
+-
+- action = new QAction(i18nc("@action:never for this site", "Ne&ver for this site"), this);
+- connect(action, SIGNAL(triggered()), this, SLOT(onNeverButtonClicked()));
+- addAction(action);
+-
+- action = new QAction(i18nc("@action:not now", "N&ot now"), this);
+- connect(action, SIGNAL(triggered()), this, SLOT(onNotNowButtonClicked()));
+- addAction(action);
+-}
+-
+-PasswordBar::~PasswordBar()
+-{
+-}
+-
+-QUrl PasswordBar::url() const
+-{
+- return m_url;
+-}
+-
+-QString PasswordBar::requestKey() const
+-{
+- return m_requestKey;
+-}
+-
+-void PasswordBar::setUrl (const QUrl& url)
+-{
+- m_url = url;
+-}
+-
+-void PasswordBar::setRequestKey (const QString& key)
+-{
+- m_requestKey = key;
+-}
+-
+-void PasswordBar::onNotNowButtonClicked()
+-{
+- animatedHide();
+- emit saveFormDataRejected (m_requestKey);
+- emit done();
+- clear();
+-}
+-
+-void PasswordBar::onNeverButtonClicked()
+-{
+- WebEngineSettings::self()->addNonPasswordStorableSite(m_url.host());
+- onNotNowButtonClicked();
+-}
+-
+-void PasswordBar::onRememberButtonClicked()
+-{
+- animatedHide();
+- emit saveFormDataAccepted(m_requestKey);
+- emit done();
+- clear();
+-}
+-
+-void PasswordBar::clear()
+-{
+- m_requestKey.clear();
+- m_url.clear();
+-}
+-
+-#include "passwordbar.moc"
+diff --git a/webenginepart/src/ui/passwordbar.h a/webenginepart/src/ui/passwordbar.h
+deleted file mode 100644
+index 9f641a625..000000000
+--- a/webenginepart/src/ui/passwordbar.h
++++ /dev/null
+@@ -1,60 +0,0 @@
+-/*
+- * This file is part of the KDE project.
+- *
+- * Copyright (C) 2009 Dawit Alemayehu <adawit @ kde.org>
+- *
+- * 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.
+- */
+-
+-#ifndef PASSWORDBAR_H
+-#define PASSWORDBAR_H
+-
+-#include <KMessageWidget>
+-
+-#include <QUrl>
+-
+-
+-class PasswordBar : public KMessageWidget
+-{
+- Q_OBJECT
+-public:
+- explicit PasswordBar(QWidget *parent = Q_NULLPTR);
+- ~PasswordBar();
+-
+- QUrl url() const;
+- QString requestKey() const;
+-
+- void setUrl(const QUrl&);
+- void setRequestKey(const QString&);
+-
+-Q_SIGNALS:
+- void saveFormDataRejected(const QString &key);
+- void saveFormDataAccepted(const QString &key);
+- void done();
+-
+-private Q_SLOTS:
+- void onNotNowButtonClicked();
+- void onNeverButtonClicked();
+- void onRememberButtonClicked();
+-
+-private:
+- void clear();
+-
+- QUrl m_url;
+- QString m_requestKey;
+-};
+-
+-#endif // PASSWORDBAR_H
+diff --git a/webenginepart/src/ui/searchbar.cpp a/webenginepart/src/ui/searchbar.cpp
+deleted file mode 100644
+index aca133ff6..000000000
+--- a/webenginepart/src/ui/searchbar.cpp
++++ /dev/null
+@@ -1,194 +0,0 @@
+-/*
+- * This file is part of the KDE project.
+- *
+- * Copyright (C) 2008 Laurent Montel <montel@kde.org>
+- * Copyright (C) 2008 Benjamin C. Meyer <ben@meyerhome.net>
+- * Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
+- * Copyright (C) 2009 Dawit Alemayehu <adawit @ kde.org>
+- *
+- * 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 "searchbar.h"
+-
+-#include <KLineEdit>
+-#include <KColorScheme>
+-#include <QIcon>
+-#include <KLocalizedString>
+-
+-#include <QResizeEvent>
+-
+-
+-SearchBar::SearchBar(QWidget *parent)
+- :QWidget(parent)
+-{
+-
+- // Get the widget that currently has the focus so we can properly
+- // restore it when the filter bar is closed.
+- QWidget* widgetWindow = (parent ? parent->window() : 0);
+- m_focusWidget = (widgetWindow ? widgetWindow->focusWidget() : 0);
+-
+- // Initialize the user interface...
+- m_ui.setupUi(this);
+- m_ui.optionsButton->addAction(m_ui.actionMatchCase);
+- m_ui.optionsButton->addAction(m_ui.actionHighlightMatch);
+- m_ui.optionsButton->addAction(m_ui.actionSearchAutomatically);
+- m_ui.closeButton->setIcon(QIcon::fromTheme(QStringLiteral("dialog-close")));
+- m_ui.previousButton->setIcon(QIcon::fromTheme(QStringLiteral("go-up-search")));
+- m_ui.nextButton->setIcon(QIcon::fromTheme(QStringLiteral("go-down-search")));
+- m_ui.previousButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+- m_ui.nextButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+- m_ui.searchInfo->setText(i18nc("label for input line to find text", "&Find:"));
+-
+- setFocusProxy(m_ui.searchComboBox);
+-
+- connect(m_ui.nextButton, SIGNAL(clicked()),
+- this, SLOT(findNext()));
+- connect(m_ui.previousButton, SIGNAL(clicked()),
+- this, SLOT(findPrevious()));
+- connect(m_ui.searchComboBox, SIGNAL(returnPressed()),
+- this, SLOT(findNext()));
+- connect(m_ui.searchComboBox, SIGNAL(editTextChanged(QString)),
+- this, SLOT(textChanged(QString)));
+-
+- // Start off hidden by default...
+- setVisible(false);
+-}
+-
+-SearchBar::~SearchBar()
+-{
+- // NOTE: For some reason, if we do not clear the focus from the line edit
+- // widget before we delete this object, it seems to cause a crash!!
+- m_ui.searchComboBox->clearFocus();
+-}
+-
+-void SearchBar::clear()
+-{
+- m_ui.searchComboBox->clear();
+-}
+-
+-void SearchBar::setVisible (bool visible)
+-{
+- if (visible) {
+- m_ui.searchComboBox->setFocus(Qt::ActiveWindowFocusReason);
+- m_ui.searchComboBox->lineEdit()->selectAll();
+- } else {
+- m_ui.searchComboBox->setPalette(QPalette());
+- emit searchTextChanged(QString());
+- }
+-
+- QWidget::setVisible(visible);
+-}
+-
+-QString SearchBar::searchText() const
+-{
+- return m_ui.searchComboBox->currentText();
+-}
+-
+-bool SearchBar::caseSensitive() const
+-{
+- return m_ui.actionMatchCase->isChecked();
+-}
+-
+-bool SearchBar::highlightMatches() const
+-{
+- return m_ui.actionHighlightMatch->isChecked();
+-}
+-
+-void SearchBar::setSearchText(const QString& text)
+-{
+- show();
+- m_ui.searchComboBox->setEditText(text);
+-}
+-
+-void SearchBar::setFoundMatch(bool match)
+-{
+- //kDebug() << match;
+- if (m_ui.searchComboBox->currentText().isEmpty()) {
+- m_ui.searchComboBox->setPalette(QPalette());
+- return;
+- }
+-
+- KColorScheme::BackgroundRole role = (match ? KColorScheme::PositiveBackground : KColorScheme::NegativeBackground);
+- QPalette newPal(m_ui.searchComboBox->palette());
+- KColorScheme::adjustBackground(newPal, role);
+- m_ui.searchComboBox->setPalette(newPal);
+-}
+-
+-void SearchBar::findNext()
+-{
+- if (!isVisible())
+- return;
+-
+- const QString text (m_ui.searchComboBox->currentText());
+- if (m_ui.searchComboBox->findText(text) == -1) {
+- m_ui.searchComboBox->addItem(text);
+- }
+-
+- emit searchTextChanged(text);
+-}
+-
+-void SearchBar::findPrevious()
+-{
+- if (!isVisible())
+- return;
+-
+- const QString text (m_ui.searchComboBox->currentText());
+- if (m_ui.searchComboBox->findText(text) == -1) {
+- m_ui.searchComboBox->addItem(text);
+- }
+-
+- emit searchTextChanged(m_ui.searchComboBox->currentText(), true);
+-}
+-
+-void SearchBar::textChanged(const QString &text)
+-{
+- if (text.isEmpty()) {
+- m_ui.searchComboBox->setPalette(QPalette());
+- m_ui.nextButton->setEnabled(false);
+- m_ui.previousButton->setEnabled(false);
+- } else {
+- m_ui.nextButton->setEnabled(true);
+- m_ui.previousButton->setEnabled(true);
+- }
+-
+- if (m_ui.actionSearchAutomatically->isChecked()) {
+- emit searchTextChanged(m_ui.searchComboBox->currentText());
+- }
+-}
+-
+-bool SearchBar::event(QEvent* e)
+-{
+- // Close the bar when Escape is pressed. Note we cannot
+- // assign Escape as a shortcut key because it would cause
+- // a conflict with the Stop button.
+- if (e->type() == QEvent::ShortcutOverride) {
+- QKeyEvent* kev = static_cast<QKeyEvent*>(e);
+- if (kev->key() == Qt::Key_Escape) {
+- e->accept();
+- close();
+- if (m_focusWidget) {
+- m_focusWidget->setFocus();
+- m_focusWidget = 0;
+- }
+- return true;
+- }
+- }
+- return QWidget::event(e);
+-}
+-
+-#include "searchbar.moc"
+diff --git a/webenginepart/src/ui/searchbar.h a/webenginepart/src/ui/searchbar.h
+deleted file mode 100644
+index 598fe69ff..000000000
+--- a/webenginepart/src/ui/searchbar.h
++++ /dev/null
+@@ -1,68 +0,0 @@
+-/*
+- * This file is part of the KDE project.
+- *
+- * Copyright (C) 2008 Laurent Montel <montel@kde.org>
+- * Copyright 2008 Benjamin C. Meyer <ben@meyerhome.net>
+- * Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
+- * Copyright (C) 2009 Dawit Alemayehu <adawit @ kde.org>
+- *
+- * 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.
+- */
+-
+-#ifndef SEARCHBAR_P_H
+-#define SEARCHBAR_P_H
+-
+-#include <QWidget>
+-
+-#include "ui_searchbar.h"
+-
+-class QEvent;
+-
+-/**
+- * This is the widget that shows up when the search is initiated.
+- */
+-class SearchBar : public QWidget
+-{
+- Q_OBJECT
+-
+-public:
+- SearchBar(QWidget *parent = Q_NULLPTR);
+- ~SearchBar();
+-
+- QString searchText() const;
+- bool caseSensitive() const;
+- bool highlightMatches() const;
+- void setFoundMatch(bool match);
+- void setSearchText(const QString&);
+-
+- bool event(QEvent* e) Q_DECL_OVERRIDE;
+-
+-public Q_SLOTS:
+- void setVisible(bool visible) Q_DECL_OVERRIDE;
+- void clear();
+- void findNext();
+- void findPrevious();
+- void textChanged(const QString&);
+-
+-Q_SIGNALS:
+- void searchTextChanged(const QString& text, bool backward = false);
+-
+-private:
+- Ui::SearchBar m_ui;
+- QPointer<QWidget> m_focusWidget;
+-};
+-
+-#endif // SEARCHBAR_P_H
+diff --git a/webenginepart/src/ui/searchbar.ui a/webenginepart/src/ui/searchbar.ui
+deleted file mode 100644
+index 0ed50bdda..000000000
+--- a/webenginepart/src/ui/searchbar.ui
++++ /dev/null
+@@ -1,168 +0,0 @@
+-<?xml version="1.0" encoding="UTF-8"?>
+-<ui version="4.0">
+- <class>SearchBar</class>
+- <widget class="QWidget" name="SearchBar">
+- <property name="geometry">
+- <rect>
+- <x>0</x>
+- <y>0</y>
+- <width>564</width>
+- <height>34</height>
+- </rect>
+- </property>
+- <property name="sizePolicy">
+- <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+- <horstretch>0</horstretch>
+- <verstretch>0</verstretch>
+- </sizepolicy>
+- </property>
+- <layout class="QHBoxLayout" name="horizontalLayout">
+- <item>
+- <widget class="QToolButton" name="closeButton">
+- <property name="toolTip">
+- <string>Close the search bar</string>
+- </property>
+- <property name="autoRaise">
+- <bool>true</bool>
+- </property>
+- </widget>
+- </item>
+- <item>
+- <widget class="QLabel" name="searchInfo">
+- <property name="text">
+- <string>&amp;Find:</string>
+- </property>
+- <property name="buddy">
+- <cstring>searchComboBox</cstring>
+- </property>
+- </widget>
+- </item>
+- <item>
+- <widget class="KHistoryComboBox" name="searchComboBox">
+- <property name="sizePolicy">
+- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+- <horstretch>0</horstretch>
+- <verstretch>0</verstretch>
+- </sizepolicy>
+- </property>
+- </widget>
+- </item>
+- <item>
+- <widget class="QToolButton" name="nextButton">
+- <property name="enabled">
+- <bool>false</bool>
+- </property>
+- <property name="toolTip">
+- <string>Find the next match for the current search phrase</string>
+- </property>
+- <property name="text">
+- <string>&amp;Next</string>
+- </property>
+- </widget>
+- </item>
+- <item>
+- <widget class="QToolButton" name="previousButton">
+- <property name="enabled">
+- <bool>false</bool>
+- </property>
+- <property name="toolTip">
+- <string>Find the previous match for the current search phrase</string>
+- </property>
+- <property name="text">
+- <string>&amp;Previous</string>
+- </property>
+- </widget>
+- </item>
+- <item>
+- <widget class="QToolButton" name="optionsButton">
+- <property name="toolTip">
+- <string>Find the previous match for the current search phrase</string>
+- </property>
+- <property name="text">
+- <string>&amp;Options</string>
+- </property>
+- <property name="popupMode">
+- <enum>QToolButton::InstantPopup</enum>
+- </property>
+- </widget>
+- </item>
+- <item>
+- <spacer name="horizontalSpacer">
+- <property name="orientation">
+- <enum>Qt::Horizontal</enum>
+- </property>
+- <property name="sizeType">
+- <enum>QSizePolicy::MinimumExpanding</enum>
+- </property>
+- <property name="sizeHint" stdset="0">
+- <size>
+- <width>20</width>
+- <height>20</height>
+- </size>
+- </property>
+- </spacer>
+- </item>
+- </layout>
+- <action name="actionMatchCase">
+- <property name="checkable">
+- <bool>true</bool>
+- </property>
+- <property name="text">
+- <string>&amp;Match Case</string>
+- </property>
+- </action>
+- <action name="actionSearchAutomatically">
+- <property name="checkable">
+- <bool>true</bool>
+- </property>
+- <property name="checked">
+- <bool>true</bool>
+- </property>
+- <property name="text">
+- <string>&amp;Search As You Type</string>
+- </property>
+- </action>
+- <action name="actionHighlightMatch">
+- <property name="checkable">
+- <bool>true</bool>
+- </property>
+- <property name="text">
+- <string>&amp;Highlight All Matches</string>
+- </property>
+- <property name="toolTip">
+- <string>Highlight Matches</string>
+- </property>
+- </action>
+- </widget>
+- <customwidgets>
+- <customwidget>
+- <class>KComboBox</class>
+- <extends>QComboBox</extends>
+- <header>kcombobox.h</header>
+- </customwidget>
+- <customwidget>
+- <class>KHistoryComboBox</class>
+- <extends>KComboBox</extends>
+- <header>khistorycombobox.h</header>
+- </customwidget>
+- </customwidgets>
+- <resources/>
+- <connections>
+- <connection>
+- <sender>closeButton</sender>
+- <signal>clicked()</signal>
+- <receiver>SearchBar</receiver>
+- <slot>close()</slot>
+- <hints>
+- <hint type="sourcelabel">
+- <x>16</x>
+- <y>16</y>
+- </hint>
+- <hint type="destinationlabel">
+- <x>290</x>
+- <y>16</y>
+- </hint>
+- </hints>
+- </connection>
+- </connections>
+-</ui>
+diff --git a/webenginepart/src/utils.h a/webenginepart/src/utils.h
+deleted file mode 100644
+index c3b33267c..000000000
+--- a/webenginepart/src/utils.h
++++ /dev/null
+@@ -1,16 +0,0 @@
+-#ifndef WEBENGINEPART_UTILS_H
+-#define WEBENGINEPART_UTILS_H
+-
+-namespace Utils
+-{
+-
+-#define QL1S(x) QLatin1String(x)
+-#define QL1C(x) QLatin1Char(x)
+-
+-inline bool isBlankUrl(const QUrl& url)
+-{
+- return (url.isEmpty() || url.url() == QL1S("about:blank"));
+-}
+-
+-}
+-#endif // WEBENGINEPART_UTILS_H
+diff --git a/webenginepart/src/webenginepage.cpp a/webenginepart/src/webenginepage.cpp
+deleted file mode 100644
+index cde853641..000000000
+--- a/webenginepart/src/webenginepage.cpp
++++ /dev/null
+@@ -1,888 +0,0 @@
+-/*
+- * This file is part of the KDE project.
+- *
+- * Copyright (C) 2008 Dirk Mueller <mueller@kde.org>
+- * Copyright (C) 2008 - 2010 Urs Wolfer <uwolfer @ kde.org>
+- * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
+- *
+- * 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 <http://www.gnu.org/licenses/>.
+- *
+- */
+-
+-#include "webenginepage.h"
+-
+-#include "webenginepart.h"
+-#include "websslinfo.h"
+-#include "webengineview.h"
+-#include "settings/webenginesettings.h"
+-#include <QWebEngineSettings>
+-#include <QWebEngineProfile>
+-
+-#include <KMessageBox>
+-#include <KRun>
+-#include <KLocalizedString>
+-#include <KShell>
+-#include <KAuthorized>
+-#include <KStringHandler>
+-#include <KUrlAuthorized>
+-#include <KSharedConfig>
+-#include <KIO/Job>
+-#include <KIO/AccessManager>
+-#include <KIO/Scheduler>
+-#include <KParts/HtmlExtension>
+-#include <QStandardPaths>
+-#include <QDesktopWidget>
+-
+-#include <QFile>
+-#include <QApplication>
+-#include <QTextDocument> // Qt::escape
+-#include <QNetworkReply>
+-#include <QWebEngineHistory>
+-#include <QWebEngineHistoryItem>
+-#include <QWebEngineDownloadItem>
+-#include <QUrlQuery>
+-#include <KConfigGroup>
+-//#include <QWebSecurityOrigin>
+-#include "utils.h"
+-
+-
+-WebEnginePage::WebEnginePage(WebEnginePart *part, QWidget *parent)
+- : QWebEnginePage(parent),
+- m_kioErrorCode(0),
+- m_ignoreError(false),
+- m_part(part)
+-{
+- if (view())
+- WebEngineSettings::self()->computeFontSizes(view()->logicalDpiY());
+-
+- //setForwardUnsupportedContent(true);
+-
+- connect(this, &QWebEnginePage::geometryChangeRequested,
+- this, &WebEnginePage::slotGeometryChangeRequested);
+-// connect(this, SIGNAL(unsupportedContent(QNetworkReply*)),
+-// this, SLOT(slotUnsupportedContent(QNetworkReply*)));
+- connect(this, &QWebEnginePage::featurePermissionRequested,
+- this, &WebEnginePage::slotFeaturePermissionRequested);
+- connect(this, &QWebEnginePage::loadFinished,
+- this, &WebEnginePage::slotLoadFinished);
+- connect(this->profile(), &QWebEngineProfile::downloadRequested, this, &WebEnginePage::downloadRequest);
+- if(!this->profile()->httpUserAgent().contains(QLatin1String("Konqueror")))
+- {
+- this->profile()->setHttpUserAgent(this->profile()->httpUserAgent() + " Konqueror (WebEnginePart)");
+- }
+-}
+-
+-WebEnginePage::~WebEnginePage()
+-{
+- //kDebug() << this;
+-}
+-
+-const WebSslInfo& WebEnginePage::sslInfo() const
+-{
+- return m_sslInfo;
+-}
+-
+-void WebEnginePage::setSslInfo (const WebSslInfo& info)
+-{
+- m_sslInfo = info;
+-}
+-
+-static void checkForDownloadManager(QWidget* widget, QString& cmd)
+-{
+- cmd.clear();
+- KConfigGroup cfg (KSharedConfig::openConfig(QStringLiteral("konquerorrc"), KConfig::NoGlobals), "HTML Settings");
+- const QString fileName (cfg.readPathEntry("DownloadManager", QString()));
+- if (fileName.isEmpty())
+- return;
+-
+- const QString exeName = QStandardPaths::findExecutable(fileName);
+- if (exeName.isEmpty()) {
+- KMessageBox::detailedSorry(widget,
+- i18n("The download manager (%1) could not be found in your installation.", fileName),
+- i18n("Try to reinstall it and make sure that it is available in $PATH. \n\nThe integration will be disabled."));
+- cfg.writePathEntry("DownloadManager", QString());
+- cfg.sync();
+- return;
+- }
+-
+- cmd = exeName;
+-}
+-
+-void WebEnginePage::downloadRequest(QWebEngineDownloadItem* request)
+-{
+- const QUrl url(request->url());
+-
+- // Integration with a download manager...
+- if (!url.isLocalFile()) {
+- QString managerExe;
+- checkForDownloadManager(view(), managerExe);
+- if (!managerExe.isEmpty()) {
+- //kDebug() << "Calling command" << cmd;
+- KRun::runCommand((managerExe + QLatin1Char(' ') + KShell::quoteArg(url.url())), view());
+- return;
+- }
+- }
+- request->accept();
+-
+-}
+-
+-QWebEnginePage *WebEnginePage::createWindow(WebWindowType type)
+-{
+- //qDebug() << "window type:" << type;
+- // Crete an instance of NewWindowPage class to capture all the
+- // information we need to create a new window. See documentation of
+- // the class for more information...
+- NewWindowPage* page = new NewWindowPage(type, part());
+- return page;
+-}
+-
+-// Returns true if the scheme and domain of the two urls match...
+-static bool domainSchemeMatch(const QUrl& u1, const QUrl& u2)
+-{
+- if (u1.scheme() != u2.scheme())
+- return false;
+-
+- QStringList u1List = u1.host().split(QL1C('.'), QString::SkipEmptyParts);
+- QStringList u2List = u2.host().split(QL1C('.'), QString::SkipEmptyParts);
+-
+- if (qMin(u1List.count(), u2List.count()) < 2)
+- return false; // better safe than sorry...
+-
+- while (u1List.count() > 2)
+- u1List.removeFirst();
+-
+- while (u2List.count() > 2)
+- u2List.removeFirst();
+-
+- return (u1List == u2List);
+-}
+-
+-bool WebEnginePage::acceptNavigationRequest(const QUrl& url, NavigationType type, bool isMainFrame)
+-{
+- qDebug() << url << "type=" << type;
+- QUrl reqUrl(url);
+-
+- // Handle "mailto:" url here...
+- if (handleMailToUrl(reqUrl, type))
+- return false;
+-
+- const bool isTypedUrl = property("NavigationTypeUrlEntered").toBool();
+-
+- /*
+- NOTE: We use a dynamic QObject property called "NavigationTypeUrlEntered"
+- to distinguish between requests generated by user entering a url vs those
+- that were generated programatically through javascript (AJAX requests).
+- */
+- if (isMainFrame && isTypedUrl)
+- setProperty("NavigationTypeUrlEntered", QVariant());
+-
+- // inPage requests are those generarted within the current page through
+- // link clicks, javascript queries, and button clicks (form submission).
+- bool inPageRequest = true;
+- switch (type) {
+- case QWebEnginePage::NavigationTypeFormSubmitted:
+- //if (!checkFormData(request))
+- // return false;
+- break;
+-#if 0
+- case QWebEnginePage::NavigationTypeFormResubmitted:
+- if (!checkFormData(request))
+- return false;
+- if (KMessageBox::warningContinueCancel(view(),
+- i18n("<qt><p>To display the requested web page again, "
+- "the browser needs to resend information you have "
+- "previously submitted.</p>"
+- "<p>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.</p>"),
+- 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()));
+- // Insert the request into the queue...
+- 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<QNetworkRequest::Attribute>(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<QWebFrame *>(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<QNetworkRequest::Attribute>(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<QNetworkRequest::Attribute>(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<NewWindowPage*>(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("<qt>This untrusted page links to<br/><b>%1</b>."
+- "<br/>Do you want to follow the link?</qt>", linkUrl.url());
+- title = i18n("Security Warning");
+- buttonText = i18nc("follow link despite of security warning", "Follow");
+- } else {
+- title = i18n("Security Alert");
+- message = i18n("<qt>Access by untrusted page to<br/><b>%1</b><br/> denied.</qt>",
+- 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
+-{
+- const QString scheme (req.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<QPair<QString, QString> > 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 (QString::compare(url.scheme(), QL1S("mailto"), Qt::CaseInsensitive) == 0) {
+- QStringList files;
+- QUrl mailtoUrl (sanitizeMailToUrl(url, files));
+-
+- switch (type) {
+- case QWebEnginePage::NavigationTypeLinkClicked:
+- if (!files.isEmpty() && KMessageBox::warningContinueCancelList(0,
+- i18n("<qt>Do you want to allow this site to attach "
+- "the following files to the email message?</qt>"),
+- 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));
+-}
+-
+-
+-
+-
+-
+-/************************************* 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("<qt>This site is requesting to open a popup window to"
+- "<p>%1</p><br/>Do you want to allow this?</qt>",
+- 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<WebEnginePart*>(newWindowPart);
+- WebEngineView* webView = webenginePart ? qobject_cast<WebEngineView*>(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;
+- }
+-
+- 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<WebEnginePart*>(newWindowPart) : 0;
+- WebEngineView* webView = webenginePart ? qobject_cast<WebEngineView*>(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 a/webenginepart/src/webenginepage.h
+deleted file mode 100644
+index 0cd74ac1b..000000000
+--- a/webenginepart/src/webenginepage.h
++++ /dev/null
+@@ -1,162 +0,0 @@
+-/*
+- * This file is part of the KDE project.
+- *
+- * Copyright (C) 2008 Dirk Mueller <mueller@kde.org>
+- * Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
+- * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
+- *
+- * 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 <http://www.gnu.org/licenses/>.
+- *
+- */
+-
+-#ifndef WEBENGINEPAGE_H
+-#define WEBENGINEPAGE_H
+-
+-#include "websslinfo.h"
+-
+-#include <KParts/BrowserExtension>
+-#include <QtWebEngineWidgets/QWebEnginePage>
+-
+-#include <QUrl>
+-#include <QDebug>
+-#include <QMultiHash>
+-#include <QPointer>
+-
+-class QUrl;
+-class WebSslInfo;
+-class WebEnginePart;
+-class QWebEngineDownloadItem;
+-
+-
+-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);
+-
+- /**
+- * Reimplemented for internal reasons. The API is not affected.
+- *
+- * @internal
+- * @see KWebEnginePage::downloadRequest.
+- */
+- void downloadRequest(QWebEngineDownloadItem* request);
+-
+-Q_SIGNALS:
+- /**
+- * This signal is emitted whenever a user cancels/aborts a load resource
+- * request.
+- */
+- void loadAborted(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);
+-
+-private:
+- bool checkLinkSecurity(const QNetworkRequest& req, NavigationType type) const;
+- bool checkFormData(const QNetworkRequest& req) 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<WebEnginePart> m_part;
+-};
+-
+-
+-/**
+- * 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;
+-};
+-
+-#endif // WEBENGINEPAGE_H
+diff --git a/webenginepart/src/webenginepart.cpp a/webenginepart/src/webenginepart.cpp
+deleted file mode 100644
+index 10bbffc15..000000000
+--- a/webenginepart/src/webenginepart.cpp
++++ /dev/null
+@@ -1,926 +0,0 @@
+-/*
+- * This file is part of the KDE project.
+- *
+- * Copyright (C) 2007 Trolltech ASA
+- * Copyright (C) 2008 - 2010 Urs Wolfer <uwolfer @ kde.org>
+- * Copyright (C) 2008 Laurent Montel <montel@kde.org>
+- * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
+- * Copyright (C) 2013 Allan Sandfeld Jensen <sandfeld@kde.org>
+- *
+- * 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 <http://www.gnu.org/licenses/>.
+- *
+- */
+-
+-#include "webenginepart.h"
+-
+-//#include <QWebHistoryItem>
+-#include <QWebEngineSettings>
+-#include <QWebEngineProfile>
+-#include <QUrlQuery>
+-
+-#include "webenginepart_ext.h"
+-#include "webengineview.h"
+-#include "webenginepage.h"
+-#include "websslinfo.h"
+-#include "webhistoryinterface.h"
+-
+-#include "ui/searchbar.h"
+-#include "ui/passwordbar.h"
+-#include "ui/featurepermissionbar.h"
+-#include "settings/webenginesettings.h"
+-
+-#include <kcodecaction.h>
+-#include <kio/global.h>
+-
+-#include <KActionCollection>
+-#include <KAboutData>
+-#include <KUrlLabel>
+-#include <KMessageBox>
+-#include <KStringHandler>
+-#include <KToolInvocation>
+-#include <KAcceleratorManager>
+-#include <KFileItem>
+-#include <KMessageWidget>
+-#include <KProtocolInfo>
+-#include <KToggleAction>
+-#include <KParts/StatusBarExtension>
+-#include <KParts/GUIActivateEvent>
+-#include <KLocalizedString>
+-#include <KConfigGroup>
+-#include <KSharedConfig>
+-#include <KSslInfoDialog>
+-
+-#include <QUrl>
+-#include <QFile>
+-#include <QTextCodec>
+-#include <QCoreApplication>
+-#include <QVBoxLayout>
+-#include <QDBusInterface>
+-#include <QMenu>
+-#include <QStatusBar>
+-#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)
+-{
+- 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();
+-}
+-
+-WebEnginePart::~WebEnginePart()
+-{
+-}
+-
+-WebEnginePage* WebEnginePart::page()
+-{
+- if (m_webView)
+- return qobject_cast<WebEnginePage*>(m_webView->page());
+- return Q_NULLPTR;
+-}
+-
+-const WebEnginePage* WebEnginePart::page() const
+-{
+- if (m_webView)
+- return qobject_cast<const WebEnginePage*>(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> () << 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> () << 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", "<h3>Find text</h3>"
+- "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()));
+- }
+-#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 <title> 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 {
+-// Attempt to fill the web form...
+-// KWebWallet *webWallet = page() ? page()->wallet() : 0;
+-// if (webWallet) {
+-// webWallet->fillFormData(frame, false);
+-// }
+- }
+- }
+-
+- 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<QString, QStringList> fields;
+- QUrlQuery query(linkUrl);
+- QList<QPair<QString, QString> > queryItems = query.queryItems();
+- const int count = queryItems.count();
+-
+- for(int i = 0; i < count; ++i) {
+- const QPair<QString, QString> 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<QBoxLayout*>(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("<qt>Do you want to search for <b>%1</b>?</qt>", 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())
+- return;
+-
+-// page()->wallet()->removeFormData(page()->mainFrame(), true);
+- 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()));
+- QBoxLayout* lay = qobject_cast<QBoxLayout*>(widget()->layout());
+- if (lay)
+- lay->insertWidget(0, m_featurePermissionBar);
+- }
+- m_featurePermissionBar->setFeature(feature);
+-// m_featurePermissionBar->setText(i18n("<html>Do you want to grant the site <b>%1</b> "
+-// "access to information about your current physical location?",
+-// url.host()));
+- m_featurePermissionBar->setText(i18n("<html>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!";
+- return;
+- }
+- connect(m_passwordBar, SIGNAL(saveFormDataAccepted(QString)),
+- wallet, SLOT(acceptSaveFormDataRequest(QString)));
+- connect(m_passwordBar, SIGNAL(saveFormDataRejected(QString)),
+- 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("<html>Do you want %1 to remember the login "
+- "information for <b>%2</b>?</html>",
+- QCoreApplication::applicationName(),
+- url.host()));
+-
+- QBoxLayout* lay = qobject_cast<QBoxLayout*>(widget()->layout());
+- if (lay)
+- lay->insertWidget(0, m_passwordBar);
+-
+- m_passwordBar->animatedShow();
+-}
+-
+-void WebEnginePart::slotSaveFormDataDone()
+-{
+- if (!m_passwordBar)
+- return;
+-
+- QBoxLayout* lay = qobject_cast<QBoxLayout*>(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.desktop a/webenginepart/src/webenginepart.desktop
+deleted file mode 100644
+index 5d6085773..000000000
+--- a/webenginepart/src/webenginepart.desktop
++++ /dev/null
+@@ -1,65 +0,0 @@
+-[Desktop Entry]
+-Type=Service
+-Comment=Embeddable HTML component
+-Comment[ca]=Component HTML incrustable
+-Comment[ca@valencia]=Component HTML incrustable
+-Comment[cs]=Zapouzdřitelná HTML komponenta
+-Comment[da]=HTML-komponent som kan indlejres
+-Comment[de]=Einbettungsfähige HTML-Komponente
+-Comment[en_GB]=Embeddable HTML component
+-Comment[es]=Componente HTML empotrable
+-Comment[et]=Põimitav HTML-komponent
+-Comment[fi]=Upotettava HTML-osa
+-Comment[it]=Componente HTML incorporabile
+-Comment[ko]=끼워넣을 수 있는 HTML 구성 요소
+-Comment[nb]=Innebyggbar HTML-komponent
+-Comment[nl]=In te bedden HTML-component
+-Comment[nn]=Innebyggbar HTML-komponent
+-Comment[pl]=Osadzalny składnik HTML
+-Comment[pt]=Componente incorporada de HTML
+-Comment[pt_BR]=Componete HTML embutido
+-Comment[sk]=Vložiteľný HTML komponent
+-Comment[sl]=Vgradljiv sestavni del HTML
+-Comment[sr]=Угнездива ХТМЛ компонента
+-Comment[sr@ijekavian]=Угњездива ХТМЛ компонента
+-Comment[sr@ijekavianlatin]=Ugnjezdiva HTML komponenta
+-Comment[sr@latin]=Ugnezdiva HTML komponenta
+-Comment[sv]=Inbäddningsbar HTML-komponent
+-Comment[uk]=Придатний до вбудовування компонент HTML
+-Comment[x-test]=xxEmbeddable HTML componentxx
+-Comment[zh_CN]=可嵌入的 HTML 组件
+-Comment[zh_TW]=可內嵌的 HTML 元件
+-Icon=webengine
+-MimeType=text/html;application/xml;application/xhtml+xml;
+-Name=WebEngine
+-Name[ca]=WebEngine
+-Name[ca@valencia]=WebEngine
+-Name[cs]=WebEngine
+-Name[da]=WebEngine
+-Name[de]=Webengine
+-Name[en_GB]=WebEngine
+-Name[es]=Motor Web
+-Name[et]=WebEngine
+-Name[fi]=WebEngine
+-Name[it]=WebEngine
+-Name[ko]=WebEngine
+-Name[nl]=WebEngine
+-Name[nn]=Vevmotor
+-Name[pl]=SilnikSieciowy
+-Name[pt]=Motor Web
+-Name[pt_BR]=WebEngine
+-Name[sk]=WebEngine
+-Name[sl]=Spletni pogon
+-Name[sr]=КуТ‑вебенџин
+-Name[sr@ijekavian]=КуТ‑вебенџин
+-Name[sr@ijekavianlatin]=QtWebEngine
+-Name[sr@latin]=QtWebEngine
+-Name[sv]=Webbgränssnitt
+-Name[uk]=Вебрушій
+-Name[x-test]=xxWebEnginexx
+-Name[zh_CN]=WebEngine
+-Name[zh_TW]=WebEngine
+-X-KDE-Default-UserAgent=Mozilla/5.0 (%PLATFORM%; %SECURITY%; %OSNAME% %OSVERSION% %SYSTYPE%; %LANGUAGE%) AppleWebKit/534.34 (KHTML, like Gecko) %APPVERSION% Safari/534.34
+-X-KDE-ServiceTypes=KParts/ReadOnlyPart,Browser/View
+-X-KDE-Library=kf5/parts/webenginepart
+-InitialPreference=12
+diff --git a/webenginepart/src/webenginepart.h a/webenginepart/src/webenginepart.h
+deleted file mode 100644
+index 6889e6d7f..000000000
+--- a/webenginepart/src/webenginepart.h
++++ /dev/null
+@@ -1,165 +0,0 @@
+-/*
+- * This file is part of the KDE project.
+- *
+- * Copyright (C) 2007 Trolltech ASA
+- * Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
+- * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
+- *
+- * 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 <http://www.gnu.org/licenses/>.
+- *
+- */
+-#ifndef WEBENGINEPART_H
+-#define WEBENGINEPART_H
+-
+-#include "kwebenginepartlib_export.h"
+-
+-#include <QtWebEngineWidgets/QWebEnginePage>
+-
+-#include <KParts/ReadOnlyPart>
+-#include <QUrl>
+-
+-namespace KParts {
+- class BrowserExtension;
+- class StatusBarExtension;
+-}
+-
+-class QWebEngineView;
+-class WebEngineView;
+-class WebEnginePage;
+-class SearchBar;
+-class PasswordBar;
+-class FeaturePermissionBar;
+-class KUrlLabel;
+-class WebEngineBrowserExtension;
+-
+-/**
+- * 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);
+-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;
+-};
+-
+-#endif // WEBENGINEPART_H
+diff --git a/webenginepart/src/webenginepart.rc a/webenginepart/src/webenginepart.rc
+deleted file mode 100644
+index 2b564ca97..000000000
+--- a/webenginepart/src/webenginepart.rc
++++ /dev/null
+@@ -1,32 +0,0 @@
+-<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
+-<kpartgui name="kwebkitpart" version="8">
+-<MenuBar>
+- <Menu name="file">
+- <Action name="saveDocument" />
+- <Action name="saveFrame" />
+- <Separator />
+- <Action name="printPreview" group="print" />
+- </Menu>
+- <Menu name="edit">
+- <Action name="selectAll" />
+- <Separator />
+- <Action name="find" />
+- </Menu>
+- <Menu name="view">
+- <Action name="zoomIn" />
+- <Action name="zoomOut" />
+- <Action name="zoomNormal" />
+- <Action name="zoomTextOnly" />
+- <Action name="zoomToDPI" />
+- <Separator />
+- <Action name="setEncoding" />
+- <Action name="viewDocumentSource" />
+- <ActionList name="debugScriptList" />
+- </Menu>
+-</MenuBar>
+-<ToolBar name="htmlToolBar" iconText="icononly" iconSize="22" hidden="true"><text>HTML Toolbar</text>
+- <Action name="zoomIn" />
+- <Action name="zoomOut" />
+- <Action name="zoomNormal" />
+-</ToolBar>
+-</kpartgui>
+diff --git a/webenginepart/src/webenginepart_ext.cpp a/webenginepart/src/webenginepart_ext.cpp
+deleted file mode 100644
+index b80de84ad..000000000
+--- a/webenginepart/src/webenginepart_ext.cpp
++++ /dev/null
+@@ -1,1237 +0,0 @@
+-/*
+- * This file is part of the KDE project.
+- *
+- * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
+- *
+- * 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 <http://www.gnu.org/licenses/>.
+- *
+- */
+-
+-#include <QtWebEngine/QtWebEngineVersion>
+-#include "webenginepart_ext.h"
+-
+-#include "webenginepart.h"
+-#include "webengineview.h"
+-#include "webenginepage.h"
+-#include "settings/webenginesettings.h"
+-#include <QtWebEngineWidgets/QWebEngineSettings>
+-
+-#include <KDesktopFile>
+-#include <KConfigGroup>
+-#include <KToolInvocation>
+-#include <KSharedConfig>
+-#include <KRun>
+-#include <KProtocolInfo>
+-#include <QInputDialog>
+-#include <KLocalizedString>
+-#include <QTemporaryFile>
+-#include <KUriFilter>
+-#include <Sonnet/Dialog>
+-#include <sonnet/backgroundchecker.h>
+-
+-#include <QBuffer>
+-#include <QVariant>
+-#include <QClipboard>
+-#include <QApplication>
+-#include <QAction>
+-#include <QPrinter>
+-#include <QPrintDialog>
+-#include <QPrintPreviewDialog>
+-#include <QInputDialog>
+-#include <QWebEngineHistory>
+-#include <QMimeData>
+-#define QL1S(x) QLatin1String(x)
+-#define QL1C(x) QLatin1Char(x)
+-
+-template<typename Arg, typename R, typename C>
+-struct InvokeWrapper {
+- R *receiver;
+- void (C::*memberFun)(Arg);
+- void operator()(Arg result)
+- {
+- (receiver->*memberFun)(result);
+- }
+-};
+-
+-template<typename Arg, typename R, typename C>
+-InvokeWrapper<Arg, R, C> invoke(R *receiver, void (C::*memberFun)(Arg))
+-{
+- InvokeWrapper<Arg, R, C> wrapper = {receiver, memberFun};
+- return wrapper;
+-}
+-
+-WebEngineBrowserExtension::WebEngineBrowserExtension(WebEnginePart *parent, const QByteArray& cachedHistoryData)
+- :KParts::BrowserExtension(parent),
+- m_part(parent),
+- mCurrentPrinter(Q_NULLPTR)
+-{
+- enableAction("cut", false);
+- enableAction("copy", false);
+- enableAction("paste", false);
+- enableAction("print", true);
+-
+- if (cachedHistoryData.isEmpty()) {
+- return;
+- }
+-
+- QBuffer buffer;
+- buffer.setData(cachedHistoryData);
+- if (!buffer.open(QIODevice::ReadOnly)) {
+- return;
+- }
+-
+- // NOTE: When restoring history, webengine PORTING_TODO automatically navigates to
+- // the previous "currentItem". Since we do not want that to happen,
+- // we set a property on the WebEnginePage object that is used to allow or
+- // disallow history navigation in WebEnginePage::acceptNavigationRequest.
+- view()->page()->setProperty("HistoryNavigationLocked", true);
+- QDataStream s (&buffer);
+- s >> *(view()->history());
+-}
+-
+-WebEngineBrowserExtension::~WebEngineBrowserExtension()
+-{
+-}
+-
+-WebEngineView* WebEngineBrowserExtension::view()
+-{
+- if (!m_view && m_part) {
+- m_view = qobject_cast<WebEngineView*>(m_part->view());
+- }
+-
+- return m_view;
+-}
+-
+-int WebEngineBrowserExtension::xOffset()
+-{
+-#if QTWEBENGINE_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+- if (view())
+- return view()->page()->scrollPosition().x();
+-#endif
+-
+- return KParts::BrowserExtension::xOffset();
+-}
+-
+-int WebEngineBrowserExtension::yOffset()
+-{
+-#if QTWEBENGINE_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+- if (view())
+- return view()->page()->scrollPosition().y();
+-#endif
+-
+- return KParts::BrowserExtension::yOffset();
+-}
+-
+-void WebEngineBrowserExtension::saveState(QDataStream &stream)
+-{
+- // TODO: Save information such as form data from the current page.
+- QWebEngineHistory* history = (view() ? view()->history() : 0);
+- const int historyIndex = (history ? history->currentItemIndex() : -1);
+- const QUrl historyUrl = (history && historyIndex > -1) ? QUrl(history->currentItem().url()) : m_part->url();
+-
+- stream << historyUrl
+- << static_cast<qint32>(xOffset())
+- << static_cast<qint32>(yOffset())
+- << historyIndex
+- << m_historyData;
+-}
+-
+-void WebEngineBrowserExtension::restoreState(QDataStream &stream)
+-{
+- QUrl u;
+- QByteArray historyData;
+- qint32 xOfs = -1, yOfs = -1, historyItemIndex = -1;
+- stream >> u >> xOfs >> yOfs >> historyItemIndex >> historyData;
+-
+- QWebEngineHistory* history = (view() ? view()->page()->history() : 0);
+- if (history) {
+- bool success = false;
+- if (history->count() == 0) { // Handle restoration: crash recovery, tab close undo, session restore
+- if (!historyData.isEmpty()) {
+- historyData = qUncompress(historyData); // uncompress the history data...
+- QBuffer buffer (&historyData);
+- if (buffer.open(QIODevice::ReadOnly)) {
+- QDataStream stream (&buffer);
+- view()->page()->setProperty("HistoryNavigationLocked", true);
+- stream >> *history;
+- QWebEngineHistoryItem currentItem (history->currentItem());
+- if (currentItem.isValid()) {
+- if (currentItem.isValid() && (xOfs != -1 || yOfs != -1)) {
+- const QPoint scrollPos (xOfs, yOfs);
+-// currentItem.setUserData(scrollPos);
+- }
+- // NOTE 1: The following Konqueror specific workaround is necessary
+- // because Konqueror only preserves information for the last visited
+- // page. However, we save the entire history content in saveState and
+- // and hence need to elimiate all but the current item here.
+- // NOTE 2: This condition only applies when Konqueror is restored from
+- // abnormal termination ; a crash and/or a session restoration.
+- if (QCoreApplication::applicationName() == QLatin1String("konqueror")) {
+- history->clear();
+- }
+- //kDebug() << "Restoring URL:" << currentItem.url();
+- m_part->setProperty("NoEmitOpenUrlNotification", true);
+- history->goToItem(currentItem);
+- }
+- }
+- }
+- success = (history->count() > 0);
+- } else { // Handle navigation: back and forward button navigation.
+- //kDebug() << "history count:" << history->count() << "request index:" << historyItemIndex;
+- if (history->count() > historyItemIndex && historyItemIndex > -1) {
+- QWebEngineHistoryItem item (history->itemAt(historyItemIndex));
+- //kDebug() << "URL:" << u << "Item URL:" << item.url();
+- if (u == item.url()) {
+- if (item.isValid() && (xOfs != -1 || yOfs != -1)) {
+- const QPoint scrollPos (xOfs, yOfs);
+-// item.setUserData(scrollPos);
+- }
+- m_part->setProperty("NoEmitOpenUrlNotification", true);
+- history->goToItem(item);
+- success = true;
+- }
+- }
+- }
+-
+- if (success) {
+- return;
+- }
+- }
+-
+- // As a last resort, in case the history restoration logic above fails,
+- // attempt to open the requested URL directly.
+- qDebug() << "Normal history navgation logic failed! Falling back to opening url directly.";
+- m_part->openUrl(u);
+-}
+-
+-
+-void WebEngineBrowserExtension::cut()
+-{
+- if (view())
+- view()->triggerPageAction(QWebEnginePage::Cut);
+-}
+-
+-void WebEngineBrowserExtension::copy()
+-{
+- if (view())
+- view()->triggerPageAction(QWebEnginePage::Copy);
+-}
+-
+-void WebEngineBrowserExtension::paste()
+-{
+- if (view())
+- view()->triggerPageAction(QWebEnginePage::Paste);
+-}
+-
+-void WebEngineBrowserExtension::slotSaveDocument()
+-{
+- if (view())
+- emit saveUrl(view()->url());
+-}
+-
+-void WebEngineBrowserExtension::slotSaveFrame()
+-{
+- if (view())
+- emit saveUrl(view()->page()->url()); // TODO lol
+-}
+-
+-void WebEngineBrowserExtension::print()
+-{
+-#if QTWEBENGINE_VERSION >= QT_VERSION_CHECK(5, 8, 0)
+- if (view()) {
+- mCurrentPrinter = new QPrinter();
+- QPointer<QPrintDialog> dialog = new QPrintDialog(mCurrentPrinter, Q_NULLPTR);
+- dialog->setWindowTitle(i18n("Print Document"));
+- if (dialog->exec() != QDialog::Accepted) {
+- slotHandlePagePrinted(false);
+- delete dialog;
+- return;
+- }
+- delete dialog;
+- view()->page()->print(mCurrentPrinter, invoke(this, &WebEngineBrowserExtension::slotHandlePagePrinted));
+- }
+-#endif
+-}
+-
+-void WebEngineBrowserExtension::slotHandlePagePrinted(bool result)
+-{
+- Q_UNUSED(result);
+- delete mCurrentPrinter;
+- mCurrentPrinter = Q_NULLPTR;
+-}
+-
+-
+-void WebEngineBrowserExtension::updateEditActions()
+-{
+- if (!view())
+- return;
+-
+- enableAction("cut", view()->pageAction(QWebEnginePage::Cut)->isEnabled());
+- enableAction("copy", view()->pageAction(QWebEnginePage::Copy)->isEnabled());
+- enableAction("paste", view()->pageAction(QWebEnginePage::Paste)->isEnabled());
+-}
+-
+-void WebEngineBrowserExtension::updateActions()
+-{
+- const QString protocol (m_part->url().scheme());
+- const bool isValidDocument = (protocol != QL1S("about") && protocol != QL1S("error"));
+- enableAction("print", isValidDocument);
+-}
+-
+-void WebEngineBrowserExtension::searchProvider()
+-{
+- if (!view())
+- return;
+-
+- QAction *action = qobject_cast<QAction*>(sender());
+- if (!action)
+- return;
+-
+- QUrl url = action->data().toUrl();
+-
+- if (url.host().isEmpty()) {
+- KUriFilterData data;
+- data.setData(action->data().toString());
+- if (KUriFilter::self()->filterSearchUri(data, KUriFilter::WebShortcutFilter))
+- url = data.uri();
+- }
+-
+- if (!url.isValid())
+- return;
+-
+- KParts::BrowserArguments bargs;
+- bargs.frameName = QL1S("_blank");
+- emit openUrlRequest(url, KParts::OpenUrlArguments(), bargs);
+-}
+-
+-void WebEngineBrowserExtension::reparseConfiguration()
+-{
+- // Force the configuration stuff to reparse...
+- WebEngineSettings::self()->init();
+-}
+-
+-void WebEngineBrowserExtension::disableScrolling()
+-{
+- QWebEngineView* currentView = view();
+- QWebEnginePage* page = currentView ? currentView->page() : 0;
+-
+- if (!page)
+- return;
+-
+- page->runJavaScript(QStringLiteral("document.documentElement.style.overflow = 'hidden';"));
+-}
+-
+-void WebEngineBrowserExtension::zoomIn()
+-{
+- if (view())
+- view()->setZoomFactor(view()->zoomFactor() + 0.1);
+-}
+-
+-void WebEngineBrowserExtension::zoomOut()
+-{
+- if (view())
+- view()->setZoomFactor(view()->zoomFactor() - 0.1);
+-}
+-
+-void WebEngineBrowserExtension::zoomNormal()
+-{
+- if (view()) {
+- if (WebEngineSettings::self()->zoomToDPI())
+- view()->setZoomFactor(view()->logicalDpiY() / 96.0f);
+- else
+- view()->setZoomFactor(1);
+- }
+-}
+-
+-void WebEngineBrowserExtension::toogleZoomTextOnly()
+-{
+- if (!view())
+- return;
+-
+- KConfigGroup cgHtml(KSharedConfig::openConfig(), "HTML Settings");
+- bool zoomTextOnly = cgHtml.readEntry( "ZoomTextOnly", false );
+- cgHtml.writeEntry("ZoomTextOnly", !zoomTextOnly);
+- cgHtml.sync();
+-
+- // view()->settings()->setAttribute(QWebEngineSettings::ZoomTextOnly, !zoomTextOnly);
+-}
+-
+-void WebEngineBrowserExtension::toogleZoomToDPI()
+-{
+- if (!view())
+- return;
+-
+- bool zoomToDPI = !WebEngineSettings::self()->zoomToDPI();
+- WebEngineSettings::self()->setZoomToDPI(zoomToDPI);
+-
+- if (zoomToDPI)
+- view()->setZoomFactor(view()->zoomFactor() * view()->logicalDpiY() / 96.0f);
+- else
+- view()->setZoomFactor(view()->zoomFactor() * 96.0f / view()->logicalDpiY());
+-
+- // Recompute default font-sizes since they are only DPI dependent when zoomToDPI is false.
+- WebEngineSettings::self()->computeFontSizes(view()->logicalDpiY());
+-}
+-
+-void WebEngineBrowserExtension::slotSelectAll()
+-{
+- if (view())
+- view()->triggerPageAction(QWebEnginePage::SelectAll);
+-}
+-
+-void WebEngineBrowserExtension::slotSaveImageAs()
+-{
+- if (view())
+- view()->triggerPageAction(QWebEnginePage::DownloadImageToDisk);
+-}
+-
+-void WebEngineBrowserExtension::slotSendImage()
+-{
+-#if QTWEBENGINE_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+- if (!view())
+- return;
+-
+- QStringList urls;
+- urls.append(view()->contextMenuResult().mediaUrl().path());
+- const QString subject = view()->contextMenuResult().mediaUrl().path();
+- KToolInvocation::invokeMailer(QString(), QString(), QString(), subject,
+- QString(), //body
+- QString(),
+- urls); // attachments
+-#endif
+-}
+-
+-void WebEngineBrowserExtension::slotCopyImageURL()
+-{
+-#if QTWEBENGINE_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+- if (!view())
+- return;
+-
+- QUrl safeURL = view()->contextMenuResult().mediaUrl();
+- safeURL.setPassword(QString());
+- // Set it in both the mouse selection and in the clipboard
+- QMimeData* mimeData = new QMimeData;
+-//TODO: Porting: test
+- QList<QUrl> safeURLList;
+- safeURLList.append(safeURL);
+- mimeData->setUrls(safeURLList);
+- QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard);
+-
+- mimeData = new QMimeData;
+- mimeData->setUrls(safeURLList);
+- QApplication::clipboard()->setMimeData(mimeData, QClipboard::Selection);
+-#endif
+-}
+-
+-
+-void WebEngineBrowserExtension::slotCopyImage()
+-{
+-#if QTWEBENGINE_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+- if (!view())
+- return;
+-
+- QUrl safeURL; //(view()->contextMenuResult().imageUrl());
+- safeURL.setPassword(QString());
+-
+- // Set it in both the mouse selection and in the clipboard
+- QMimeData* mimeData = new QMimeData;
+-// mimeData->setImageData(view()->contextMenuResult().pixmap());
+-//TODO: Porting: test
+- QList<QUrl> safeURLList;
+- safeURLList.append(safeURL);
+- mimeData->setUrls(safeURLList);
+- QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard);
+-
+- mimeData = new QMimeData;
+-// mimeData->setImageData(view()->contextMenuResult().pixmap());
+- mimeData->setUrls(safeURLList);
+- QApplication::clipboard()->setMimeData(mimeData, QClipboard::Selection);
+-#endif
+-}
+-
+-void WebEngineBrowserExtension::slotViewImage()
+-{
+-#if QTWEBENGINE_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+- if (view())
+- emit createNewWindow(view()->contextMenuResult().mediaUrl());
+-#endif
+-}
+-
+-void WebEngineBrowserExtension::slotBlockImage()
+-{
+-#if QTWEBENGINE_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+- if (!view())
+- return;
+-
+- bool ok = false;
+- const QString url = QInputDialog::getText(view(), i18n("Add URL to Filter"),
+- i18n("Enter the URL:"), QLineEdit::Normal,
+- view()->contextMenuResult().mediaUrl().toString(),
+- &ok);
+- if (ok) {
+- WebEngineSettings::self()->addAdFilter(url);
+- reparseConfiguration();
+- }
+-#endif
+-}
+-
+-void WebEngineBrowserExtension::slotBlockHost()
+-{
+- if (!view())
+- return;
+-
+- QUrl url; // (view()->contextMenuResult().imageUrl());
+- url.setPath(QL1S("/*"));
+- WebEngineSettings::self()->addAdFilter(url.toString(QUrl::RemoveUserInfo | QUrl::RemovePort));
+- reparseConfiguration();
+-}
+-
+-void WebEngineBrowserExtension::slotCopyLinkURL()
+-{
+- if (view())
+- view()->triggerPageAction(QWebEnginePage::CopyLinkToClipboard);
+-}
+-
+-void WebEngineBrowserExtension::slotCopyLinkText()
+-{
+-#if QTWEBENGINE_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+- if (view()) {
+- QMimeData* data = new QMimeData;
+- data->setText(view()->contextMenuResult().linkText());
+- QApplication::clipboard()->setMimeData(data, QClipboard::Clipboard);
+- }
+-#endif
+-}
+-
+-void WebEngineBrowserExtension::slotCopyEmailAddress()
+-{
+-#if QTWEBENGINE_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+- if (view()) {
+- QMimeData* data = new QMimeData;
+- const QUrl url(view()->contextMenuResult().linkUrl());
+- data->setText(url.path());
+- QApplication::clipboard()->setMimeData(data, QClipboard::Clipboard);
+- }
+-#endif
+-}
+-
+-void WebEngineBrowserExtension::slotSaveLinkAs()
+-{
+- if (view())
+- view()->triggerPageAction(QWebEnginePage::DownloadLinkToDisk);
+-}
+-
+-void WebEngineBrowserExtension::slotViewDocumentSource()
+-{
+- if (!view())
+- return;
+-
+- const QUrl pageUrl (view()->url());
+- if (pageUrl.isLocalFile()) {
+- KRun::runUrl(pageUrl, QL1S("text/plain"), view(), false);
+- } else {
+- view()->page()->toHtml([this](const QString& html) {
+- QTemporaryFile tempFile;
+- tempFile.setFileTemplate(tempFile.fileTemplate() + QL1S(".html"));
+- tempFile.setAutoRemove(false);
+- if (tempFile.open()) {
+- tempFile.write(html.toUtf8());
+- KRun::runUrl(QUrl::fromLocalFile(tempFile.fileName()), QL1S("text/plain"), view(), true, false);
+- }
+- });
+- }
+-}
+-
+-#if QTWEBENGINE_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+-static bool isMultimediaElement(QWebEngineContextMenuData::MediaType mediaType)
+-{
+- switch(mediaType)
+- {
+- case QWebEngineContextMenuData::MediaTypeVideo:
+- case QWebEngineContextMenuData::MediaTypeAudio:
+- return true;
+- default:
+- return false;
+- }
+-}
+-#endif
+-
+-void WebEngineBrowserExtension::slotLoopMedia()
+-{
+-#if QTWEBENGINE_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+- if (!view())
+- return;
+-
+- QWebEngineContextMenuData data = view()->contextMenuResult();
+- if (!isMultimediaElement( data.mediaType()))
+- return;
+- view()->page()->triggerAction(QWebEnginePage::ToggleMediaLoop);
+-#endif
+-}
+-
+-void WebEngineBrowserExtension::slotMuteMedia()
+-{
+-#if QTWEBENGINE_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+- if (!view())
+- return;
+-
+- QWebEngineContextMenuData data = view()->contextMenuResult();
+- if (!isMultimediaElement( data.mediaType()))
+- return;
+- view()->page()->triggerAction(QWebEnginePage::ToggleMediaMute);
+-#endif
+-}
+-
+-void WebEngineBrowserExtension::slotPlayMedia()
+-{
+-#if QTWEBENGINE_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+- if (!view())
+- return;
+-
+- QWebEngineContextMenuData data = view()->contextMenuResult();
+- if (!isMultimediaElement( data.mediaType()))
+- return;
+- view()->page()->triggerAction(QWebEnginePage::ToggleMediaPlayPause);
+-#endif
+-}
+-
+-void WebEngineBrowserExtension::slotShowMediaControls()
+-{
+-#if QTWEBENGINE_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+- if (!view())
+- return;
+-
+- QWebEngineContextMenuData data = view()->contextMenuResult();
+- if (!isMultimediaElement( data.mediaType()))
+- return;
+- view()->page()->triggerAction(QWebEnginePage::ToggleMediaControls);
+-#endif
+-}
+-
+-#if 0
+-static QUrl mediaUrlFrom(QWebElement& element)
+-{
+- QWebFrame* frame = element.webFrame();
+- QString src = frame ? element.attribute(QL1S("src")) : QString();
+- if (src.isEmpty())
+- src = frame ? element.evaluateJavaScript(QL1S("this.src")).toString() : QString();
+-
+- if (src.isEmpty())
+- return QUrl();
+-
+- return QUrl(frame->baseUrl().resolved(QUrl::fromEncoded(QUrl::toPercentEncoding(src), QUrl::StrictMode)));
+-}
+-#endif
+-
+-void WebEngineBrowserExtension::slotSaveMedia()
+-{
+-#if QTWEBENGINE_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+- if (!view())
+- return;
+-
+- QWebEngineContextMenuData data = view()->contextMenuResult();
+- if (!isMultimediaElement( data.mediaType()))
+- return;
+- emit saveUrl(data.mediaUrl());
+-#endif
+-}
+-
+-void WebEngineBrowserExtension::slotCopyMedia()
+-{
+-#if QTWEBENGINE_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+- if (!view())
+- return;
+- QWebEngineContextMenuData data = view()->contextMenuResult();
+- if (!isMultimediaElement( data.mediaType()))
+- return;
+-
+- QUrl safeURL(data.mediaUrl());
+- if (!safeURL.isValid())
+- return;
+-
+- safeURL.setPassword(QString());
+- // Set it in both the mouse selection and in the clipboard
+- QMimeData* mimeData = new QMimeData;
+-//TODO: Porting: test
+- QList<QUrl> safeURLList;
+- safeURLList.append(safeURL);
+- mimeData->setUrls(safeURLList);
+- QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard);
+-
+- mimeData = new QMimeData;
+- mimeData->setUrls(safeURLList);
+- QApplication::clipboard()->setMimeData(mimeData, QClipboard::Selection);
+-#endif
+-}
+-
+-void WebEngineBrowserExtension::slotTextDirectionChanged()
+-{
+- QAction* action = qobject_cast<QAction*>(sender());
+- if (action) {
+- bool ok = false;
+- const int value = action->data().toInt(&ok);
+- if (ok) {
+- view()->triggerPageAction(static_cast<QWebEnginePage::WebAction>(value));
+- }
+- }
+-}
+-
+-static QVariant execJScript(WebEngineView* view, const QString& script)
+-{
+-#if 0
+- QWebElement element (view->contextMenuResult().element());
+- if (element.isNull())
+- return QVariant();
+- return element.evaluateJavaScript(script);
+-#endif
+- return QVariant();
+-}
+-
+-void WebEngineBrowserExtension::slotCheckSpelling()
+-{
+- const QString text (execJScript(view(), QL1S("this.value")).toString());
+-
+- if ( text.isEmpty() ) {
+- return;
+- }
+-
+- m_spellTextSelectionStart = 0;
+- m_spellTextSelectionEnd = 0;
+-
+- Sonnet::BackgroundChecker *backgroundSpellCheck = new Sonnet::BackgroundChecker;
+- Sonnet::Dialog* spellDialog = new Sonnet::Dialog(backgroundSpellCheck, view());
+- backgroundSpellCheck->setParent(spellDialog);
+- spellDialog->setAttribute(Qt::WA_DeleteOnClose, true);
+- spellDialog->showSpellCheckCompletionMessage(true);
+- connect(spellDialog, SIGNAL(replace(QString,int,QString)), this, SLOT(spellCheckerCorrected(QString,int,QString)));
+- connect(spellDialog, SIGNAL(misspelling(QString,int)), this, SLOT(spellCheckerMisspelling(QString,int)));
+- spellDialog->setBuffer(text);
+- spellDialog->show();
+-}
+-
+-void WebEngineBrowserExtension::slotSpellCheckSelection()
+-{
+- QString text (execJScript(view(), QL1S("this.value")).toString());
+-
+- if ( text.isEmpty() ) {
+- return;
+- }
+-
+- m_spellTextSelectionStart = qMax(0, execJScript(view(), QL1S("this.selectionStart")).toInt());
+- m_spellTextSelectionEnd = qMax(0, execJScript(view(), QL1S("this.selectionEnd")).toInt());
+- // kDebug() << "selection start:" << m_spellTextSelectionStart << "end:" << m_spellTextSelectionEnd;
+-
+- Sonnet::BackgroundChecker *backgroundSpellCheck = new Sonnet::BackgroundChecker;
+- Sonnet::Dialog* spellDialog = new Sonnet::Dialog(backgroundSpellCheck, view());
+- backgroundSpellCheck->setParent(spellDialog);
+- spellDialog->setAttribute(Qt::WA_DeleteOnClose, true);
+- spellDialog->showSpellCheckCompletionMessage(true);
+- connect(spellDialog, SIGNAL(replace(QString,int,QString)), this, SLOT(spellCheckerCorrected(QString,int,QString)));
+- connect(spellDialog, SIGNAL(misspelling(QString,int)), this, SLOT(spellCheckerMisspelling(QString,int)));
+- connect(spellDialog, SIGNAL(done(QString)), this, SLOT(slotSpellCheckDone(QString)));
+- spellDialog->setBuffer(text.mid(m_spellTextSelectionStart, (m_spellTextSelectionEnd - m_spellTextSelectionStart)));
+- spellDialog->show();
+-}
+-
+-void WebEngineBrowserExtension::spellCheckerCorrected(const QString& original, int pos, const QString& replacement)
+-{
+- // Adjust the selection end...
+- if (m_spellTextSelectionEnd > 0) {
+- m_spellTextSelectionEnd += qMax (0, (replacement.length() - original.length()));
+- }
+-
+- const int index = pos + m_spellTextSelectionStart;
+- QString script(QL1S("this.value=this.value.substring(0,"));
+- script += QString::number(index);
+- script += QL1S(") + \"");
+- script += replacement;
+- script += QL1S("\" + this.value.substring(");
+- script += QString::number(index + original.length());
+- script += QL1S(")");
+-
+- //kDebug() << "**** script:" << script;
+- execJScript(view(), script);
+-}
+-
+-void WebEngineBrowserExtension::spellCheckerMisspelling(const QString& text, int pos)
+-{
+- // kDebug() << text << pos;
+- QString selectionScript (QL1S("this.setSelectionRange("));
+- selectionScript += QString::number(pos + m_spellTextSelectionStart);
+- selectionScript += QL1C(',');
+- selectionScript += QString::number(pos + text.length() + m_spellTextSelectionStart);
+- selectionScript += QL1C(')');
+- execJScript(view(), selectionScript);
+-}
+-
+-void WebEngineBrowserExtension::slotSpellCheckDone(const QString&)
+-{
+- // Restore the text selection if one was present before we started the
+- // spell check.
+- if (m_spellTextSelectionStart > 0 || m_spellTextSelectionEnd > 0) {
+- QString script (QL1S("; this.setSelectionRange("));
+- script += QString::number(m_spellTextSelectionStart);
+- script += QL1C(',');
+- script += QString::number(m_spellTextSelectionEnd);
+- script += QL1C(')');
+- execJScript(view(), script);
+- }
+-}
+-
+-
+-void WebEngineBrowserExtension::saveHistory()
+-{
+- QWebEngineHistory* history = (view() ? view()->history() : 0);
+-
+- if (history && history->count() > 0) {
+- //kDebug() << "Current history: index=" << history->currentItemIndex() << "url=" << history->currentItem().url();
+- QByteArray histData;
+- QBuffer buff (&histData);
+- m_historyData.clear();
+- if (buff.open(QIODevice::WriteOnly)) {
+- QDataStream stream (&buff);
+- stream << *history;
+- m_historyData = qCompress(histData, 9);
+- }
+- QWidget* mainWidget = m_part ? m_part->widget() : 0;
+- QWidget* frameWidget = mainWidget ? mainWidget->parentWidget() : 0;
+- if (frameWidget) {
+- emit saveHistory(frameWidget, m_historyData);
+- // kDebug() << "# of items:" << history->count() << "current item:" << history->currentItemIndex() << "url:" << history->currentItem().url();
+- }
+- } else {
+- Q_ASSERT(false); // should never happen!!!
+- }
+-}
+-
+-void WebEngineBrowserExtension::slotPrintPreview()
+-{
+-#if 0
+- // Make it non-modal, in case a redirection deletes the part
+- QPointer<QPrintPreviewDialog> dlg (new QPrintPreviewDialog(view()));
+- connect(dlg.data(), SIGNAL(paintRequested(QPrinter*)),
+- view()->page()->currentFrame(), SLOT(print(QPrinter*)));
+- dlg->exec();
+- delete dlg;
+-#endif
+-}
+-
+-void WebEngineBrowserExtension::slotOpenSelection()
+-{
+- QAction *action = qobject_cast<QAction*>(sender());
+- if (action) {
+- KParts::BrowserArguments browserArgs;
+- browserArgs.frameName = QStringLiteral("_blank");
+- emit openUrlRequest(QUrl(action->data().toUrl()), KParts::OpenUrlArguments(), browserArgs);
+- }
+-}
+-
+-void WebEngineBrowserExtension::slotLinkInTop()
+-{
+-#if QTWEBENGINE_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+- if (!view())
+- return;
+-
+- KParts::OpenUrlArguments uargs;
+- uargs.setActionRequestedByUser(true);
+-
+- KParts::BrowserArguments bargs;
+- bargs.frameName = QL1S("_top");
+-
+- const QUrl url(view()->contextMenuResult().linkUrl());
+-
+- emit openUrlRequest(url, uargs, bargs);
+-#endif
+-}
+-
+-////
+-
+-WebEngineTextExtension::WebEngineTextExtension(WebEnginePart* part)
+- : KParts::TextExtension(part)
+-{
+- connect(part->view(), SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
+-}
+-
+-WebEnginePart* WebEngineTextExtension::part() const
+-{
+- return static_cast<WebEnginePart*>(parent());
+-}
+-
+-bool WebEngineTextExtension::hasSelection() const
+-{
+- return part()->view()->hasSelection();
+-}
+-
+-QString WebEngineTextExtension::selectedText(Format format) const
+-{
+- switch(format) {
+- case PlainText:
+- return part()->view()->selectedText();
+- case HTML:
+- // PORTING_TODO selectedText might not be html
+- return part()->view()->selectedText();
+- }
+- return QString();
+-}
+-
+-QString WebEngineTextExtension::completeText(Format format) const
+-{
+- // TODO David will hunt me down with a rusty spork if he sees this
+- QEventLoop ev;
+- QString str;
+- switch(format) {
+- case PlainText:
+- part()->view()->page()->toPlainText([&ev,&str](const QString& data) {
+- str = data;
+- ev.quit();
+- });
+- case HTML:
+- part()->view()->page()->toHtml([&ev,&str](const QString& data) {
+- str = data;
+- ev.quit();
+- });
+- }
+- ev.exec();
+- return QString();
+-}
+-
+-////
+-
+-WebEngineHtmlExtension::WebEngineHtmlExtension(WebEnginePart* part)
+- : KParts::HtmlExtension(part)
+-{
+-}
+-
+-
+-QUrl WebEngineHtmlExtension::baseUrl() const
+-{
+- return part()->view()->page()->url();
+-}
+-
+-bool WebEngineHtmlExtension::hasSelection() const
+-{
+- return part()->view()->hasSelection();
+-}
+-
+-KParts::SelectorInterface::QueryMethods WebEngineHtmlExtension::supportedQueryMethods() const
+-{
+- return (KParts::SelectorInterface::EntireContent
+- | KParts::SelectorInterface::SelectedContent);
+-}
+-
+-#if 0
+-static KParts::SelectorInterface::Element convertWebElement(const QWebElement& webElem)
+-{
+- KParts::SelectorInterface::Element element;
+- element.setTagName(webElem.tagName());
+- Q_FOREACH(const QString &attr, webElem.attributeNames()) {
+- element.setAttribute(attr, webElem.attribute(attr));
+- }
+- return element;
+-}
+-#endif
+-
+-static QString queryOne(const QString& query)
+-{
+- QString jsQuery = QL1S("(function(query) { var element; var selectedElement = window.getSelection().getRangeAt(0).cloneContents().querySelector(\"");
+- jsQuery += query;
+- jsQuery += QL1S("\"); if (selectedElement && selectedElement.length > 0) { element = new Object; "
+- "element.tagName = String(selectedElements[0].tagName); element.href = String(selectedElements[0].href); } "
+- "return element; }())");
+- return jsQuery;
+-}
+-
+-static QString queryAll(const QString& query)
+-{
+- QString jsQuery = QL1S("(function(query) { var elements = []; var selectedElements = window.getSelection().getRangeAt(0).cloneContents().querySelectorAll(\"");
+- jsQuery += query;
+- jsQuery += QL1S("\"); var numSelectedElements = (selectedElements ? selectedElements.length : 0);"
+- "for (var i = 0; i < numSelectedElements; ++i) { var element = new Object; "
+- "element.tagName = String(selectedElements[i].tagName); element.href = String(selectedElements[i].href);"
+- "elements.push(element); } return elements; } ())");
+- return jsQuery;
+-}
+-
+-static KParts::SelectorInterface::Element convertSelectionElement(const QVariant& variant)
+-{
+- KParts::SelectorInterface::Element element;
+- if (!variant.isNull() && variant.type() == QVariant::Map) {
+- const QVariantMap elementMap (variant.toMap());
+- element.setTagName(elementMap.value(QL1S("tagName")).toString());
+- element.setAttribute(QL1S("href"), elementMap.value(QL1S("href")).toString());
+- }
+- return element;
+-}
+-
+-static QList<KParts::SelectorInterface::Element> convertSelectionElements(const QVariant& variant)
+-{
+- QList<KParts::SelectorInterface::Element> elements;
+- const QVariantList resultList (variant.toList());
+- Q_FOREACH(const QVariant& result, resultList) {
+- const QVariantMap elementMap = result.toMap();
+- KParts::SelectorInterface::Element element;
+- element.setTagName(elementMap.value(QL1S("tagName")).toString());
+- element.setAttribute(QL1S("href"), elementMap.value(QL1S("href")).toString());
+- elements.append(element);
+- }
+- return elements;
+-}
+-
+-KParts::SelectorInterface::Element WebEngineHtmlExtension::querySelector(const QString& query, KParts::SelectorInterface::QueryMethod method) const
+-{
+- KParts::SelectorInterface::Element element;
+-
+- // If the specified method is None, return an empty list...
+- if (method == KParts::SelectorInterface::None)
+- return element;
+-
+- // If the specified method is not supported, return an empty list...
+- if (!(supportedQueryMethods() & method))
+- return element;
+-
+-#if 0
+- switch (method) {
+- case KParts::SelectorInterface::EntireContent: {
+- const QWebFrame* webFrame = part()->view()->page()->mainFrame();
+- element = convertWebElement(webFrame->findFirstElement(query));
+- break;
+- }
+- case KParts::SelectorInterface::SelectedContent: {
+- QWebFrame* webFrame = part()->view()->page()->mainFrame();
+- element = convertSelectionElement(webFrame->evaluateJavaScript(queryOne(query)));
+- break;
+- }
+- default:
+- break;
+- }
+-#endif
+-
+- return element;
+-}
+-
+-QList<KParts::SelectorInterface::Element> WebEngineHtmlExtension::querySelectorAll(const QString& query, KParts::SelectorInterface::QueryMethod method) const
+-{
+- QList<KParts::SelectorInterface::Element> elements;
+-
+- // If the specified method is None, return an empty list...
+- if (method == KParts::SelectorInterface::None)
+- return elements;
+-
+- // If the specified method is not supported, return an empty list...
+- if (!(supportedQueryMethods() & method))
+- return elements;
+-#if 0
+- switch (method) {
+- case KParts::SelectorInterface::EntireContent: {
+- const QWebFrame* webFrame = part()->view()->page()->mainFrame();
+- const QWebElementCollection collection = webFrame->findAllElements(query);
+- elements.reserve(collection.count());
+- Q_FOREACH(const QWebElement& element, collection)
+- elements.append(convertWebElement(element));
+- break;
+- }
+- case KParts::SelectorInterface::SelectedContent: {
+- QWebFrame* webFrame = part()->view()->page()->mainFrame();
+- elements = convertSelectionElements(webFrame->evaluateJavaScript(queryAll(query)));
+- break;
+- }
+- default:
+- break;
+- }
+-#endif
+- return elements;
+-}
+-
+-QVariant WebEngineHtmlExtension::htmlSettingsProperty(KParts::HtmlSettingsInterface::HtmlSettingsType type) const
+-{
+- QWebEngineView* view = part() ? part()->view() : 0;
+- QWebEnginePage* page = view ? view->page() : 0;
+- QWebEngineSettings* settings = page ? page->settings() : 0;
+-
+- if (settings) {
+- switch (type) {
+- case KParts::HtmlSettingsInterface::AutoLoadImages:
+- return settings->testAttribute(QWebEngineSettings::AutoLoadImages);
+- case KParts::HtmlSettingsInterface::JavaEnabled:
+- return false; // settings->testAttribute(QWebEngineSettings::JavaEnabled);
+- case KParts::HtmlSettingsInterface::JavascriptEnabled:
+- return settings->testAttribute(QWebEngineSettings::JavascriptEnabled);
+- case KParts::HtmlSettingsInterface::PluginsEnabled:
+- return settings->testAttribute(QWebEngineSettings::PluginsEnabled);
+- case KParts::HtmlSettingsInterface::DnsPrefetchEnabled:
+- return false; //settings->testAttribute(QWebEngineSettings::DnsPrefetchEnabled);
+- case KParts::HtmlSettingsInterface::MetaRefreshEnabled:
+- return view->pageAction(QWebEnginePage::Stop)->isEnabled();
+- case KParts::HtmlSettingsInterface::LocalStorageEnabled:
+- return settings->testAttribute(QWebEngineSettings::LocalStorageEnabled);
+- case KParts::HtmlSettingsInterface::OfflineStorageDatabaseEnabled:
+- return false; //settings->testAttribute(QWebEngineSettings::OfflineStorageDatabaseEnabled);
+- case KParts::HtmlSettingsInterface::OfflineWebApplicationCacheEnabled:
+- return false ;//settings->testAttribute(QWebEngineSettings::OfflineWebApplicationCacheEnabled);
+- case KParts::HtmlSettingsInterface::PrivateBrowsingEnabled:
+- return false; //settings->testAttribute(QWebEngineSettings::PrivateBrowsingEnabled);
+- case KParts::HtmlSettingsInterface::UserDefinedStyleSheetURL:
+- return false; //settings->userStyleSheetUrl();
+- default:
+- break;
+- }
+- }
+-
+- return QVariant();
+-}
+-
+-bool WebEngineHtmlExtension::setHtmlSettingsProperty(KParts::HtmlSettingsInterface::HtmlSettingsType type, const QVariant& value)
+-{
+- QWebEngineView* view = part() ? part()->view() : 0;
+- QWebEnginePage* page = view ? view->page() : 0;
+- QWebEngineSettings* settings = page ? page->settings() : 0;
+-
+- if (settings) {
+- switch (type) {
+- case KParts::HtmlSettingsInterface::AutoLoadImages:
+- settings->setAttribute(QWebEngineSettings::AutoLoadImages, value.toBool());
+- return true;
+- case KParts::HtmlSettingsInterface::JavaEnabled:
+- //settings->setAttribute(QWebESettings::JavaEnabled, value.toBool());
+- return false;
+- case KParts::HtmlSettingsInterface::JavascriptEnabled:
+- settings->setAttribute(QWebEngineSettings::JavascriptEnabled, value.toBool());
+- return true;
+- case KParts::HtmlSettingsInterface::PluginsEnabled:
+- settings->setAttribute(QWebEngineSettings::PluginsEnabled, value.toBool());
+- return true;
+- case KParts::HtmlSettingsInterface::DnsPrefetchEnabled:
+-// settings->setAttribute(QWebEngineSettings::DnsPrefetchEnabled, value.toBool());
+- return false;
+- case KParts::HtmlSettingsInterface::MetaRefreshEnabled:
+- view->triggerPageAction(QWebEnginePage::Stop);
+- return true;
+- case KParts::HtmlSettingsInterface::LocalStorageEnabled:
+- settings->setAttribute(QWebEngineSettings::LocalStorageEnabled, value.toBool());
+- return false;
+- case KParts::HtmlSettingsInterface::OfflineStorageDatabaseEnabled:
+- //settings->setAttribute(QWebEngineSettings::OfflineStorageDatabaseEnabled, value.toBool());
+- return false;
+- case KParts::HtmlSettingsInterface::OfflineWebApplicationCacheEnabled:
+- //settings->setAttribute(QWebEngineSettings::OfflineWebApplicationCacheEnabled, value.toBool());
+- return false;
+- case KParts::HtmlSettingsInterface::PrivateBrowsingEnabled:
+- //settings->setAttribute(QWebEnngineSettings::PrivateBrowsingEnabled, value.toBool());
+- return false;
+- case KParts::HtmlSettingsInterface::UserDefinedStyleSheetURL:
+- //kDebug() << "Setting user style sheet for" << page << "to" << value.toUrl();
+- // settings->setUserStyleSheetUrl(value.toUrl());
+- return false;
+- default:
+- break;
+- }
+- }
+-
+- return false;
+-}
+-
+-WebEnginePart* WebEngineHtmlExtension::part() const
+-{
+- return static_cast<WebEnginePart*>(parent());
+-}
+-
+-WebEngineScriptableExtension::WebEngineScriptableExtension(WebEnginePart* part)
+- : ScriptableExtension(part)
+-{
+-}
+-
+-QVariant WebEngineScriptableExtension::rootObject()
+-{
+- return QVariant::fromValue(KParts::ScriptableExtension::Object(this, reinterpret_cast<quint64>(this)));
+-}
+-
+-bool WebEngineScriptableExtension::setException (KParts::ScriptableExtension* callerPrincipal, const QString& message)
+-{
+- return KParts::ScriptableExtension::setException (callerPrincipal, message);
+-}
+-
+-QVariant WebEngineScriptableExtension::get (KParts::ScriptableExtension* callerPrincipal, quint64 objId, const QString& propName)
+-{
+- //kDebug() << "caller:" << callerPrincipal << "id:" << objId << "propName:" << propName;
+- return callerPrincipal->get (0, objId, propName);
+-}
+-
+-bool WebEngineScriptableExtension::put (KParts::ScriptableExtension* callerPrincipal, quint64 objId, const QString& propName, const QVariant& value)
+-{
+- return KParts::ScriptableExtension::put (callerPrincipal, objId, propName, value);
+-}
+-
+-static QVariant exception(const char* msg)
+-{
+- qWarning() << msg;
+- return QVariant::fromValue(KParts::ScriptableExtension::Exception(QString::fromLatin1(msg)));
+-}
+-
+-QVariant WebEngineScriptableExtension::evaluateScript (KParts::ScriptableExtension* callerPrincipal,
+- quint64 contextObjectId,
+- const QString& code,
+- KParts::ScriptableExtension::ScriptLanguage lang)
+-{
+- Q_UNUSED(contextObjectId);
+- Q_UNUSED(code)
+- //kDebug() << "principal:" << callerPrincipal << "id:" << contextObjectId << "language:" << lang << "code:" << code;
+-
+- if (lang != ECMAScript)
+- return exception("unsupported language");
+-
+-
+- KParts::ReadOnlyPart* part = callerPrincipal ? qobject_cast<KParts::ReadOnlyPart*>(callerPrincipal->parent()) : 0;
+- // QWebFrame* frame = part ? qobject_cast<QWebFrame*>(part->parent()) : 0;
+- // if (!frame)
+- return exception("failed to resolve principal");
+-#if 0
+- QVariant result (frame->evaluateJavaScript(code));
+-
+- if (result.type() == QVariant::Map) {
+- const QVariantMap map (result.toMap());
+- for (QVariantMap::const_iterator it = map.constBegin(), itEnd = map.constEnd(); it != itEnd; ++it) {
+- callerPrincipal->put(callerPrincipal, 0, it.key(), it.value());
+- }
+- } else {
+- const QString propName(code.contains(QLatin1String("__nsplugin")) ? QLatin1String("__nsplugin") : QString());
+- callerPrincipal->put(callerPrincipal, 0, propName, result.toString());
+- }
+-
+- return QVariant::fromValue(ScriptableExtension::Null());
+-#endif
+-}
+-
+-bool WebEngineScriptableExtension::isScriptLanguageSupported (KParts::ScriptableExtension::ScriptLanguage lang) const
+-{
+- return (lang == KParts::ScriptableExtension::ECMAScript);
+-}
+-
+-QVariant WebEngineScriptableExtension::encloserForKid (KParts::ScriptableExtension* kid)
+-{
+-#if 0
+- KParts::ReadOnlyPart* part = kid ? qobject_cast<KParts::ReadOnlyPart*>(kid->parent()) : 0;
+- QWebFrame* frame = part ? qobject_cast<QWebFrame*>(part->parent()) : 0;
+- if (frame) {
+- return QVariant::fromValue(KParts::ScriptableExtension::Object(kid, reinterpret_cast<quint64>(kid)));
+- }
+-#endif
+-
+- return QVariant::fromValue(ScriptableExtension::Null());
+-}
+-
+-WebEnginePart* WebEngineScriptableExtension::part()
+-{
+- return qobject_cast<WebEnginePart*>(parent());
+-}
+-
+diff --git a/webenginepart/src/webenginepart_ext.h a/webenginepart/src/webenginepart_ext.h
+deleted file mode 100644
+index 550daa7d8..000000000
+--- a/webenginepart/src/webenginepart_ext.h
++++ /dev/null
+@@ -1,201 +0,0 @@
+-/*
+- * This file is part of the KDE project.
+- *
+- * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
+- *
+- * 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 <http://www.gnu.org/licenses/>.
+- *
+- */
+-
+-#ifndef WEBENGINEPART_EXT_H
+-#define WEBENGINEPART_EXT_H
+-
+-#include "kwebenginepartlib_export.h"
+-
+-#include <QPointer>
+-
+-#include <KParts/BrowserExtension>
+-#include <KParts/TextExtension>
+-#include <KParts/HtmlExtension>
+-#include <KParts/HtmlSettingsInterface>
+-#include <KParts/ScriptableExtension>
+-#include <KParts/SelectorInterface>
+-
+-class QUrl;
+-class WebEnginePart;
+-class WebEngineView;
+-class QPrinter;
+-class KWEBENGINEPARTLIB_EXPORT WebEngineBrowserExtension : public KParts::BrowserExtension
+-{
+- Q_OBJECT
+-
+-public:
+- WebEngineBrowserExtension(WebEnginePart *parent, const QByteArray& cachedHistoryData);
+- ~WebEngineBrowserExtension();
+-
+- virtual int xOffset() override;
+- virtual int yOffset() override;
+- virtual void saveState(QDataStream &) override;
+- virtual void restoreState(QDataStream &) override;
+- void saveHistory();
+-
+-Q_SIGNALS:
+- void saveUrl(const QUrl &);
+- void saveHistory(QObject*, const QByteArray&);
+-
+-public Q_SLOTS:
+- void cut();
+- void copy();
+- void paste();
+- void print();
+-
+- void slotSaveDocument();
+- void slotSaveFrame();
+- void searchProvider();
+- void reparseConfiguration();
+- void disableScrolling();
+-
+- void zoomIn();
+- void zoomOut();
+- void zoomNormal();
+- void toogleZoomTextOnly();
+- void toogleZoomToDPI();
+- void slotSelectAll();
+-
+- void slotSaveImageAs();
+- void slotSendImage();
+- void slotCopyImageURL();
+- void slotCopyImage();
+- void slotViewImage();
+- void slotBlockImage();
+- void slotBlockHost();
+-
+- void slotCopyLinkURL();
+- void slotCopyLinkText();
+- void slotSaveLinkAs();
+- void slotCopyEmailAddress();
+-
+- void slotViewDocumentSource();
+-
+- void updateEditActions();
+- void updateActions();
+-
+- void slotPlayMedia();
+- void slotMuteMedia();
+- void slotLoopMedia();
+- void slotShowMediaControls();
+- void slotSaveMedia();
+- void slotCopyMedia();
+- void slotTextDirectionChanged();
+- void slotCheckSpelling();
+- void slotSpellCheckSelection();
+- void slotSpellCheckDone(const QString&);
+- void spellCheckerCorrected(const QString&, int, const QString&);
+- void spellCheckerMisspelling(const QString&, int);
+- //void slotPrintRequested(QWebFrame*);
+- void slotPrintPreview();
+-
+- void slotOpenSelection();
+- void slotLinkInTop();
+-
+-private Q_SLOTS:
+- void slotHandlePagePrinted(bool result);
+-private:
+- WebEngineView* view();
+- QPointer<WebEnginePart> m_part;
+- QPointer<WebEngineView> m_view;
+- quint32 m_spellTextSelectionStart;
+- quint32 m_spellTextSelectionEnd;
+- QByteArray m_historyData;
+- QPrinter *mCurrentPrinter;
+-};
+-
+-/**
+- * @internal
+- * Implements the TextExtension interface
+- */
+-class WebEngineTextExtension : public KParts::TextExtension
+-{
+- Q_OBJECT
+-public:
+- WebEngineTextExtension(WebEnginePart* part);
+-
+- bool hasSelection() const Q_DECL_OVERRIDE;
+- QString selectedText(Format format) const Q_DECL_OVERRIDE;
+- QString completeText(Format format) const Q_DECL_OVERRIDE;
+-
+-private:
+- WebEnginePart* part() const;
+-};
+-
+-/**
+- * @internal
+- * Implements the HtmlExtension interface
+- */
+-class WebEngineHtmlExtension : public KParts::HtmlExtension,
+- public KParts::SelectorInterface,
+- public KParts::HtmlSettingsInterface
+-{
+- Q_OBJECT
+- Q_INTERFACES(KParts::SelectorInterface)
+- Q_INTERFACES(KParts::HtmlSettingsInterface)
+-
+-public:
+- WebEngineHtmlExtension(WebEnginePart* part);
+-
+- // HtmlExtension
+- QUrl baseUrl() const Q_DECL_OVERRIDE;
+- bool hasSelection() const Q_DECL_OVERRIDE;
+-
+- // SelectorInterface
+- QueryMethods supportedQueryMethods() const Q_DECL_OVERRIDE;
+- Element querySelector(const QString& query, KParts::SelectorInterface::QueryMethod method) const Q_DECL_OVERRIDE;
+- QList<Element> querySelectorAll(const QString& query, KParts::SelectorInterface::QueryMethod method) const Q_DECL_OVERRIDE;
+-
+- // HtmlSettingsInterface
+- QVariant htmlSettingsProperty(HtmlSettingsType type) const Q_DECL_OVERRIDE;
+- bool setHtmlSettingsProperty(HtmlSettingsType type, const QVariant& value) Q_DECL_OVERRIDE;
+-
+-private:
+- WebEnginePart* part() const;
+-};
+-
+-class WebEngineScriptableExtension : public KParts::ScriptableExtension
+-{
+- Q_OBJECT
+-
+-public:
+- WebEngineScriptableExtension(WebEnginePart* part);
+-
+- QVariant rootObject() Q_DECL_OVERRIDE;
+-
+- QVariant get(ScriptableExtension* callerPrincipal, quint64 objId, const QString& propName) Q_DECL_OVERRIDE;
+-
+- bool put(ScriptableExtension* callerPrincipal, quint64 objId, const QString& propName, const QVariant& value) Q_DECL_OVERRIDE;
+-
+- bool setException(ScriptableExtension* callerPrincipal, const QString& message) Q_DECL_OVERRIDE;
+-
+- QVariant evaluateScript(ScriptableExtension* callerPrincipal,
+- quint64 contextObjectId,
+- const QString& code,
+- ScriptLanguage language = ECMAScript) Q_DECL_OVERRIDE;
+-
+- bool isScriptLanguageSupported(ScriptLanguage lang) const Q_DECL_OVERRIDE;
+-
+-private:
+- QVariant encloserForKid(KParts::ScriptableExtension* kid) Q_DECL_OVERRIDE;
+- WebEnginePart* part();
+-};
+-
+-#endif // WEBENGINEPART_EXT_H
+diff --git a/webenginepart/src/webenginepartfactory.cpp a/webenginepart/src/webenginepartfactory.cpp
+deleted file mode 100644
+index 04853bd27..000000000
+--- a/webenginepart/src/webenginepartfactory.cpp
++++ /dev/null
+@@ -1,65 +0,0 @@
+-/*
+- * This file is part of the KDE project.
+- *
+- * Copyright (C) 2008 Laurent Montel <montel@kde.org>
+- *
+- * 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 <http://www.gnu.org/licenses/>.
+- *
+- */
+-
+-#include "webenginepartfactory.h"
+-#include "webenginepart_ext.h"
+-#include "webenginepart.h"
+-
+-#include <QWidget>
+-
+-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<WebEngineBrowserExtension*>(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/webenginepartfactory.h a/webenginepart/src/webenginepartfactory.h
+deleted file mode 100644
+index 1eaaf42ba..000000000
+--- a/webenginepart/src/webenginepartfactory.h
++++ /dev/null
+@@ -1,47 +0,0 @@
+-/*
+- * This file is part of the KDE project.
+- *
+- * Copyright (C) 2008 Laurent Montel <montel@kde.org>
+- *
+- * 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 <http://www.gnu.org/licenses/>.
+- *
+- */
+-
+-#ifndef WEBENGINEPARTFACTORY
+-#define WEBENGINEPARTFACTORY
+-
+-#include <kpluginfactory.h>
+-
+-#include <QHash>
+-
+-class QWidget;
+-
+-class WebEngineFactory : public KPluginFactory
+-{
+- Q_OBJECT
+- Q_PLUGIN_METADATA(IID "org.kde.KPluginFactory" FILE "")
+- Q_INTERFACES(KPluginFactory)
+-public:
+- virtual ~WebEngineFactory();
+- QObject *create(const char* iface, QWidget *parentWidget, QObject *parent, const QVariantList& args, const QString &keyword) Q_DECL_OVERRIDE;
+-
+-private Q_SLOTS:
+- void slotDestroyed(QObject* object);
+- void slotSaveHistory(QObject* widget, const QByteArray&);
+-
+-private:
+- QHash<QObject*, QByteArray> m_historyBufContainer;
+-};
+-
+-#endif // WEBENGINEPARTFACTORY
+diff --git a/webenginepart/src/webengineview.cpp a/webenginepart/src/webengineview.cpp
+deleted file mode 100644
+index 1bed6110f..000000000
+--- a/webenginepart/src/webengineview.cpp
++++ /dev/null
+@@ -1,594 +0,0 @@
+-/*
+- * This file is part of the KDE project.
+- *
+- * Copyright (C) 2007 Trolltech ASA
+- * Copyright (C) 2008 - 2010 Urs Wolfer <uwolfer @ kde.org>
+- * Copyright (C) 2008 Laurent Montel <montel@kde.org>
+- * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
+- *
+- * 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 <http://www.gnu.org/licenses/>.
+- *
+- */
+-
+-#include "webengineview.h"
+-#include "webenginepage.h"
+-#include "webenginepart.h"
+-#include "settings/webenginesettings.h"
+-
+-#include <kio/global.h>
+-#include <KAboutData>
+-#include <KActionCollection>
+-#include <KConfigGroup>
+-#include <KService>
+-#include <KUriFilter>
+-#include <KActionMenu>
+-#include <KIO/AccessManager>
+-#include <KStringHandler>
+-#include <KLocalizedString>
+-
+-#include <QTimer>
+-#include <QMimeData>
+-#include <QDropEvent>
+-#include <QLabel>
+-#include <QNetworkRequest>
+-#include <QToolTip>
+-#include <QCoreApplication>
+-#include <unistd.h>
+-#include <QMimeType>
+-#include <QMimeDatabase>
+-
+-#define QL1S(x) QLatin1String(x)
+-#define QL1C(x) QLatin1Char(x)
+-
+-#define ALTERNATE_DEFAULT_WEB_SHORTCUT QL1S("google")
+-#define ALTERNATE_WEB_SHORTCUTS QStringList() << QL1S("google") << QL1S("wikipedia") << QL1S("webster") << QL1S("dmoz")
+-
+-WebEngineView::WebEngineView(WebEnginePart* part, QWidget* parent)
+- :QWebEngineView(parent),
+- m_actionCollection(new KActionCollection(this)),
+- m_part(part),
+- m_autoScrollTimerId(-1),
+- m_verticalAutoScrollSpeed(0),
+- m_horizontalAutoScrollSpeed(0)
+-{
+- setAcceptDrops(true);
+-
+- // Create the custom page...
+- setPage(new WebEnginePage(part, this));
+-
+- connect(this, SIGNAL(loadStarted()), this, SLOT(slotStopAutoScroll()));
+-
+- if (WebEngineSettings::self()->zoomToDPI())
+- setZoomFactor(logicalDpiY() / 96.0f);
+-
+-#ifndef HAVE_WEBENGINECONTEXTMENUDATA
+- m_result = 0;
+-#endif
+-}
+-
+-WebEngineView::~WebEngineView()
+-{
+- //kDebug();
+-}
+-
+-void WebEngineView::loadUrl(const QUrl& url, const KParts::OpenUrlArguments& args, const KParts::BrowserArguments& bargs)
+-{
+- page()->setProperty("NavigationTypeUrlEntered", true);
+-
+- if (args.reload() && url == this->url()) {
+- reload();
+- return;
+- }
+-
+- QNetworkRequest request(url);
+- if (args.reload()) {
+- request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork);
+- }
+-
+- if (bargs.postData.isEmpty()) {
+- QWebEngineView::load(url);
+- } else {
+- // QWebEngineView::load(url, QNetworkAccessManager::PostOperation, bargs.postData);
+- }
+-}
+-
+-QWebEngineContextMenuData WebEngineView::contextMenuResult() const
+-{
+- return m_result;
+-}
+-
+-static void extractMimeTypeFor(const QUrl& url, QString& mimeType)
+-{
+- const QString fname(url.fileName());
+-
+- if (fname.isEmpty() || url.hasFragment() || url.hasQuery())
+- return;
+-
+- QMimeType pmt = QMimeDatabase().mimeTypeForFile(fname);
+-
+- // Further check for mime types guessed from the extension which,
+- // on a web page, are more likely to be a script delivering content
+- // of undecidable type. If the mime type from the extension is one
+- // of these, don't use it. Retain the original type 'text/html'.
+- if (pmt.isDefault() ||
+- pmt.inherits(QL1S("application/x-perl")) ||
+- pmt.inherits(QL1S("application/x-perl-module")) ||
+- pmt.inherits(QL1S("application/x-php")) ||
+- pmt.inherits(QL1S("application/x-python-bytecode")) ||
+- pmt.inherits(QL1S("application/x-python")) ||
+- pmt.inherits(QL1S("application/x-shellscript")))
+- return;
+-
+- mimeType = pmt.name();
+-}
+-
+-void WebEngineView::contextMenuEvent(QContextMenuEvent* e)
+-{
+-#ifdef HAVE_WEBENGINECONTEXTMENUDATA
+- m_result = page()->contextMenuData();
+-
+- // Clear the previous collection entries first...
+- m_actionCollection->clear();
+-
+- KParts::BrowserExtension::PopupFlags flags = KParts::BrowserExtension::DefaultPopupItems;
+- KParts::BrowserExtension::ActionGroupMap mapAction;
+- QString mimeType (QL1S("text/html"));
+- bool forcesNewWindow = false;
+-
+- QUrl emitUrl;
+-
+- if (m_result.isContentEditable()) {
+- flags |= KParts::BrowserExtension::ShowTextSelectionItems;
+- editableContentActionPopupMenu(mapAction);
+- } else if (m_result.mediaType() == QWebEngineContextMenuData::MediaTypeVideo || m_result.mediaType() == QWebEngineContextMenuData::MediaTypeAudio) {
+- multimediaActionPopupMenu(mapAction);
+- } else if (!m_result.linkUrl().isValid()) {
+- if (m_result.mediaType() == QWebEngineContextMenuData::MediaTypeImage) {
+- emitUrl = m_result.mediaUrl();
+- extractMimeTypeFor(emitUrl, mimeType);
+- } else {
+- flags |= KParts::BrowserExtension::ShowBookmark;
+- emitUrl = m_part->url();
+-
+- if (!m_result.selectedText().isEmpty()) {
+- flags |= KParts::BrowserExtension::ShowTextSelectionItems;
+- selectActionPopupMenu(mapAction);
+- }
+- }
+- partActionPopupMenu(mapAction);
+- } else {
+- flags |= KParts::BrowserExtension::ShowBookmark;
+- flags |= KParts::BrowserExtension::IsLink;
+- emitUrl = m_result.linkUrl();
+- linkActionPopupMenu(mapAction);
+- if (emitUrl.isLocalFile())
+- mimeType = QMimeDatabase().mimeTypeForUrl(emitUrl).name();
+- else
+- extractMimeTypeFor(emitUrl, mimeType);
+- partActionPopupMenu(mapAction);
+-
+- // Show the OpenInThisWindow context menu item
+-// forcesNewWindow = (page()->currentFrame() != m_result.linkTargetFrame());
+- }
+-
+- if (!mapAction.isEmpty()) {
+- KParts::OpenUrlArguments args;
+- KParts::BrowserArguments bargs;
+- args.setMimeType(mimeType);
+- bargs.setForcesNewWindow(forcesNewWindow);
+- e->accept();
+- emit m_part->browserExtension()->popupMenu(e->globalPos(), emitUrl, static_cast<mode_t>(-1), args, bargs, flags, mapAction);
+- return;
+- }
+-
+-#endif
+- QWebEngineView::contextMenuEvent(e);
+-}
+-
+-void WebEngineView::keyPressEvent(QKeyEvent* e)
+-{
+- if (e && hasFocus()) {
+- const int key = e->key();
+- if (e->modifiers() & Qt::ShiftModifier) {
+- switch (key) {
+- case Qt::Key_Up:
+- /* if (!isEditableElement(page()))*/ {
+- m_verticalAutoScrollSpeed--;
+- if (m_autoScrollTimerId == -1)
+- m_autoScrollTimerId = startTimer(100);
+- e->accept();
+- return;
+- }
+- break;
+- case Qt::Key_Down:
+- /*if (!isEditableElement(page()))*/ {
+- m_verticalAutoScrollSpeed++;
+- if (m_autoScrollTimerId == -1)
+- m_autoScrollTimerId = startTimer(100);
+- e->accept();
+- return;
+- }
+- break;
+- case Qt::Key_Left:
+- /*if (!isEditableElement(page()))*/ {
+- m_horizontalAutoScrollSpeed--;
+- if (m_autoScrollTimerId == -1)
+- m_autoScrollTimerId = startTimer(100);
+- e->accept();
+- return;
+- }
+- break;
+- case Qt::Key_Right:
+- /*if (!isEditableElement(page()))*/ {
+- m_horizontalAutoScrollSpeed--;
+- if (m_autoScrollTimerId == -1)
+- m_autoScrollTimerId = startTimer(100);
+- e->accept();
+- return;
+- }
+- break;
+- default:
+- break;
+- }
+- } else if (m_autoScrollTimerId != -1) {
+- // kDebug() << "scroll timer id:" << m_autoScrollTimerId;
+- slotStopAutoScroll();
+- e->accept();
+- return;
+- }
+- }
+- QWebEngineView::keyPressEvent(e);
+-}
+-
+-void WebEngineView::keyReleaseEvent(QKeyEvent *e)
+-{
+- QWebEngineView::keyReleaseEvent(e);
+-}
+-
+-void WebEngineView::mouseReleaseEvent(QMouseEvent* e)
+-{
+- QWebEngineView::mouseReleaseEvent(e);
+-}
+-
+-void WebEngineView::wheelEvent (QWheelEvent* e)
+-{
+- QWebEngineView::wheelEvent(e);
+-}
+-
+-
+-void WebEngineView::timerEvent(QTimerEvent* e)
+-{
+-#if 0
+- if (e && e->timerId() == m_autoScrollTimerId) {
+- // do the scrolling
+- scroll(m_horizontalAutoScrollSpeed, m_verticalAutoScrollSpeed);
+- // check if we reached the end
+- const int y = page()->scrollPosition().y();
+- if (y == page()->currentFrame()->scrollBarMinimum(Qt::Vertical) ||
+- y == page()->currentFrame()->scrollBarMaximum(Qt::Vertical)) {
+- m_verticalAutoScrollSpeed = 0;
+- }
+-
+- const int x = page()->scrollPosition().x();
+- if (x == page()->currentFrame()->scrollBarMinimum(Qt::Horizontal) ||
+- x == page()->currentFrame()->scrollBarMaximum(Qt::Horizontal)) {
+- m_horizontalAutoScrollSpeed = 0;
+- }
+-
+- // Kill the timer once the max/min scroll limit is reached.
+- if (m_horizontalAutoScrollSpeed == 0 && m_verticalAutoScrollSpeed == 0) {
+- killTimer(m_autoScrollTimerId);
+- m_autoScrollTimerId = -1;
+- }
+- e->accept();
+- return;
+- }
+-#endif
+- QWebEngineView::timerEvent(e);
+-}
+-
+-void WebEngineView::editableContentActionPopupMenu(KParts::BrowserExtension::ActionGroupMap& partGroupMap)
+-{
+- QList<QAction*> editableContentActions;
+-
+- QActionGroup* group = new QActionGroup(this);
+- group->setExclusive(true);
+-
+- QAction* action = new QAction(m_actionCollection);
+- action->setSeparator(true);
+- editableContentActions.append(action);
+-
+- action = m_actionCollection->addAction(KStandardAction::Copy, QL1S("copy"), m_part->browserExtension(), SLOT(copy()));
+- action->setEnabled(pageAction(QWebEnginePage::Copy)->isEnabled());
+- editableContentActions.append(action);
+-
+- action = m_actionCollection->addAction(KStandardAction::Cut, QL1S("cut"), m_part->browserExtension(), SLOT(cut()));
+- action->setEnabled(pageAction(QWebEnginePage::Cut)->isEnabled());
+- editableContentActions.append(action);
+-
+- action = m_actionCollection->addAction(KStandardAction::Paste, QL1S("paste"), m_part->browserExtension(), SLOT(paste()));
+- action->setEnabled(pageAction(QWebEnginePage::Paste)->isEnabled());
+- editableContentActions.append(action);
+-
+- action = new QAction(m_actionCollection);
+- action->setSeparator(true);
+- editableContentActions.append(action);
+-
+- editableContentActions.append(pageAction(QWebEnginePage::SelectAll));
+- editableContentActions.append(pageAction(QWebEnginePage::InspectElement));
+-
+- partGroupMap.insert(QStringLiteral("editactions") , editableContentActions);
+-}
+-
+-
+-void WebEngineView::partActionPopupMenu(KParts::BrowserExtension::ActionGroupMap& partGroupMap)
+-{
+- QList<QAction*> partActions;
+-
+-#ifdef HAVE_WEBENGINECONTEXTMENUDATA
+- if (m_result.mediaUrl().isValid()) {
+- QAction *action;
+- action = new QAction(i18n("Save Image As..."), this);
+- m_actionCollection->addAction(QL1S("saveimageas"), action);
+- connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotSaveImageAs()));
+- partActions.append(action);
+-
+- action = new QAction(i18n("Send Image..."), this);
+- m_actionCollection->addAction(QL1S("sendimage"), action);
+- connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotSendImage()));
+- partActions.append(action);
+-
+- action = new QAction(i18n("Copy Image URL"), this);
+- m_actionCollection->addAction(QL1S("copyimageurl"), action);
+- connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotCopyImageURL()));
+- partActions.append(action);
+-
+-#if 0
+- action = new QAction(i18n("Copy Image"), this);
+- m_actionCollection->addAction(QL1S("copyimage"), action);
+- connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotCopyImage()));
+- action->setEnabled(!m_result.pixmap().isNull());
+- partActions.append(action);
+-#endif
+-
+- action = new QAction(i18n("View Image (%1)", QUrl(m_result.mediaUrl()).fileName()), this);
+- m_actionCollection->addAction(QL1S("viewimage"), action);
+- connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotViewImage()));
+- partActions.append(action);
+-
+- if (WebEngineSettings::self()->isAdFilterEnabled()) {
+- action = new QAction(i18n("Block Image..."), this);
+- m_actionCollection->addAction(QL1S("blockimage"), action);
+- connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotBlockImage()));
+- partActions.append(action);
+-
+- if (!m_result.mediaUrl().host().isEmpty() &&
+- !m_result.mediaUrl().scheme().isEmpty())
+- {
+- action = new QAction(i18n("Block Images From %1" , m_result.mediaUrl().host()), this);
+- m_actionCollection->addAction(QL1S("blockhost"), action);
+- connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotBlockHost()));
+- partActions.append(action);
+- }
+- }
+- }
+-#endif
+-
+- {
+- QAction *separatorAction = new QAction(m_actionCollection);
+- separatorAction->setSeparator(true);
+- partActions.append(separatorAction);
+- }
+-
+- partActions.append(m_part->actionCollection()->action(QStringLiteral("viewDocumentSource")));
+-
+- partActions.append(pageAction(QWebEnginePage::InspectElement));
+-
+- partGroupMap.insert(QStringLiteral("partactions"), partActions);
+-}
+-
+-void WebEngineView::selectActionPopupMenu(KParts::BrowserExtension::ActionGroupMap& selectGroupMap)
+-{
+- QList<QAction*> selectActions;
+-
+- QAction* copyAction = m_actionCollection->addAction(KStandardAction::Copy, QL1S("copy"), m_part->browserExtension(), SLOT(copy()));
+- copyAction->setText(i18n("&Copy Text"));
+- copyAction->setEnabled(m_part->browserExtension()->isActionEnabled("copy"));
+- selectActions.append(copyAction);
+-
+- addSearchActions(selectActions, this);
+-
+- KUriFilterData data (selectedText().simplified().left(256));
+- data.setCheckForExecutables(false);
+- if (KUriFilter::self()->filterUri(data, QStringList() << QStringLiteral("kshorturifilter") << QStringLiteral("fixhosturifilter")) &&
+- data.uri().isValid() && data.uriType() == KUriFilterData::NetProtocol) {
+- QAction *action = new QAction(QIcon::fromTheme(QStringLiteral("window-new")), i18nc("open selected url", "Open '%1'",
+- KStringHandler::rsqueeze(data.uri().url(), 18)), this);
+- m_actionCollection->addAction(QL1S("openSelection"), action);
+- action->setData(QUrl(data.uri()));
+- connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotOpenSelection()));
+- selectActions.append(action);
+- }
+-
+- selectGroupMap.insert(QStringLiteral("editactions"), selectActions);
+-}
+-
+-void WebEngineView::linkActionPopupMenu(KParts::BrowserExtension::ActionGroupMap& linkGroupMap)
+-{
+-#ifdef HAVE_WEBENGINECONTEXTMENUDATA
+- Q_ASSERT(!m_result.linkUrl().isEmpty());
+-
+- const QUrl url(m_result.linkUrl());
+-#else
+- const QUrl url;
+-#endif
+-
+- QList<QAction*> linkActions;
+-
+- QAction* action;
+-
+-#ifdef HAVE_WEBENGINECONTEXTMENUDATA
+- if (!m_result.selectedText().isEmpty()) {
+- action = m_actionCollection->addAction(KStandardAction::Copy, QL1S("copy"), m_part->browserExtension(), SLOT(copy()));
+- action->setText(i18n("&Copy Text"));
+- action->setEnabled(m_part->browserExtension()->isActionEnabled("copy"));
+- linkActions.append(action);
+- }
+-#endif
+-
+- if (url.scheme() == QLatin1String("mailto")) {
+-#ifdef HAVE_WEBENGINECONTEXTMENUDATA
+- action = new QAction(i18n("&Copy Email Address"), this);
+- m_actionCollection->addAction(QL1S("copylinklocation"), action);
+- connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotCopyEmailAddress()));
+- linkActions.append(action);
+-#endif
+- } else {
+-#ifdef HAVE_WEBENGINECONTEXTMENUDATA
+- if (!m_result.linkText().isEmpty()) {
+- action = new QAction(QIcon::fromTheme(QStringLiteral("edit-copy")), i18n("Copy Link &Text"), this);
+- m_actionCollection->addAction(QL1S("copylinktext"), action);
+- connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotCopyLinkText()));
+- linkActions.append(action);
+- }
+-#endif
+-
+- action = new QAction(i18n("Copy Link &URL"), this);
+- m_actionCollection->addAction(QL1S("copylinkurl"), action);
+- connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotCopyLinkURL()));
+- linkActions.append(action);
+-
+- action = new QAction(i18n("&Save Link As..."), this);
+- m_actionCollection->addAction(QL1S("savelinkas"), action);
+- connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotSaveLinkAs()));
+- linkActions.append(action);
+- }
+-
+- linkGroupMap.insert(QStringLiteral("linkactions"), linkActions);
+-}
+-
+-void WebEngineView::multimediaActionPopupMenu(KParts::BrowserExtension::ActionGroupMap& mmGroupMap)
+-{
+-#ifdef HAVE_WEBENGINECONTEXTMENUDATA
+- QList<QAction*> multimediaActions;
+-
+- const bool isVideoElement = m_result.mediaType() == QWebEngineContextMenuData::MediaTypeVideo;
+- const bool isAudioElement = m_result.mediaType() == QWebEngineContextMenuData::MediaTypeAudio;
+-
+- QAction* action = new QAction(i18n("&Play/Pause"), this);
+- m_actionCollection->addAction(QL1S("playmultimedia"), action);
+- connect(action, SIGNAL(triggered()), m_part->browserExtension(), SLOT(slotPlayMedia()));
+- multimediaActions.append(action);
+-
+- action = new QAction(i18n("Un&mute/&Mute"), this);
+- m_actionCollection->addAction(QL1S("mutemultimedia"), action);
+- connect(action, SIGNAL(triggered()), m_part->browserExtension(), SLOT(slotMuteMedia()));
+- multimediaActions.append(action);
+-
+- action = new QAction(i18n("Toggle &Loop"), this);
+- m_actionCollection->addAction(QL1S("loopmultimedia"), action);
+- connect(action, SIGNAL(triggered()), m_part->browserExtension(), SLOT(slotLoopMedia()));
+- multimediaActions.append(action);
+-
+- action = new QAction(i18n("Toggle &Controls"), this);
+- m_actionCollection->addAction(QL1S("showmultimediacontrols"), action);
+- connect(action, SIGNAL(triggered()), m_part->browserExtension(), SLOT(slotShowMediaControls()));
+- multimediaActions.append(action);
+-
+- action = new QAction(m_actionCollection);
+- action->setSeparator(true);
+- multimediaActions.append(action);
+-
+- QString saveMediaText, copyMediaText;
+- if (isVideoElement) {
+- saveMediaText = i18n("Sa&ve Video As...");
+- copyMediaText = i18n("C&opy Video URL");
+- } else if (isAudioElement) {
+- saveMediaText = i18n("Sa&ve Audio As...");
+- copyMediaText = i18n("C&opy Audio URL");
+- } else {
+- saveMediaText = i18n("Sa&ve Media As...");
+- copyMediaText = i18n("C&opy Media URL");
+- }
+-
+- action = new QAction(saveMediaText, this);
+- m_actionCollection->addAction(QL1S("savemultimedia"), action);
+- connect(action, SIGNAL(triggered()), m_part->browserExtension(), SLOT(slotSaveMedia()));
+- multimediaActions.append(action);
+-
+- action = new QAction(copyMediaText, this);
+- m_actionCollection->addAction(QL1S("copymultimediaurl"), action);
+- connect(action, SIGNAL(triggered()), m_part->browserExtension(), SLOT(slotCopyMedia()));
+- multimediaActions.append(action);
+-
+- mmGroupMap.insert(QStringLiteral("partactions"), multimediaActions);
+-#endif
+-}
+-
+-void WebEngineView::slotStopAutoScroll()
+-{
+- if (m_autoScrollTimerId == -1) {
+- return;
+- }
+-
+- killTimer(m_autoScrollTimerId);
+- m_autoScrollTimerId = -1;
+- m_verticalAutoScrollSpeed = 0;
+- m_horizontalAutoScrollSpeed = 0;
+-
+-}
+-
+-void WebEngineView::addSearchActions(QList<QAction*>& selectActions, QWebEngineView* view)
+-{
+- // search text
+- const QString selectedText = view->selectedText().simplified();
+- if (selectedText.isEmpty())
+- return;
+-
+- KUriFilterData data;
+- data.setData(selectedText);
+- data.setAlternateDefaultSearchProvider(ALTERNATE_DEFAULT_WEB_SHORTCUT);
+- data.setAlternateSearchProviders(ALTERNATE_WEB_SHORTCUTS);
+-
+- if (KUriFilter::self()->filterSearchUri(data, KUriFilter::NormalTextFilter)) {
+- const QString squeezedText = KStringHandler::rsqueeze(selectedText, 20);
+- QAction *action = new QAction(QIcon::fromTheme(data.iconName()),
+- i18nc("Search \"search provider\" for \"text\"", "Search %1 for '%2'",
+- data.searchProvider(), squeezedText), view);
+- action->setData(QUrl(data.uri()));
+- connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(searchProvider()));
+- m_actionCollection->addAction(QL1S("defaultSearchProvider"), action);
+- selectActions.append(action);
+-
+-
+- const QStringList preferredSearchProviders = data.preferredSearchProviders();
+- if (!preferredSearchProviders.isEmpty()) {
+- KActionMenu* providerList = new KActionMenu(i18nc("Search for \"text\" with",
+- "Search for '%1' with", squeezedText), view);
+- Q_FOREACH(const QString &searchProvider, preferredSearchProviders) {
+- if (searchProvider == data.searchProvider())
+- continue;
+-
+- QAction *action = new QAction(QIcon::fromTheme(data.iconNameForPreferredSearchProvider(searchProvider)), searchProvider, view);
+- action->setData(data.queryForPreferredSearchProvider(searchProvider));
+- m_actionCollection->addAction(searchProvider, action);
+- connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(searchProvider()));
+-
+- providerList->addAction(action);
+- }
+- m_actionCollection->addAction(QL1S("searchProviderList"), providerList);
+- selectActions.append(providerList);
+- }
+- }
+-}
+diff --git a/webenginepart/src/webengineview.h a/webenginepart/src/webengineview.h
+deleted file mode 100644
+index 25b13eae9..000000000
+--- a/webenginepart/src/webengineview.h
++++ /dev/null
+@@ -1,132 +0,0 @@
+-/*
+- * This file is part of the KDE project.
+- *
+- * Copyright (C) 2007 Trolltech ASA
+- * Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
+- * Copyright (C) 2008 Laurent Montel <montel@kde.org>
+- * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
+- *
+- * 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 <http://www.gnu.org/licenses/>.
+- *
+- */
+-#ifndef WEBENGINEVIEW_H
+-#define WEBENGINEVIEW_H
+-
+-#include <QPointer>
+-#include <KParts/BrowserExtension>
+-
+-#include <QWebEngineView>
+-#include <QtWebEngine/QtWebEngineVersion>
+-#if QTWEBENGINE_VERSION >= QT_VERSION_CHECK(5, 7, 0)
+-#define HAVE_WEBENGINECONTEXTMENUDATA
+-#include <QWebEngineContextMenuData>
+-#else
+-typedef void* QWebEngineContextMenuData;
+-#endif
+-
+-class QUrl;
+-class WebEnginePart;
+-
+-class WebEngineView : public QWebEngineView
+-{
+- Q_OBJECT
+-public:
+- WebEngineView(WebEnginePart* part, QWidget* parent);
+- ~WebEngineView();
+-
+- /**
+- * Same as QWebEnginePage::load, but with KParts style arguments instead.
+- *
+- * @see KParts::OpenUrlArguments, KParts::BrowserArguments.
+- *
+- * @param url the url to load.
+- * @param args reference to a OpenUrlArguments object.
+- * @param bargs reference to a BrowserArguments object.
+- */
+- void loadUrl(const QUrl& url, const KParts::OpenUrlArguments& args, const KParts::BrowserArguments& bargs);
+-
+- QWebEngineContextMenuData contextMenuResult() const;
+-
+-protected:
+- /**
+- * Reimplemented for internal reasons, the API is not affected.
+- *
+- * @see QWidget::contextMenuEvent
+- * @internal
+- */
+- void contextMenuEvent(QContextMenuEvent*) Q_DECL_OVERRIDE;
+-
+- /**
+- * Reimplemented for internal reasons, the API is not affected.
+- *
+- * @see QWidget::keyPressEvent
+- * @internal
+- */
+- void keyPressEvent(QKeyEvent*) Q_DECL_OVERRIDE;
+-
+- /**
+- * Reimplemented for internal reasons, the API is not affected.
+- *
+- * @see QWidget::keyReleaseEvent
+- * @internal
+- */
+- void keyReleaseEvent(QKeyEvent*) Q_DECL_OVERRIDE;
+-
+- /**
+- * Reimplemented for internal reasons, the API is not affected.
+- *
+- * @see QWidget::mouseReleaseEvent
+- * @internal
+- */
+- void mouseReleaseEvent(QMouseEvent*) Q_DECL_OVERRIDE;
+-
+- /**
+- * Reimplemented for internal reasons, the API is not affected.
+- *
+- * @see QObject::timerEvent
+- * @internal
+- */
+- void timerEvent(QTimerEvent*) Q_DECL_OVERRIDE;
+-
+- /**
+- * Reimplemented for internal reasons, the API is not affected.
+- *
+- * @see QWidget::wheelEvent
+- * @internal
+- */
+- void wheelEvent(QWheelEvent*) Q_DECL_OVERRIDE;
+-
+-private Q_SLOTS:
+- void slotStopAutoScroll();
+-
+-private:
+- void editableContentActionPopupMenu(KParts::BrowserExtension::ActionGroupMap&);
+- void selectActionPopupMenu(KParts::BrowserExtension::ActionGroupMap&);
+- void linkActionPopupMenu(KParts::BrowserExtension::ActionGroupMap&);
+- void partActionPopupMenu(KParts::BrowserExtension::ActionGroupMap &);
+- void multimediaActionPopupMenu(KParts::BrowserExtension::ActionGroupMap&);
+- void addSearchActions(QList<QAction*>& selectActions, QWebEngineView*);
+-
+- KActionCollection* m_actionCollection;
+- QWebEngineContextMenuData m_result;
+- QPointer<WebEnginePart> m_part;
+-
+- qint32 m_autoScrollTimerId;
+- qint32 m_verticalAutoScrollSpeed;
+- qint32 m_horizontalAutoScrollSpeed;
+-
+- QHash<QString, QChar> m_duplicateLinkElements;
+-};
+-
+-#endif // WEBENGINEVIEW_H
+diff --git a/webenginepart/src/webhistoryinterface.cpp a/webenginepart/src/webhistoryinterface.cpp
+deleted file mode 100644
+index 74e2c096e..000000000
+--- a/webenginepart/src/webhistoryinterface.cpp
++++ /dev/null
+@@ -1,38 +0,0 @@
+-/*
+- * This file is part of the KDE project.
+- *
+- * Copyright (C) 2011 Dawit Alemayehu <adawit@kde.org>
+- *
+- * 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 <http://www.gnu.org/licenses/>.
+- *
+- */
+-
+-#include "webhistoryinterface.h"
+-
+-#include <KParts/HistoryProvider>
+-
+-
+-WebHistoryInterface::WebHistoryInterface(QObject* parent)
+-{
+-}
+-
+-void WebHistoryInterface::addHistoryEntry(const QString& url)
+-{
+- KParts::HistoryProvider::self()->insert(url);
+-}
+-
+-bool WebHistoryInterface::historyContains(const QString& url) const
+-{
+- return KParts::HistoryProvider::self()->contains(url);
+-}
+diff --git a/webenginepart/src/webhistoryinterface.h a/webenginepart/src/webhistoryinterface.h
+deleted file mode 100644
+index fbc6d6f8b..000000000
+--- a/webenginepart/src/webhistoryinterface.h
++++ /dev/null
+@@ -1,34 +0,0 @@
+-/*
+- * This file is part of the KDE project.
+- *
+- * Copyright (C) 2011 Dawit Alemayehu <adawit@kde.org>
+- *
+- * 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 <http://www.gnu.org/licenses/>.
+- *
+- */
+-#ifndef WEBHISTORYINTERFACE_H
+-#define WEBHISTORYINTERFACE_H
+-
+-#include <QObject>
+-
+-
+-class WebHistoryInterface
+-{
+-public:
+- WebHistoryInterface(QObject* parent = Q_NULLPTR);
+- void addHistoryEntry (const QString & url);
+- bool historyContains (const QString & url) const;
+-};
+-
+-#endif //WEBHISTORYINTERFACE_H
+diff --git a/webenginepart/src/websslinfo.cpp a/webenginepart/src/websslinfo.cpp
+deleted file mode 100644
+index 7960007d0..000000000
+--- a/webenginepart/src/websslinfo.cpp
++++ /dev/null
+@@ -1,224 +0,0 @@
+-/*
+- * This file is part of the KDE project.
+- *
+- * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
+- *
+- * 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 <http://www.gnu.org/licenses/>.
+- *
+- */
+-
+-#include "websslinfo.h"
+-
+-#include <QVariant>
+-
+-
+-class WebSslInfo::WebSslInfoPrivate
+-{
+-public:
+- WebSslInfoPrivate()
+- : usedCipherBits(0), supportedCipherBits(0) {}
+-
+- QUrl url;
+- QString ciphers;
+- QString protocol;
+- QString certErrors;
+- QHostAddress peerAddress;
+- QHostAddress parentAddress;
+- QList<QSslCertificate> certificateChain;
+-
+- int usedCipherBits;
+- int supportedCipherBits;
+-};
+-
+-WebSslInfo::WebSslInfo()
+- :d(new WebSslInfo::WebSslInfoPrivate)
+-{
+-}
+-
+-WebSslInfo::WebSslInfo(const WebSslInfo& other)
+- :d(new WebSslInfo::WebSslInfoPrivate)
+-{
+- *this = other;
+-}
+-
+-WebSslInfo::~WebSslInfo()
+-{
+- delete d;
+- d = 0;
+-}
+-
+-bool WebSslInfo::isValid() const
+-{
+- return (d ? !d->peerAddress.isNull() : false);
+-}
+-
+-QUrl WebSslInfo::url() const
+-{
+- return (d ? d->url : QUrl());
+-}
+-
+-QHostAddress WebSslInfo::parentAddress() const
+-{
+- return (d ? d->parentAddress : QHostAddress());
+-}
+-
+-QHostAddress WebSslInfo::peerAddress() const
+-{
+- return (d ? d->peerAddress : QHostAddress());
+-}
+-
+-QString WebSslInfo::protocol() const
+-{
+- return (d ? d->protocol : QString());
+-}
+-
+-QString WebSslInfo::ciphers() const
+-{
+- return (d ? d->ciphers : QString());
+-}
+-
+-QString WebSslInfo::certificateErrors() const
+-{
+- return (d ? d->certErrors : QString());
+-}
+-
+-int WebSslInfo::supportedChiperBits () const
+-{
+- return (d ? d->supportedCipherBits : 0);
+-}
+-
+-int WebSslInfo::usedChiperBits () const
+-{
+- return (d ? d->usedCipherBits : 0);
+-}
+-
+-QList<QSslCertificate> WebSslInfo::certificateChain() const
+-{
+- return (d ? d->certificateChain : QList<QSslCertificate>());
+-}
+-
+-WebSslInfo& WebSslInfo::operator=(const WebSslInfo& other)
+-{
+- if (d) {
+- d->ciphers = other.d->ciphers;
+- d->protocol = other.d->protocol;
+- d->certErrors = other.d->certErrors;
+- d->peerAddress = other.d->peerAddress;
+- d->parentAddress = other.d->parentAddress;
+- d->certificateChain = other.d->certificateChain;
+-
+- d->usedCipherBits = other.d->usedCipherBits;
+- d->supportedCipherBits = other.d->supportedCipherBits;
+- d->url = other.d->url;
+- }
+-
+- return *this;
+-}
+-
+-bool WebSslInfo::saveTo(QMap<QString, QVariant>& data) const
+-{
+- const bool ok = isValid();
+- if (ok) {
+- data.insert(QStringLiteral("ssl_in_use"), true);
+- data.insert(QStringLiteral("ssl_peer_ip"), d->peerAddress.toString());
+- data.insert(QStringLiteral("ssl_parent_ip"), d->parentAddress.toString());
+- data.insert(QStringLiteral("ssl_protocol_version"), d->protocol);
+- data.insert(QStringLiteral("ssl_cipher"), d->ciphers);
+- data.insert(QStringLiteral("ssl_cert_errors"), d->certErrors);
+- data.insert(QStringLiteral("ssl_cipher_used_bits"), d->usedCipherBits);
+- data.insert(QStringLiteral("ssl_cipher_bits"), d->supportedCipherBits);
+- QByteArray certChain;
+- Q_FOREACH(const QSslCertificate& cert, d->certificateChain)
+- certChain += cert.toPem();
+- data.insert(QStringLiteral("ssl_peer_chain"), certChain);
+- }
+-
+- return ok;
+-}
+-
+-void WebSslInfo::restoreFrom(const QVariant& value, const QUrl& url, bool reset)
+-{
+- if (reset) {
+- *this = WebSslInfo();
+- }
+-
+- if (value.isValid() && value.type() == QVariant::Map) {
+- QMap<QString,QVariant> metaData = value.toMap();
+- if (metaData.value(QStringLiteral("ssl_in_use"), false).toBool()) {
+- setCertificateChain(metaData.value(QStringLiteral("ssl_peer_chain")).toByteArray());
+- setPeerAddress(metaData.value(QStringLiteral("ssl_peer_ip")).toString());
+- setParentAddress(metaData.value(QStringLiteral("ssl_parent_ip")).toString());
+- setProtocol(metaData.value(QStringLiteral("ssl_protocol_version")).toString());
+- setCiphers(metaData.value(QStringLiteral("ssl_cipher")).toString());
+- setCertificateErrors(metaData.value(QStringLiteral("ssl_cert_errors")).toString());
+- setUsedCipherBits(metaData.value(QStringLiteral("ssl_cipher_used_bits")).toString());
+- setSupportedCipherBits(metaData.value(QStringLiteral("ssl_cipher_bits")).toString());
+- setUrl(url);
+- }
+- }
+-}
+-
+-void WebSslInfo::setUrl (const QUrl &url)
+-{
+- if (d)
+- d->url = url;
+-}
+-
+-void WebSslInfo::setPeerAddress(const QString& address)
+-{
+- if (d)
+- d->peerAddress = address;
+-}
+-
+-void WebSslInfo::setParentAddress(const QString& address)
+-{
+- if (d)
+- d->parentAddress = address;
+-}
+-
+-void WebSslInfo::setProtocol(const QString& protocol)
+-{
+- if (d)
+- d->protocol = protocol;
+-}
+-
+-void WebSslInfo::setCertificateChain(const QByteArray& chain)
+-{
+- if (d)
+- d->certificateChain = QSslCertificate::fromData(chain);
+-}
+-
+-void WebSslInfo::setCiphers(const QString& ciphers)
+-{
+- if (d)
+- d->ciphers = ciphers;
+-}
+-
+-void WebSslInfo::setUsedCipherBits(const QString& bits)
+-{
+- if (d)
+- d->usedCipherBits = bits.toInt();
+-}
+-
+-void WebSslInfo::setSupportedCipherBits(const QString& bits)
+-{
+- if (d)
+- d->supportedCipherBits = bits.toInt();
+-}
+-
+-void WebSslInfo::setCertificateErrors(const QString& certErrors)
+-{
+- if (d)
+- d->certErrors = certErrors;
+-}
+diff --git a/webenginepart/src/websslinfo.h a/webenginepart/src/websslinfo.h
+deleted file mode 100644
+index 7c7d09ca7..000000000
+--- a/webenginepart/src/websslinfo.h
++++ /dev/null
+@@ -1,70 +0,0 @@
+-/*
+- * This file is part of the KDE project.
+- *
+- * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
+- *
+- * 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 <http://www.gnu.org/licenses/>.
+- *
+- */
+-#ifndef WEBSSLINFO_H
+-#define WEBSSLINFO_H
+-
+-//#include <kdemacros.h>
+-
+-#include <QUrl>
+-#include <QList>
+-#include <QString>
+-#include <QHostAddress>
+-#include <QSslCertificate>
+-
+-class WebSslInfo
+-{
+-public:
+- WebSslInfo();
+- WebSslInfo(const WebSslInfo&);
+- virtual ~WebSslInfo();
+-
+- bool isValid() const;
+- QUrl url() const;
+- QHostAddress peerAddress() const;
+- QHostAddress parentAddress() const;
+- QString ciphers() const;
+- QString protocol() const;
+- QString certificateErrors() const;
+- int supportedChiperBits () const;
+- int usedChiperBits () const;
+- QList<QSslCertificate> certificateChain() const;
+-
+- bool saveTo(QMap<QString, QVariant>&) const;
+- void restoreFrom(const QVariant &, const QUrl& = QUrl(), bool reset = false);
+-
+- void setUrl (const QUrl &url);
+- WebSslInfo& operator = (const WebSslInfo&);
+-
+-protected:
+- void setCiphers(const QString& ciphers);
+- void setProtocol(const QString& protocol);
+- void setPeerAddress(const QString& address);
+- void setParentAddress(const QString& address);
+- void setCertificateChain(const QByteArray& chain);
+- void setCertificateErrors(const QString& certErrors);
+- void setUsedCipherBits(const QString& bits);
+- void setSupportedCipherBits(const QString& bits);
+-
+-private:
+- class WebSslInfoPrivate;
+- WebSslInfoPrivate* d;
+-};
+-
+-#endif // WEBSSLINFO_H
+diff --git a/webenginepart/testfiles/embed_tag_test.html a/webenginepart/testfiles/embed_tag_test.html
+deleted file mode 100644
+index 8afe2d611..000000000
+--- a/webenginepart/testfiles/embed_tag_test.html
++++ /dev/null
+@@ -1,20 +0,0 @@
+-<html>
+-<head>
+- <title> &lt;EMBED&gt; tests</title>
+-</head>
+-<body>
+- <h1>KDE e.V. Report 2011 Q2</h1>
+- <center>
+- <embed type="application/pdf" src="http://ev.kde.org/reports/ev-quarterly-2011_Q2.pdf" width="75%" height="400"/>
+- </center>
+- <p/>
+- <h1>KDE e.V. Report 2011 Q1</h1>
+- <center>
+- <embed type="application/pdf" src="http://ev.kde.org/reports/ev-quarterly-2011_Q1.pdf" width="75%" height="400"/>
+- </center>
+- <p/>
+- <center>
+- <video src="http://blip.tv/file/get/Sebasje-ThePlasmaDesktopShellInKDE42312.ogv" controls="controls" width="75%" height="450"/>
+- </center>
+-</body>
+-</html>
+diff --git a/webenginepart/testfiles/form_save_restore_test.html a/webenginepart/testfiles/form_save_restore_test.html
+deleted file mode 100644
+index d1adaeb76..000000000
+--- a/webenginepart/testfiles/form_save_restore_test.html
++++ /dev/null
+@@ -1,68 +0,0 @@
+-<html>
+-<head>
+- <title>Form save restore test</title>
+-</head>
+-<body>
+-
+-<form name="testform">
+-<label for="testedit">Enter text:</label>
+-<input type="text" name="testinputtext" id="testedit">
+-<br>
+-<label>Check this box</label>
+-<input type="checkbox" name="testinputcheckbox" value="checked">
+-<br>
+-<label>File to upload:</label>
+-<input type="file" name="testinputfile">
+-<br>
+-<input type="radio" name="testinputradio" value="one">One</input>
+-<br>
+-<input type="radio" name="testinputradio" value="two">Two</input>
+-<br>
+-<input type="radio" name="testinputradio" value="three">Three</input>
+-<br>
+-</form>
+-
+-<p>
+-Enter some text in the box below:<br/>
+-<textarea name="testtextarea"></textarea>
+-</p>
+-
+-<p>
+-Disabled text area:<br/>
+-<textarea name="testtextarea" disabled></textarea>
+-</p>
+-
+-<p>
+-Read only text area:<br/>
+-<textarea name="testtextarea" readonly>This is a read only text area.</textarea>
+-</p>
+-
+-<p>
+-Text area with spell check disabled:<br/>
+-<textarea name="testtextarea" spellcheck="false"></textarea>
+-</p>
+-
+-<p>
+-Choose one:
+-<select name="testcombobox">
+-<option>First</option>
+-<option>Second</option>
+-<option>Third</option>
+-<option>Fourth</option>
+-<option>Fifth</option>
+-</select>
+-</p><p/>
+-
+-<p>
+-Select one or more items:<br/>
+-<select name="testlist" multiple>
+-<option>One</option>
+-<option>Two</option>
+-<option>Three</option>
+-<option>Four</option>
+-<option>Five</option>
+-</select>
+-</p>
+-
+-</body>
+-</html>
+diff --git a/webenginepart/testfiles/frameset_test.html a/webenginepart/testfiles/frameset_test.html
+deleted file mode 100644
+index 25a295937..000000000
+--- a/webenginepart/testfiles/frameset_test.html
++++ /dev/null
+@@ -1,9 +0,0 @@
+-<html>
+-<head>
+-<title>&lt;FRAMESET&gt; test</title>
+-</head>
+-<frameset cols="120,*">
+- <frame src="frametest/frame_navigation.html" />
+- <frame src="frametest/frame_a.html" name="showframe" />
+-</frameset>
+-</html>
+diff --git a/webenginepart/testfiles/frametest/frame_a.html a/webenginepart/testfiles/frametest/frame_a.html
+deleted file mode 100644
+index 0ea08f3f6..000000000
+--- a/webenginepart/testfiles/frametest/frame_a.html
++++ /dev/null
+@@ -1,7 +0,0 @@
+-<html>
+-<body bgcolor="#8F8FBD">
+-
+-<h3>Frame A</h3>
+-
+-</body>
+-</html>
+diff --git a/webenginepart/testfiles/frametest/frame_b.html a/webenginepart/testfiles/frametest/frame_b.html
+deleted file mode 100644
+index fe36a8d98..000000000
+--- a/webenginepart/testfiles/frametest/frame_b.html
++++ /dev/null
+@@ -1,7 +0,0 @@
+-<html>
+-<body bgcolor="#EBC79E">
+-
+-<h3>Frame B</h3>
+-
+-</body>
+-</html>
+\ No newline at end of file
+diff --git a/webenginepart/testfiles/frametest/frame_c.html a/webenginepart/testfiles/frametest/frame_c.html
+deleted file mode 100644
+index 3ed0e0e67..000000000
+--- a/webenginepart/testfiles/frametest/frame_c.html
++++ /dev/null
+@@ -1,7 +0,0 @@
+-<html>
+-<body bgcolor="#FFFFCC">
+-
+-<h3>Frame C</h3>
+-<a href="http://www.kde.org">Go to KDE website</a>
+-</body>
+-</html>
+\ No newline at end of file
+diff --git a/webenginepart/testfiles/frametest/frame_navigation.html a/webenginepart/testfiles/frametest/frame_navigation.html
+deleted file mode 100644
+index 3632a0d8b..000000000
+--- a/webenginepart/testfiles/frametest/frame_navigation.html
++++ /dev/null
+@@ -1,9 +0,0 @@
+-<html>
+-<body>
+-<a href ="frame_a.html" target ="showframe">Frame a</a><br/>
+-<a href ="frame_b.html" target ="showframe">Frame b</a><br/>
+-<a href ="frame_c.html" target ="showframe">Frame c</a><br/>
+-<a href ="frame_d.html" target ="showframe">Invalid frame</a><br/>
+-<a href ="https://bugs.kde.org" target ="showframe">bugs.kde.org</a>
+-</body>
+-</html>
+\ No newline at end of file
+diff --git a/webenginepart/testfiles/js.html a/webenginepart/testfiles/js.html
+deleted file mode 100644
+index 4c03c3473..000000000
+--- a/webenginepart/testfiles/js.html
++++ /dev/null
+@@ -1,52 +0,0 @@
+-<html>
+-<head>
+-<title>Javascript Link Tests</title>
+-<script type="text/javascript">
+-function resize()
+-{
+- window.resizeTo(580, 420);
+-}
+-
+-function move()
+-{
+- window.moveTo(180, 120);
+-}
+-
+-function promptAndAlertMessage()
+-{
+- var message = prompt("Enter a message.", "");
+- alert(message);
+-}
+-
+-function statusMessage()
+-{
+- window.status = 'A new status message.';
+-}
+-
+-function openWindow()
+-{
+- window.open("about:blank", "NewWindowTest1", "width=300, height=400");
+-}
+-
+-function openWindowFrameTest()
+-{
+- var new_window = window.open('about:blank','testpage','width=800,height=600');
+- new_window.location="frameset_test.html";
+-}
+-
+-</script>
+-</head>
+-<body>
+-<script type="text/javascript">
+-document.writeln("navigator.appName: " + navigator.appName + "<br />");
+-document.writeln("navigator.appVersion: " + navigator.appVersion + "<br />");
+-</script>
+-<h1>Javascript Link Tests</h1>
+-<a href="javascript:resize()">resizeTo</a><br />
+-<a href="javascript:move()">moveTo</a><br />
+-<a href="javascript:promptAndAlertMessage()">promptAndAlertMessage</a><br />
+-<a href="javascript:statusMessage()">status</a><br />
+-<a href="javascript:window.open('about:blank', 'NewWindowTest1', 'width=300, height=400')">JS open new window</a><br />
+-<a href="javascript:openWindowFrameTest()">JS open new frameset</a><br />
+-</body>
+-</html>
+diff --git a/webenginepart/testfiles/link_tests.html a/webenginepart/testfiles/link_tests.html
+deleted file mode 100644
+index f2d73007a..000000000
+--- a/webenginepart/testfiles/link_tests.html
++++ /dev/null
+@@ -1,136 +0,0 @@
+-<html>
+-<head>
+- <title>Link Tests</title>
+-</head>
+-<script type="text/javascript">
+- function delayedRedirect() {
+- setTimeout(window.open("http://kde-look.org/CONTENT/content-files/52338-kÃy.jpg"), 3000)
+- }
+- function openWin(url,name,features) {
+- url = url || ''
+- name = name || ''
+- features = features || 'width=200,height=100'
+- var myWindow = window.open(url,name,features);
+- if (!url) {
+- myWindow.document.write("<p>This is 'myWindow'</p>");
+- myWindow.focus();
+- }
+- }
+-</script>
+-<body>
+-<h2>MAILTO Link Tests</h2>
+- <a href="mailto:joe@xyz.com&amp;CC=bob@xyz.com&amp;BCC=bob@xyz.com&amp;attach=%2Fetc%2Fpasswd&amp;subject=hello&amp;body=hello">Email link #1</a>
+- <br/>
+- <a href="mailto:joe@xyz.com">Email link #2</a>
+- <br/>
+-<h2>FTP Link Tests</h2>
+- <a href="ftp://ftp.kde.org" target="_blank">FTP link #1 (new window)</a>
+- <br/>
+- <a href="ftp://ftp.kde.org/pub" target="_blank">FTP link #2 (new window)</a>
+- <br/>
+- <a href="ftp://upload.kde.org">FTP link #3</a>
+- <br/>
+- <a href="ftp://ftp.kde.org/pub/kde/README_UPLOAD">Text File Link</a>
+- <br/>
+- <a href="#fragments" target="_top">Anchor test</a>
+- <br/>
+- <a href="#fragments" target="_blank">Anchor test (new window)</a>
+- <br/>
+-<h2>HTTP Link Tests</h2>
+- <a href="http://www.kde.org" target="_blank">Web site link (new window)</a>
+- <br/>
+- <a href="http://foo@www.kde.org">Web site link with bogus username</a>
+- <br/>
+- <a href="http://bar@www.kde.org">Web site link with different bogus username</a>
+- <br/>
+- <a href="http://ev.kde.org/reports/ev-quarterly-2012_Q1.pdf">PDF link</a>
+- <br/>
+- <a href="http://ev.kde.org/reports/ev-quarterly-2012_Q1.pdf" target="_blank">PDF link (new window)</a>
+- <br/>
+- <a href="http://ev.kde.org/reports/ev-quarterly-2012_Q1.pdf" target="_blank">Duplicate PDF link (new window)</a>
+- <br/>
+- <a href="http://blip.tv/file/get/Sebasje-WindowManagingFeaturesInKDEPlasma44222.ogg">Movie link</a>
+- <br/>
+- <a href="http://blip.tv/file/get/Sebasje-WindowManagingFeaturesInKDEPlasma44222.ogg" target="_blank">Movie link (new window)</a>
+- <br/>
+- <a href="http://www.ietf.org/rfc/rfc2344.txt">Text Document Link</a>
+- <br/>
+- <a href="http://www.microsoft.com%26item%3Dq209354rexsddiuyjkiuylkuryt2583453453fsesfsdfsfasfdfdsf@www.kde.org/">Bogus link</a>
+- <br/>
+-<h2>Javascript Link Tests</h2>
+- <a href="javascript:openWin('http://www.kde.org','', 'width=600,height=600,statusbar=no,toolbar=no')">Open dialog like window link #1</a>
+- <br/>
+- <a href="javascript:openWin('file:///usr/local/src/KDE/git/extragear/kwebkitpart/tests/link_tests.html','','dialog','width=600,height=600,statusbar=no,toolbar=no')">Open dialog like window link #2</a>
+- <br/>
+- <a href="javascript:openWin('http://www.kde.org','', 'width=0,height=0')">Open new window link #2 (might be opened as Tab)</a>
+- <br/>
+- <a href="javascript:openWin('http://ev.kde.org/reports/ev-quarterly-2009Q1.pdf', '_blank', 'width=600,height=600,statusbar=no,toolbar=no')">Open PDF Document (new window)</a>
+- <br/>
+- <a href='empty.html' onclick="openWin('empty.html', 'dz_orders','toolbar=false,height=100,width=100,resizable=1,scrollbars=1')" target='dz_orders'>Javscript + Target test</a>
+- <br/>
+- <a href="javascript:window.close">Close window</a>
+- <br/>
+- <a href="" onmouseover="openWin()">On mouse over open window test</a>
+- <br/>
+- <a href="javascript:setTimeout(delayedRedirect(), 3000)" target="_blank">Redirect test</a>
+- <br/>
+-<h2>KDE specific URL Tests</h2>
+- <a href="applications:/Internet/">Text Document Link</a>
+- <br/>
+-<h2>Form Tests</h2>
+- <form action="mailto:someone@example.com?CC='bob@example.com&amp;attach=%2fetc%2fpasswd&amp;body=" method="post" enctype="application/x-www-form-urlencoded">
+- Choose file to upload:<br />
+- <input type="file" name="upload_file" size="20" /><br/>
+- <input type="submit" value="Send" />
+- <input type="reset" value="Reset" />
+- </form>
+- <br/>
+- <a name="fragments"><h2>URL Fragment Test</h2></a>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+- <br/>
+-</body>
+-</html>
+diff --git a/webenginepart/testfiles/meta_tag_refresh_test.html a/webenginepart/testfiles/meta_tag_refresh_test.html
+deleted file mode 100644
+index 4ea95a59c..000000000
+--- a/webenginepart/testfiles/meta_tag_refresh_test.html
++++ /dev/null
+@@ -1,14 +0,0 @@
+-<html>
+-<head>
+- <title>Meta redirect test</title>
+- <meta HTTP-EQUIV="Refresh" CONTENT="10;URL=http://kde.org">
+-</head>
+-<body>
+-You will be redirected to <a href="http://www.kde.org">kde.org</a> in 10 seconds.<br/>
+-<p>
+-If the stop button is active (not disabled) after the page has completely loaded, it
+-means the rendering engine allows you to cancel &lt;META&gt; based redirect requests.
+-Otherwise, you are not able to stop redirects or refresh requests set by web pages.
+-</p>
+-</body>
+-</html>
+\ No newline at end of file
+diff --git a/webenginepart/tests/CMakeLists.txt a/webenginepart/tests/CMakeLists.txt
+deleted file mode 100644
+index 5589c1b18..000000000
+--- a/webenginepart/tests/CMakeLists.txt
++++ /dev/null
+@@ -1,2 +0,0 @@
+-add_executable(webenginepart_tester webenginepart_tester.cpp)
+-target_link_libraries(webenginepart_tester kwebenginepartlib Qt5::Core Qt5::Gui Qt5::Widgets Qt5::WebEngineWidgets KF5::I18n KF5::KDELibs4Support)
+diff --git a/webenginepart/tests/webenginepart_tester.cpp a/webenginepart/tests/webenginepart_tester.cpp
+deleted file mode 100644
+index 069a4323f..000000000
+--- a/webenginepart/tests/webenginepart_tester.cpp
++++ /dev/null
+@@ -1,437 +0,0 @@
+-/*
+- * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+- * Copyright (C) 2006 George Staikos <staikos@kde.org>
+- * Copyright (C) 2006 Dirk Mueller <mueller@kde.org>
+- * Copyright (C) 2006 Zack Rusin <zack@kde.org>
+- * Copyright (C) 2006 Simon Hausmann <hausmann@kde.org>
+- *
+- * All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- * notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- * notice, this list of conditions and the following disclaimer in the
+- * documentation and/or other materials provided with the distribution.
+- *
+- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-#include <KApplication>
+-#include <KAboutData>
+-#include <KCmdLineArgs>
+-#include <KDebug>
+-#include <KIO/AccessManager>
+-#include <KUriFilter>
+-#include <KInputDialog>
+-#include <KLineEdit>
+-#include <webenginepart.h>
+-
+-#include <QInputDialog>
+-
+-//#include <QUiLoader>
+-//#include <QWebEnginePage>
+-#include <QWebEngineView>
+-//#include <QWebFrame>
+-#include <QWebEngineSettings>
+-//#include <QWebElement>
+-//#include <QWebElementCollection>
+-
+-#if !defined(QT_NO_PRINTER)
+-#include <QPrintPreviewDialog>
+-#endif
+-
+-#include <QAction>
+-#include <QCompleter>
+-#include <QMainWindow>
+-#include <QMenu>
+-#include <QMenuBar>
+-#include <QProgressBar>
+-#include <QStatusBar>
+-#include <QStringListModel>
+-#include <QToolBar>
+-#include <QToolTip>
+-#include <QDir>
+-#include <QFile>
+-#include <QVector>
+-#include <QTextStream>
+-#include <QApplication>
+-#include <KAboutData>
+-#include <KLocalizedString>
+-#include <QCommandLineParser>
+-
+-
+-class MainWindow : public QMainWindow
+-{
+- Q_OBJECT
+-public:
+- MainWindow(const QString& url = QString()): currentZoom(100) {
+- view = new WebEnginePart(this);
+- setCentralWidget(view->widget());
+-
+- connect(view->view(), &QWebEngineView::loadFinished,
+- this, &MainWindow::loadFinished);
+- connect(view->view(), SIGNAL(titleChanged(QString)),
+- this, SLOT(setWindowTitle(QString)));
+- connect(view->view()->page(), SIGNAL(linkHovered(QString)),
+- this, SLOT(showLinkHover(QString)));
+- connect(view->view()->page(), SIGNAL(windowCloseRequested()), this, SLOT(deleteLater()));
+-
+- setupUI();
+-
+- QUrl qurl(KUriFilter::self()->filteredUri(url, QStringList() << QStringLiteral("kshorturifilter")));
+- if (qurl.isValid()) {
+- urlEdit->setText(qurl.toEncoded());
+- view->openUrl(qurl);
+-
+- // the zoom values are chosen to be like in Mozilla Firefox 3
+- zoomLevels << 30 << 50 << 67 << 80 << 90;
+- zoomLevels << 100;
+- zoomLevels << 110 << 120 << 133 << 150 << 170 << 200 << 240 << 300;
+- }
+- }
+-
+- QWebEnginePage* webPage() const {
+- return view->view()->page();
+- }
+-
+- QWebEngineView* webView() const {
+- return view->view();
+- }
+-
+-protected slots:
+-
+- void changeLocation() {
+- QUrl url (KUriFilter::self()->filteredUri(urlEdit->text(), QStringList() << QStringLiteral("kshorturifilter")));
+- view->openUrl(url);
+- view->view()->setFocus(Qt::OtherFocusReason);
+- }
+-
+- void loadFinished() {
+- urlEdit->setText(view->url().toString());
+-
+- QUrl::FormattingOptions opts;
+- opts |= QUrl::RemoveScheme;
+- opts |= QUrl::RemoveUserInfo;
+- opts |= QUrl::StripTrailingSlash;
+- QString s = view->url().toString(opts);
+- s = s.mid(2);
+- if (s.isEmpty())
+- return;
+-
+- if (!urlList.contains(s))
+- urlList += s;
+- urlModel.setStringList(urlList);
+- }
+-
+- void showLinkHover(const QString &link) {
+- statusBar()->showMessage(link);
+- }
+-
+- void zoomIn() {
+- int i = zoomLevels.indexOf(currentZoom);
+- Q_ASSERT(i >= 0);
+- if (i < zoomLevels.count() - 1)
+- currentZoom = zoomLevels[i + 1];
+-
+- view->view()->setZoomFactor(qreal(currentZoom)/100.0);
+- }
+-
+- void zoomOut() {
+- int i = zoomLevels.indexOf(currentZoom);
+- Q_ASSERT(i >= 0);
+- if (i > 0)
+- currentZoom = zoomLevels[i - 1];
+-
+- view->view()->setZoomFactor(qreal(currentZoom)/100.0);
+- }
+-
+- void resetZoom()
+- {
+- currentZoom = 100;
+- view->view()->setZoomFactor(1.0);
+- }
+-
+- void toggleZoomTextOnly(bool b)
+- {
+-// view->view()->page()->settings()->setAttribute(QWebEngineSettings::ZoomTextOnly, b);
+- }
+-
+- void print() {
+-#if !defined(QT_NO_PRINTER)
+- QScopedPointer<QPrintPreviewDialog> dlg (new QPrintPreviewDialog(this));
+- connect(dlg.data(), SIGNAL(paintRequested(QPrinter*)),
+- view, SLOT(print(QPrinter*)));
+- dlg->exec();
+-#endif
+- }
+-
+- void setEditable(bool on) {
+-// view->view()->page()->setContentEditable(on);
+- formatMenuAction->setVisible(on);
+- }
+-
+- void dumpHtml() {
+- view->view()->page()->toHtml([](const QString& text) {
+- kDebug() << "HTML: " << text;
+- });
+- }
+-
+- void selectElements() {
+- bool ok;
+- QString str = QInputDialog::getText(this, i18nc("input dialog window title for selecting html elements", "Select elements"),
+- i18nc("input dialog text for selecting html elements", "Choose elements"), QLineEdit::Normal,
+- QStringLiteral("a"), &ok);
+- if (ok && !str.isEmpty()) {
+- //QWebElementCollection collection = view->page()->mainFrame()->findAllElements(str);
+- //const int count = collection.count();
+- //for (int i=0; i < count; i++)
+- // collection.at(i).setStyleProperty("background-color", "yellow");
+- //statusBar()->showMessage(i18np("%1 element selected", "%1 elements selected", count), 5000);
+- }
+- }
+-
+-public slots:
+-
+- void newWindow(const QString &url = QString()) {
+- MainWindow *mw = new MainWindow(url);
+- mw->show();
+- }
+-
+-private:
+-
+- QVector<int> zoomLevels;
+- int currentZoom;
+-
+- // create the status bar, tool bar & menu
+- void setupUI() {
+- progress = new QProgressBar(this);
+- progress->setRange(0, 100);
+- progress->setMinimumSize(100, 20);
+- progress->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
+- progress->hide();
+- statusBar()->addPermanentWidget(progress);
+-
+- connect(view->view(), SIGNAL(loadProgress(int)), progress, SLOT(show()));
+- connect(view->view(), SIGNAL(loadProgress(int)), progress, SLOT(setValue(int)));
+- connect(view->view(), SIGNAL(loadFinished(bool)), progress, SLOT(hide()));
+-
+- urlEdit = new KLineEdit(this);
+- urlEdit->setSizePolicy(QSizePolicy::Expanding, urlEdit->sizePolicy().verticalPolicy());
+- connect(urlEdit, SIGNAL(returnPressed()),
+- SLOT(changeLocation()));
+- QCompleter *completer = new QCompleter(this);
+- urlEdit->setCompleter(completer);
+- completer->setModel(&urlModel);
+-
+- QToolBar *bar = addToolBar(QStringLiteral("Navigation"));
+- bar->addAction(view->view()->pageAction(QWebEnginePage::Back));
+- bar->addAction(view->view()->pageAction(QWebEnginePage::Forward));
+- bar->addAction(view->view()->pageAction(QWebEnginePage::Reload));
+- bar->addAction(view->view()->pageAction(QWebEnginePage::Stop));
+- bar->addWidget(urlEdit);
+-
+- QMenu *fileMenu = menuBar()->addMenu(i18n("&File"));
+- QAction *newWindow = fileMenu->addAction(i18n("New Window"), this, SLOT(newWindow()));
+-
+- fileMenu->addAction(i18n("Print"), this, SLOT(print()));
+- fileMenu->addAction(i18n("Close"), this, SLOT(close()));
+-
+- QMenu *editMenu = menuBar()->addMenu(i18n("&Edit"));
+- editMenu->addAction(view->view()->pageAction(QWebEnginePage::Undo));
+- editMenu->addAction(view->view()->pageAction(QWebEnginePage::Redo));
+- editMenu->addSeparator();
+- editMenu->addAction(view->view()->pageAction(QWebEnginePage::Cut));
+- editMenu->addAction(view->view()->pageAction(QWebEnginePage::Copy));
+- editMenu->addAction(view->view()->pageAction(QWebEnginePage::Paste));
+- editMenu->addSeparator();
+- QAction *setEditable = editMenu->addAction(i18n("Set Editable"), this, SLOT(setEditable(bool)));
+- setEditable->setCheckable(true);
+-
+- QMenu *viewMenu = menuBar()->addMenu(i18n("&View"));
+- viewMenu->addAction(view->view()->pageAction(QWebEnginePage::Stop));
+- viewMenu->addAction(view->view()->pageAction(QWebEnginePage::Reload));
+- viewMenu->addSeparator();
+- QAction *zoomIn = viewMenu->addAction(i18n("Zoom &In"), this, SLOT(zoomIn()));
+- QAction *zoomOut = viewMenu->addAction(i18n("Zoom &Out"), this, SLOT(zoomOut()));
+- QAction *resetZoom = viewMenu->addAction(i18n("Reset Zoom"), this, SLOT(resetZoom()));
+- QAction *zoomTextOnly = viewMenu->addAction(i18n("Zoom Text Only"), this, SLOT(toggleZoomTextOnly(bool)));
+- zoomTextOnly->setCheckable(true);
+- zoomTextOnly->setChecked(false);
+- viewMenu->addSeparator();
+- viewMenu->addAction(i18n("Dump HTML"), this, SLOT(dumpHtml()));
+-
+-#if 0
+- QMenu *formatMenu = new QMenu(i18n("F&ormat"));
+- formatMenuAction = menuBar()->addMenu(formatMenu);
+- formatMenuAction->setVisible(false);
+- formatMenu->addAction(view->view()->pageAction(QWebEnginePage::ToggleBold));
+- formatMenu->addAction(view->view()->pageAction(QWebEnginePage::ToggleItalic));
+- formatMenu->addAction(view->view()->pageAction(QWebEnginePage::ToggleUnderline));
+- QMenu *writingMenu = formatMenu->addMenu(i18n("Writing Direction"));
+- writingMenu->addAction(view->view()->pageAction(QWebEnginePage::SetTextDirectionDefault));
+- writingMenu->addAction(view->view()->pageAction(QWebEnginePage::SetTextDirectionLeftToRight));
+- writingMenu->addAction(view->view()->pageAction(QWebEnginePage::SetTextDirectionRightToLeft));
+-#endif
+- newWindow->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_N));
+- view->view()->pageAction(QWebEnginePage::Back)->setShortcut(QKeySequence::Back);
+- view->view()->pageAction(QWebEnginePage::Stop)->setShortcut(Qt::Key_Escape);
+- view->view()->pageAction(QWebEnginePage::Forward)->setShortcut(QKeySequence::Forward);
+- view->view()->pageAction(QWebEnginePage::Reload)->setShortcut(QKeySequence::Refresh);
+- view->view()->pageAction(QWebEnginePage::Undo)->setShortcut(QKeySequence::Undo);
+- view->view()->pageAction(QWebEnginePage::Redo)->setShortcut(QKeySequence::Redo);
+- view->view()->pageAction(QWebEnginePage::Cut)->setShortcut(QKeySequence::Cut);
+- view->view()->pageAction(QWebEnginePage::Copy)->setShortcut(QKeySequence::Copy);
+- view->view()->pageAction(QWebEnginePage::Paste)->setShortcut(QKeySequence::Paste);
+- zoomIn->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Plus));
+- zoomOut->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Minus));
+- resetZoom->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_0));
+-// view->view()->pageAction(QWebEnginePage::ToggleBold)->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_B));
+-// view->view()->pageAction(QWebEnginePage::ToggleItalic)->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_I));
+-// view->view()->pageAction(QWebEnginePage::ToggleUnderline)->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_U));
+-
+- QMenu *toolsMenu = menuBar()->addMenu(i18n("&Tools"));
+- toolsMenu->addAction(i18n("Select elements..."), this, SLOT(selectElements()));
+-
+- }
+-
+- WebEnginePart *view;
+- KLineEdit *urlEdit;
+- QProgressBar *progress;
+-
+- QAction *formatMenuAction;
+-
+- QStringList urlList;
+- QStringListModel urlModel;
+-};
+-
+-class URLLoader : public QObject
+-{
+- Q_OBJECT
+-public:
+- URLLoader(QWebEngineView* view, const QString& inputFileName)
+- : m_view(view)
+- , m_stdOut(stdout)
+- {
+- init(inputFileName);
+- }
+-
+-public slots:
+- void loadNext()
+- {
+- QString qstr;
+- if (getUrl(qstr)) {
+- QUrl url(qstr, QUrl::StrictMode);
+- if (url.isValid()) {
+- m_stdOut << "Loading " << qstr << " ......" << endl;
+- m_view->load(url);
+- } else
+- loadNext();
+- } else
+- disconnect(m_view, 0, this, 0);
+- }
+-
+-private:
+- void init(const QString& inputFileName)
+- {
+- QFile inputFile(inputFileName);
+- if (inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+- QTextStream stream(&inputFile);
+- QString line;
+- while (true) {
+- line = stream.readLine();
+- if (line.isNull())
+- break;
+- m_urls.append(line);
+- }
+- } else {
+- kDebug() << "Can't open list file";
+- exit(0);
+- }
+- m_index = 0;
+- inputFile.close();
+- }
+-
+- bool getUrl(QString& qstr)
+- {
+- if (m_index == m_urls.size())
+- return false;
+-
+- qstr = m_urls[m_index++];
+- return true;
+- }
+-
+-private:
+- QVector<QString> m_urls;
+- int m_index;
+- QWebEngineView* m_view;
+- QTextStream m_stdOut;
+-};
+-
+-
+-int main(int argc, char **argv)
+-{
+- KAboutData about(QStringLiteral("KDELauncher"), i18n("KDELauncher"), QStringLiteral("0.0000013"));
+- QApplication app(argc, argv);
+- QCommandLineParser parser;
+- KAboutData::setApplicationData(about);
+- parser.addVersionOption();
+- parser.addHelpOption();
+- //PORTING SCRIPT: adapt aboutdata variable if necessary
+- about.setupCommandLine(&parser);
+- parser.process(app);
+- about.processCommandLine(&parser);
+-
+- QString url = QStringLiteral("%1/%2").arg(QDir::homePath()).arg(QStringLiteral("index.html"));
+-
+-// QWebEngineSettings::globalSettings()->setMaximumPagesInCache(4);
+-
+-// QWebEngineSettings::setObjectCacheCapacities((16*1024*1024) / 8, (16*1024*1024) / 8, 16*1024*1024);
+-
+- QWebEngineSettings::globalSettings()->setAttribute(QWebEngineSettings::PluginsEnabled, true);
+-// QWebEngineSettings::globalSettings()->setAttribute(QWebEngineSettings::DeveloperExtrasEnabled, true);
+-
+- const QStringList args = app.arguments();
+-
+- if (args.contains(QStringLiteral("-r"))) {
+- // robotized
+- QString listFile = args.at(2);
+- if (!(args.count() == 3) && QFile::exists(listFile)) {
+- kDebug() << "Usage: KDELauncher -r listfile";
+- exit(0);
+- }
+- MainWindow window;
+- QWebEngineView *view = window.webView();
+- URLLoader loader(view, listFile);
+- QObject::connect(view, SIGNAL(loadFinished(bool)), &loader, SLOT(loadNext()));
+- loader.loadNext();
+- window.show();
+- return app.exec();
+- } else {
+- if (args.count() > 1)
+- url = args.at(1);
+-
+- MainWindow window(url);
+-
+- // Opens every given urls in new windows
+- for (int i = 2; i < args.count(); i++)
+- window.newWindow(args.at(i));
+-
+- window.show();
+- return app.exec();
+- }
+-}
+-
+-#include "webenginepart_tester.moc"
+diff --git a/webenginepart/webenginepart.lsm a/webenginepart/webenginepart.lsm
+deleted file mode 100644
+index 99b4fbe5a..000000000
+--- a/webenginepart/webenginepart.lsm
++++ /dev/null
+@@ -1,18 +0,0 @@
+-Begin3
+-Title: webenginepart
+-Version: 1.2.0
+-Entered-date: 06APR2011
+-Description: A WebEngine browser component for KDE (KPart)
+-Keywords: webengine, webenginepart
+-Author: Trolltech ASA
+- Urs Wolfer <uwolfer @ kde.org>
+- Laurent Montel <montel@kde.org>
+- Dawit Alemayehu <adawit@kde.org>
+- Sune Vuorela <sune@kde.org>
+-Maintained-by: Sune Vuorela <sune@kde.org>
+-Primary-site:
+-Home-Page:
+-Original-site: None
+-Platforms: KF5 and higher
+-Copying-policy: LGPL
+-End
+diff --git b/webkitpart/CMakeLists.txt b/webkitpart/CMakeLists.txt
+new file mode 100644
+index 000000000..b62735e8b
+--- /dev/null
++++ b/webkitpart/CMakeLists.txt
+@@ -0,0 +1,4 @@
++add_subdirectory(icons)
++add_subdirectory(src)
++add_subdirectory(tests)
++add_subdirectory(autotests)
+diff --git b/webkitpart/COPYING.LIB b/webkitpart/COPYING.LIB
+new file mode 100644
+index 000000000..01148ab6f
+--- /dev/null
++++ b/webkitpart/COPYING.LIB
+@@ -0,0 +1,486 @@
++NOTE! The LGPL below is copyrighted by the Free Software Foundation, but
++the instance of code that it refers to (the kde libraries) are copyrighted
++by the authors who actually wrote it.
++
++---------------------------------------------------------------------------
++ GNU LIBRARY GENERAL PUBLIC LICENSE
++ Version 2, June 1991
++
++ Copyright (C) 1991 Free Software Foundation, Inc.
++ 51 Franklin Street, Fifth Floor
++ Boston, MA 02110-1301, USA.
++ Everyone is permitted to copy and distribute verbatim copies
++ of this license document, but changing it is not allowed.
++
++[This is the first released version of the library GPL. It is
++ numbered 2 because it goes with version 2 of the ordinary GPL.]
++
++ Preamble
++
++ The licenses for most software are designed to take away your
++freedom to share and change it. By contrast, the GNU General Public
++Licenses are intended to guarantee your freedom to share and change
++free software--to make sure the software is free for all its users.
++
++ This license, the Library General Public License, applies to some
++specially designated Free Software Foundation software, and to any
++other libraries whose authors decide to use it. You can use it for
++your libraries, too.
++
++ When we speak of free software, we are referring to freedom, not
++price. Our General Public Licenses are designed to make sure that you
++have the freedom to distribute copies of free software (and charge for
++this service if you wish), that you receive source code or can get it
++if you want it, that you can change the software or use pieces of it
++in new free programs; and that you know you can do these things.
++
++ To protect your rights, we need to make restrictions that forbid
++anyone to deny you these rights or to ask you to surrender the rights.
++These restrictions translate to certain responsibilities for you if
++you distribute copies of the library, or if you modify it.
++
++ For example, if you distribute copies of the library, whether gratis
++or for a fee, you must give the recipients all the rights that we gave
++you. You must make sure that they, too, receive or can get the source
++code. If you link a program with the library, you must provide
++complete object files to the recipients so that they can relink them
++with the library, after making changes to the library and recompiling
++it. And you must show them these terms so they know their rights.
++
++ Our method of protecting your rights has two steps: (1) copyright
++the library, and (2) offer you this license which gives you legal
++permission to copy, distribute and/or modify the library.
++
++ Also, for each distributor's protection, we want to make certain
++that everyone understands that there is no warranty for this free
++library. If the library is modified by someone else and passed on, we
++want its recipients to know that what they have is not the original
++version, so that any problems introduced by others will not reflect on
++the original authors' reputations.
++
++ Finally, any free program is threatened constantly by software
++patents. We wish to avoid the danger that companies distributing free
++software will individually obtain patent licenses, thus in effect
++transforming the program into proprietary software. To prevent this,
++we have made it clear that any patent must be licensed for everyone's
++free use or not licensed at all.
++
++ Most GNU software, including some libraries, is covered by the ordinary
++GNU General Public License, which was designed for utility programs. This
++license, the GNU Library General Public License, applies to certain
++designated libraries. This license is quite different from the ordinary
++one; be sure to read it in full, and don't assume that anything in it is
++the same as in the ordinary license.
++
++ The reason we have a separate public license for some libraries is that
++they blur the distinction we usually make between modifying or adding to a
++program and simply using it. Linking a program with a library, without
++changing the library, is in some sense simply using the library, and is
++analogous to running a utility program or application program. However, in
++a textual and legal sense, the linked executable is a combined work, a
++derivative of the original library, and the ordinary General Public License
++treats it as such.
++
++ Because of this blurred distinction, using the ordinary General
++Public License for libraries did not effectively promote software
++sharing, because most developers did not use the libraries. We
++concluded that weaker conditions might promote sharing better.
++
++ However, unrestricted linking of non-free programs would deprive the
++users of those programs of all benefit from the free status of the
++libraries themselves. This Library General Public License is intended to
++permit developers of non-free programs to use free libraries, while
++preserving your freedom as a user of such programs to change the free
++libraries that are incorporated in them. (We have not seen how to achieve
++this as regards changes in header files, but we have achieved it as regards
++changes in the actual functions of the Library.) The hope is that this
++will lead to faster development of free libraries.
++
++ The precise terms and conditions for copying, distribution and
++modification follow. Pay close attention to the difference between a
++"work based on the library" and a "work that uses the library". The
++former contains code derived from the library, while the latter only
++works together with the library.
++
++ Note that it is possible for a library to be covered by the ordinary
++General Public License rather than by this special one.
++
++ GNU LIBRARY GENERAL PUBLIC LICENSE
++ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
++
++ 0. This License Agreement applies to any software library which
++contains a notice placed by the copyright holder or other authorized
++party saying it may be distributed under the terms of this Library
++General Public License (also called "this License"). Each licensee is
++addressed as "you".
++
++ A "library" means a collection of software functions and/or data
++prepared so as to be conveniently linked with application programs
++(which use some of those functions and data) to form executables.
++
++ The "Library", below, refers to any such software library or work
++which has been distributed under these terms. A "work based on the
++Library" means either the Library or any derivative work under
++copyright law: that is to say, a work containing the Library or a
++portion of it, either verbatim or with modifications and/or translated
++straightforwardly into another language. (Hereinafter, translation is
++included without limitation in the term "modification".)
++
++ "Source code" for a work means the preferred form of the work for
++making modifications to it. For a library, complete source code means
++all the source code for all modules it contains, plus any associated
++interface definition files, plus the scripts used to control compilation
++and installation of the library.
++
++ Activities other than copying, distribution and modification are not
++covered by this License; they are outside its scope. The act of
++running a program using the Library is not restricted, and output from
++such a program is covered only if its contents constitute a work based
++on the Library (independent of the use of the Library in a tool for
++writing it). Whether that is true depends on what the Library does
++and what the program that uses the Library does.
++
++ 1. You may copy and distribute verbatim copies of the Library's
++complete source code as you receive it, in any medium, provided that
++you conspicuously and appropriately publish on each copy an
++appropriate copyright notice and disclaimer of warranty; keep intact
++all the notices that refer to this License and to the absence of any
++warranty; and distribute a copy of this License along with the
++Library.
++
++ You may charge a fee for the physical act of transferring a copy,
++and you may at your option offer warranty protection in exchange for a
++fee.
++
++ 2. You may modify your copy or copies of the Library or any portion
++of it, thus forming a work based on the Library, and copy and
++distribute such modifications or work under the terms of Section 1
++above, provided that you also meet all of these conditions:
++
++ a) The modified work must itself be a software library.
++
++ b) You must cause the files modified to carry prominent notices
++ stating that you changed the files and the date of any change.
++
++ c) You must cause the whole of the work to be licensed at no
++ charge to all third parties under the terms of this License.
++
++ d) If a facility in the modified Library refers to a function or a
++ table of data to be supplied by an application program that uses
++ the facility, other than as an argument passed when the facility
++ is invoked, then you must make a good faith effort to ensure that,
++ in the event an application does not supply such function or
++ table, the facility still operates, and performs whatever part of
++ its purpose remains meaningful.
++
++ (For example, a function in a library to compute square roots has
++ a purpose that is entirely well-defined independent of the
++ application. Therefore, Subsection 2d requires that any
++ application-supplied function or table used by this function must
++ be optional: if the application does not supply it, the square
++ root function must still compute square roots.)
++
++These requirements apply to the modified work as a whole. If
++identifiable sections of that work are not derived from the Library,
++and can be reasonably considered independent and separate works in
++themselves, then this License, and its terms, do not apply to those
++sections when you distribute them as separate works. But when you
++distribute the same sections as part of a whole which is a work based
++on the Library, the distribution of the whole must be on the terms of
++this License, whose permissions for other licensees extend to the
++entire whole, and thus to each and every part regardless of who wrote
++it.
++
++Thus, it is not the intent of this section to claim rights or contest
++your rights to work written entirely by you; rather, the intent is to
++exercise the right to control the distribution of derivative or
++collective works based on the Library.
++
++In addition, mere aggregation of another work not based on the Library
++with the Library (or with a work based on the Library) on a volume of
++a storage or distribution medium does not bring the other work under
++the scope of this License.
++
++ 3. You may opt to apply the terms of the ordinary GNU General Public
++License instead of this License to a given copy of the Library. To do
++this, you must alter all the notices that refer to this License, so
++that they refer to the ordinary GNU General Public License, version 2,
++instead of to this License. (If a newer version than version 2 of the
++ordinary GNU General Public License has appeared, then you can specify
++that version instead if you wish.) Do not make any other change in
++these notices.
++
++ Once this change is made in a given copy, it is irreversible for
++that copy, so the ordinary GNU General Public License applies to all
++subsequent copies and derivative works made from that copy.
++
++ This option is useful when you wish to copy part of the code of
++the Library into a program that is not a library.
++
++ 4. You may copy and distribute the Library (or a portion or
++derivative of it, under Section 2) in object code or executable form
++under the terms of Sections 1 and 2 above provided that you accompany
++it with the complete corresponding machine-readable source code, which
++must be distributed under the terms of Sections 1 and 2 above on a
++medium customarily used for software interchange.
++
++ If distribution of object code is made by offering access to copy
++from a designated place, then offering equivalent access to copy the
++source code from the same place satisfies the requirement to
++distribute the source code, even though third parties are not
++compelled to copy the source along with the object code.
++
++ 5. A program that contains no derivative of any portion of the
++Library, but is designed to work with the Library by being compiled or
++linked with it, is called a "work that uses the Library". Such a
++work, in isolation, is not a derivative work of the Library, and
++therefore falls outside the scope of this License.
++
++ However, linking a "work that uses the Library" with the Library
++creates an executable that is a derivative of the Library (because it
++contains portions of the Library), rather than a "work that uses the
++library". The executable is therefore covered by this License.
++Section 6 states terms for distribution of such executables.
++
++ When a "work that uses the Library" uses material from a header file
++that is part of the Library, the object code for the work may be a
++derivative work of the Library even though the source code is not.
++Whether this is true is especially significant if the work can be
++linked without the Library, or if the work is itself a library. The
++threshold for this to be true is not precisely defined by law.
++
++ If such an object file uses only numerical parameters, data
++structure layouts and accessors, and small macros and small inline
++functions (ten lines or less in length), then the use of the object
++file is unrestricted, regardless of whether it is legally a derivative
++work. (Executables containing this object code plus portions of the
++Library will still fall under Section 6.)
++
++ Otherwise, if the work is a derivative of the Library, you may
++distribute the object code for the work under the terms of Section 6.
++Any executables containing that work also fall under Section 6,
++whether or not they are linked directly with the Library itself.
++
++ 6. As an exception to the Sections above, you may also compile or
++link a "work that uses the Library" with the Library to produce a
++work containing portions of the Library, and distribute that work
++under terms of your choice, provided that the terms permit
++modification of the work for the customer's own use and reverse
++engineering for debugging such modifications.
++
++ You must give prominent notice with each copy of the work that the
++Library is used in it and that the Library and its use are covered by
++this License. You must supply a copy of this License. If the work
++during execution displays copyright notices, you must include the
++copyright notice for the Library among them, as well as a reference
++directing the user to the copy of this License. Also, you must do one
++of these things:
++
++ a) Accompany the work with the complete corresponding
++ machine-readable source code for the Library including whatever
++ changes were used in the work (which must be distributed under
++ Sections 1 and 2 above); and, if the work is an executable linked
++ with the Library, with the complete machine-readable "work that
++ uses the Library", as object code and/or source code, so that the
++ user can modify the Library and then relink to produce a modified
++ executable containing the modified Library. (It is understood
++ that the user who changes the contents of definitions files in the
++ Library will not necessarily be able to recompile the application
++ to use the modified definitions.)
++
++ b) Accompany the work with a written offer, valid for at
++ least three years, to give the same user the materials
++ specified in Subsection 6a, above, for a charge no more
++ than the cost of performing this distribution.
++
++ c) If distribution of the work is made by offering access to copy
++ from a designated place, offer equivalent access to copy the above
++ specified materials from the same place.
++
++ d) Verify that the user has already received a copy of these
++ materials or that you have already sent this user a copy.
++
++ For an executable, the required form of the "work that uses the
++Library" must include any data and utility programs needed for
++reproducing the executable from it. However, as a special exception,
++the source code distributed need not include anything that is normally
++distributed (in either source or binary form) with the major
++components (compiler, kernel, and so on) of the operating system on
++which the executable runs, unless that component itself accompanies
++the executable.
++
++ It may happen that this requirement contradicts the license
++restrictions of other proprietary libraries that do not normally
++accompany the operating system. Such a contradiction means you cannot
++use both them and the Library together in an executable that you
++distribute.
++
++ 7. You may place library facilities that are a work based on the
++Library side-by-side in a single library together with other library
++facilities not covered by this License, and distribute such a combined
++library, provided that the separate distribution of the work based on
++the Library and of the other library facilities is otherwise
++permitted, and provided that you do these two things:
++
++ a) Accompany the combined library with a copy of the same work
++ based on the Library, uncombined with any other library
++ facilities. This must be distributed under the terms of the
++ Sections above.
++
++ b) Give prominent notice with the combined library of the fact
++ that part of it is a work based on the Library, and explaining
++ where to find the accompanying uncombined form of the same work.
++
++ 8. You may not copy, modify, sublicense, link with, or distribute
++the Library except as expressly provided under this License. Any
++attempt otherwise to copy, modify, sublicense, link with, or
++distribute the Library is void, and will automatically terminate your
++rights under this License. However, parties who have received copies,
++or rights, from you under this License will not have their licenses
++terminated so long as such parties remain in full compliance.
++
++ 9. You are not required to accept this License, since you have not
++signed it. However, nothing else grants you permission to modify or
++distribute the Library or its derivative works. These actions are
++prohibited by law if you do not accept this License. Therefore, by
++modifying or distributing the Library (or any work based on the
++Library), you indicate your acceptance of this License to do so, and
++all its terms and conditions for copying, distributing or modifying
++the Library or works based on it.
++
++ 10. Each time you redistribute the Library (or any work based on the
++Library), the recipient automatically receives a license from the
++original licensor to copy, distribute, link with or modify the Library
++subject to these terms and conditions. You may not impose any further
++restrictions on the recipients' exercise of the rights granted herein.
++You are not responsible for enforcing compliance by third parties to
++this License.
++
++ 11. If, as a consequence of a court judgment or allegation of patent
++infringement or for any other reason (not limited to patent issues),
++conditions are imposed on you (whether by court order, agreement or
++otherwise) that contradict the conditions of this License, they do not
++excuse you from the conditions of this License. If you cannot
++distribute so as to satisfy simultaneously your obligations under this
++License and any other pertinent obligations, then as a consequence you
++may not distribute the Library at all. For example, if a patent
++license would not permit royalty-free redistribution of the Library by
++all those who receive copies directly or indirectly through you, then
++the only way you could satisfy both it and this License would be to
++refrain entirely from distribution of the Library.
++
++If any portion of this section is held invalid or unenforceable under any
++particular circumstance, the balance of the section is intended to apply,
++and the section as a whole is intended to apply in other circumstances.
++
++It is not the purpose of this section to induce you to infringe any
++patents or other property right claims or to contest validity of any
++such claims; this section has the sole purpose of protecting the
++integrity of the free software distribution system which is
++implemented by public license practices. Many people have made
++generous contributions to the wide range of software distributed
++through that system in reliance on consistent application of that
++system; it is up to the author/donor to decide if he or she is willing
++to distribute software through any other system and a licensee cannot
++impose that choice.
++
++This section is intended to make thoroughly clear what is believed to
++be a consequence of the rest of this License.
++
++ 12. If the distribution and/or use of the Library is restricted in
++certain countries either by patents or by copyrighted interfaces, the
++original copyright holder who places the Library under this License may add
++an explicit geographical distribution limitation excluding those countries,
++so that distribution is permitted only in or among countries not thus
++excluded. In such case, this License incorporates the limitation as if
++written in the body of this License.
++
++ 13. The Free Software Foundation may publish revised and/or new
++versions of the Library General Public License from time to time.
++Such new versions will be similar in spirit to the present version,
++but may differ in detail to address new problems or concerns.
++
++Each version is given a distinguishing version number. If the Library
++specifies a version number of this License which applies to it and
++"any later version", you have the option of following the terms and
++conditions either of that version or of any later version published by
++the Free Software Foundation. If the Library does not specify a
++license version number, you may choose any version ever published by
++the Free Software Foundation.
++
++ 14. If you wish to incorporate parts of the Library into other free
++programs whose distribution conditions are incompatible with these,
++write to the author to ask for permission. For software which is
++copyrighted by the Free Software Foundation, write to the Free
++Software Foundation; we sometimes make exceptions for this. Our
++decision will be guided by the two goals of preserving the free status
++of all derivatives of our free software and of promoting the sharing
++and reuse of software generally.
++
++ NO WARRANTY
++
++ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
++WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
++EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
++OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
++KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
++IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
++LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
++THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
++
++ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
++WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
++AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
++FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
++CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
++LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
++RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
++FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
++SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
++DAMAGES.
++
++ END OF TERMS AND CONDITIONS
++ How to Apply These Terms to Your New Libraries
++
++ If you develop a new library, and you want it to be of the greatest
++possible use to the public, we recommend making it free software that
++everyone can redistribute and change. You can do so by permitting
++redistribution under these terms (or, alternatively, under the terms of the
++ordinary General Public License).
++
++ To apply these terms, attach the following notices to the library. It is
++safest to attach them to the start of each source file to most effectively
++convey the exclusion of warranty; and each file should have at least the
++"copyright" line and a pointer to where the full notice is found.
++
++ <one line to give the library's name and a brief idea of what it does.>
++ Copyright (C) <year> <name of author>
++
++ 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 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, write to the Free Software
++ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++
++Also add information on how to contact you by electronic and paper mail.
++
++You should also get your employer (if you work as a programmer) or your
++school, if any, to sign a "copyright disclaimer" for the library, if
++necessary. Here is a sample; alter the names:
++
++ Yoyodyne, Inc., hereby disclaims all copyright interest in the
++ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
++
++ <signature of Ty Coon>, 1 April 1990
++ Ty Coon, President of Vice
++
++That's all there is to it!
+diff --git b/webkitpart/Mainpage.dox b/webkitpart/Mainpage.dox
+new file mode 100644
+index 000000000..832196aef
+--- /dev/null
++++ b/webkitpart/Mainpage.dox
+@@ -0,0 +1,4 @@
++/** @mainpage
++*
++* Main Doxygen page for KWebKitPart.
++*/
+diff --git b/webkitpart/Messages.sh b/webkitpart/Messages.sh
+new file mode 100644
+index 000000000..ce16bc912
+--- /dev/null
++++ b/webkitpart/Messages.sh
+@@ -0,0 +1,4 @@
++#! /usr/bin/env bash
++$EXTRACTRC `find . -name '*.rc' -or -name '*.ui'` >> rc.cpp || exit 11
++$XGETTEXT `find . -name '*.cpp' | grep -v '/tests/'` -o $podir/webkitpart.pot
++rm -f rc.cpp
+diff --git b/webkitpart/README b/webkitpart/README
+new file mode 100644
+index 000000000..f73bfc864
+--- /dev/null
++++ b/webkitpart/README
+@@ -0,0 +1,40 @@
++KWebKitPart
++===========
++
++KWebKitPart is a KDE component (KPart) wrapper for QtWebKit. It is intended to
++allow KPart based KDE applications such as Konqueror to use it in place of other
++browser engine, such as KHTML, to browse the web in Konqueror.
++
++Known limitations and unimplemented features are listed in the following
++documents:
++
++* https://projects.kde.org/projects/kde/kdelibs/repository/revisions/master/entry/kdewebkit/ISSUES
++* https://projects.kde.org/projects/extragear/base/kwebkitpart/repository/revisions/master/entry/TODO
++
++Please report any issues to: https://bugs.kde.org
++IMPORTANT NOTE: Do not select "konqueror" as product, but "kwebkitpart"!
++
++There is also a public mailing list available for support:
++
++ webkit-devel @ kde.org
++
++How to use KWebKitPart in Konqueror
++===================================
++
++You can switch between the different rendering engines:
++View -> View Mode -> {KHTML, WebKit} (website needs to be open)
++If WebKit does not show up in Konqueror, run 'kbuildsycoca4' and
++restart Konqueror. Note that this change does not persist. If you
++press the reload button or open a new website, it will fall back
++to the default rendering engine.
++
++If you want to set KWebKitPart as default for any website, run:
++'keditfiletype text/html'
++and move "WebKit (kwebkitpart)" in the "Embedding" tab to the top.
++
++In KDE 4.6 and higher you can choose the default rendering engine
++in Konqueror's configuration dialog under the "General" section.
++
++For more information about this project please see also:
++http://techbase.kde.org/Projects/WebKit
++
+diff --git b/webkitpart/TODO b/webkitpart/TODO
+new file mode 100644
+index 000000000..f6ba03459
+--- /dev/null
++++ b/webkitpart/TODO
+@@ -0,0 +1,23 @@
++* Proper support for KWebKitPart in the following Konqueror plugins:
++ - adblock This plugin's GUI needs to be changed to use the KPart plugin
++ extensions so that it is not khtml specific. Other than that
++ kwebkitpart supports the ad filtering functionalities supported
++ by khtml.
++
++* Add KPartStatusBarExtension support for the following plugins/features:
++ - Popup blocker (non-plugin)
++
++* Implement some means of showing information about the webkit rendering engine:
++ - KWebKitPart's version #
++ - QtWebKit's version #
++ - UserAgent string ???
++
++* Look through all of Konqueror's web configuration options and make sure we
++ honor all those we possibly can. Here is a non-complete list of features
++ that are either partially implemented or not implemented at all:
++ - Change cursor over links (TODO, QtWebKit ???).
++ - Smooth scrolling support (TODO, QtWebKit ???).
++ - Underline links support (Partial, does not work as intended).
++ - Enable access key navigation with Ctrl key (TODO, QtWebKit ???).
++ - Animations (TODO, QtWebKit ???).
++ - Draw frames around not completely loaded images (TODO, QtWebKit ???).
+diff --git b/webkitpart/autotests/CMakeLists.txt b/webkitpart/autotests/CMakeLists.txt
+new file mode 100644
+index 000000000..69a14a1a1
+--- /dev/null
++++ b/webkitpart/autotests/CMakeLists.txt
+@@ -0,0 +1,14 @@
++include(ECMAddTests)
++
++find_package(Qt5Test ${QT_MIN_VERSION} CONFIG REQUIRED)
++
++macro(webkitpart_unit_tests)
++ foreach(_testname ${ARGN})
++ ecm_add_test(${_testname}.cpp TEST_NAME ${_testname}
++ LINK_LIBRARIES kwebkitpartlib Qt5::Test)
++ endforeach()
++endmacro(webkitpart_unit_tests)
++
++webkitpart_unit_tests(
++ webkit_partapi_test
++)
+diff --git b/webkitpart/autotests/data/hello.html b/webkitpart/autotests/data/hello.html
+new file mode 100644
+index 000000000..e965047ad
+--- /dev/null
++++ b/webkitpart/autotests/data/hello.html
+@@ -0,0 +1 @@
++Hello
+diff --git b/webkitpart/autotests/data/page-with-link.html b/webkitpart/autotests/data/page-with-link.html
+new file mode 100644
+index 000000000..df85219d6
+--- /dev/null
++++ b/webkitpart/autotests/data/page-with-link.html
+@@ -0,0 +1 @@
++<a href="hello.html" id="linkid">click me</a>
+diff --git b/webkitpart/autotests/webkit_partapi_test.cpp b/webkitpart/autotests/webkit_partapi_test.cpp
+new file mode 100644
+index 000000000..107677692
+--- /dev/null
++++ b/webkitpart/autotests/webkit_partapi_test.cpp
+@@ -0,0 +1,133 @@
++/*
++ Copyright (c) 2016 David Faure <faure@kde.org>
++
++ 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 of the License or ( at
++ your option ) version 3 or, at the discretion of KDE e.V. ( which shall
++ act as a proxy as in section 14 of the GPLv3 ), 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 Lesser 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 <webkitpart.h>
++#include "webkit_testutils.h"
++
++#include <KIO/Job>
++#include <KParts/BrowserExtension>
++
++#include <QTest>
++#include <QObject>
++#include <QSignalSpy>
++#include <QWebView>
++
++class WebKitPartApiTest : public QObject
++{
++ Q_OBJECT
++private Q_SLOTS:
++ void initTestCase();
++ void shouldHaveBrowserExtension();
++ void shouldEmitStartedAndCompleted();
++ void shouldEmitSetWindowCaption();
++ void shouldEmitOpenUrlNotifyOnClick();
++
++};
++
++void WebKitPartApiTest::initTestCase()
++{
++ qRegisterMetaType<KIO::Job *>(); // for the KParts started signal
++}
++
++void WebKitPartApiTest::shouldHaveBrowserExtension()
++{
++ // GIVEN
++ WebKitPart part;
++
++ // WHEN
++ KParts::BrowserExtension *ext = KParts::BrowserExtension::childObject(&part);
++
++ // THEN
++ QVERIFY(ext);
++}
++
++void WebKitPartApiTest::shouldEmitStartedAndCompleted()
++{
++ // GIVEN
++ WebKitPart part;
++ QSignalSpy spyStarted(&part, &KParts::ReadOnlyPart::started);
++ QSignalSpy spyCompleted(&part, SIGNAL(completed(bool)));
++ QSignalSpy spySetWindowCaption(&part, &KParts::ReadOnlyPart::setWindowCaption);
++ KParts::BrowserExtension *ext = KParts::BrowserExtension::childObject(&part);
++ QSignalSpy spyOpenUrlNotify(ext, &KParts::BrowserExtension::openUrlNotify);
++ const QUrl url(QStringLiteral("data:text/html, <p>Hello World</p>"));
++
++ // WHEN
++ part.openUrl(url);
++
++ // THEN
++ QVERIFY(spyStarted.wait());
++ QVERIFY(spySetWindowCaption.wait());
++ QCOMPARE(spySetWindowCaption.at(0).at(0).toUrl().toString(), url.toString());
++ QVERIFY(spyCompleted.wait());
++ QVERIFY(!spyCompleted.at(0).at(0).toBool());
++ QVERIFY(spyOpenUrlNotify.isEmpty());
++}
++
++void WebKitPartApiTest::shouldEmitSetWindowCaption()
++{
++ // GIVEN
++ WebKitPart part;
++ QSignalSpy spyStarted(&part, &KParts::ReadOnlyPart::started);
++ QSignalSpy spyCompleted(&part, SIGNAL(completed(bool)));
++ QSignalSpy spySetWindowCaption(&part, &KParts::ReadOnlyPart::setWindowCaption);
++
++ // WHEN opening a URL with a title tag
++ part.openUrl(QUrl(QStringLiteral("data:text/html, <title>Custom Title</title><p>Hello World</p>")));
++
++ // THEN
++ QVERIFY(spyStarted.wait());
++ QVERIFY(spyCompleted.wait());
++ QVERIFY(!spyCompleted.at(0).at(0).toBool());
++ QCOMPARE(spySetWindowCaption.count(), 2);
++ QCOMPARE(spySetWindowCaption.at(1).at(0).toUrl().toString(), QStringLiteral("Custom Title"));
++}
++
++void WebKitPartApiTest::shouldEmitOpenUrlNotifyOnClick()
++{
++ // GIVEN
++ WebKitPart part;
++ QSignalSpy spyStarted(&part, &KParts::ReadOnlyPart::started);
++ QSignalSpy spyCompleted(&part, SIGNAL(completed(bool)));
++ QSignalSpy spySetWindowCaption(&part, &KParts::ReadOnlyPart::setWindowCaption);
++ KParts::BrowserExtension *ext = KParts::BrowserExtension::childObject(&part);
++ QSignalSpy spyOpenUrlNotify(ext, &KParts::BrowserExtension::openUrlNotify);
++ const QString file = QFINDTESTDATA("data/page-with-link.html");
++ QVERIFY(!file.isEmpty());
++ const QUrl url = QUrl::fromLocalFile(file);
++ part.openUrl(url);
++ QVERIFY(spyCompleted.wait());
++ QVERIFY(spyOpenUrlNotify.isEmpty());
++ QWebPage *page = part.view()->page();
++ const QPoint pos = elementCenter(page, QStringLiteral("linkid")); // doesn't seem fully correct...
++ part.widget()->show();
++ spyCompleted.clear();
++
++ // WHEN clicking on the link
++ QTest::mouseClick(part.view()->focusProxy(), Qt::LeftButton, Qt::KeyboardModifiers(), pos);
++
++ // THEN
++ QVERIFY(spyCompleted.wait());
++ QCOMPARE(spyOpenUrlNotify.count(), 1);
++ QCOMPARE(part.url().fileName(), QStringLiteral("hello.html"));
++}
++
++QTEST_MAIN(WebKitPartApiTest)
++#include "webkit_partapi_test.moc"
+diff --git b/webkitpart/autotests/webkit_testutils.h b/webkitpart/autotests/webkit_testutils.h
+new file mode 100644
+index 000000000..73ac53d85
+--- /dev/null
++++ b/webkitpart/autotests/webkit_testutils.h
+@@ -0,0 +1,108 @@
++/****************************************************************************
++ **
++ ** Copyright (C) 2016 The Qt Company Ltd.
++ ** Contact: https://www.qt.io/licensing/
++ **
++ ** This file is part of the QtWebKit module of the Qt Toolkit.
++ **
++ ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
++ ** Commercial License Usage
++ ** Licensees holding valid commercial Qt licenses may use this file in
++ ** accordance with the commercial license agreement provided with the
++ ** Software or, alternatively, in accordance with the terms contained in
++ ** a written agreement between you and The Qt Company. For licensing terms
++ ** and conditions see https://www.qt.io/terms-conditions. For further
++ ** information use the contact form at https://www.qt.io/contact-us.
++ **
++ ** GNU General Public License Usage
++ ** Alternatively, this file may be used under the terms of the GNU
++ ** General Public License version 3 as published by the Free Software
++ ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
++ ** included in the packaging of this file. Please review the following
++ ** information to ensure the GNU General Public License requirements will
++ ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
++ **
++ ** $QT_END_LICENSE$
++ **
++ ****************************************************************************/
++
++#include <QEventLoop>
++#include <QTimer>
++#include <QWebPage>
++
++template<typename T, typename R>
++struct RefWrapper {
++ R &ref;
++ void operator()(const T& result) {
++ ref(result);
++ }
++};
++
++template<typename T>
++class CallbackSpy {
++public:
++ CallbackSpy() : called(false) {
++ timeoutTimer.setSingleShot(true);
++ QObject::connect(&timeoutTimer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
++ }
++
++ T waitForResult() {
++ if (!called) {
++ timeoutTimer.start(10000);
++ eventLoop.exec();
++ }
++ return result;
++ }
++
++ bool wasCalled() const {
++ return called;
++ }
++
++ void operator()(const T &result) {
++ this->result = result;
++ called = true;
++ eventLoop.quit();
++ }
++
++ // Cheap rip-off of boost/std::ref
++ RefWrapper<T, CallbackSpy<T> > ref()
++ {
++ RefWrapper<T, CallbackSpy<T> > wrapper = {*this};
++ return wrapper;
++ }
++
++private:
++ Q_DISABLE_COPY(CallbackSpy)
++ bool called;
++ QTimer timeoutTimer;
++ QEventLoop eventLoop;
++ T result;
++};
++
++// taken from the qwebkit unittests
++static inline QVariant evaluateJavaScriptSync(QWebPage *page, const QString &script)
++{
++ CallbackSpy<QVariant> spy;
++ page->runJavaScript(script, spy.ref());
++ return spy.waitForResult();
++}
++
++// Taken from QtWebKit's tst_qwebkitpage.cpp
++static QPoint elementCenter(QWebPage *page, const QString &id)
++{
++ QVariantList rectList = evaluateJavaScriptSync(page,
++ "(function(){"
++ "var elem = document.getElementById('" + id + "');"
++ "var rect = elem.getBoundingClientRect();"
++ "return [rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top];"
++ "})()").toList();
++
++ if (rectList.count() != 4) {
++ qWarning("elementCenter failed.");
++ return QPoint();
++ }
++ const QRect rect(rectList.at(0).toInt(), rectList.at(1).toInt(),
++ rectList.at(2).toInt(), rectList.at(3).toInt());
++ return rect.center();
++}
++
+diff --git b/webkitpart/icons/CMakeLists.txt b/webkitpart/icons/CMakeLists.txt
+new file mode 100644
+index 000000000..4b820aeb3
+--- /dev/null
++++ b/webkitpart/icons/CMakeLists.txt
+@@ -0,0 +1,2 @@
++include(ECMInstallIcons)
++ecm_install_icons(${ICON_INSTALL_DIR})
+diff --git b/webkitpart/icons/hi128-apps-webkit.png b/webkitpart/icons/hi128-apps-webkit.png
+new file mode 100644
+index 000000000..f6580be51
+Binary files /dev/null and b/webkitpart/icons/hi128-apps-webkit.png differ
+diff --git b/webkitpart/icons/hi16-apps-webkit.png b/webkitpart/icons/hi16-apps-webkit.png
+new file mode 100644
+index 000000000..17c14d129
+Binary files /dev/null and b/webkitpart/icons/hi16-apps-webkit.png differ
+diff --git b/webkitpart/icons/hi22-apps-webkit.png b/webkitpart/icons/hi22-apps-webkit.png
+new file mode 100644
+index 000000000..03f0a4f38
+Binary files /dev/null and b/webkitpart/icons/hi22-apps-webkit.png differ
+diff --git b/webkitpart/icons/hi32-apps-webkit.png b/webkitpart/icons/hi32-apps-webkit.png
+new file mode 100644
+index 000000000..4325d32a0
+Binary files /dev/null and b/webkitpart/icons/hi32-apps-webkit.png differ
+diff --git b/webkitpart/icons/hi48-apps-webkit.png b/webkitpart/icons/hi48-apps-webkit.png
+new file mode 100644
+index 000000000..3d9c79853
+Binary files /dev/null and b/webkitpart/icons/hi48-apps-webkit.png differ
+diff --git b/webkitpart/icons/hi64-apps-webkit.png b/webkitpart/icons/hi64-apps-webkit.png
+new file mode 100644
+index 000000000..e915bfa0d
+Binary files /dev/null and b/webkitpart/icons/hi64-apps-webkit.png differ
+diff --git b/webkitpart/icons/webkit.svg b/webkitpart/icons/webkit.svg
+new file mode 100644
+index 000000000..ac2e6b9af
+--- /dev/null
++++ b/webkitpart/icons/webkit.svg
+@@ -0,0 +1,104 @@
++<?xml version="1.0" encoding="UTF-8" standalone="no"?>
++<!-- Created with Inkscape (http://www.inkscape.org/) -->
++
++<svg
++ xmlns:dc="http://purl.org/dc/elements/1.1/"
++ xmlns:cc="http://creativecommons.org/ns#"
++ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
++ xmlns:svg="http://www.w3.org/2000/svg"
++ xmlns="http://www.w3.org/2000/svg"
++ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
++ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
++ width="64"
++ height="64"
++ id="svg3360"
++ version="1.1"
++ inkscape:version="0.91 r13725"
++ viewBox="0 0 64 64"
++ sodipodi:docname="webkit.svg"
++ inkscape:export-filename="/home/sune/git/kwebkitpart/icons/hi128-app-webkit.png"
++ inkscape:export-xdpi="180"
++ inkscape:export-ydpi="180">
++ <defs
++ id="defs3362" />
++ <sodipodi:namedview
++ id="base"
++ pagecolor="#ffffff"
++ bordercolor="#666666"
++ borderopacity="1.0"
++ inkscape:pageopacity="0.0"
++ inkscape:pageshadow="2"
++ inkscape:zoom="5.5"
++ inkscape:cx="-5.0909091"
++ inkscape:cy="24.727273"
++ inkscape:current-layer="layer1"
++ showgrid="true"
++ inkscape:document-units="px"
++ inkscape:grid-bbox="true"
++ inkscape:window-width="3200"
++ inkscape:window-height="1685"
++ inkscape:window-x="0"
++ inkscape:window-y="0"
++ inkscape:window-maximized="1" />
++ <metadata
++ id="metadata3365">
++ <rdf:RDF>
++ <cc:Work
++ rdf:about="">
++ <dc:format>image/svg+xml</dc:format>
++ <dc:type
++ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
++ <dc:title></dc:title>
++ </cc:Work>
++ </rdf:RDF>
++ </metadata>
++ <g
++ id="layer1"
++ inkscape:label="Layer 1"
++ inkscape:groupmode="layer">
++ <text
++ xml:space="preserve"
++ style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#0079b1;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
++ x="1.6363635"
++ y="32.545456"
++ id="text3368"
++ sodipodi:linespacing="125%"><tspan
++ sodipodi:role="line"
++ id="tspan3370"
++ x="1.6363635"
++ y="32.545456">W</tspan></text>
++ <text
++ xml:space="preserve"
++ style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#b0009d;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
++ x="14.545453"
++ y="46"
++ id="text4172"
++ sodipodi:linespacing="125%"><tspan
++ sodipodi:role="line"
++ id="tspan4174"
++ x="14.545453"
++ y="46">E</tspan></text>
++ <text
++ xml:space="preserve"
++ style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#b0009d;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
++ x="39.40696"
++ y="32.398262"
++ id="text4172-3"
++ sodipodi:linespacing="125%"><tspan
++ sodipodi:role="line"
++ id="tspan4174-6"
++ x="39.40696"
++ y="32.398262">E</tspan></text>
++ <text
++ xml:space="preserve"
++ style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#848400;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
++ x="28"
++ y="59.818184"
++ id="text4194"
++ sodipodi:linespacing="125%"><tspan
++ sodipodi:role="line"
++ id="tspan4196"
++ x="28"
++ y="59.818184">B</tspan></text>
++ </g>
++</svg>
+diff --git b/webkitpart/scripts/codingstyle.sh b/webkitpart/scripts/codingstyle.sh
+new file mode 100755
+index 000000000..1761942d6
+--- /dev/null
++++ b/webkitpart/scripts/codingstyle.sh
+@@ -0,0 +1,19 @@
++#!/bin/sh
++#
++# Kdelibs coding style is defined in http://techbase.kde.org/Policies/Kdelibs_Coding_Style
++#
++
++PWD=$(pwd)
++cd $PWD
++
++echo "Applying astyle rules..."
++astyle -v --indent=spaces=4 \
++ --brackets=linux \
++ --indent-labels \
++ --pad=oper --unpad=paren \
++ --one-line=keep-statements \
++ --convert-tabs --indent-preprocessor \
++ `find -type f -name '*.cpp' -or -name '*.h' -or -name '*.cc' | grep -Ev "\./.+/settings/"`
++
++echo "Done!"
++
+diff --git b/webkitpart/scripts/create_release_package.sh b/webkitpart/scripts/create_release_package.sh
+new file mode 100755
+index 000000000..a8694c897
+--- /dev/null
++++ b/webkitpart/scripts/create_release_package.sh
+@@ -0,0 +1,16 @@
++#!/bin/sh
++
++VERSION=${1}
++GITREPO=${2}
++OUTPUTDIR=${3}
++
++if [ -z ${VERSION} ] || [ -z {GITREPO} ]; then
++ echo "Usage: `basename ${0}` <VERSION> <GITREPO> [<OUTPUTDIR>]"
++ exit 1
++fi
++
++if [ -z $OUTPUTDIR ] || [ ! -d $OUTPUTDIR ]; then
++ OUTPUTDIR="${PWD}"
++fi
++
++git archive --format=tar --prefix=kwebkitpart-${VERSION}/ ${GITREPO} | bzip2 -9 > ${OUTPUTDIR}/kwebkitpart-${VERSION}.tar.bz2
+diff --git b/webkitpart/src/CMakeLists.txt b/webkitpart/src/CMakeLists.txt
+new file mode 100644
+index 000000000..9685b28e6
+--- /dev/null
++++ b/webkitpart/src/CMakeLists.txt
+@@ -0,0 +1,41 @@
++include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_BINARY_DIR})
++
++set(kwebkitpartlib_LIB_SRCS
++ webkitpart.cpp
++ webkitpart_ext.cpp
++ webkitview.cpp
++ webkitpage.cpp
++ websslinfo.cpp
++ webhistoryinterface.cpp
++ settings/webkitsettings.cpp
++ settings/webkit_filter.cpp
++ ui/searchbar.cpp
++ ui/passwordbar.cpp
++ ui/featurepermissionbar.cpp
++)
++
++qt5_wrap_ui(kwebkitpartlib_LIB_SRCS
++ ui/searchbar.ui
++)
++
++add_library(kwebkitpartlib ${kwebkitpartlib_LIB_SRCS})
++
++generate_export_header(kwebkitpartlib)
++
++target_link_libraries(kwebkitpartlib Qt5::Core Qt5::DBus Qt5::Gui Qt5::Widgets Qt5::WebKitWidgets Qt5::PrintSupport KF5::Parts KF5::SonnetCore)
++
++target_include_directories(kwebkitpartlib PUBLIC
++ "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/>"
++)
++
++install(TARGETS kwebkitpartlib ${KF5_INSTALL_TARGETS_DEFAULT_ARGS})
++
++add_library(webkitpart MODULE webkitpartfactory.cpp)
++
++target_link_libraries(webkitpart kwebkitpartlib)
++
++install(TARGETS webkitpart DESTINATION ${KDE_INSTALL_PLUGINDIR}/kf5/parts)
++
++install(FILES webkitpart.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR})
++
++install(FILES webkitpart.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/webkitpart)
+diff --git b/webkitpart/src/settings/webkit_filter.cpp b/webkitpart/src/settings/webkit_filter.cpp
+new file mode 100644
+index 000000000..f70620053
+--- /dev/null
++++ b/webkitpart/src/settings/webkit_filter.cpp
+@@ -0,0 +1,344 @@
++/* This file is part of the KDE project
++
++ Copyright (C) 2005 Ivor Hewitt <ivor@kde.org>
++ Copyright (C) 2008 Maksim Orlovich <maksim@kde.org>
++ Copyright (C) 2008 Vyacheslav Tokarev <tsjoker@gmail.com>
++
++ 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 "webkit_filter.h"
++
++#include <QHash>
++#include <QBitArray>
++
++// rolling hash parameters
++#define HASH_P (1997)
++#define HASH_Q (17509)
++// HASH_MOD = (HASH_P^7) % HASH_Q
++#define HASH_MOD (523)
++
++
++using namespace KDEPrivate;
++
++// Updateable Multi-String Matcher based on Rabin-Karp's algorithm
++class StringsMatcher {
++public:
++ // add filter to matching set
++ void addString(const QString& pattern)
++ {
++ if (pattern.length() < 8) {
++ // handle short string differently
++ shortStringFilters.append(pattern);
++ } else {
++ // use modified Rabin-Karp's algorithm with 8-length string hash
++ // i.e. store hash of first 8 chars in the HashMap for fast look-up
++ stringFilters.append(pattern);
++ int ind = stringFilters.size() - 1;
++ int current = 0;
++
++ // compute hash using rolling hash
++ // hash for string: x0,x1,x2...xn-1 will be:
++ // (p^(n-1)*x0 + p^(n-2)*x1 + ... + p * xn-2 + xn-1) % q
++ // where p and q some wisely-chosen integers
++ /*for (int k = 0; k < 8; ++k)*/
++ int len = pattern.length();
++ for (int k = len - 8; k < len; ++k)
++ current = (current * HASH_P + pattern[k].unicode()) % HASH_Q;
++
++ // insert computed hash value into HashMap
++ QHash<int, QVector<int> >::iterator it = stringFiltersHash.find(current + 1);
++ if (it == stringFiltersHash.end()) {
++ QVector<int> list;
++ list.append(ind);
++ stringFiltersHash.insert(current + 1, list);
++ fastLookUp.setBit(current);
++ } else {
++ it->append(ind);
++ }
++ }
++ }
++
++
++ // check if string match at least one string from matching set
++ bool isMatched(const QString& str, QString *by = 0) const
++ {
++ // check short strings first
++ for (int i = 0; i < shortStringFilters.size(); ++i) {
++ if (str.contains(shortStringFilters[i]))
++ {
++ if (by != 0) *by = shortStringFilters[i];
++ return true;
++ }
++ }
++
++ int len = str.length();
++ int k;
++
++ int current = 0;
++ int next = 0;
++ // compute hash for first 8 characters
++ for (k = 0; k < 8 && k < len; ++k)
++ current = (current * HASH_P + str[k].unicode()) % HASH_Q;
++
++ QHash<int, QVector<int> >::const_iterator hashEnd = stringFiltersHash.end();
++ // main Rabin-Karp's algorithm loop
++ for (k = 7; k < len; ++k, current = next) {
++ // roll the hash if not at the end
++ // (calculate hash for the next iteration)
++ if (k + 1 < len)
++ next = (HASH_P * ((current + HASH_Q - ((HASH_MOD * str[k - 7].unicode()) % HASH_Q)) % HASH_Q) + str[k + 1].unicode()) % HASH_Q;
++
++ if (!fastLookUp.testBit(current))
++ continue;
++
++ // look-up the hash in the HashMap and check all strings
++ QHash<int, QVector<int> >::const_iterator it = stringFiltersHash.find(current + 1);
++
++ // check possible strings
++ if (it != hashEnd) {
++ for (int j = 0; j < it->size(); ++j) {
++ int index = it->value(j);
++ // check if we got simple string or REs prefix
++ if (index >= 0) {
++ int flen = stringFilters[index].length();
++ if (k - flen + 1 >= 0 && stringFilters[index] == str.midRef(k - flen + 1 , flen))
++ {
++ if (by != 0) *by = stringFilters[index];
++ return true;
++ }
++ } else {
++ index = -index - 1;
++ int flen = rePrefixes[index].length();
++ if (k - 8 + flen < len && rePrefixes[index] == str.midRef(k - 7, flen))
++ {
++ int remStart = k - 7 + flen;
++ QString remainder = QString::fromRawData(str.unicode() + remStart,
++ str.length() - remStart);
++ if (reFilters[index].exactMatch(remainder)) {
++ if (by != 0) *by = rePrefixes[index]+reFilters[index].pattern();
++ return true;
++ }
++ }
++ }
++ }
++ }
++ }
++
++ return false;
++ }
++
++ // add filter to matching set with wildcards (*,?) in it
++ void addWildedString(const QString& prefix, const QRegExp& rx)
++ {
++ rePrefixes.append(prefix);
++ reFilters.append(rx);
++ int index = -rePrefixes.size();
++
++ int current = 0;
++ for (int k = 0; k < 8; ++k)
++ current = (current * HASH_P + prefix[k].unicode()) % HASH_Q;
++
++ // insert computed hash value into HashMap
++ QHash<int, QVector<int> >::iterator it = stringFiltersHash.find(current + 1);
++ if (it == stringFiltersHash.end()) {
++ QVector<int> list;
++ list.append(index);
++ stringFiltersHash.insert(current + 1, list);
++ fastLookUp.setBit(current);
++ } else {
++ it->append(index);
++ }
++ }
++
++ void clear()
++ {
++ stringFilters.clear();
++ shortStringFilters.clear();
++ reFilters.clear();
++ rePrefixes.clear();
++ stringFiltersHash.clear();
++ fastLookUp.resize(HASH_Q);
++ fastLookUp.fill(0, 0, HASH_Q);
++ }
++
++private:
++ QVector<QString> stringFilters;
++ QVector<QString> shortStringFilters;
++ QVector<QRegExp> reFilters;
++ QVector<QString> rePrefixes;
++ QBitArray fastLookUp;
++
++ QHash<int, QVector<int> > stringFiltersHash;
++};
++
++
++// We only want a subset of features of wildcards -- just the
++// star, so we escape the rest before passing to QRegExp.
++// The \ is escaped due to a QRegExp bug.
++// ### we really should rather parse it ourselves, in order to
++// handle adblock-special things like | and ^ properly.
++static QRegExp fromAdBlockWildcard(const QString& wcStr) {
++ QRegExp rx;
++ rx.setPatternSyntax(QRegExp::Wildcard);
++
++ QString out;
++ for (int p = 0; p < wcStr.length(); ++p) {
++ QChar c = wcStr[p];
++ if (c == QLatin1Char('?'))
++ out += QLatin1String("[?]");
++ else if (c == QLatin1Char('['))
++ out += QLatin1String("[[]");
++ else if (c == QLatin1Char('\\'))
++ out += QLatin1String("[\\]");
++ else
++ out += c;
++ }
++
++ rx.setPattern(out);
++ return rx;
++}
++
++FilterSet::FilterSet()
++ :stringFiltersMatcher(new StringsMatcher)
++{
++}
++
++FilterSet::~FilterSet()
++{
++ delete stringFiltersMatcher;
++}
++
++void FilterSet::addFilter(const QString& filterStr)
++{
++ QString filter = filterStr;
++
++ /** ignore special lines starting with "[", "!", "&", or "#" or contain "#" (comments or features are not supported by KHTML's AdBlock */
++ QChar firstChar = filter.at(0);
++ if (firstChar == QLatin1Char('[') || firstChar == QLatin1Char('!') || firstChar == QLatin1Char('&') || firstChar == QLatin1Char('#') || filter.contains(QLatin1Char('#')))
++ return;
++
++ // Strip leading @@
++ int first = 0;
++ int last = filter.length() - 1;
++ if (filter.startsWith(QLatin1String("@@")))
++ first = 2;
++
++ // Strip options, we ignore them for now.
++ // TODO: Add support for filters with options. See #310230.
++ int dollar = filter.lastIndexOf(QLatin1Char('$'));
++ if (dollar != -1) {
++ return;
++ }
++
++ // Perhaps nothing left?
++ if (first > last)
++ return;
++
++ filter = filter.mid(first, last - first + 1);
++
++ // Is it a regexp filter?
++ if (filter.length()>2 && filter.startsWith(QLatin1Char('/')) && filter.endsWith(QLatin1Char('/')))
++ {
++ QString inside = filter.mid(1, filter.length()-2);
++ QRegExp rx(inside);
++ reFilters.append(rx);
++// qDebug() << "R:" << inside;
++ }
++ else
++ {
++ // Nope, a wildcard one.
++ // Note: For these, we also need to handle |.
++
++ // Strip wildcards at the ends
++ first = 0;
++ last = filter.length() - 1;
++
++ while (first < filter.length() && filter[first] == QLatin1Char('*'))
++ ++first;
++
++ while (last >= 0 && filter[last] == QLatin1Char('*'))
++ --last;
++
++ if (first > last)
++ filter = QStringLiteral("*"); // erm... Well, they asked for it.
++ else
++ filter = filter.mid(first, last - first + 1);
++
++ // Now, do we still have any wildcard stuff left?
++ if (filter.contains(QLatin1String("*")))
++ {
++ // check if we can use RK first (and then check full RE for the rest) for better performance
++ int aPos = filter.indexOf('*');
++ if (aPos < 0)
++ aPos = filter.length();
++ if (aPos > 7) {
++ QRegExp rx = fromAdBlockWildcard(filter.mid(aPos) + QLatin1Char('*'));
++ // We pad the final r.e. with * so we can check for an exact match
++ stringFiltersMatcher->addWildedString(filter.mid(0, aPos), rx);
++ } else {
++ QRegExp rx = fromAdBlockWildcard(filter);
++ reFilters.append(rx);
++ }
++ }
++ else
++ {
++ // Fast path
++ stringFiltersMatcher->addString(filter);
++ }
++ }
++}
++
++bool FilterSet::isUrlMatched(const QString& url)
++{
++ if (stringFiltersMatcher->isMatched(url))
++ return true;
++
++ for (int c = 0; c < reFilters.size(); ++c)
++ {
++ if (url.contains(reFilters[c]))
++ return true;
++ }
++
++ return false;
++}
++
++QString FilterSet::urlMatchedBy(const QString& url)
++{
++ QString by;
++
++ if (stringFiltersMatcher->isMatched(url, &by))
++ return by;
++
++ for (int c = 0; c < reFilters.size(); ++c)
++ {
++ if (url.contains(reFilters[c]))
++ {
++ by = reFilters[c].pattern();
++ break;
++ }
++ }
++
++ return by;
++}
++
++void FilterSet::clear()
++{
++ reFilters.clear();
++ stringFiltersMatcher->clear();
++}
++
++// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;
+diff --git b/webkitpart/src/settings/webkit_filter.h b/webkitpart/src/settings/webkit_filter.h
+new file mode 100644
+index 000000000..732cf1538
+--- /dev/null
++++ b/webkitpart/src/settings/webkit_filter.h
+@@ -0,0 +1,60 @@
++/* This file is part of the KDE project
++
++ Copyright (C) 2005 Ivor Hewitt <ivor@kde.org>
++ Copyright (C) 2008 Maksim Orlovich <maksim@kde.org>
++ Copyright (C) 2008 Vyacheslav Tokarev <tsjoker@gmail.com>
++
++ 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.
++*/
++
++#ifndef WEBENGNINE_FILTER_P_H
++#define WEBENGNINE_FILTER_P_H
++
++#include <QString>
++#include <QRegExp>
++#include <QVector>
++#include <webkitpart.h>
++
++class StringsMatcher;
++
++namespace KDEPrivate
++{
++// This represents a set of filters that may match URLs.
++// Currently it supports a subset of AddBlock Plus functionality.
++class FilterSet {
++public:
++ FilterSet();
++ ~FilterSet();
++
++ // Parses and registers a filter. This will also strip @@ for exclusion rules, skip comments, etc.
++ // The user does have to split black and white lists into separate sets, however
++ void addFilter(const QString& filter);
++
++ bool isUrlMatched(const QString& url);
++ QString urlMatchedBy(const QString& url);
++
++ void clear();
++
++private:
++ QVector<QRegExp> reFilters;
++ StringsMatcher* stringFiltersMatcher;
++};
++
++}
++
++#endif // WEBKIT_FILTER_P_H
++
++// kate: indent-width 4; replace-tabs on; tab-width 4; space-indent on;
+diff --git b/webkitpart/src/settings/webkitsettings.cpp b/webkitpart/src/settings/webkitsettings.cpp
+new file mode 100644
+index 000000000..d20e320b5
+--- /dev/null
++++ b/webkitpart/src/settings/webkitsettings.cpp
+@@ -0,0 +1,1276 @@
++/* This file is part of the KDE project
++ Copyright (C) 1999 David Faure <faure@kde.org>
++
++ 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 "webkitsettings.h"
++
++#include "webkit_filter.h"
++
++#include <KConfig>
++#include <KSharedConfig>
++#include <KLocalizedString>
++#include <KConfigGroup>
++#include <KJob>
++#include <KIO/Job>
++#include <KMessageBox>
++
++#include <QtWebKit/QWebSettings>
++#include <QFontDatabase>
++#include <QFileInfo>
++
++// browser window color defaults -- Bernd
++#define HTML_DEFAULT_LNK_COLOR Qt::blue
++#define HTML_DEFAULT_TXT_COLOR Qt::black
++#define HTML_DEFAULT_VLNK_COLOR Qt::magenta
++#define HTML_DEFAULT_BASE_COLOR Qt::white
++
++#define HTML_DEFAULT_VIEW_FONT "Sans Serif"
++#define HTML_DEFAULT_VIEW_FIXED_FONT "Monospace"
++#define HTML_DEFAULT_VIEW_SERIF_FONT "Serif"
++#define HTML_DEFAULT_VIEW_SANSSERIF_FONT "Sans Serif"
++#define HTML_DEFAULT_VIEW_CURSIVE_FONT "Sans Serif"
++#define HTML_DEFAULT_VIEW_FANTASY_FONT "Sans Serif"
++#define HTML_DEFAULT_MIN_FONT_SIZE 7 // everything smaller is usually unreadable.
++
++/**
++ * @internal
++ * Contains all settings which are both available globally and per-domain
++ */
++struct KPerDomainSettings {
++ bool m_bEnableJava : 1;
++ bool m_bEnableJavaScript : 1;
++ bool m_bEnablePlugins : 1;
++ // don't forget to maintain the bitfields as the enums grow
++ KParts::HtmlSettingsInterface::JSWindowOpenPolicy m_windowOpenPolicy : 2;
++ KParts::HtmlSettingsInterface::JSWindowStatusPolicy m_windowStatusPolicy : 1;
++ KParts::HtmlSettingsInterface::JSWindowFocusPolicy m_windowFocusPolicy : 1;
++ KParts::HtmlSettingsInterface::JSWindowMovePolicy m_windowMovePolicy : 1;
++ KParts::HtmlSettingsInterface::JSWindowResizePolicy m_windowResizePolicy : 1;
++
++#ifdef DEBUG_SETTINGS
++ void dump(const QString &infix = QString()) const {
++ kDebug() << "KPerDomainSettings " << infix << " @" << this << ":";
++ kDebug() << " m_bEnableJava: " << m_bEnableJava;
++ kDebug() << " m_bEnableJavaScript: " << m_bEnableJavaScript;
++ kDebug() << " m_bEnablePlugins: " << m_bEnablePlugins;
++ kDebug() << " m_windowOpenPolicy: " << m_windowOpenPolicy;
++ kDebug() << " m_windowStatusPolicy: " << m_windowStatusPolicy;
++ kDebug() << " m_windowFocusPolicy: " << m_windowFocusPolicy;
++ kDebug() << " m_windowMovePolicy: " << m_windowMovePolicy;
++ kDebug() << " m_windowResizePolicy: " << m_windowResizePolicy;
++ }
++#endif
++};
++
++typedef QMap<QString,KPerDomainSettings> PolicyMap;
++
++class WebSettingsData
++{
++public:
++ bool m_bChangeCursor : 1;
++ bool m_bOpenMiddleClick : 1;
++ bool m_underlineLink : 1;
++ bool m_hoverLink : 1;
++ bool m_bEnableJavaScriptDebug : 1;
++ bool m_bEnableJavaScriptErrorReporting : 1;
++ bool enforceCharset : 1;
++ bool m_bAutoLoadImages : 1;
++ bool m_bUnfinishedImageFrame : 1;
++ bool m_formCompletionEnabled : 1;
++ bool m_autoDelayedActionsEnabled : 1;
++ bool m_jsErrorsEnabled : 1;
++ bool m_follow_system_colors : 1;
++ bool m_allowTabulation : 1;
++ bool m_autoSpellCheck : 1;
++ bool m_adFilterEnabled : 1;
++ bool m_hideAdsEnabled : 1;
++ bool m_jsPopupBlockerPassivePopup : 1;
++ bool m_accessKeysEnabled : 1;
++ bool m_zoomTextOnly : 1;
++ bool m_useCookieJar : 1;
++ bool m_bAutoRefreshPage: 1;
++ bool m_bEnableFavicon:1;
++ bool m_disableInternalPluginHandling:1;
++ bool m_offerToSaveWebSitePassword:1;
++ bool m_loadPluginsOnDemand:1;
++ bool m_enableLocalStorage:1;
++ bool m_enableOfflineStorageDb:1;
++ bool m_enableOfflineWebAppCache:1;
++ bool m_enableWebGL:1;
++ bool m_zoomToDPI:1;
++ bool m_allowActiveMixedContent:1;
++ bool m_allowMixedContentDisplay:1;
++
++ // the virtual global "domain"
++ KPerDomainSettings global;
++
++ int m_fontSize;
++ int m_minFontSize;
++ int m_maxFormCompletionItems;
++ WebSettings::KAnimationAdvice m_showAnimations;
++ WebSettings::KSmoothScrollingMode m_smoothScrolling;
++
++ QString m_encoding;
++ QString m_userSheet;
++
++ QColor m_textColor;
++ QColor m_baseColor;
++ QColor m_linkColor;
++ QColor m_vLinkColor;
++
++ PolicyMap domainPolicy;
++ QStringList fonts;
++ QStringList defaultFonts;
++
++ KDEPrivate::FilterSet adBlackList;
++ KDEPrivate::FilterSet adWhiteList;
++ QList< QPair< QString, QChar > > m_fallbackAccessKeysAssignments;
++
++ KSharedConfig::Ptr nonPasswordStorableSites;
++};
++
++class WebSettingsPrivate : public QObject, public WebSettingsData
++{
++ Q_OBJECT
++public:
++ void adblockFilterLoadList(const QString& filename)
++ {
++ /** load list file and process each line */
++ QFile file(filename);
++ if (file.open(QIODevice::ReadOnly)) {
++ QTextStream ts(&file);
++ QString line = ts.readLine();
++ while (!line.isEmpty()) {
++ //kDebug() << "Adding filter:" << line;
++ /** white list lines start with "@@" */
++ if (line.startsWith(QLatin1String("@@")))
++ adWhiteList.addFilter(line);
++ else
++ adBlackList.addFilter(line);
++ line = ts.readLine();
++ }
++ file.close();
++ }
++ }
++
++public Q_SLOTS:
++ void adblockFilterResult(KJob *job)
++ {
++ KIO::StoredTransferJob *tJob = qobject_cast<KIO::StoredTransferJob*>(job);
++ Q_ASSERT(tJob);
++
++ if ( job->error() == KJob::NoError )
++ {
++ const QByteArray byteArray = tJob->data();
++ const QString localFileName = tJob->property( "websettings_adBlock_filename" ).toString();
++
++ QFile file(localFileName);
++ if ( file.open(QFile::WriteOnly) )
++ {
++ const bool success = (file.write(byteArray) == byteArray.size());
++ if ( success )
++ adblockFilterLoadList(localFileName);
++ else
++ qWarning() << "Could not write" << byteArray.size() << "to file" << localFileName;
++ file.close();
++ }
++ else
++ qDebug() << "Cannot open file" << localFileName << "for filter list";
++ }
++ else
++ qDebug() << "Downloading" << tJob->url() << "failed with message:" << job->errorText();
++ }
++};
++
++
++/** Returns a writeable per-domains settings instance for the given domain
++ * or a deep copy of the global settings if not existent.
++ */
++static KPerDomainSettings &setup_per_domain_policy(WebSettingsPrivate* const d, const QString &domain)
++{
++ if (domain.isEmpty())
++ qWarning() << "setup_per_domain_policy: domain is empty";
++
++ const QString ldomain = domain.toLower();
++ PolicyMap::iterator it = d->domainPolicy.find(ldomain);
++ if (it == d->domainPolicy.end()) {
++ // simply copy global domain settings (they should have been initialized
++ // by this time)
++ it = d->domainPolicy.insert(ldomain,d->global);
++ }
++ return *it;
++}
++
++template<typename T>
++static T readEntry(const KConfigGroup& config, const QString& key, int defaultValue)
++{
++ return static_cast<T>(config.readEntry(key, defaultValue));
++}
++
++void WebSettings::readDomainSettings(const KConfigGroup &config, bool reset,
++ bool global, KPerDomainSettings &pd_settings)
++{
++ const QString javaPrefix ((global ? QString() : QStringLiteral("java.")));
++ const QString jsPrefix ((global ? QString() : QStringLiteral("javascript.")));
++ const QString pluginsPrefix (global ? QString() : QStringLiteral("plugins."));
++
++ // The setting for Java
++ QString key = javaPrefix + QLatin1String("EnableJava");
++ if ( (global && reset) || config.hasKey( key ) )
++ pd_settings.m_bEnableJava = config.readEntry( key, false );
++ else if ( !global )
++ pd_settings.m_bEnableJava = d->global.m_bEnableJava;
++
++ // The setting for Plugins
++ key = pluginsPrefix + QLatin1String("EnablePlugins");
++ if ( (global && reset) || config.hasKey( key ) )
++ pd_settings.m_bEnablePlugins = config.readEntry( key, true );
++ else if ( !global )
++ pd_settings.m_bEnablePlugins = d->global.m_bEnablePlugins;
++
++ // The setting for JavaScript
++ key = jsPrefix + QLatin1String("EnableJavaScript");
++ if ( (global && reset) || config.hasKey( key ) )
++ pd_settings.m_bEnableJavaScript = config.readEntry( key, true );
++ else if ( !global )
++ pd_settings.m_bEnableJavaScript = d->global.m_bEnableJavaScript;
++
++ // window property policies
++ key = jsPrefix + QLatin1String("WindowOpenPolicy");
++ if ( (global && reset) || config.hasKey( key ) )
++ pd_settings.m_windowOpenPolicy = readEntry<KParts::HtmlSettingsInterface::JSWindowOpenPolicy>(config, key, KParts::HtmlSettingsInterface::JSWindowOpenSmart);
++ else if ( !global )
++ pd_settings.m_windowOpenPolicy = d->global.m_windowOpenPolicy;
++
++ key = jsPrefix + QLatin1String("WindowMovePolicy");
++ if ( (global && reset) || config.hasKey( key ) )
++ pd_settings.m_windowMovePolicy = readEntry<KParts::HtmlSettingsInterface::JSWindowMovePolicy>(config, key, KParts::HtmlSettingsInterface::JSWindowMoveAllow);
++ else if ( !global )
++ pd_settings.m_windowMovePolicy = d->global.m_windowMovePolicy;
++
++ key = jsPrefix + QLatin1String("WindowResizePolicy");
++ if ( (global && reset) || config.hasKey( key ) )
++ pd_settings.m_windowResizePolicy = readEntry<KParts::HtmlSettingsInterface::JSWindowResizePolicy>(config, key, KParts::HtmlSettingsInterface::JSWindowResizeAllow);
++ else if ( !global )
++ pd_settings.m_windowResizePolicy = d->global.m_windowResizePolicy;
++
++ key = jsPrefix + QLatin1String("WindowStatusPolicy");
++ if ( (global && reset) || config.hasKey( key ) )
++ pd_settings.m_windowStatusPolicy = readEntry<KParts::HtmlSettingsInterface::JSWindowStatusPolicy>(config, key, KParts::HtmlSettingsInterface::JSWindowStatusAllow);
++ else if ( !global )
++ pd_settings.m_windowStatusPolicy = d->global.m_windowStatusPolicy;
++
++ key = jsPrefix + QLatin1String("WindowFocusPolicy");
++ if ( (global && reset) || config.hasKey( key ) )
++ pd_settings.m_windowFocusPolicy = readEntry<KParts::HtmlSettingsInterface::JSWindowFocusPolicy>(config, key, KParts::HtmlSettingsInterface::JSWindowFocusAllow);
++ else if ( !global )
++ pd_settings.m_windowFocusPolicy = d->global.m_windowFocusPolicy;
++}
++
++
++WebSettings::WebSettings()
++ :d (new WebSettingsPrivate)
++{
++ init();
++}
++
++WebSettings::~WebSettings()
++{
++ delete d;
++}
++
++bool WebSettings::changeCursor() const
++{
++ return d->m_bChangeCursor;
++}
++
++bool WebSettings::underlineLink() const
++{
++ return d->m_underlineLink;
++}
++
++bool WebSettings::hoverLink() const
++{
++ return d->m_hoverLink;
++}
++
++void WebSettings::init()
++{
++ initWebSettings();
++
++ KConfig global( QStringLiteral("khtmlrc"), KConfig::NoGlobals );
++ init( &global, true );
++
++ KSharedConfig::Ptr local = KSharedConfig::openConfig();
++ if ( local ) {
++ init( local.data(), false );
++ }
++
++ initNSPluginSettings();
++ initCookieJarSettings();
++}
++
++void WebSettings::init( KConfig * config, bool reset )
++{
++ KConfigGroup cg( config, "MainView Settings" );
++ if (reset || cg.exists() )
++ {
++ if ( reset || cg.hasKey( "OpenMiddleClick" ) )
++ d->m_bOpenMiddleClick = cg.readEntry( "OpenMiddleClick", true );
++ }
++
++ KConfigGroup cgAccess(config,"Access Keys" );
++ if (reset || cgAccess.exists() ) {
++ d->m_accessKeysEnabled = cgAccess.readEntry( "Enabled", true );
++ }
++
++ KConfigGroup cgFilter( config, "Filter Settings" );
++
++ if ((reset || cgFilter.exists()) && (d->m_adFilterEnabled = cgFilter.readEntry("Enabled", false)))
++ {
++ d->m_hideAdsEnabled = cgFilter.readEntry("Shrink", false);
++
++ d->adBlackList.clear();
++ d->adWhiteList.clear();
++
++ /** read maximum age for filter list files, minimum is one day */
++ int htmlFilterListMaxAgeDays = cgFilter.readEntry(QStringLiteral("HTMLFilterListMaxAgeDays")).toInt();
++ if (htmlFilterListMaxAgeDays < 1)
++ htmlFilterListMaxAgeDays = 1;
++
++ QMapIterator<QString,QString> it (cgFilter.entryMap());
++ while (it.hasNext())
++ {
++ it.next();
++ int id = -1;
++ const QString name = it.key();
++ const QString url = it.value();
++
++ if (name.startsWith(QLatin1String("Filter")))
++ {
++ if (url.startsWith(QLatin1String("@@")))
++ d->adWhiteList.addFilter(url);
++ else
++ d->adBlackList.addFilter(url);
++ }
++ else if (name.startsWith(QLatin1String("HTMLFilterListName-")) && (id = name.midRef(19).toInt()) > 0)
++ {
++ /** check if entry is enabled */
++ bool filterEnabled = cgFilter.readEntry(QStringLiteral("HTMLFilterListEnabled-").append(QString::number(id))) != QLatin1String("false");
++
++ /** get url for HTMLFilterList */
++ QUrl url(cgFilter.readEntry(QStringLiteral("HTMLFilterListURL-").append(QString::number(id))));
++
++ if (filterEnabled && url.isValid()) {
++ /** determine where to cache HTMLFilterList file */
++ QString localFile = cgFilter.readEntry(QStringLiteral("HTMLFilterListLocalFilename-").append(QString::number(id)));
++ localFile = QStandardPaths::locate(QStandardPaths::ConfigLocation, "khtml/" + localFile);
++
++ /** determine existence and age of cache file */
++ QFileInfo fileInfo(localFile);
++
++ /** load cached file if it exists, irrespective of age */
++ if (fileInfo.exists())
++ d->adblockFilterLoadList( localFile );
++
++ /** if no cache list file exists or if it is too old ... */
++ if (!fileInfo.exists() || fileInfo.lastModified().daysTo(QDateTime::currentDateTime()) > htmlFilterListMaxAgeDays)
++ {
++ /** ... in this case, refetch list asynchronously */
++ // kDebug() << "Fetching filter list from" << url << "to" << localFile;
++ KIO::StoredTransferJob *job = KIO::storedGet( url, KIO::Reload, KIO::HideProgressInfo );
++ QObject::connect( job, SIGNAL(result(KJob*)), d, SLOT(adblockFilterResult(KJob*)) );
++ /** for later reference, store name of cache file */
++ job->setProperty("websettings_adBlock_filename", localFile);
++ }
++ }
++ }
++ }
++ }
++
++ KConfigGroup cgHtml( config, "HTML Settings" );
++ if (reset || cgHtml.exists() )
++ {
++ // Fonts and colors
++ if( reset ) {
++ d->defaultFonts = QStringList();
++ d->defaultFonts.append( cgHtml.readEntry( "StandardFont", QFontDatabase::systemFont(QFontDatabase::GeneralFont).family() ) );
++ d->defaultFonts.append( cgHtml.readEntry( "FixedFont", QFontDatabase::systemFont(QFontDatabase::FixedFont).family() ));
++ d->defaultFonts.append( cgHtml.readEntry( "SerifFont", HTML_DEFAULT_VIEW_SERIF_FONT ) );
++ d->defaultFonts.append( cgHtml.readEntry( "SansSerifFont", HTML_DEFAULT_VIEW_SANSSERIF_FONT ) );
++ d->defaultFonts.append( cgHtml.readEntry( "CursiveFont", HTML_DEFAULT_VIEW_CURSIVE_FONT ) );
++ d->defaultFonts.append( cgHtml.readEntry( "FantasyFont", HTML_DEFAULT_VIEW_FANTASY_FONT ) );
++ d->defaultFonts.append( QStringLiteral( "0" ) ); // font size adjustment
++ }
++
++ if ( reset || cgHtml.hasKey( "MinimumFontSize" ) )
++ d->m_minFontSize = cgHtml.readEntry( "MinimumFontSize", HTML_DEFAULT_MIN_FONT_SIZE );
++
++ if ( reset || cgHtml.hasKey( "MediumFontSize" ) )
++ d->m_fontSize = cgHtml.readEntry( "MediumFontSize", 12 );
++
++ d->fonts = cgHtml.readEntry( "Fonts", QStringList() );
++
++ if ( reset || cgHtml.hasKey( "DefaultEncoding" ) )
++ d->m_encoding = cgHtml.readEntry( "DefaultEncoding", "" );
++
++ if ( reset || cgHtml.hasKey( "EnforceDefaultCharset" ) )
++ d->enforceCharset = cgHtml.readEntry( "EnforceDefaultCharset", false );
++
++ // Behavior
++
++ if ( reset || cgHtml.hasKey("UnderlineLinks") )
++ d->m_underlineLink = cgHtml.readEntry( "UnderlineLinks", true );
++
++ if ( reset || cgHtml.hasKey( "HoverLinks" ) )
++ {
++ if ( (d->m_hoverLink = cgHtml.readEntry( "HoverLinks", false )))
++ d->m_underlineLink = false;
++ }
++
++ if ( reset || cgHtml.hasKey( "AllowTabulation" ) )
++ d->m_allowTabulation = cgHtml.readEntry( "AllowTabulation", false );
++
++ if ( reset || cgHtml.hasKey( "AutoSpellCheck" ) )
++ d->m_autoSpellCheck = cgHtml.readEntry( "AutoSpellCheck", true );
++
++ // Other
++ if ( reset || cgHtml.hasKey( "AutoLoadImages" ) )
++ d->m_bAutoLoadImages = cgHtml.readEntry( "AutoLoadImages", true );
++
++ if ( reset || cgHtml.hasKey( "AutoDelayedActions" ) )
++ d->m_bAutoRefreshPage = cgHtml.readEntry( "AutoDelayedActions", true );
++
++ if ( reset || cgHtml.hasKey( "UnfinishedImageFrame" ) )
++ d->m_bUnfinishedImageFrame = cgHtml.readEntry( "UnfinishedImageFrame", true );
++
++ if ( reset || cgHtml.hasKey( "ShowAnimations" ) )
++ {
++ QString value = cgHtml.readEntry( "ShowAnimations").toLower();
++ if (value == QLatin1String("disabled"))
++ d->m_showAnimations = KAnimationDisabled;
++ else if (value == QLatin1String("looponce"))
++ d->m_showAnimations = KAnimationLoopOnce;
++ else
++ d->m_showAnimations = KAnimationEnabled;
++ }
++
++ if ( reset || cgHtml.hasKey( "SmoothScrolling" ) )
++ {
++ QString value = cgHtml.readEntry( "SmoothScrolling", "whenefficient" ).toLower();
++ if (value == QLatin1String("disabled"))
++ d->m_smoothScrolling = KSmoothScrollingDisabled;
++ else if (value == QLatin1String("whenefficient"))
++ d->m_smoothScrolling = KSmoothScrollingWhenEfficient;
++ else
++ d->m_smoothScrolling = KSmoothScrollingEnabled;
++ }
++
++ if ( reset || cgHtml.hasKey( "ZoomTextOnly" ) ) {
++ d->m_zoomTextOnly = cgHtml.readEntry( "ZoomTextOnly", false );
++ }
++
++ if ( reset || cgHtml.hasKey( "ZoomToDPI" ) ) {
++ d->m_zoomToDPI = cgHtml.readEntry( "ZoomToDPI", false );
++ }
++
++ if (cgHtml.readEntry("UserStyleSheetEnabled", false)) {
++ if (reset || cgHtml.hasKey("UserStyleSheet"))
++ d->m_userSheet = cgHtml.readEntry("UserStyleSheet", QString());
++ } else {
++ d->m_userSheet.clear();
++ }
++
++ d->m_formCompletionEnabled = cgHtml.readEntry("FormCompletion", true);
++ d->m_maxFormCompletionItems = cgHtml.readEntry("MaxFormCompletionItems", 10);
++ d->m_autoDelayedActionsEnabled = cgHtml.readEntry ("AutoDelayedActions", true);
++ d->m_jsErrorsEnabled = cgHtml.readEntry("ReportJSErrors", true);
++ const QStringList accesskeys = cgHtml.readEntry("FallbackAccessKeysAssignments", QStringList());
++ d->m_fallbackAccessKeysAssignments.clear();
++ for( QStringList::ConstIterator it = accesskeys.begin(); it != accesskeys.end(); ++it )
++ if( (*it).length() > 2 && (*it)[ 1 ] == ':' )
++ d->m_fallbackAccessKeysAssignments.append( qMakePair( (*it).mid( 2 ), (*it)[ 0 ] ));
++
++ d->m_bEnableFavicon = cgHtml.readEntry("EnableFavicon", true);
++ d->m_offerToSaveWebSitePassword = cgHtml.readEntry("OfferToSaveWebsitePassword", true);
++ }
++
++ // Colors
++ //In which group ?????
++ if ( reset || cg.hasKey( "FollowSystemColors" ) )
++ d->m_follow_system_colors = cg.readEntry( "FollowSystemColors", false );
++
++ KConfigGroup cgGeneral( config, "General" );
++ if ( reset || cgGeneral.exists( ) )
++ {
++ if ( reset || cgGeneral.hasKey( "foreground" ) ) {
++ QColor def(HTML_DEFAULT_TXT_COLOR);
++ d->m_textColor = cgGeneral.readEntry( "foreground", def );
++ }
++
++ if ( reset || cgGeneral.hasKey( "linkColor" ) ) {
++ QColor def(HTML_DEFAULT_LNK_COLOR);
++ d->m_linkColor = cgGeneral.readEntry( "linkColor", def );
++ }
++
++ if ( reset || cgGeneral.hasKey( "visitedLinkColor" ) ) {
++ QColor def(HTML_DEFAULT_VLNK_COLOR);
++ d->m_vLinkColor = cgGeneral.readEntry( "visitedLinkColor", def);
++ }
++
++ if ( reset || cgGeneral.hasKey( "background" ) ) {
++ QColor def(HTML_DEFAULT_BASE_COLOR);
++ d->m_baseColor = cgGeneral.readEntry( "background", def);
++ }
++ }
++
++ KConfigGroup cgJava( config, "Java/JavaScript Settings" );
++ if( reset || cgJava.exists() )
++ {
++ // The global setting for JavaScript debugging
++ // This is currently always enabled by default
++ if ( reset || cgJava.hasKey( "EnableJavaScriptDebug" ) )
++ d->m_bEnableJavaScriptDebug = cgJava.readEntry( "EnableJavaScriptDebug", false );
++
++ // The global setting for JavaScript error reporting
++ if ( reset || cgJava.hasKey( "ReportJavaScriptErrors" ) )
++ d->m_bEnableJavaScriptErrorReporting = cgJava.readEntry( "ReportJavaScriptErrors", false );
++
++ // The global setting for popup block passive popup
++ if ( reset || cgJava.hasKey( "PopupBlockerPassivePopup" ) )
++ d->m_jsPopupBlockerPassivePopup = cgJava.readEntry("PopupBlockerPassivePopup", true );
++
++ // Read options from the global "domain"
++ readDomainSettings(cgJava,reset,true,d->global);
++#ifdef DEBUG_SETTINGS
++ d->global.dump("init global");
++#endif
++
++ // The domain-specific settings.
++
++ static const char *const domain_keys[] = { // always keep order of keys
++ "ECMADomains", "JavaDomains", "PluginDomains"
++ };
++ bool check_old_ecma_settings = true;
++ bool check_old_java_settings = true;
++ // merge all domains into one list
++ QSet<QString> domainList;
++ for (unsigned i = 0; i < sizeof domain_keys/sizeof domain_keys[0]; ++i) {
++ if (reset || cgJava.hasKey(domain_keys[i])) {
++ if (i == 0) check_old_ecma_settings = false;
++ else if (i == 1) check_old_java_settings = false;
++ const QStringList dl = cgJava.readEntry( domain_keys[i], QStringList() );
++ const QSet<QString>::Iterator notfound = domainList.end();
++ QStringList::ConstIterator it = dl.begin();
++ const QStringList::ConstIterator itEnd = dl.end();
++ for (; it != itEnd; ++it) {
++ const QString domain = (*it).toLower();
++ QSet<QString>::Iterator pos = domainList.find(domain);
++ if (pos == notfound) domainList.insert(domain);
++ }/*next it*/
++ }
++ }/*next i*/
++
++ if (reset)
++ d->domainPolicy.clear();
++
++ {
++ QSet<QString>::ConstIterator it = domainList.constBegin();
++ const QSet<QString>::ConstIterator itEnd = domainList.constEnd();
++ for ( ; it != itEnd; ++it)
++ {
++ const QString domain = *it;
++ KConfigGroup cg( config, domain );
++ readDomainSettings(cg,reset,false,d->domainPolicy[domain]);
++#ifdef DEBUG_SETTINGS
++ d->domainPolicy[domain].dump("init "+domain);
++#endif
++ }
++ }
++
++ bool check_old_java = true;
++ if( (reset || cgJava.hasKey("JavaDomainSettings")) && check_old_java_settings)
++ {
++ check_old_java = false;
++ const QStringList domainList = cgJava.readEntry( "JavaDomainSettings", QStringList() );
++ QStringList::ConstIterator it = domainList.constBegin();
++ const QStringList::ConstIterator itEnd = domainList.constEnd();
++ for ( ; it != itEnd; ++it)
++ {
++ QString domain;
++ KParts::HtmlSettingsInterface::JavaScriptAdvice javaAdvice;
++ KParts::HtmlSettingsInterface::JavaScriptAdvice javaScriptAdvice;
++ KParts::HtmlSettingsInterface::splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice);
++ setup_per_domain_policy(d,domain).m_bEnableJava = javaAdvice == KParts::HtmlSettingsInterface::JavaScriptAccept;
++#ifdef DEBUG_SETTINGS
++ setup_per_domain_policy(d,domain).dump("JavaDomainSettings 4 "+domain);
++#endif
++ }
++ }
++
++ bool check_old_ecma = true;
++ if( ( reset || cgJava.hasKey( "ECMADomainSettings" ) ) && check_old_ecma_settings )
++ {
++ check_old_ecma = false;
++ const QStringList domainList = cgJava.readEntry( "ECMADomainSettings", QStringList() );
++ QStringList::ConstIterator it = domainList.constBegin();
++ const QStringList::ConstIterator itEnd = domainList.constEnd();
++ for ( ; it != itEnd; ++it)
++ {
++ QString domain;
++ KParts::HtmlSettingsInterface::JavaScriptAdvice javaAdvice;
++ KParts::HtmlSettingsInterface::JavaScriptAdvice javaScriptAdvice;
++ KParts::HtmlSettingsInterface::splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice);
++ setup_per_domain_policy(d,domain).m_bEnableJavaScript = javaScriptAdvice == KParts::HtmlSettingsInterface::JavaScriptAccept;
++#ifdef DEBUG_SETTINGS
++ setup_per_domain_policy(d,domain).dump("ECMADomainSettings 4 "+domain);
++#endif
++ }
++ }
++
++ if( ( reset || cgJava.hasKey( "JavaScriptDomainAdvice" ) )
++ && ( check_old_java || check_old_ecma )
++ && ( check_old_ecma_settings || check_old_java_settings ) )
++ {
++ const QStringList domainList = cgJava.readEntry( "JavaScriptDomainAdvice", QStringList() );
++ QStringList::ConstIterator it = domainList.constBegin();
++ const QStringList::ConstIterator itEnd = domainList.constEnd();
++ for ( ; it != itEnd; ++it)
++ {
++ QString domain;
++ KParts::HtmlSettingsInterface::JavaScriptAdvice javaAdvice;
++ KParts::HtmlSettingsInterface::JavaScriptAdvice javaScriptAdvice;
++ KParts::HtmlSettingsInterface::splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice);
++ if( check_old_java )
++ setup_per_domain_policy(d,domain).m_bEnableJava = javaAdvice == KParts::HtmlSettingsInterface::JavaScriptAccept;
++ if( check_old_ecma )
++ setup_per_domain_policy(d,domain).m_bEnableJavaScript = javaScriptAdvice == KParts::HtmlSettingsInterface::JavaScriptAccept;
++#ifdef DEBUG_SETTINGS
++ setup_per_domain_policy(d,domain).dump("JavaScriptDomainAdvice 4 "+domain);
++#endif
++ }
++ }
++ }
++
++#if 0
++ // DNS Prefect support...
++ if ( reset || cgHtml.hasKey( "DNSPrefetch" ) )
++ {
++ // Enabled, Disabled, OnlyWWWAndSLD
++ QString value = cgHtml.readEntry( "DNSPrefetch", "Enabled" ).toLower();
++
++ if (value == "enabled")
++ QWebSettings::globalSettings()->setAttribute(QWebSettings::DnsPrefetchEnabled, true);
++ else
++ QWebSettings::globalSettings()->setAttribute(QWebSettings::DnsPrefetchEnabled, false);
++ }
++
++ // Sync with QWebSettings.
++ if (!d->m_encoding.isEmpty())
++ QWebSettings::globalSettings()->setDefaultTextEncoding(d->m_encoding);
++ QWebSettings::globalSettings()->setUserStyleSheetUrl(QUrl::fromUserInput(userStyleSheet()));
++#endif
++
++ QWebSettings::globalSettings()->setAttribute(QWebSettings::AutoLoadImages, autoLoadImages());
++ QWebSettings::globalSettings()->setAttribute(QWebSettings::JavascriptEnabled, isJavaScriptEnabled());
++// QWebSettings::globalSettings()->setAttribute(QWebSettings::JavaEnabled, isJavaEnabled());
++ QWebSettings::globalSettings()->setAttribute(QWebSettings::PluginsEnabled, isPluginsEnabled());
++
++ // By default disable JS window.open when policy is deny or smart.
++ const KParts::HtmlSettingsInterface::JSWindowOpenPolicy policy = windowOpenPolicy();
++ if (policy == KParts::HtmlSettingsInterface::JSWindowOpenDeny || policy == KParts::HtmlSettingsInterface::JSWindowOpenSmart)
++ QWebSettings::globalSettings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, false);
++ else
++ QWebSettings::globalSettings()->setAttribute(QWebSettings::JavascriptCanOpenWindows, true);
++
++// QWebSettings::globalSettings()->setAttribute(QWebSettings::ZoomTextOnly, zoomTextOnly());
++// QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, isJavaScriptDebugEnabled());
++ QWebSettings::globalSettings()->setFontFamily(QWebSettings::StandardFont, stdFontName());
++ QWebSettings::globalSettings()->setFontFamily(QWebSettings::FixedFont, fixedFontName());
++ QWebSettings::globalSettings()->setFontFamily(QWebSettings::SerifFont, serifFontName());
++ QWebSettings::globalSettings()->setFontFamily(QWebSettings::SansSerifFont, sansSerifFontName());
++ QWebSettings::globalSettings()->setFontFamily(QWebSettings::CursiveFont, cursiveFontName());
++ QWebSettings::globalSettings()->setFontFamily(QWebSettings::FantasyFont, fantasyFontName());
++
++ // TODO: Create a webkit config module that gets embeded into Konqueror's kcm.
++ // Turn on WebGL support
++// QWebSettings::globalSettings()->setAttribute(QWebSettings::WebGLEnabled, d->m_enableWebGL);
++ // Turn on HTML 5 local and offline storage capabilities...
++// QWebSettings::globalSettings()->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, d->m_enableOfflineStorageDb);
++// QWebSettings::globalSettings()->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled, d->m_enableOfflineWebAppCache);
++ QWebSettings::globalSettings()->setAttribute(QWebSettings::LocalStorageEnabled, d->m_enableLocalStorage);
++
++ QWebSettings::globalSettings()->setAttribute(QWebSettings::ScrollAnimatorEnabled, smoothScrolling() != KSmoothScrollingDisabled);
++
++ // These numbers should be calculated from real "logical" DPI/72, using a default dpi of 96 for now
++ computeFontSizes(96);
++}
++
++
++void WebSettings::computeFontSizes( int logicalDpi )
++{
++ if (zoomToDPI())
++ logicalDpi = 96;
++
++ float toPix = logicalDpi/72.0;
++
++ if (toPix < 96.0/72.0)
++ toPix = 96.0/72.0;
++
++ QWebSettings::globalSettings()->setFontSize(QWebSettings::MinimumFontSize, qRound(minFontSize() * toPix));
++ QWebSettings::globalSettings()->setFontSize(QWebSettings::DefaultFontSize, qRound(mediumFontSize() * toPix));
++}
++
++bool WebSettings::zoomToDPI() const
++{
++ return d->m_zoomToDPI;
++}
++
++void WebSettings::setZoomToDPI(bool enabled)
++{
++ d->m_zoomToDPI = enabled;
++ // save it
++ KConfigGroup cg( KSharedConfig::openConfig(), "HTML Settings");
++ cg.writeEntry("ZoomToDPI", enabled);
++ cg.sync();
++}
++
++/** Local helper for retrieving per-domain settings.
++ *
++ * In case of doubt, the global domain is returned.
++ */
++static const KPerDomainSettings& lookup_hostname_policy(const WebSettingsPrivate* const d,
++ const QString& hostname)
++{
++#ifdef DEBUG_SETTINGS
++ kDebug() << "lookup_hostname_policy(" << hostname << ")";
++#endif
++ if (hostname.isEmpty()) {
++#ifdef DEBUG_SETTINGS
++ d->global.dump("global");
++#endif
++ return d->global;
++ }
++
++ const PolicyMap::const_iterator notfound = d->domainPolicy.constEnd();
++
++ // First check whether there is a perfect match.
++ PolicyMap::const_iterator it = d->domainPolicy.find(hostname);
++ if( it != notfound ) {
++#ifdef DEBUG_SETTINGS
++ kDebug() << "perfect match";
++ (*it).dump(hostname);
++#endif
++ // yes, use it (unless dunno)
++ return *it;
++ }
++
++ // Now, check for partial match. Chop host from the left until
++ // there's no dots left.
++ QString host_part = hostname;
++ int dot_idx = -1;
++ while( (dot_idx = host_part.indexOf(QChar('.'))) >= 0 ) {
++ host_part.remove(0,dot_idx);
++ it = d->domainPolicy.find(host_part);
++ Q_ASSERT(notfound == d->domainPolicy.end());
++ if( it != notfound ) {
++#ifdef DEBUG_SETTINGS
++ kDebug() << "partial match";
++ (*it).dump(host_part);
++#endif
++ return *it;
++ }
++ // assert(host_part[0] == QChar('.'));
++ host_part.remove(0,1); // Chop off the dot.
++ }
++
++ // No domain-specific entry: use global domain
++#ifdef DEBUG_SETTINGS
++ kDebug() << "no match";
++ d->global.dump("global");
++#endif
++ return d->global;
++}
++
++bool WebSettings::isOpenMiddleClickEnabled()
++{
++ return d->m_bOpenMiddleClick;
++}
++
++bool WebSettings::accessKeysEnabled() const
++{
++ return d->m_accessKeysEnabled;
++}
++
++bool WebSettings::favIconsEnabled() const
++{
++ return d->m_bEnableFavicon;
++}
++
++bool WebSettings::isAdFilterEnabled() const
++{
++ return d->m_adFilterEnabled;
++}
++
++bool WebSettings::isHideAdsEnabled() const
++{
++ return d->m_hideAdsEnabled;
++}
++
++bool WebSettings::isAdFiltered( const QString &url ) const
++{
++ if (!d->m_adFilterEnabled)
++ return false;
++
++ if (url.startsWith(QLatin1String("data:")))
++ return false;
++
++ return d->adBlackList.isUrlMatched(url) && !d->adWhiteList.isUrlMatched(url);
++}
++
++QString WebSettings::adFilteredBy( const QString &url, bool *isWhiteListed ) const
++{
++ QString m = d->adWhiteList.urlMatchedBy(url);
++
++ if (!m.isEmpty()) {
++ if (isWhiteListed != 0)
++ *isWhiteListed = true;
++ return m;
++ }
++
++ m = d->adBlackList.urlMatchedBy(url);
++ if (m.isEmpty())
++ return QString();
++
++ if (isWhiteListed != 0)
++ *isWhiteListed = false;
++ return m;
++}
++
++void WebSettings::addAdFilter( const QString &url )
++{
++ KConfigGroup config = KSharedConfig::openConfig( QStringLiteral("khtmlrc"), KConfig::NoGlobals )->group( "Filter Settings" );
++
++ QRegExp rx;
++
++ // Try compiling to avoid invalid stuff. Only support the basic syntax here...
++ // ### refactor somewhat
++ if (url.length()>2 && url[0]=='/' && url[url.length()-1] == '/')
++ {
++ const QString inside = url.mid(1, url.length()-2);
++ rx.setPattern(inside);
++ }
++ else
++ {
++ rx.setPatternSyntax(QRegExp::Wildcard);
++ rx.setPattern(url);
++ }
++
++ if (rx.isValid())
++ {
++ int last=config.readEntry("Count", 0);
++ const QString key = "Filter-" + QString::number(last);
++ config.writeEntry(key, url);
++ config.writeEntry("Count",last+1);
++ config.sync();
++
++ if (url.startsWith(QLatin1String("@@")))
++ d->adWhiteList.addFilter(url);
++ else
++ d->adBlackList.addFilter(url);
++ }
++ else
++ {
++ KMessageBox::error(0,
++ rx.errorString(),
++ i18n("Filter error"));
++ }
++}
++
++bool WebSettings::isJavaEnabled( const QString& hostname ) const
++{
++ return lookup_hostname_policy(d,hostname.toLower()).m_bEnableJava;
++}
++
++bool WebSettings::isJavaScriptEnabled( const QString& hostname ) const
++{
++ return lookup_hostname_policy(d,hostname.toLower()).m_bEnableJavaScript;
++}
++
++bool WebSettings::isJavaScriptDebugEnabled( const QString& /*hostname*/ ) const
++{
++ // debug setting is global for now, but could change in the future
++ return d->m_bEnableJavaScriptDebug;
++}
++
++bool WebSettings::isJavaScriptErrorReportingEnabled( const QString& /*hostname*/ ) const
++{
++ // error reporting setting is global for now, but could change in the future
++ return d->m_bEnableJavaScriptErrorReporting;
++}
++
++bool WebSettings::isPluginsEnabled( const QString& hostname ) const
++{
++ return lookup_hostname_policy(d,hostname.toLower()).m_bEnablePlugins;
++}
++
++KParts::HtmlSettingsInterface::JSWindowOpenPolicy WebSettings::windowOpenPolicy(const QString& hostname) const {
++ return lookup_hostname_policy(d,hostname.toLower()).m_windowOpenPolicy;
++}
++
++KParts::HtmlSettingsInterface::JSWindowMovePolicy WebSettings::windowMovePolicy(const QString& hostname) const {
++ return lookup_hostname_policy(d,hostname.toLower()).m_windowMovePolicy;
++}
++
++KParts::HtmlSettingsInterface::JSWindowResizePolicy WebSettings::windowResizePolicy(const QString& hostname) const {
++ return lookup_hostname_policy(d,hostname.toLower()).m_windowResizePolicy;
++}
++
++KParts::HtmlSettingsInterface::JSWindowStatusPolicy WebSettings::windowStatusPolicy(const QString& hostname) const {
++ return lookup_hostname_policy(d,hostname.toLower()).m_windowStatusPolicy;
++}
++
++KParts::HtmlSettingsInterface::JSWindowFocusPolicy WebSettings::windowFocusPolicy(const QString& hostname) const {
++ return lookup_hostname_policy(d,hostname.toLower()).m_windowFocusPolicy;
++}
++
++int WebSettings::mediumFontSize() const
++{
++ return d->m_fontSize;
++}
++
++int WebSettings::minFontSize() const
++{
++ return d->m_minFontSize;
++}
++
++QString WebSettings::settingsToCSS() const
++{
++ // lets start with the link properties
++ QString str = QStringLiteral("a:link {\ncolor: ");
++ str += d->m_linkColor.name();
++ str += ';';
++ if(d->m_underlineLink)
++ str += QLatin1String("\ntext-decoration: underline;");
++
++ if( d->m_bChangeCursor )
++ {
++ str += QLatin1String("\ncursor: pointer;");
++ str += QLatin1String("\n}\ninput[type=image] { cursor: pointer;");
++ }
++ str += QLatin1String("\n}\n");
++ str += QLatin1String("a:visited {\ncolor: ");
++ str += d->m_vLinkColor.name();
++ str += ';';
++ if(d->m_underlineLink)
++ str += QLatin1String("\ntext-decoration: underline;");
++
++ if( d->m_bChangeCursor )
++ str += QLatin1String("\ncursor: pointer;");
++ str += QLatin1String("\n}\n");
++
++ if(d->m_hoverLink)
++ str += QLatin1String("a:link:hover, a:visited:hover { text-decoration: underline; }\n");
++
++ return str;
++}
++
++QString WebSettings::lookupFont(int i) const
++{
++ if (d->fonts.count() > i) {
++ return d->fonts.at(i);
++ }
++
++ if (d->defaultFonts.count() > i) {
++ return d->defaultFonts.at(i);
++ }
++
++ return QString();
++}
++
++QString WebSettings::stdFontName() const
++{
++ return lookupFont(0);
++}
++
++QString WebSettings::fixedFontName() const
++{
++ return lookupFont(1);
++}
++
++QString WebSettings::serifFontName() const
++{
++ return lookupFont(2);
++}
++
++QString WebSettings::sansSerifFontName() const
++{
++ return lookupFont(3);
++}
++
++QString WebSettings::cursiveFontName() const
++{
++ return lookupFont(4);
++}
++
++QString WebSettings::fantasyFontName() const
++{
++ return lookupFont(5);
++}
++
++void WebSettings::setStdFontName(const QString &n)
++{
++ while(d->fonts.count() <= 0)
++ d->fonts.append(QString());
++ d->fonts[0] = n;
++}
++
++void WebSettings::setFixedFontName(const QString &n)
++{
++ while(d->fonts.count() <= 1)
++ d->fonts.append(QString());
++ d->fonts[1] = n;
++}
++
++QString WebSettings::userStyleSheet() const
++{
++ return d->m_userSheet;
++}
++
++bool WebSettings::isFormCompletionEnabled() const
++{
++ return d->m_formCompletionEnabled;
++}
++
++int WebSettings::maxFormCompletionItems() const
++{
++ return d->m_maxFormCompletionItems;
++}
++
++const QString &WebSettings::encoding() const
++{
++ return d->m_encoding;
++}
++
++bool WebSettings::followSystemColors() const
++{
++ return d->m_follow_system_colors;
++}
++
++const QColor& WebSettings::textColor() const
++{
++ return d->m_textColor;
++}
++
++const QColor& WebSettings::baseColor() const
++{
++ return d->m_baseColor;
++}
++
++const QColor& WebSettings::linkColor() const
++{
++ return d->m_linkColor;
++}
++
++const QColor& WebSettings::vLinkColor() const
++{
++ return d->m_vLinkColor;
++}
++
++bool WebSettings::autoPageRefresh() const
++{
++ return d->m_bAutoRefreshPage;
++}
++
++bool WebSettings::autoLoadImages() const
++{
++ return d->m_bAutoLoadImages;
++}
++
++bool WebSettings::unfinishedImageFrame() const
++{
++ return d->m_bUnfinishedImageFrame;
++}
++
++WebSettings::KAnimationAdvice WebSettings::showAnimations() const
++{
++ return d->m_showAnimations;
++}
++
++WebSettings::KSmoothScrollingMode WebSettings::smoothScrolling() const
++{
++ return d->m_smoothScrolling;
++}
++
++bool WebSettings::zoomTextOnly() const
++{
++ return d->m_zoomTextOnly;
++}
++
++bool WebSettings::isAutoDelayedActionsEnabled() const
++{
++ return d->m_autoDelayedActionsEnabled;
++}
++
++bool WebSettings::jsErrorsEnabled() const
++{
++ return d->m_jsErrorsEnabled;
++}
++
++void WebSettings::setJSErrorsEnabled(bool enabled)
++{
++ d->m_jsErrorsEnabled = enabled;
++ // save it
++ KConfigGroup cg( KSharedConfig::openConfig(), "HTML Settings");
++ cg.writeEntry("ReportJSErrors", enabled);
++ cg.sync();
++}
++
++bool WebSettings::allowTabulation() const
++{
++ return d->m_allowTabulation;
++}
++
++bool WebSettings::autoSpellCheck() const
++{
++ return d->m_autoSpellCheck;
++}
++
++QList< QPair< QString, QChar > > WebSettings::fallbackAccessKeysAssignments() const
++{
++ return d->m_fallbackAccessKeysAssignments;
++}
++
++void WebSettings::setJSPopupBlockerPassivePopup(bool enabled)
++{
++ d->m_jsPopupBlockerPassivePopup = enabled;
++ // save it
++ KConfigGroup cg( KSharedConfig::openConfig(), "Java/JavaScript Settings");
++ cg.writeEntry("PopupBlockerPassivePopup", enabled);
++ cg.sync();
++}
++
++bool WebSettings::jsPopupBlockerPassivePopup() const
++{
++ return d->m_jsPopupBlockerPassivePopup;
++}
++
++bool WebSettings::isCookieJarEnabled() const
++{
++ return d->m_useCookieJar;
++}
++
++// Password storage...
++static KConfigGroup nonPasswordStorableSitesCg(KSharedConfig::Ptr& configPtr)
++{
++ if (!configPtr) {
++ configPtr = KSharedConfig::openConfig(QStandardPaths::locate(QStandardPaths::DataLocation, QStringLiteral("khtml/formcompletions")), KConfig::NoGlobals);
++ }
++
++ return KConfigGroup(configPtr, "NonPasswordStorableSites");
++}
++
++bool WebSettings::isNonPasswordStorableSite(const QString &host) const
++{
++ KConfigGroup cg = nonPasswordStorableSitesCg(d->nonPasswordStorableSites);
++ const QStringList sites = cg.readEntry("Sites", QStringList());
++ return sites.contains(host);
++}
++
++void WebSettings::addNonPasswordStorableSite(const QString &host)
++{
++ KConfigGroup cg = nonPasswordStorableSitesCg(d->nonPasswordStorableSites);
++ QStringList sites = cg.readEntry("Sites", QStringList());
++ sites.append(host);
++ cg.writeEntry("Sites", sites);
++ cg.sync();
++}
++
++void WebSettings::removeNonPasswordStorableSite(const QString &host)
++{
++ KConfigGroup cg = nonPasswordStorableSitesCg(d->nonPasswordStorableSites);
++ QStringList sites = cg.readEntry("Sites", QStringList());
++ sites.removeOne(host);
++ cg.writeEntry("Sites", sites);
++ cg.sync();
++}
++
++bool WebSettings::askToSaveSitePassword() const
++{
++ return d->m_offerToSaveWebSitePassword;
++}
++
++bool WebSettings::isInternalPluginHandlingDisabled() const
++{
++ return d->m_disableInternalPluginHandling;
++}
++
++bool WebSettings::isLoadPluginsOnDemandEnabled() const
++{
++ return d->m_loadPluginsOnDemand;
++}
++
++bool WebSettings::allowMixedContentDisplay() const
++{
++ return d->m_allowMixedContentDisplay;
++}
++
++bool WebSettings::alowActiveMixedContent() const
++{
++ return d->m_allowActiveMixedContent;
++}
++
++
++void WebSettings::initWebSettings()
++{
++ KConfig cfg (QStringLiteral("webkitpartrc"), KConfig::NoGlobals);
++ KConfigGroup generalCfg (&cfg, "General");
++ d->m_disableInternalPluginHandling = generalCfg.readEntry("DisableInternalPluginHandling", false);
++ d->m_enableLocalStorage = generalCfg.readEntry("EnableLocalStorage", true);
++ d->m_enableOfflineStorageDb = generalCfg.readEntry("EnableOfflineStorageDatabase", true);
++ d->m_enableOfflineWebAppCache = generalCfg.readEntry("EnableOfflineWebApplicationCache", true);
++ d->m_enableWebGL = generalCfg.readEntry("EnableWebGL", true);
++ d->m_allowActiveMixedContent = generalCfg.readEntry("AllowActiveMixedContent", false);
++ d->m_allowMixedContentDisplay = generalCfg.readEntry("AllowMixedContentDisplay", true);
++
++ // Force the reloading of the non password storable sites settings.
++ d->nonPasswordStorableSites.reset();
++}
++
++void WebSettings::initCookieJarSettings()
++{
++ KSharedConfig::Ptr cookieCfgPtr = KSharedConfig::openConfig(QStringLiteral("kcookiejarrc"), KConfig::NoGlobals);
++ KConfigGroup cookieCfg ( cookieCfgPtr, "Cookie Policy");
++ d->m_useCookieJar = cookieCfg.readEntry("Cookies", false);
++}
++
++void WebSettings::initNSPluginSettings()
++{
++ KSharedConfig::Ptr cookieCfgPtr = KSharedConfig::openConfig(QStringLiteral("kcmnspluginrc"), KConfig::NoGlobals);
++ KConfigGroup cookieCfg ( cookieCfgPtr, "Misc");
++ d->m_loadPluginsOnDemand = cookieCfg.readEntry("demandLoad", false);
++}
++
++
++WebSettings* WebSettings::self()
++{
++ static WebSettings s_WebSettings;
++ return &s_WebSettings;
++}
++
++#include "webkitsettings.moc"
+diff --git b/webkitpart/src/settings/webkitsettings.h b/webkitpart/src/settings/webkitsettings.h
+new file mode 100644
+index 000000000..bf850c980
+--- /dev/null
++++ b/webkitpart/src/settings/webkitsettings.h
+@@ -0,0 +1,213 @@
++/* This file is part of the KDE project
++ Copyright (C) 1999 David Faure <faure@kde.org>
++
++ 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.
++*/
++
++#ifndef WEBSETTINGS_H
++#define WEBSETTINGS_H
++
++class KConfig;
++class KConfigGroup;
++
++#include <QColor>
++#include <QStringList>
++#include <QPair>
++
++#include <KParts/HtmlExtension>
++#include <KParts/HtmlSettingsInterface>
++
++struct KPerDomainSettings;
++class WebSettingsPrivate;
++
++/**
++ * Settings for the HTML view.
++ */
++class WebSettings
++{
++public:
++
++ enum KAnimationAdvice {
++ KAnimationDisabled=0,
++ KAnimationLoopOnce,
++ KAnimationEnabled
++ };
++
++ enum KSmoothScrollingMode {
++ KSmoothScrollingDisabled=0,
++ KSmoothScrollingWhenEfficient,
++ KSmoothScrollingEnabled
++ };
++
++ /**
++ * Called by constructor and reparseConfiguration
++ */
++ void init();
++
++ /**
++ * Destructor. Don't delete any instance by yourself.
++ */
++ virtual ~WebSettings();
++
++ void computeFontSizes(int logicalDpi);
++ bool zoomToDPI() const;
++ void setZoomToDPI(bool b);
++
++ // Automatic page reload/refresh...
++ bool autoPageRefresh() const;
++
++ bool isOpenMiddleClickEnabled();
++
++ // Java and JavaScript
++ bool isJavaEnabled( const QString& hostname = QString() ) const;
++ bool isJavaScriptEnabled( const QString& hostname = QString() ) const;
++ bool isJavaScriptDebugEnabled( const QString& hostname = QString() ) const;
++ bool isJavaScriptErrorReportingEnabled( const QString& hostname = QString() ) const;
++ bool isPluginsEnabled( const QString& hostname = QString() ) const;
++ bool isLoadPluginsOnDemandEnabled() const;
++ bool isInternalPluginHandlingDisabled() const;
++
++ // AdBlocK Filtering
++ bool isAdFiltered( const QString &url ) const;
++ bool isAdFilterEnabled() const;
++ bool isHideAdsEnabled() const;
++ void addAdFilter( const QString &url );
++ QString adFilteredBy( const QString &url, bool *isWhiteListed = 0 ) const;
++
++ // Access Keys
++ bool accessKeysEnabled() const;
++
++ // Favicons
++ bool favIconsEnabled() const;
++
++ KParts::HtmlSettingsInterface::JSWindowOpenPolicy windowOpenPolicy( const QString& hostname = QString() ) const;
++ KParts::HtmlSettingsInterface::JSWindowMovePolicy windowMovePolicy( const QString& hostname = QString() ) const;
++ KParts::HtmlSettingsInterface::JSWindowResizePolicy windowResizePolicy( const QString& hostname = QString() ) const;
++ KParts::HtmlSettingsInterface::JSWindowStatusPolicy windowStatusPolicy( const QString& hostname = QString() ) const;
++ KParts::HtmlSettingsInterface::JSWindowFocusPolicy windowFocusPolicy( const QString& hostname = QString() ) const;
++
++ QString settingsToCSS() const;
++ QString userStyleSheet() const;
++
++ // Form completion
++ bool isFormCompletionEnabled() const;
++ int maxFormCompletionItems() const;
++
++ // Meta refresh/redirect (http-equiv)
++ bool isAutoDelayedActionsEnabled () const;
++
++ // CookieJar...
++ bool isCookieJarEnabled() const;
++
++ // Password storage...
++ bool isNonPasswordStorableSite(const QString &host) const;
++ void addNonPasswordStorableSite(const QString &host);
++ void removeNonPasswordStorableSite(const QString &host);
++ bool askToSaveSitePassword() const;
++
++ // Mixed content
++ bool alowActiveMixedContent() const;
++ bool allowMixedContentDisplay() const;
++
++ // Global config object stuff.
++ static WebSettings* self();
++
++private:
++ /**
++ * Read settings from @p config.
++ * @param config is a pointer to KConfig object.
++ * @param reset if true, settings are always set; if false,
++ * settings are only set if the config file has a corresponding key.
++ */
++ void init( KConfig * config, bool reset = true );
++
++ // Behavior settings
++ bool changeCursor() const;
++ bool underlineLink() const;
++ bool hoverLink() const;
++ bool allowTabulation() const;
++ bool autoSpellCheck() const;
++ KAnimationAdvice showAnimations() const;
++ KSmoothScrollingMode smoothScrolling() const;
++ bool zoomTextOnly() const;
++
++ // Font settings
++ QString stdFontName() const;
++ QString fixedFontName() const;
++ QString serifFontName() const;
++ QString sansSerifFontName() const;
++ QString cursiveFontName() const;
++ QString fantasyFontName() const;
++
++ // these two can be set. Mainly for historical reasons (the method in KHTMLPart exists...)
++ void setStdFontName(const QString &n);
++ void setFixedFontName(const QString &n);
++
++ int minFontSize() const;
++ int mediumFontSize() const;
++
++ bool jsErrorsEnabled() const;
++ void setJSErrorsEnabled(bool enabled);
++
++ const QString &encoding() const;
++
++ bool followSystemColors() const;
++
++ // Color settings
++ const QColor& textColor() const;
++ const QColor& baseColor() const;
++ const QColor& linkColor() const;
++ const QColor& vLinkColor() const;
++
++ // Autoload images
++ bool autoLoadImages() const;
++ bool unfinishedImageFrame() const;
++
++ /**
++ * reads from @p config's current group, forcing initialization
++ * if @p reset is true.
++ * @param config is a pointer to KConfig object.
++ * @param reset true if initialization is to be forced.
++ * @param global true if the global domain is to be read.
++ * @param pd_settings will be initialised with the computed (inherited)
++ * settings.
++ */
++ void readDomainSettings(const KConfigGroup &config, bool reset,
++ bool global, KPerDomainSettings &pd_settings);
++
++
++ QList< QPair< QString, QChar > > fallbackAccessKeysAssignments() const;
++
++ // Whether to show passive popup when windows are blocked
++ void setJSPopupBlockerPassivePopup(bool enabled);
++ bool jsPopupBlockerPassivePopup() const;
++
++
++ QString lookupFont(int i) const;
++
++ void initWebSettings();
++ void initCookieJarSettings();
++ void initNSPluginSettings();
++
++ /**
++ * @internal Constructor
++ */
++ WebSettings();
++
++ WebSettingsPrivate* const d;
++};
++
++#endif
+diff --git b/webkitpart/src/ui/featurepermissionbar.cpp b/webkitpart/src/ui/featurepermissionbar.cpp
+new file mode 100644
+index 000000000..538c658aa
+--- /dev/null
++++ b/webkitpart/src/ui/featurepermissionbar.cpp
+@@ -0,0 +1,75 @@
++/*
++ * This file is part of the KDE project.
++ *
++ * Copyright (C) 2009 Dawit Alemayehu <adawit @ kde.org>
++ * Copyright (C) 2013 Allan Sandfeld Jensen <sandfeld@kde.org>
++ *
++ * 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 "featurepermissionbar.h"
++
++#include <KLocalizedString>
++
++#include <QAction>
++
++
++FeaturePermissionBar::FeaturePermissionBar(QWidget *parent)
++ :KMessageWidget(parent)
++{
++ setCloseButtonVisible(false);
++ setMessageType(KMessageWidget::Information);
++
++ QAction* action = new QAction(i18nc("@action:deny access", "&Deny access"), this);
++ connect(action, SIGNAL(triggered()), this, SLOT(onDeniedButtonClicked()));
++ addAction(action);
++
++ action = new QAction(i18nc("@action:grant access", "&Grant access"), this);
++ connect(action, SIGNAL(triggered()), this, SLOT(onGrantedButtonClicked()));
++ addAction(action);
++
++ // FIXME: Add option to allow and remember for this site.
++}
++
++FeaturePermissionBar::~FeaturePermissionBar()
++{
++}
++
++QWebPage::Feature FeaturePermissionBar::feature() const
++{
++ return m_feature;
++}
++
++void FeaturePermissionBar::setFeature (QWebPage::Feature feature)
++{
++ m_feature = feature;
++}
++
++void FeaturePermissionBar::onDeniedButtonClicked()
++{
++ animatedHide();
++ emit permissionDenied(m_feature);
++ emit done();
++}
++
++void FeaturePermissionBar::onGrantedButtonClicked()
++{
++ animatedHide();
++ emit permissionGranted(m_feature);
++ emit done();
++}
++
++#include "featurepermissionbar.moc"
+diff --git b/webkitpart/src/ui/featurepermissionbar.h b/webkitpart/src/ui/featurepermissionbar.h
+new file mode 100644
+index 000000000..ca4b7e6eb
+--- /dev/null
++++ b/webkitpart/src/ui/featurepermissionbar.h
+@@ -0,0 +1,54 @@
++/*
++ * This file is part of the KDE project.
++ *
++ * Copyright (C) 2013 Allan Sandfeld Jensen <sandfeld @ kde.org>
++ *
++ * 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.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
++ * 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.
++ */
++
++#ifndef FEATUREPERMISSIONBAR_H
++#define FEATUREPERMISSIONBAR_H
++
++#include <KMessageWidget>
++
++#include <QtWebKitWidgets/QWebPage>
++
++
++class FeaturePermissionBar : public KMessageWidget
++{
++ Q_OBJECT
++public:
++ explicit FeaturePermissionBar(QWidget *parent = Q_NULLPTR);
++ ~FeaturePermissionBar();
++
++ QWebPage::Feature feature() const;
++
++ void setFeature(QWebPage::Feature);
++
++Q_SIGNALS:
++ void permissionGranted(QWebPage::Feature);
++ void permissionDenied(QWebPage::Feature);
++ void done();
++
++private Q_SLOTS:
++ void onDeniedButtonClicked();
++ void onGrantedButtonClicked();
++
++private:
++ QWebPage::Feature m_feature;
++};
++
++#endif // FEATUREPERMISSIONBAR_H
+diff --git b/webkitpart/src/ui/passwordbar.cpp b/webkitpart/src/ui/passwordbar.cpp
+new file mode 100644
+index 000000000..b6dde17ed
+--- /dev/null
++++ b/webkitpart/src/ui/passwordbar.cpp
+@@ -0,0 +1,105 @@
++/*
++ * This file is part of the KDE project.
++ *
++ * Copyright (C) 2009 Dawit Alemayehu <adawit @ kde.org>
++ *
++ * 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 "passwordbar.h"
++
++#include "settings/websettings.h"
++
++#include <KColorScheme>
++#include <KLocalizedString>
++
++#include <QCoreApplication>
++#include <QAction>
++#include <QPalette>
++
++
++PasswordBar::PasswordBar(QWidget *parent)
++ :KMessageWidget(parent)
++{
++ setCloseButtonVisible(false);
++ setMessageType(KMessageWidget::Information);
++
++ QAction* action = new QAction(i18nc("@action:remember password", "&Remember"), this);
++ connect(action, SIGNAL(triggered()), this, SLOT(onRememberButtonClicked()));
++ addAction(action);
++
++ action = new QAction(i18nc("@action:never for this site", "Ne&ver for this site"), this);
++ connect(action, SIGNAL(triggered()), this, SLOT(onNeverButtonClicked()));
++ addAction(action);
++
++ action = new QAction(i18nc("@action:not now", "N&ot now"), this);
++ connect(action, SIGNAL(triggered()), this, SLOT(onNotNowButtonClicked()));
++ addAction(action);
++}
++
++PasswordBar::~PasswordBar()
++{
++}
++
++QUrl PasswordBar::url() const
++{
++ return m_url;
++}
++
++QString PasswordBar::requestKey() const
++{
++ return m_requestKey;
++}
++
++void PasswordBar::setUrl (const QUrl& url)
++{
++ m_url = url;
++}
++
++void PasswordBar::setRequestKey (const QString& key)
++{
++ m_requestKey = key;
++}
++
++void PasswordBar::onNotNowButtonClicked()
++{
++ animatedHide();
++ emit saveFormDataRejected (m_requestKey);
++ emit done();
++ clear();
++}
++
++void PasswordBar::onNeverButtonClicked()
++{
++ WebSettings::self()->addNonPasswordStorableSite(m_url.host());
++ onNotNowButtonClicked();
++}
++
++void PasswordBar::onRememberButtonClicked()
++{
++ animatedHide();
++ emit saveFormDataAccepted(m_requestKey);
++ emit done();
++ clear();
++}
++
++void PasswordBar::clear()
++{
++ m_requestKey.clear();
++ m_url.clear();
++}
++
++#include "passwordbar.moc"
+diff --git b/webkitpart/src/ui/passwordbar.h b/webkitpart/src/ui/passwordbar.h
+new file mode 100644
+index 000000000..9f641a625
+--- /dev/null
++++ b/webkitpart/src/ui/passwordbar.h
+@@ -0,0 +1,60 @@
++/*
++ * This file is part of the KDE project.
++ *
++ * Copyright (C) 2009 Dawit Alemayehu <adawit @ kde.org>
++ *
++ * 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.
++ */
++
++#ifndef PASSWORDBAR_H
++#define PASSWORDBAR_H
++
++#include <KMessageWidget>
++
++#include <QUrl>
++
++
++class PasswordBar : public KMessageWidget
++{
++ Q_OBJECT
++public:
++ explicit PasswordBar(QWidget *parent = Q_NULLPTR);
++ ~PasswordBar();
++
++ QUrl url() const;
++ QString requestKey() const;
++
++ void setUrl(const QUrl&);
++ void setRequestKey(const QString&);
++
++Q_SIGNALS:
++ void saveFormDataRejected(const QString &key);
++ void saveFormDataAccepted(const QString &key);
++ void done();
++
++private Q_SLOTS:
++ void onNotNowButtonClicked();
++ void onNeverButtonClicked();
++ void onRememberButtonClicked();
++
++private:
++ void clear();
++
++ QUrl m_url;
++ QString m_requestKey;
++};
++
++#endif // PASSWORDBAR_H
+diff --git b/webkitpart/src/ui/searchbar.cpp b/webkitpart/src/ui/searchbar.cpp
+new file mode 100644
+index 000000000..aca133ff6
+--- /dev/null
++++ b/webkitpart/src/ui/searchbar.cpp
+@@ -0,0 +1,194 @@
++/*
++ * This file is part of the KDE project.
++ *
++ * Copyright (C) 2008 Laurent Montel <montel@kde.org>
++ * Copyright (C) 2008 Benjamin C. Meyer <ben@meyerhome.net>
++ * Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
++ * Copyright (C) 2009 Dawit Alemayehu <adawit @ kde.org>
++ *
++ * 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 "searchbar.h"
++
++#include <KLineEdit>
++#include <KColorScheme>
++#include <QIcon>
++#include <KLocalizedString>
++
++#include <QResizeEvent>
++
++
++SearchBar::SearchBar(QWidget *parent)
++ :QWidget(parent)
++{
++
++ // Get the widget that currently has the focus so we can properly
++ // restore it when the filter bar is closed.
++ QWidget* widgetWindow = (parent ? parent->window() : 0);
++ m_focusWidget = (widgetWindow ? widgetWindow->focusWidget() : 0);
++
++ // Initialize the user interface...
++ m_ui.setupUi(this);
++ m_ui.optionsButton->addAction(m_ui.actionMatchCase);
++ m_ui.optionsButton->addAction(m_ui.actionHighlightMatch);
++ m_ui.optionsButton->addAction(m_ui.actionSearchAutomatically);
++ m_ui.closeButton->setIcon(QIcon::fromTheme(QStringLiteral("dialog-close")));
++ m_ui.previousButton->setIcon(QIcon::fromTheme(QStringLiteral("go-up-search")));
++ m_ui.nextButton->setIcon(QIcon::fromTheme(QStringLiteral("go-down-search")));
++ m_ui.previousButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
++ m_ui.nextButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
++ m_ui.searchInfo->setText(i18nc("label for input line to find text", "&Find:"));
++
++ setFocusProxy(m_ui.searchComboBox);
++
++ connect(m_ui.nextButton, SIGNAL(clicked()),
++ this, SLOT(findNext()));
++ connect(m_ui.previousButton, SIGNAL(clicked()),
++ this, SLOT(findPrevious()));
++ connect(m_ui.searchComboBox, SIGNAL(returnPressed()),
++ this, SLOT(findNext()));
++ connect(m_ui.searchComboBox, SIGNAL(editTextChanged(QString)),
++ this, SLOT(textChanged(QString)));
++
++ // Start off hidden by default...
++ setVisible(false);
++}
++
++SearchBar::~SearchBar()
++{
++ // NOTE: For some reason, if we do not clear the focus from the line edit
++ // widget before we delete this object, it seems to cause a crash!!
++ m_ui.searchComboBox->clearFocus();
++}
++
++void SearchBar::clear()
++{
++ m_ui.searchComboBox->clear();
++}
++
++void SearchBar::setVisible (bool visible)
++{
++ if (visible) {
++ m_ui.searchComboBox->setFocus(Qt::ActiveWindowFocusReason);
++ m_ui.searchComboBox->lineEdit()->selectAll();
++ } else {
++ m_ui.searchComboBox->setPalette(QPalette());
++ emit searchTextChanged(QString());
++ }
++
++ QWidget::setVisible(visible);
++}
++
++QString SearchBar::searchText() const
++{
++ return m_ui.searchComboBox->currentText();
++}
++
++bool SearchBar::caseSensitive() const
++{
++ return m_ui.actionMatchCase->isChecked();
++}
++
++bool SearchBar::highlightMatches() const
++{
++ return m_ui.actionHighlightMatch->isChecked();
++}
++
++void SearchBar::setSearchText(const QString& text)
++{
++ show();
++ m_ui.searchComboBox->setEditText(text);
++}
++
++void SearchBar::setFoundMatch(bool match)
++{
++ //kDebug() << match;
++ if (m_ui.searchComboBox->currentText().isEmpty()) {
++ m_ui.searchComboBox->setPalette(QPalette());
++ return;
++ }
++
++ KColorScheme::BackgroundRole role = (match ? KColorScheme::PositiveBackground : KColorScheme::NegativeBackground);
++ QPalette newPal(m_ui.searchComboBox->palette());
++ KColorScheme::adjustBackground(newPal, role);
++ m_ui.searchComboBox->setPalette(newPal);
++}
++
++void SearchBar::findNext()
++{
++ if (!isVisible())
++ return;
++
++ const QString text (m_ui.searchComboBox->currentText());
++ if (m_ui.searchComboBox->findText(text) == -1) {
++ m_ui.searchComboBox->addItem(text);
++ }
++
++ emit searchTextChanged(text);
++}
++
++void SearchBar::findPrevious()
++{
++ if (!isVisible())
++ return;
++
++ const QString text (m_ui.searchComboBox->currentText());
++ if (m_ui.searchComboBox->findText(text) == -1) {
++ m_ui.searchComboBox->addItem(text);
++ }
++
++ emit searchTextChanged(m_ui.searchComboBox->currentText(), true);
++}
++
++void SearchBar::textChanged(const QString &text)
++{
++ if (text.isEmpty()) {
++ m_ui.searchComboBox->setPalette(QPalette());
++ m_ui.nextButton->setEnabled(false);
++ m_ui.previousButton->setEnabled(false);
++ } else {
++ m_ui.nextButton->setEnabled(true);
++ m_ui.previousButton->setEnabled(true);
++ }
++
++ if (m_ui.actionSearchAutomatically->isChecked()) {
++ emit searchTextChanged(m_ui.searchComboBox->currentText());
++ }
++}
++
++bool SearchBar::event(QEvent* e)
++{
++ // Close the bar when Escape is pressed. Note we cannot
++ // assign Escape as a shortcut key because it would cause
++ // a conflict with the Stop button.
++ if (e->type() == QEvent::ShortcutOverride) {
++ QKeyEvent* kev = static_cast<QKeyEvent*>(e);
++ if (kev->key() == Qt::Key_Escape) {
++ e->accept();
++ close();
++ if (m_focusWidget) {
++ m_focusWidget->setFocus();
++ m_focusWidget = 0;
++ }
++ return true;
++ }
++ }
++ return QWidget::event(e);
++}
++
++#include "searchbar.moc"
+diff --git b/webkitpart/src/ui/searchbar.h b/webkitpart/src/ui/searchbar.h
+new file mode 100644
+index 000000000..598fe69ff
+--- /dev/null
++++ b/webkitpart/src/ui/searchbar.h
+@@ -0,0 +1,68 @@
++/*
++ * This file is part of the KDE project.
++ *
++ * Copyright (C) 2008 Laurent Montel <montel@kde.org>
++ * Copyright 2008 Benjamin C. Meyer <ben@meyerhome.net>
++ * Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
++ * Copyright (C) 2009 Dawit Alemayehu <adawit @ kde.org>
++ *
++ * 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.
++ */
++
++#ifndef SEARCHBAR_P_H
++#define SEARCHBAR_P_H
++
++#include <QWidget>
++
++#include "ui_searchbar.h"
++
++class QEvent;
++
++/**
++ * This is the widget that shows up when the search is initiated.
++ */
++class SearchBar : public QWidget
++{
++ Q_OBJECT
++
++public:
++ SearchBar(QWidget *parent = Q_NULLPTR);
++ ~SearchBar();
++
++ QString searchText() const;
++ bool caseSensitive() const;
++ bool highlightMatches() const;
++ void setFoundMatch(bool match);
++ void setSearchText(const QString&);
++
++ bool event(QEvent* e) Q_DECL_OVERRIDE;
++
++public Q_SLOTS:
++ void setVisible(bool visible) Q_DECL_OVERRIDE;
++ void clear();
++ void findNext();
++ void findPrevious();
++ void textChanged(const QString&);
++
++Q_SIGNALS:
++ void searchTextChanged(const QString& text, bool backward = false);
++
++private:
++ Ui::SearchBar m_ui;
++ QPointer<QWidget> m_focusWidget;
++};
++
++#endif // SEARCHBAR_P_H
+diff --git b/webkitpart/src/ui/searchbar.ui b/webkitpart/src/ui/searchbar.ui
+new file mode 100644
+index 000000000..0ed50bdda
+--- /dev/null
++++ b/webkitpart/src/ui/searchbar.ui
+@@ -0,0 +1,168 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<ui version="4.0">
++ <class>SearchBar</class>
++ <widget class="QWidget" name="SearchBar">
++ <property name="geometry">
++ <rect>
++ <x>0</x>
++ <y>0</y>
++ <width>564</width>
++ <height>34</height>
++ </rect>
++ </property>
++ <property name="sizePolicy">
++ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
++ <horstretch>0</horstretch>
++ <verstretch>0</verstretch>
++ </sizepolicy>
++ </property>
++ <layout class="QHBoxLayout" name="horizontalLayout">
++ <item>
++ <widget class="QToolButton" name="closeButton">
++ <property name="toolTip">
++ <string>Close the search bar</string>
++ </property>
++ <property name="autoRaise">
++ <bool>true</bool>
++ </property>
++ </widget>
++ </item>
++ <item>
++ <widget class="QLabel" name="searchInfo">
++ <property name="text">
++ <string>&amp;Find:</string>
++ </property>
++ <property name="buddy">
++ <cstring>searchComboBox</cstring>
++ </property>
++ </widget>
++ </item>
++ <item>
++ <widget class="KHistoryComboBox" name="searchComboBox">
++ <property name="sizePolicy">
++ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
++ <horstretch>0</horstretch>
++ <verstretch>0</verstretch>
++ </sizepolicy>
++ </property>
++ </widget>
++ </item>
++ <item>
++ <widget class="QToolButton" name="nextButton">
++ <property name="enabled">
++ <bool>false</bool>
++ </property>
++ <property name="toolTip">
++ <string>Find the next match for the current search phrase</string>
++ </property>
++ <property name="text">
++ <string>&amp;Next</string>
++ </property>
++ </widget>
++ </item>
++ <item>
++ <widget class="QToolButton" name="previousButton">
++ <property name="enabled">
++ <bool>false</bool>
++ </property>
++ <property name="toolTip">
++ <string>Find the previous match for the current search phrase</string>
++ </property>
++ <property name="text">
++ <string>&amp;Previous</string>
++ </property>
++ </widget>
++ </item>
++ <item>
++ <widget class="QToolButton" name="optionsButton">
++ <property name="toolTip">
++ <string>Find the previous match for the current search phrase</string>
++ </property>
++ <property name="text">
++ <string>&amp;Options</string>
++ </property>
++ <property name="popupMode">
++ <enum>QToolButton::InstantPopup</enum>
++ </property>
++ </widget>
++ </item>
++ <item>
++ <spacer name="horizontalSpacer">
++ <property name="orientation">
++ <enum>Qt::Horizontal</enum>
++ </property>
++ <property name="sizeType">
++ <enum>QSizePolicy::MinimumExpanding</enum>
++ </property>
++ <property name="sizeHint" stdset="0">
++ <size>
++ <width>20</width>
++ <height>20</height>
++ </size>
++ </property>
++ </spacer>
++ </item>
++ </layout>
++ <action name="actionMatchCase">
++ <property name="checkable">
++ <bool>true</bool>
++ </property>
++ <property name="text">
++ <string>&amp;Match Case</string>
++ </property>
++ </action>
++ <action name="actionSearchAutomatically">
++ <property name="checkable">
++ <bool>true</bool>
++ </property>
++ <property name="checked">
++ <bool>true</bool>
++ </property>
++ <property name="text">
++ <string>&amp;Search As You Type</string>
++ </property>
++ </action>
++ <action name="actionHighlightMatch">
++ <property name="checkable">
++ <bool>true</bool>
++ </property>
++ <property name="text">
++ <string>&amp;Highlight All Matches</string>
++ </property>
++ <property name="toolTip">
++ <string>Highlight Matches</string>
++ </property>
++ </action>
++ </widget>
++ <customwidgets>
++ <customwidget>
++ <class>KComboBox</class>
++ <extends>QComboBox</extends>
++ <header>kcombobox.h</header>
++ </customwidget>
++ <customwidget>
++ <class>KHistoryComboBox</class>
++ <extends>KComboBox</extends>
++ <header>khistorycombobox.h</header>
++ </customwidget>
++ </customwidgets>
++ <resources/>
++ <connections>
++ <connection>
++ <sender>closeButton</sender>
++ <signal>clicked()</signal>
++ <receiver>SearchBar</receiver>
++ <slot>close()</slot>
++ <hints>
++ <hint type="sourcelabel">
++ <x>16</x>
++ <y>16</y>
++ </hint>
++ <hint type="destinationlabel">
++ <x>290</x>
++ <y>16</y>
++ </hint>
++ </hints>
++ </connection>
++ </connections>
++</ui>
+diff --git b/webkitpart/src/utils.h b/webkitpart/src/utils.h
+new file mode 100644
+index 000000000..fc35a28c2
+--- /dev/null
++++ b/webkitpart/src/utils.h
+@@ -0,0 +1,16 @@
++#ifndef WEBKITPART_UTILS_H
++#define WEBKITPART_UTILS_H
++
++namespace Utils
++{
++
++#define QL1S(x) QLatin1String(x)
++#define QL1C(x) QLatin1Char(x)
++
++inline bool isBlankUrl(const QUrl& url)
++{
++ return (url.isEmpty() || url.url() == QL1S("about:blank"));
++}
++
++}
++#endif // WEBKITPART_UTILS_H
+diff --git b/webkitpart/src/webhistoryinterface.cpp b/webkitpart/src/webhistoryinterface.cpp
+new file mode 100644
+index 000000000..74e2c096e
+--- /dev/null
++++ b/webkitpart/src/webhistoryinterface.cpp
+@@ -0,0 +1,38 @@
++/*
++ * This file is part of the KDE project.
++ *
++ * Copyright (C) 2011 Dawit Alemayehu <adawit@kde.org>
++ *
++ * 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 <http://www.gnu.org/licenses/>.
++ *
++ */
++
++#include "webhistoryinterface.h"
++
++#include <KParts/HistoryProvider>
++
++
++WebHistoryInterface::WebHistoryInterface(QObject* parent)
++{
++}
++
++void WebHistoryInterface::addHistoryEntry(const QString& url)
++{
++ KParts::HistoryProvider::self()->insert(url);
++}
++
++bool WebHistoryInterface::historyContains(const QString& url) const
++{
++ return KParts::HistoryProvider::self()->contains(url);
++}
+diff --git b/webkitpart/src/webhistoryinterface.h b/webkitpart/src/webhistoryinterface.h
+new file mode 100644
+index 000000000..fbc6d6f8b
+--- /dev/null
++++ b/webkitpart/src/webhistoryinterface.h
+@@ -0,0 +1,34 @@
++/*
++ * This file is part of the KDE project.
++ *
++ * Copyright (C) 2011 Dawit Alemayehu <adawit@kde.org>
++ *
++ * 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 <http://www.gnu.org/licenses/>.
++ *
++ */
++#ifndef WEBHISTORYINTERFACE_H
++#define WEBHISTORYINTERFACE_H
++
++#include <QObject>
++
++
++class WebHistoryInterface
++{
++public:
++ WebHistoryInterface(QObject* parent = Q_NULLPTR);
++ void addHistoryEntry (const QString & url);
++ bool historyContains (const QString & url) const;
++};
++
++#endif //WEBHISTORYINTERFACE_H
+diff --git b/webkitpart/src/webkitpage.cpp b/webkitpart/src/webkitpage.cpp
+new file mode 100644
+index 000000000..1cef75875
+--- /dev/null
++++ b/webkitpart/src/webkitpage.cpp
+@@ -0,0 +1,887 @@
++/*
++ * This file is part of the KDE project.
++ *
++ * Copyright (C) 2008 Dirk Mueller <mueller@kde.org>
++ * Copyright (C) 2008 - 2010 Urs Wolfer <uwolfer @ kde.org>
++ * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
++ *
++ * 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 <http://www.gnu.org/licenses/>.
++ *
++ */
++
++#include "webkitpage.h"
++
++#include "webkitpart.h"
++#include "websslinfo.h"
++#include "webkitview.h"
++#include "settings/webkitsettings.h"
++#include <QWebSettings>
++
++#include <KMessageBox>
++#include <KRun>
++#include <KLocalizedString>
++#include <KShell>
++#include <KAuthorized>
++#include <KStringHandler>
++#include <KUrlAuthorized>
++#include <KSharedConfig>
++#include <KIO/Job>
++#include <KIO/AccessManager>
++#include <KIO/Scheduler>
++#include <KParts/HtmlExtension>
++#include <QStandardPaths>
++#include <QDesktopWidget>
++
++#include <QFile>
++#include <QApplication>
++#include <QTextDocument> // Qt::escape
++#include <QNetworkReply>
++#include <QWebHistory>
++#include <QWebHistoryItem>
++#include <QWebDownloadItem>
++#include <QUrlQuery>
++#include <KConfigGroup>
++//#include <QWebSecurityOrigin>
++#include "utils.h"
++
++
++WebPage::WebPage(WebKitPart *part, QWidget *parent)
++ : QWebPage(parent),
++ m_kioErrorCode(0),
++ m_ignoreError(false),
++ m_part(part)
++{
++ if (view())
++ WebSettings::self()->computeFontSizes(view()->logicalDpiY());
++
++ //setForwardUnsupportedContent(true);
++
++ connect(this, &QWebPage::geometryChangeRequested,
++ this, &WebPage::slotGeometryChangeRequested);
++// connect(this, SIGNAL(unsupportedContent(QNetworkReply*)),
++// this, SLOT(slotUnsupportedContent(QNetworkReply*)));
++ connect(this, &QWebPage::featurePermissionRequested,
++ this, &WebPage::slotFeaturePermissionRequested);
++ connect(this, &QWebPage::loadFinished,
++ this, &WebPage::slotLoadFinished);
++ connect(this->profile(), this, &WebPage::downloadRequest);
++ if(!this->profile()->httpUserAgent().contains(QLatin1String("Konqueror")))
++ {
++ this->profile()->setHttpUserAgent(this->profile()->httpUserAgent() + " Konqueror (WebKitPart)");
++ }
++}
++
++WebPage::~WebPage()
++{
++ //kDebug() << this;
++}
++
++const WebSslInfo& WebPage::sslInfo() const
++{
++ return m_sslInfo;
++}
++
++void WebPage::setSslInfo (const WebSslInfo& info)
++{
++ m_sslInfo = info;
++}
++
++static void checkForDownloadManager(QWidget* widget, QString& cmd)
++{
++ cmd.clear();
++ KConfigGroup cfg (KSharedConfig::openConfig(QStringLiteral("konquerorrc"), KConfig::NoGlobals), "HTML Settings");
++ const QString fileName (cfg.readPathEntry("DownloadManager", QString()));
++ if (fileName.isEmpty())
++ return;
++
++ const QString exeName = QStandardPaths::findExecutable(fileName);
++ if (exeName.isEmpty()) {
++ KMessageBox::detailedSorry(widget,
++ i18n("The download manager (%1) could not be found in your installation.", fileName),
++ i18n("Try to reinstall it and make sure that it is available in $PATH. \n\nThe integration will be disabled."));
++ cfg.writePathEntry("DownloadManager", QString());
++ cfg.sync();
++ return;
++ }
++
++ cmd = exeName;
++}
++
++void WebPage::downloadRequest(QWebDownloadItem* request)
++{
++ const QUrl url(request->url());
++
++ // Integration with a download manager...
++ if (!url.isLocalFile()) {
++ QString managerExe;
++ checkForDownloadManager(view(), managerExe);
++ if (!managerExe.isEmpty()) {
++ //kDebug() << "Calling command" << cmd;
++ KRun::runCommand((managerExe + QLatin1Char(' ') + KShell::quoteArg(url.url())), view());
++ return;
++ }
++ }
++ request->accept();
++
++}
++
++QWebPage *WebPage::createWindow(WebWindowType type)
++{
++ //qDebug() << "window type:" << type;
++ // Crete an instance of NewWindowPage class to capture all the
++ // information we need to create a new window. See documentation of
++ // the class for more information...
++ NewWindowPage* page = new NewWindowPage(type, part());
++ return page;
++}
++
++// Returns true if the scheme and domain of the two urls match...
++static bool domainSchemeMatch(const QUrl& u1, const QUrl& u2)
++{
++ if (u1.scheme() != u2.scheme())
++ return false;
++
++ QStringList u1List = u1.host().split(QL1C('.'), QString::SkipEmptyParts);
++ QStringList u2List = u2.host().split(QL1C('.'), QString::SkipEmptyParts);
++
++ if (qMin(u1List.count(), u2List.count()) < 2)
++ return false; // better safe than sorry...
++
++ while (u1List.count() > 2)
++ u1List.removeFirst();
++
++ while (u2List.count() > 2)
++ u2List.removeFirst();
++
++ return (u1List == u2List);
++}
++
++bool WebPage::acceptNavigationRequest(const QUrl& url, NavigationType type, bool isMainFrame)
++{
++ qDebug() << url << "type=" << type;
++ QUrl reqUrl(url);
++
++ // Handle "mailto:" url here...
++ if (handleMailToUrl(reqUrl, type))
++ return false;
++
++ const bool isTypedUrl = property("NavigationTypeUrlEntered").toBool();
++
++ /*
++ NOTE: We use a dynamic QObject property called "NavigationTypeUrlEntered"
++ to distinguish between requests generated by user entering a url vs those
++ that were generated programatically through javascript (AJAX requests).
++ */
++ if (isMainFrame && isTypedUrl)
++ setProperty("NavigationTypeUrlEntered", QVariant());
++
++ // inPage requests are those generarted within the current page through
++ // link clicks, javascript queries, and button clicks (form submission).
++ bool inPageRequest = true;
++ switch (type) {
++ case QWebPage::NavigationTypeFormSubmitted:
++ //if (!checkFormData(request))
++ // return false;
++ break;
++#if 0
++ case QWebPage::NavigationTypeFormResubmitted:
++ if (!checkFormData(request))
++ return false;
++ if (KMessageBox::warningContinueCancel(view(),
++ i18n("<qt><p>To display the requested web page again, "
++ "the browser needs to resend information you have "
++ "previously submitted.</p>"
++ "<p>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.</p>"),
++ i18n("Resubmit Information")) == KMessageBox::Cancel) {
++ return false;
++ }
++ break;
++#endif
++ case QWebPage::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 QWebPage::NavigationTypeReload:
++// setRequestMetaData(QL1S("cache"), QL1S("reload"));
++ inPageRequest = false;
++ break;
++ case QWebPage::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(QWebSettings::PluginsEnabled, WebSettings::self()->isPluginsEnabled(reqUrl.host()));
++ // Insert the request into the queue...
++ return QWebPage::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<QNetworkRequest::Attribute>(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
++
++WebPart* WebPage::part() const
++{
++ return m_part.data();
++}
++
++void WebPage::setPart(WebPart* part)
++{
++ m_part = part;
++}
++
++void WebPage::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<QWebFrame *>(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<QNetworkRequest::Attribute>(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<QNetworkRequest::Attribute>(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 WebPageSecurity security = (m_sslInfo.isValid() ? PageEncrypted : PageUnencrypted);
++ emit m_part->browserExtension()->setPageSecurity(security);
++ }
++}
++
++void WebPage::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<NewWindowPage*>(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 WebPage::slotFeaturePermissionRequested(const QUrl& url, QWebPage::Feature feature)
++{
++ if (url == this->url()) {
++ part()->slotShowFeaturePermissionBar(feature);
++ return;
++ }
++ switch(feature) {
++ case QWebPage::Notifications:
++ // FIXME: We should have a setting to tell if this is enabled, but so far it is always enabled.
++ setFeaturePermission(url, feature, QWebPage::PermissionGrantedByUser);
++ break;
++ case QWebPage::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, QWebPage::PermissionDeniedByUser);
++ } else {
++ setFeaturePermission(url, feature, QWebPage::PermissionGrantedByUser);
++ }
++ break;
++ default:
++ setFeaturePermission(url, feature, QWebPage::PermissionUnknown);
++ break;
++ }
++}
++
++void WebPage::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 QWebPage::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 (WebSettings::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 (WebSettings::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) && WebSettings::self()->windowMovePolicy(host) == KParts::HtmlSettingsInterface::JSWindowMoveAllow)
++ emit m_part->browserExtension()->moveTopLevelWidget(view()->x() + moveByX, view()->y() + moveByY);
++}
++
++bool WebPage::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 == QWebPage::NavigationTypeLinkClicked) {
++ message = i18n("<qt>This untrusted page links to<br/><b>%1</b>."
++ "<br/>Do you want to follow the link?</qt>", linkUrl.url());
++ title = i18n("Security Warning");
++ buttonText = i18nc("follow link despite of security warning", "Follow");
++ } else {
++ title = i18n("Security Alert");
++ message = i18n("<qt>Access by untrusted page to<br/><b>%1</b><br/> denied.</qt>",
++ 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 WebPage::checkFormData(const QNetworkRequest &req) const
++{
++ const QString scheme (req.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<QPair<QString, QString> > 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 WebPage::handleMailToUrl (const QUrl &url, NavigationType type) const
++{
++ if (QString::compare(url.scheme(), QL1S("mailto"), Qt::CaseInsensitive) == 0) {
++ QStringList files;
++ QUrl mailtoUrl (sanitizeMailToUrl(url, files));
++
++ switch (type) {
++ case QWebPage::NavigationTypeLinkClicked:
++ if (!files.isEmpty() && KMessageBox::warningContinueCancelList(0,
++ i18n("<qt>Do you want to allow this site to attach "
++ "the following files to the email message?</qt>"),
++ 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 QWebPage::NavigationTypeFormSubmitted:
++ //case QWebPage::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 WebPage::setPageJScriptPolicy(const QUrl &url)
++{
++ const QString hostname (url.host());
++ settings()->setAttribute(QWebSettings::JavascriptEnabled,
++ WebSettings::self()->isJavaScriptEnabled(hostname));
++
++ const KParts::HtmlSettingsInterface::JSWindowOpenPolicy policy = WebSettings::self()->windowOpenPolicy(hostname);
++ settings()->setAttribute(QWebSettings::JavascriptCanOpenWindows,
++ (policy != KParts::HtmlSettingsInterface::JSWindowOpenDeny &&
++ policy != KParts::HtmlSettingsInterface::JSWindowOpenSmart));
++}
++
++
++
++
++
++/************************************* Begin NewWindowPage ******************************************/
++
++NewWindowPage::NewWindowPage(WebWindowType type, WebPart* part, QWidget* parent)
++ :WebPage(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 QTWEBKIT_VERSION >= QT_VERSION_CHECK(5, 602, 3)
++ if (m_type == WebBrowserBackgroundTab) {
++ m_windowArgs.setLowerWindow(true);
++ }
++#endif
++}
++
++NewWindowPage::~NewWindowPage()
++{
++}
++
++static KParts::BrowserArguments browserArgs(WebPage::WebWindowType type)
++{
++ KParts::BrowserArguments bargs;
++ switch (type) {
++ case WebPage::WebDialog:
++ case WebPage::WebBrowserWindow:
++ bargs.setForcesNewWindow(true);
++ break;
++ case WebPage::WebBrowserTab:
++#if QTWEBKIT_VERSION >= QT_VERSION_CHECK(5, 602, 3)
++ case WebPage::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 != QWebPage::NavigationTypeOther;
++
++ if (actionRequestedByUser) {
++ if (!part() && !isMainFrame) {
++ return false;
++ }
++ const KParts::HtmlSettingsInterface::JSWindowOpenPolicy policy = WebSettings::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("<qt>This site is requesting to open a popup window to"
++ "<p>%1</p><br/>Do you want to allow this?</qt>",
++ 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...
++ WebPart* webkitPart = qobject_cast<WebKitPart*>(newWindowPart);
++ WebView* webView = webkitPart ? qobject_cast<WebView*>(webkitPart->view()) : 0;
++
++ // If the newly created window is NOT a webkitpart...
++ 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(webkitPart);
++ // Connect all the signals from this page to the slots in the new part.
++ webkitPart->connectWebPageSignals(this);
++ //Set the create new window flag to false...
++ m_createNewWindow = false;
++ }
++
++ return WebPage::acceptNavigationRequest(url, type, isMainFrame);
++}
++
++void NewWindowPage::slotGeometryChangeRequested(const QRect & rect)
++{
++ if (!rect.isValid())
++ return;
++
++ if (!m_createNewWindow) {
++ WebPage::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...
++ WebKitPart* webkitPart = newWindowPart ? qobject_cast<WebKitPart*>(newWindowPart) : 0;
++ WebView* webView = webkitPart ? qobject_cast<WebView*>(webkitPart->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(webkitPart);
++ // Connect all the signals from this page to the slots in the new part.
++ webkitPart->connectWebPageSignals(this);
++ }
++
++ //Set the create new window flag to false...
++ m_createNewWindow = false;
++}
++
++/****************************** End NewWindowPage *************************************************/
++
+diff --git b/webkitpart/src/webkitpage.h b/webkitpart/src/webkitpage.h
+new file mode 100644
+index 000000000..489f32881
+--- /dev/null
++++ b/webkitpart/src/webkitpage.h
+@@ -0,0 +1,162 @@
++/*
++ * This file is part of the KDE project.
++ *
++ * Copyright (C) 2008 Dirk Mueller <mueller@kde.org>
++ * Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
++ * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
++ *
++ * 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 <http://www.gnu.org/licenses/>.
++ *
++ */
++
++#ifndef WEBKITPAGE_H
++#define WEBKITPAGE_H
++
++#include "websslinfo.h"
++
++#include <KParts/BrowserExtension>
++#include <QtWebKitWidgets/QWebPage>
++
++#include <QUrl>
++#include <QDebug>
++#include <QMultiHash>
++#include <QPointer>
++
++class QUrl;
++class WebSslInfo;
++class WebKitPart;
++class QWebDownloadItem;
++
++
++class WebPage : public QWebPage
++{
++ Q_OBJECT
++public:
++ explicit WebPage(WebKitPart *wpart, QWidget *parent = Q_NULLPTR);
++ ~WebPage();
++
++ /**
++ * 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);
++
++ /**
++ * Reimplemented for internal reasons. The API is not affected.
++ *
++ * @internal
++ * @see KWebPage::downloadRequest.
++ */
++ void downloadRequest(QWebDownloadItem* request);
++
++Q_SIGNALS:
++ /**
++ * This signal is emitted whenever a user cancels/aborts a load resource
++ * request.
++ */
++ void loadAborted(const QUrl &url);
++
++protected:
++ /**
++ * Returns the webkit part in use by this object.
++ * @internal
++ */
++ WebKitPart* part() const;
++
++ /**
++ * Sets the webkit part to be used by this object.
++ * @internal
++ */
++ void setPart(WebKitPart*);
++
++ /**
++ * Reimplemented for internal reasons, the API is not affected.
++ * @internal
++ */
++ QWebPage* 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, QWebPage::Feature feature);
++
++private:
++ bool checkLinkSecurity(const QNetworkRequest& req, NavigationType type) const;
++ bool checkFormData(const QNetworkRequest& req) const;
++ bool handleMailToUrl (const QUrl& , NavigationType type) const;
++ void setPageJScriptPolicy(const QUrl& url);
++
++private:
++ enum WebPageSecurity { PageUnencrypted, PageEncrypted, PageMixed };
++
++ int m_kioErrorCode;
++ bool m_ignoreError;
++
++ WebSslInfo m_sslInfo;
++ QPointer<WebKitPart> m_part;
++};
++
++
++/**
++ * This is a fake implementation of WebPage to workaround the ugly API used
++ * to request for the creation of a new window from javascript in QtWebKit. PORTING_TODO
++ *
++ * The KPart API for creating new windows requires all the information about the
++ * new window up front. Unfortunately QWebPage::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 WebPage
++{
++ Q_OBJECT
++public:
++ NewWindowPage(WebWindowType windowType, WebKitPart* 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;
++};
++
++#endif // WEBPAGE_H
+diff --git b/webkitpart/src/webkitpart.cpp b/webkitpart/src/webkitpart.cpp
+new file mode 100644
+index 000000000..096475c63
+--- /dev/null
++++ b/webkitpart/src/webkitpart.cpp
+@@ -0,0 +1,925 @@
++/*
++ * This file is part of the KDE project.
++ *
++ * Copyright (C) 2007 Trolltech ASA
++ * Copyright (C) 2008 - 2010 Urs Wolfer <uwolfer @ kde.org>
++ * Copyright (C) 2008 Laurent Montel <montel@kde.org>
++ * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
++ * Copyright (C) 2013 Allan Sandfeld Jensen <sandfeld@kde.org>
++ *
++ * 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 <http://www.gnu.org/licenses/>.
++ *
++ */
++
++#include "webkitpart.h"
++
++//#include <QWebHistoryItem>
++#include <QWebSettings>
++#include <QUrlQuery>
++
++#include "webkitpart_ext.h"
++#include "webkitview.h"
++#include "webkitpage.h"
++#include "websslinfo.h"
++#include "webhistoryinterface.h"
++
++#include "ui/searchbar.h"
++#include "ui/passwordbar.h"
++#include "ui/featurepermissionbar.h"
++#include "settings/webkitsettings.h"
++
++#include <kcodecaction.h>
++#include <kio/global.h>
++
++#include <KActionCollection>
++#include <KAboutData>
++#include <KUrlLabel>
++#include <KMessageBox>
++#include <KStringHandler>
++#include <KToolInvocation>
++#include <KAcceleratorManager>
++#include <KFileItem>
++#include <KMessageWidget>
++#include <KProtocolInfo>
++#include <KToggleAction>
++#include <KParts/StatusBarExtension>
++#include <KParts/GUIActivateEvent>
++#include <KLocalizedString>
++#include <KConfigGroup>
++#include <KSharedConfig>
++#include <KSslInfoDialog>
++
++#include <QUrl>
++#include <QFile>
++#include <QTextCodec>
++#include <QCoreApplication>
++#include <QVBoxLayout>
++#include <QDBusInterface>
++#include <QMenu>
++#include <QStatusBar>
++#include "utils.h"
++
++WebKitPart::WebKitPart(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)
++{
++ KAboutData about = KAboutData(QStringLiteral("webkitpart"),
++ i18nc("Program Name", "WebKitPart"),
++ /*version*/ QStringLiteral("1.3.0"),
++ i18nc("Short Description", "QtWebKit 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("webkitpart/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 QWebPage::userAgentForUrl...
++ if (QCoreApplication::applicationVersion().isEmpty())
++ QCoreApplication::setApplicationVersion(QString("%1.%2.%3")
++ .arg(KDE::versionMajor())
++ .arg(KDE::versionMinor())
++ .arg(KDE::versionRelease()));
++#endif
++ setXMLFile(QL1S("webkitpart.rc"));
++
++ // Create this KPart's widget
++ QWidget *mainWidget = new QWidget (parentWidget);
++ mainWidget->setObjectName(QStringLiteral("webkitpart"));
++
++ // Create the WebView...
++ m_webView = new WebView (this, parentWidget);
++
++ // Create the browser extension.
++ m_browserExtension = new WebBrowserExtension(this, cachedHistory);
++
++ // Add status bar extension...
++ m_statusBarExtension = new KParts::StatusBarExtension(this);
++
++ // Add a web history interface for storing visited links.
++// if (!QWebHistoryInterface::defaultInterface())
++// QWebHistoryInterface::setDefaultInterface(new WebHistoryInterface(this));
++
++ // Add text and html extensions...
++ new WebTextExtension(this);
++ new WebHtmlExtension(this);
++ new WebScriptableExtension(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, &QWebView::titleChanged,
++ this, &Part::setWindowCaption);
++ connect(m_webView, &QWebView::urlChanged,
++ this, &WebKitPart::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, &QWebView::loadFinished,
++ this, &WebKitPart::slotLoadFinished);
++
++ // Connect the signals from the page...
++ connectWebPageSignals(page());
++
++ // Init the QAction we are going to use...
++ initActions();
++
++ // Load plugins once we are fully ready
++ loadPlugins();
++}
++
++WebKitPart::~WebKitPart()
++{
++}
++
++WebPage* WebKitPart::page()
++{
++ if (m_webView)
++ return qobject_cast<WebPage*>(m_webView->page());
++ return Q_NULLPTR;
++}
++
++const WebPage* WebKitPart::page() const
++{
++ if (m_webView)
++ return qobject_cast<const WebPage*>(m_webView->page());
++ return Q_NULLPTR;
++}
++
++void WebKitPart::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, &WebBrowserExtension::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, &WebBrowserExtension::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> () << QKeySequence(QStringLiteral("CTRL++")) << QKeySequence(QStringLiteral("CTRL+=")));
++ connect(action, &QAction::triggered, m_browserExtension, &WebBrowserExtension::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> () << QKeySequence(QStringLiteral("CTRL+-")) << QKeySequence(QStringLiteral("CTRL+_")));
++ connect(action, &QAction::triggered, m_browserExtension, &WebBrowserExtension::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, &WebBrowserExtension::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, &WebBrowserExtension::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, &WebBrowserExtension::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, &WebBrowserExtension::slotViewDocumentSource);
++
++ action = new QAction(i18nc("Secure Sockets Layer", "SSL"), this);
++ actionCollection()->addAction(QStringLiteral("security"), action);
++ connect(action, &QAction::triggered, this, &WebKitPart::slotShowSecurity);
++
++ action = actionCollection()->addAction(KStandardAction::Find, QStringLiteral("find"), this, SLOT(slotShowSearchBar()));
++ action->setWhatsThis(i18nc("find action \"whats this\" text", "<h3>Find text</h3>"
++ "Shows a dialog that allows you to find text on the displayed page."));
++}
++
++void WebKitPart::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 WebKitPart::connectWebPageSignals(WebPage* page)
++{
++ if (!page)
++ return;
++
++ connect(page, SIGNAL(loadStarted()),
++ this, SLOT(slotLoadStarted()));
++ connect(page, SIGNAL(loadAborted(QUrl)),
++ this, SLOT(slotLoadAborted(QUrl)));
++ connect(page, &QWebPage::linkHovered,
++ this, &WebKitPart::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, &QWebPage::iconUrlChanged, [page, this](const QUrl& url) {
++ if (WebSettings::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()));
++ }
++#endif
++}
++
++bool WebKitPart::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...
++ WebPage* 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 WebKitPart::closeUrl()
++{
++ m_webView->triggerPageAction(QWebPage::Stop);
++ m_webView->stop();
++ return true;
++}
++
++QWebView* WebKitPart::view()
++{
++ return m_webView;
++}
++
++bool WebKitPart::isModified() const
++{
++ //return m_webView->isModified();
++ return false;
++}
++
++void WebKitPart::guiActivateEvent(KParts::GUIActivateEvent *event)
++{
++ if (event && event->activated() && m_webView) {
++ emit setWindowCaption(m_webView->title());
++ }
++}
++
++bool WebKitPart::openFile()
++{
++ // never reached
++ return false;
++}
++
++
++/// slots...
++
++void WebKitPart::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 WebKitPart::slotLoadFinished (bool ok)
++{
++ if (!ok || !m_doLoadFinishedActions)
++ return;
++
++ slotWalletClosed();
++ m_doLoadFinishedActions = false;
++
++ // If the document contains no <title> 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 (WebSettings::self()->isNonPasswordStorableSite(url().host())) {
++ addWalletStatusBarIcon();
++ } else {
++// Attempt to fill the web form...
++// KWebWallet *webWallet = page() ? page()->wallet() : 0;
++// if (webWallet) {
++// webWallet->fillFormData(frame, false);
++// }
++ }
++ }
++
++ bool pending = false;
++ // QWebFrame* frame = (page() ? page()->currentFrame() : 0);
++ // if (ok &&
++ // frame == page()->mainFrame() &&
++ // !frame->findFirstElement(QL1S("head>meta[http-equiv=refresh]")).isNull()) {
++ // if (WebSettings::self()->autoPageRefresh()) {
++ // pending = true;
++ // } else {
++ // frame->page()->triggerAction(QWebPage::Stop);
++ // }
++ // }
++ emit completed ((ok && pending));
++
++ updateActions();
++}
++
++void WebKitPart::slotLoadAborted(const QUrl & url)
++{
++ closeUrl();
++ m_doLoadFinishedActions = false;
++ if (url.isValid())
++ emit m_browserExtension->openUrlRequest(url);
++ else
++ setUrl(m_webView->url());
++}
++
++void WebKitPart::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 WebKitPart::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 WebKitPart::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, QtWebKit 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 WebKitPart::slotRestoreFrameState(QWebFrame *frame)
++{
++ QWebPage* 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 WebKitPart::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<QString, QStringList> fields;
++ QUrlQuery query(linkUrl);
++ QList<QPair<QString, QString> > queryItems = query.queryItems();
++ const int count = queryItems.count();
++
++ for(int i = 0; i < count; ++i) {
++ const QPair<QString, QString> 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 WebKitPart::slotSearchForText(const QString &text, bool backward)
++{
++ QWebPage::FindFlags flags; // = QWebPage::FindWrapsAroundDocument;
++
++ if (backward)
++ flags |= QWebPage::FindBackward;
++
++ if (m_searchBar->caseSensitive())
++ flags |= QWebPage::FindCaseSensitively;
++
++ //kDebug() << "search for text:" << text << ", backward ?" << backward;
++ page()->findText(text, flags, [this](bool found) {
++ m_searchBar->setFoundMatch(found);
++ });
++}
++
++void WebKitPart::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<QBoxLayout*>(widget()->layout());
++ if (lay) {
++ lay->addWidget(m_searchBar);
++ }
++ }
++ const QString text = m_webView->selectedText();
++ m_searchBar->setSearchText(text.left(150));
++}
++
++void WebKitPart::slotLinkMiddleOrCtrlClicked(const QUrl& linkUrl)
++{
++ emit m_browserExtension->createNewWindow(linkUrl);
++}
++
++void WebKitPart::slotSelectionClipboardUrlPasted(const QUrl& selectedUrl, const QString& searchText)
++{
++ if (!WebSettings::self()->isOpenMiddleClickEnabled())
++ return;
++
++ if (!searchText.isEmpty() &&
++ KMessageBox::questionYesNo(m_webView,
++ i18n("<qt>Do you want to search for <b>%1</b>?</qt>", searchText),
++ i18n("Internet Search"), KGuiItem(i18n("&Search"), QStringLiteral("edit-find")),
++ KStandardGuiItem::cancel(), QStringLiteral("MiddleClickSearch")) != KMessageBox::Yes)
++ return;
++
++ emit m_browserExtension->openUrlRequest(selectedUrl);
++}
++
++void WebKitPart::slotWalletClosed()
++{
++ if (!m_statusBarWalletLabel)
++ return;
++
++ m_statusBarExtension->removeStatusBarItem(m_statusBarWalletLabel);
++ delete m_statusBarWalletLabel;
++ m_statusBarWalletLabel = 0;
++ m_hasCachedFormData = false;
++}
++
++void WebKitPart::slotShowWalletMenu()
++{
++ QMenu *menu = new QMenu(0);
++
++ if (m_webView && WebSettings::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 WebKitPart::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 WebKitPart::slotDeleteNonPasswordStorableSite()
++{
++ if (m_webView)
++ WebSettings::self()->removeNonPasswordStorableSite(m_webView->url().host());
++}
++
++void WebKitPart::slotRemoveCachedPasswords()
++{
++ if (!page()) // || !page()->wallet())
++ return;
++
++// page()->wallet()->removeFormData(page()->mainFrame(), true);
++ m_hasCachedFormData = false;
++}
++
++void WebKitPart::slotSetTextEncoding(QTextCodec * codec)
++{
++ // FIXME: The code below that sets the text encoding has been reported not to work.
++ if (!page())
++ return;
++
++ QWebSettings *localSettings = page()->settings();
++ if (!localSettings)
++ return;
++
++ qDebug() << "Encoding: new=>" << localSettings->defaultTextEncoding() << ", old=>" << codec->name();
++
++ localSettings->setDefaultTextEncoding(codec->name());
++ page()->triggerAction(QWebPage::Reload);
++}
++
++void WebKitPart::slotSetStatusBarText(const QString& text)
++{
++ const QString host (page() ? page()->url().host() : QString());
++ if (WebSettings::self()->windowStatusPolicy(host) == KParts::HtmlSettingsInterface::JSWindowStatusAllow)
++ emit setStatusBarText(text);
++}
++
++void WebKitPart::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 WebKitPart::slotShowFeaturePermissionBar(QWebPage::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(QWebPage::Feature)),
++ this, SLOT(slotFeaturePermissionGranted(QWebPage::Feature)));
++ connect(m_featurePermissionBar, SIGNAL(permissionDenied(QWebPage::Feature)),
++ this, SLOT(slotFeaturePermissionDenied(QWebPage::Feature)));
++// connect(m_passwordBar, SIGNAL(done()),
++// this, SLOT(slotSaveFormDataDone()));
++ QBoxLayout* lay = qobject_cast<QBoxLayout*>(widget()->layout());
++ if (lay)
++ lay->insertWidget(0, m_featurePermissionBar);
++ }
++ m_featurePermissionBar->setFeature(feature);
++// m_featurePermissionBar->setText(i18n("<html>Do you want to grant the site <b>%1</b> "
++// "access to information about your current physical location?",
++// url.host()));
++ m_featurePermissionBar->setText(i18n("<html>Do you want to grant the site "
++ "access to information about your current physical location?"));
++ m_featurePermissionBar->animatedShow();
++}
++
++void WebKitPart::slotFeaturePermissionGranted(QWebPage::Feature feature)
++{
++ Q_ASSERT(m_featurePermissionBar && m_featurePermissionBar->feature() == feature);
++ page()->setFeaturePermission(page()->url(), feature, QWebPage::PermissionGrantedByUser);
++}
++
++void WebKitPart::slotFeaturePermissionDenied(QWebPage::Feature feature)
++{
++ Q_ASSERT(m_featurePermissionBar && m_featurePermissionBar->feature() == feature);
++ page()->setFeaturePermission(page()->url(), feature, QWebPage::PermissionDeniedByUser);
++}
++
++void WebKitPart::slotSaveFormDataRequested (const QString& key, const QUrl& url)
++{
++ if (WebSettings::self()->isNonPasswordStorableSite(url.host()))
++ return;
++
++ if (!WebSettings::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!";
++ return;
++ }
++ connect(m_passwordBar, SIGNAL(saveFormDataAccepted(QString)),
++ wallet, SLOT(acceptSaveFormDataRequest(QString)));
++ connect(m_passwordBar, SIGNAL(saveFormDataRejected(QString)),
++ 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("<html>Do you want %1 to remember the login "
++ "information for <b>%2</b>?</html>",
++ QCoreApplication::applicationName(),
++ url.host()));
++
++ QBoxLayout* lay = qobject_cast<QBoxLayout*>(widget()->layout());
++ if (lay)
++ lay->insertWidget(0, m_passwordBar);
++
++ m_passwordBar->animatedShow();
++}
++
++void WebKitPart::slotSaveFormDataDone()
++{
++ if (!m_passwordBar)
++ return;
++
++ QBoxLayout* lay = qobject_cast<QBoxLayout*>(widget()->layout());
++ if (lay)
++ lay->removeWidget(m_passwordBar);
++}
++
++void WebKitPart::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 WebKitPart::slotFillFormRequestCompleted (bool ok)
++{
++ if ((m_hasCachedFormData = ok))
++ addWalletStatusBarIcon();
++}
++
+diff --git b/webkitpart/src/webkitpart.desktop b/webkitpart/src/webkitpart.desktop
+new file mode 100644
+index 000000000..fb77cfc8e
+--- /dev/null
++++ b/webkitpart/src/webkitpart.desktop
+@@ -0,0 +1,65 @@
++[Desktop Entry]
++Type=Service
++Comment=Embeddable HTML component
++Comment[ca]=Component HTML incrustable
++Comment[ca@valencia]=Component HTML incrustable
++Comment[cs]=Zapouzdřitelná HTML komponenta
++Comment[da]=HTML-komponent som kan indlejres
++Comment[de]=Einbettungsfähige HTML-Komponente
++Comment[en_GB]=Embeddable HTML component
++Comment[es]=Componente HTML empotrable
++Comment[et]=Põimitav HTML-komponent
++Comment[fi]=Upotettava HTML-osa
++Comment[it]=Componente HTML incorporabile
++Comment[ko]=끼워넣을 수 있는 HTML 구성 요소
++Comment[nb]=Innebyggbar HTML-komponent
++Comment[nl]=In te bedden HTML-component
++Comment[nn]=Innebyggbar HTML-komponent
++Comment[pl]=Osadzalny składnik HTML
++Comment[pt]=Componente incorporada de HTML
++Comment[pt_BR]=Componete HTML embutido
++Comment[sk]=Vložiteľný HTML komponent
++Comment[sl]=Vgradljiv sestavni del HTML
++Comment[sr]=Угнездива ХТМЛ компонента
++Comment[sr@ijekavian]=Угњездива ХТМЛ компонента
++Comment[sr@ijekavianlatin]=Ugnjezdiva HTML komponenta
++Comment[sr@latin]=Ugnezdiva HTML komponenta
++Comment[sv]=Inbäddningsbar HTML-komponent
++Comment[uk]=Придатний до вбудовування компонент HTML
++Comment[x-test]=xxEmbeddable HTML componentxx
++Comment[zh_CN]=可嵌入的 HTML 组件
++Comment[zh_TW]=可內嵌的 HTML 元件
++Icon=webkit
++MimeType=text/html;application/xml;application/xhtml+xml;
++Name=WebKit
++Name[ca]=WebKit
++Name[ca@valencia]=WebKit
++Name[cs]=WebKit
++Name[da]=WebKit
++Name[de]=WebKit
++Name[en_GB]=WebKit
++Name[es]=Motor Web
++Name[et]=WebKit
++Name[fi]=WebKit
++Name[it]=WebKit
++Name[ko]=WebKit
++Name[nl]=WebKit
++Name[nn]=Vevmotor
++Name[pl]=SilnikSieciowy
++Name[pt]=Motor Web
++Name[pt_BR]=WebKit
++Name[sk]=WebKit
++Name[sl]=Spletni pogon
++Name[sr]=КуТ‑вебенџин
++Name[sr@ijekavian]=КуТ‑вебенџин
++Name[sr@ijekavianlatin]=QtWebKit
++Name[sr@latin]=QtWebKit
++Name[sv]=Webbgränssnitt
++Name[uk]=Вебрушій
++Name[x-test]=xxWebKitxx
++Name[zh_CN]=WebKit
++Name[zh_TW]=WebKit
++X-KDE-Default-UserAgent=Mozilla/5.0 (%PLATFORM%; %SECURITY%; %OSNAME% %OSVERSION% %SYSTYPE%; %LANGUAGE%) AppleWebKit/534.34 (KHTML, like Gecko) %APPVERSION% Safari/534.34
++X-KDE-ServiceTypes=KParts/ReadOnlyPart,Browser/View
++X-KDE-Library=kf5/parts/webkitpart
++InitialPreference=12
+diff --git b/webkitpart/src/webkitpart.h b/webkitpart/src/webkitpart.h
+new file mode 100644
+index 000000000..4ee00403d
+--- /dev/null
++++ b/webkitpart/src/webkitpart.h
+@@ -0,0 +1,165 @@
++/*
++ * This file is part of the KDE project.
++ *
++ * Copyright (C) 2007 Trolltech ASA
++ * Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
++ * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
++ *
++ * 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 <http://www.gnu.org/licenses/>.
++ *
++ */
++#ifndef WEBKITPART_H
++#define WEBKITPART_H
++
++#include "kwebkitpartlib_export.h"
++
++#include <QtWebKitWidgets/QWebPage>
++
++#include <KParts/ReadOnlyPart>
++#include <QUrl>
++
++namespace KParts {
++ class BrowserExtension;
++ class StatusBarExtension;
++}
++
++class QWebView;
++class WebView;
++class WebPage;
++class SearchBar;
++class PasswordBar;
++class FeaturePermissionBar;
++class KUrlLabel;
++class WebBrowserExtension;
++
++/**
++ * A KPart wrapper for the QtWebKit'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 QtWebKit class ; @see QWebView.
++ *
++ */
++class KWEBKITPARTLIB_EXPORT WebKitPart : public KParts::ReadOnlyPart
++{
++ Q_OBJECT
++ Q_PROPERTY( bool modified READ isModified )
++public:
++ explicit WebKitPart(QWidget* parentWidget = 0, QObject* parent = Q_NULLPTR,
++ const QByteArray& cachedHistory = QByteArray(),
++ const QStringList& = QStringList());
++ ~WebKitPart();
++
++ /**
++ * 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 QWebView.
++ */
++ virtual QWebView *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 connectWebPageSignals(WebPage* page);
++
++ void slotShowFeaturePermissionBar(QWebPage::Feature);
++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(QWebPage::Feature);
++ void slotFeaturePermissionDenied(QWebPage::Feature);
++
++private:
++ WebPage* page();
++ const WebPage* 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;
++ WebBrowserExtension* m_browserExtension;
++ KParts::StatusBarExtension* m_statusBarExtension;
++ WebView* m_webView;
++};
++
++#endif // WEBPART_H
+diff --git b/webkitpart/src/webkitpart.rc b/webkitpart/src/webkitpart.rc
+new file mode 100644
+index 000000000..2b564ca97
+--- /dev/null
++++ b/webkitpart/src/webkitpart.rc
+@@ -0,0 +1,32 @@
++<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
++<kpartgui name="kwebkitpart" version="8">
++<MenuBar>
++ <Menu name="file">
++ <Action name="saveDocument" />
++ <Action name="saveFrame" />
++ <Separator />
++ <Action name="printPreview" group="print" />
++ </Menu>
++ <Menu name="edit">
++ <Action name="selectAll" />
++ <Separator />
++ <Action name="find" />
++ </Menu>
++ <Menu name="view">
++ <Action name="zoomIn" />
++ <Action name="zoomOut" />
++ <Action name="zoomNormal" />
++ <Action name="zoomTextOnly" />
++ <Action name="zoomToDPI" />
++ <Separator />
++ <Action name="setEncoding" />
++ <Action name="viewDocumentSource" />
++ <ActionList name="debugScriptList" />
++ </Menu>
++</MenuBar>
++<ToolBar name="htmlToolBar" iconText="icononly" iconSize="22" hidden="true"><text>HTML Toolbar</text>
++ <Action name="zoomIn" />
++ <Action name="zoomOut" />
++ <Action name="zoomNormal" />
++</ToolBar>
++</kpartgui>
+diff --git b/webkitpart/src/webkitpart_ext.cpp b/webkitpart/src/webkitpart_ext.cpp
+new file mode 100644
+index 000000000..d47c7e8e0
+--- /dev/null
++++ b/webkitpart/src/webkitpart_ext.cpp
+@@ -0,0 +1,1237 @@
++/*
++ * This file is part of the KDE project.
++ *
++ * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
++ *
++ * 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 <http://www.gnu.org/licenses/>.
++ *
++ */
++
++#include <QtWebKit/QtWebKitVersion>
++#include "webkitpart_ext.h"
++
++#include "webkitpart.h"
++#include "webkitview.h"
++#include "webkitpage.h"
++#include "settings/webkitsettings.h"
++#include <QtWebKit/QWebSettings>
++
++#include <KDesktopFile>
++#include <KConfigGroup>
++#include <KToolInvocation>
++#include <KSharedConfig>
++#include <KRun>
++#include <KProtocolInfo>
++#include <QInputDialog>
++#include <KLocalizedString>
++#include <QTemporaryFile>
++#include <KUriFilter>
++#include <Sonnet/Dialog>
++#include <sonnet/backgroundchecker.h>
++
++#include <QBuffer>
++#include <QVariant>
++#include <QClipboard>
++#include <QApplication>
++#include <QAction>
++#include <QPrinter>
++#include <QPrintDialog>
++#include <QPrintPreviewDialog>
++#include <QInputDialog>
++#include <QWebHistory>
++#include <QMimeData>
++#define QL1S(x) QLatin1String(x)
++#define QL1C(x) QLatin1Char(x)
++
++template<typename Arg, typename R, typename C>
++struct InvokeWrapper {
++ R *receiver;
++ void (C::*memberFun)(Arg);
++ void operator()(Arg result)
++ {
++ (receiver->*memberFun)(result);
++ }
++};
++
++template<typename Arg, typename R, typename C>
++InvokeWrapper<Arg, R, C> invoke(R *receiver, void (C::*memberFun)(Arg))
++{
++ InvokeWrapper<Arg, R, C> wrapper = {receiver, memberFun};
++ return wrapper;
++}
++
++WebBrowserExtension::WebBrowserExtension(WebKitPart *parent, const QByteArray& cachedHistoryData)
++ :KParts::BrowserExtension(parent),
++ m_part(parent),
++ mCurrentPrinter(Q_NULLPTR)
++{
++ enableAction("cut", false);
++ enableAction("copy", false);
++ enableAction("paste", false);
++ enableAction("print", true);
++
++ if (cachedHistoryData.isEmpty()) {
++ return;
++ }
++
++ QBuffer buffer;
++ buffer.setData(cachedHistoryData);
++ if (!buffer.open(QIODevice::ReadOnly)) {
++ return;
++ }
++
++ // NOTE: When restoring history, webkit PORTING_TODO automatically navigates to
++ // the previous "currentItem". Since we do not want that to happen,
++ // we set a property on the WebPage object that is used to allow or
++ // disallow history navigation in WebPage::acceptNavigationRequest.
++ view()->page()->setProperty("HistoryNavigationLocked", true);
++ QDataStream s (&buffer);
++ s >> *(view()->history());
++}
++
++WebBrowserExtension::~WebBrowserExtension()
++{
++}
++
++WebView* WebBrowserExtension::view()
++{
++ if (!m_view && m_part) {
++ m_view = qobject_cast<WebView*>(m_part->view());
++ }
++
++ return m_view;
++}
++
++int WebBrowserExtension::xOffset()
++{
++#if QTWEBKIT_VERSION >= QT_VERSION_CHECK(5, 602, 3)
++ if (view())
++ return view()->page()->scrollPosition().x();
++#endif
++
++ return KParts::BrowserExtension::xOffset();
++}
++
++int WebBrowserExtension::yOffset()
++{
++#if QTWEBKIT_VERSION >= QT_VERSION_CHECK(5, 602, 3)
++ if (view())
++ return view()->page()->scrollPosition().y();
++#endif
++
++ return KParts::BrowserExtension::yOffset();
++}
++
++void WebBrowserExtension::saveState(QDataStream &stream)
++{
++ // TODO: Save information such as form data from the current page.
++ QWebHistory* history = (view() ? view()->history() : 0);
++ const int historyIndex = (history ? history->currentItemIndex() : -1);
++ const QUrl historyUrl = (history && historyIndex > -1) ? QUrl(history->currentItem().url()) : m_part->url();
++
++ stream << historyUrl
++ << static_cast<qint32>(xOffset())
++ << static_cast<qint32>(yOffset())
++ << historyIndex
++ << m_historyData;
++}
++
++void WebBrowserExtension::restoreState(QDataStream &stream)
++{
++ QUrl u;
++ QByteArray historyData;
++ qint32 xOfs = -1, yOfs = -1, historyItemIndex = -1;
++ stream >> u >> xOfs >> yOfs >> historyItemIndex >> historyData;
++
++ QWebHistory* history = (view() ? view()->page()->history() : 0);
++ if (history) {
++ bool success = false;
++ if (history->count() == 0) { // Handle restoration: crash recovery, tab close undo, session restore
++ if (!historyData.isEmpty()) {
++ historyData = qUncompress(historyData); // uncompress the history data...
++ QBuffer buffer (&historyData);
++ if (buffer.open(QIODevice::ReadOnly)) {
++ QDataStream stream (&buffer);
++ view()->page()->setProperty("HistoryNavigationLocked", true);
++ stream >> *history;
++ QWebHistoryItem currentItem (history->currentItem());
++ if (currentItem.isValid()) {
++ if (currentItem.isValid() && (xOfs != -1 || yOfs != -1)) {
++ const QPoint scrollPos (xOfs, yOfs);
++// currentItem.setUserData(scrollPos);
++ }
++ // NOTE 1: The following Konqueror specific workaround is necessary
++ // because Konqueror only preserves information for the last visited
++ // page. However, we save the entire history content in saveState and
++ // and hence need to elimiate all but the current item here.
++ // NOTE 2: This condition only applies when Konqueror is restored from
++ // abnormal termination ; a crash and/or a session restoration.
++ if (QCoreApplication::applicationName() == QLatin1String("konqueror")) {
++ history->clear();
++ }
++ //kDebug() << "Restoring URL:" << currentItem.url();
++ m_part->setProperty("NoEmitOpenUrlNotification", true);
++ history->goToItem(currentItem);
++ }
++ }
++ }
++ success = (history->count() > 0);
++ } else { // Handle navigation: back and forward button navigation.
++ //kDebug() << "history count:" << history->count() << "request index:" << historyItemIndex;
++ if (history->count() > historyItemIndex && historyItemIndex > -1) {
++ QWebHistoryItem item (history->itemAt(historyItemIndex));
++ //kDebug() << "URL:" << u << "Item URL:" << item.url();
++ if (u == item.url()) {
++ if (item.isValid() && (xOfs != -1 || yOfs != -1)) {
++ const QPoint scrollPos (xOfs, yOfs);
++// item.setUserData(scrollPos);
++ }
++ m_part->setProperty("NoEmitOpenUrlNotification", true);
++ history->goToItem(item);
++ success = true;
++ }
++ }
++ }
++
++ if (success) {
++ return;
++ }
++ }
++
++ // As a last resort, in case the history restoration logic above fails,
++ // attempt to open the requested URL directly.
++ qDebug() << "Normal history navgation logic failed! Falling back to opening url directly.";
++ m_part->openUrl(u);
++}
++
++
++void WebBrowserExtension::cut()
++{
++ if (view())
++ view()->triggerPageAction(QWebPage::Cut);
++}
++
++void WebBrowserExtension::copy()
++{
++ if (view())
++ view()->triggerPageAction(QWebPage::Copy);
++}
++
++void WebBrowserExtension::paste()
++{
++ if (view())
++ view()->triggerPageAction(QWebPage::Paste);
++}
++
++void WebBrowserExtension::slotSaveDocument()
++{
++ if (view())
++ emit saveUrl(view()->url());
++}
++
++void WebBrowserExtension::slotSaveFrame()
++{
++ if (view())
++ emit saveUrl(view()->page()->url()); // TODO lol
++}
++
++void WebBrowserExtension::print()
++{
++#if QTWEBKIT_VERSION >= QT_VERSION_CHECK(5, 602, 3)
++ if (view()) {
++ mCurrentPrinter = new QPrinter();
++ QPointer<QPrintDialog> dialog = new QPrintDialog(mCurrentPrinter, Q_NULLPTR);
++ dialog->setWindowTitle(i18n("Print Document"));
++ if (dialog->exec() != QDialog::Accepted) {
++ slotHandlePagePrinted(false);
++ delete dialog;
++ return;
++ }
++ delete dialog;
++ view()->page()->print(mCurrentPrinter, invoke(this, &WebBrowserExtension::slotHandlePagePrinted));
++ }
++#endif
++}
++
++void WebBrowserExtension::slotHandlePagePrinted(bool result)
++{
++ Q_UNUSED(result);
++ delete mCurrentPrinter;
++ mCurrentPrinter = Q_NULLPTR;
++}
++
++
++void WebBrowserExtension::updateEditActions()
++{
++ if (!view())
++ return;
++
++ enableAction("cut", view()->pageAction(QWebPage::Cut)->isEnabled());
++ enableAction("copy", view()->pageAction(QWebPage::Copy)->isEnabled());
++ enableAction("paste", view()->pageAction(QWebPage::Paste)->isEnabled());
++}
++
++void WebBrowserExtension::updateActions()
++{
++ const QString protocol (m_part->url().scheme());
++ const bool isValidDocument = (protocol != QL1S("about") && protocol != QL1S("error"));
++ enableAction("print", isValidDocument);
++}
++
++void WebBrowserExtension::searchProvider()
++{
++ if (!view())
++ return;
++
++ QAction *action = qobject_cast<QAction*>(sender());
++ if (!action)
++ return;
++
++ QUrl url = action->data().toUrl();
++
++ if (url.host().isEmpty()) {
++ KUriFilterData data;
++ data.setData(action->data().toString());
++ if (KUriFilter::self()->filterSearchUri(data, KUriFilter::WebShortcutFilter))
++ url = data.uri();
++ }
++
++ if (!url.isValid())
++ return;
++
++ KParts::BrowserArguments bargs;
++ bargs.frameName = QL1S("_blank");
++ emit openUrlRequest(url, KParts::OpenUrlArguments(), bargs);
++}
++
++void WebBrowserExtension::reparseConfiguration()
++{
++ // Force the configuration stuff to reparse...
++ WebSettings::self()->init();
++}
++
++void WebBrowserExtension::disableScrolling()
++{
++ QWebView* currentView = view();
++ QWebPage* page = currentView ? currentView->page() : 0;
++
++ if (!page)
++ return;
++
++ page->runJavaScript(QStringLiteral("document.documentElement.style.overflow = 'hidden';"));
++}
++
++void WebBrowserExtension::zoomIn()
++{
++ if (view())
++ view()->setZoomFactor(view()->zoomFactor() + 0.1);
++}
++
++void WebBrowserExtension::zoomOut()
++{
++ if (view())
++ view()->setZoomFactor(view()->zoomFactor() - 0.1);
++}
++
++void WebBrowserExtension::zoomNormal()
++{
++ if (view()) {
++ if (WebSettings::self()->zoomToDPI())
++ view()->setZoomFactor(view()->logicalDpiY() / 96.0f);
++ else
++ view()->setZoomFactor(1);
++ }
++}
++
++void WebBrowserExtension::toogleZoomTextOnly()
++{
++ if (!view())
++ return;
++
++ KConfigGroup cgHtml(KSharedConfig::openConfig(), "HTML Settings");
++ bool zoomTextOnly = cgHtml.readEntry( "ZoomTextOnly", false );
++ cgHtml.writeEntry("ZoomTextOnly", !zoomTextOnly);
++ cgHtml.sync();
++
++ // view()->settings()->setAttribute(QWebSettings::ZoomTextOnly, !zoomTextOnly);
++}
++
++void WebBrowserExtension::toogleZoomToDPI()
++{
++ if (!view())
++ return;
++
++ bool zoomToDPI = !WebSettings::self()->zoomToDPI();
++ WebSettings::self()->setZoomToDPI(zoomToDPI);
++
++ if (zoomToDPI)
++ view()->setZoomFactor(view()->zoomFactor() * view()->logicalDpiY() / 96.0f);
++ else
++ view()->setZoomFactor(view()->zoomFactor() * 96.0f / view()->logicalDpiY());
++
++ // Recompute default font-sizes since they are only DPI dependent when zoomToDPI is false.
++ WebSettings::self()->computeFontSizes(view()->logicalDpiY());
++}
++
++void WebBrowserExtension::slotSelectAll()
++{
++ if (view())
++ view()->triggerPageAction(QWebPage::SelectAll);
++}
++
++void WebBrowserExtension::slotSaveImageAs()
++{
++ if (view())
++ view()->triggerPageAction(QWebPage::DownloadImageToDisk);
++}
++
++void WebBrowserExtension::slotSendImage()
++{
++#if QTWEBKIT_VERSION >= QT_VERSION_CHECK(5, 602, 3)
++ if (!view())
++ return;
++
++ QStringList urls;
++ urls.append(view()->contextMenuResult().mediaUrl().path());
++ const QString subject = view()->contextMenuResult().mediaUrl().path();
++ KToolInvocation::invokeMailer(QString(), QString(), QString(), subject,
++ QString(), //body
++ QString(),
++ urls); // attachments
++#endif
++}
++
++void WebBrowserExtension::slotCopyImageURL()
++{
++#if QTWEBKIT_VERSION >= QT_VERSION_CHECK(5, 602, 3)
++ if (!view())
++ return;
++
++ QUrl safeURL = view()->contextMenuResult().mediaUrl();
++ safeURL.setPassword(QString());
++ // Set it in both the mouse selection and in the clipboard
++ QMimeData* mimeData = new QMimeData;
++//TODO: Porting: test
++ QList<QUrl> safeURLList;
++ safeURLList.append(safeURL);
++ mimeData->setUrls(safeURLList);
++ QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard);
++
++ mimeData = new QMimeData;
++ mimeData->setUrls(safeURLList);
++ QApplication::clipboard()->setMimeData(mimeData, QClipboard::Selection);
++#endif
++}
++
++
++void WebBrowserExtension::slotCopyImage()
++{
++#if QTWEBKIT_VERSION >= QT_VERSION_CHECK(5, 602, 3)
++ if (!view())
++ return;
++
++ QUrl safeURL; //(view()->contextMenuResult().imageUrl());
++ safeURL.setPassword(QString());
++
++ // Set it in both the mouse selection and in the clipboard
++ QMimeData* mimeData = new QMimeData;
++// mimeData->setImageData(view()->contextMenuResult().pixmap());
++//TODO: Porting: test
++ QList<QUrl> safeURLList;
++ safeURLList.append(safeURL);
++ mimeData->setUrls(safeURLList);
++ QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard);
++
++ mimeData = new QMimeData;
++// mimeData->setImageData(view()->contextMenuResult().pixmap());
++ mimeData->setUrls(safeURLList);
++ QApplication::clipboard()->setMimeData(mimeData, QClipboard::Selection);
++#endif
++}
++
++void WebBrowserExtension::slotViewImage()
++{
++#if QTWEBKIT_VERSION >= QT_VERSION_CHECK(5, 602, 3)
++ if (view())
++ emit createNewWindow(view()->contextMenuResult().mediaUrl());
++#endif
++}
++
++void WebBrowserExtension::slotBlockImage()
++{
++#if QTWEBKIT_VERSION >= QT_VERSION_CHECK(5, 602, 3)
++ if (!view())
++ return;
++
++ bool ok = false;
++ const QString url = QInputDialog::getText(view(), i18n("Add URL to Filter"),
++ i18n("Enter the URL:"), QLineEdit::Normal,
++ view()->contextMenuResult().mediaUrl().toString(),
++ &ok);
++ if (ok) {
++ WebSettings::self()->addAdFilter(url);
++ reparseConfiguration();
++ }
++#endif
++}
++
++void WebBrowserExtension::slotBlockHost()
++{
++ if (!view())
++ return;
++
++ QUrl url; // (view()->contextMenuResult().imageUrl());
++ url.setPath(QL1S("/*"));
++ WebSettings::self()->addAdFilter(url.toString(QUrl::RemoveUserInfo | QUrl::RemovePort));
++ reparseConfiguration();
++}
++
++void WebBrowserExtension::slotCopyLinkURL()
++{
++ if (view())
++ view()->triggerPageAction(QWebPage::CopyLinkToClipboard);
++}
++
++void WebBrowserExtension::slotCopyLinkText()
++{
++#if QTWEBKIT_VERSION >= QT_VERSION_CHECK(5, 602, 3)
++ if (view()) {
++ QMimeData* data = new QMimeData;
++ data->setText(view()->contextMenuResult().linkText());
++ QApplication::clipboard()->setMimeData(data, QClipboard::Clipboard);
++ }
++#endif
++}
++
++void WebBrowserExtension::slotCopyEmailAddress()
++{
++#if QTWEBKIT_VERSION >= QT_VERSION_CHECK(5, 602, 3)
++ if (view()) {
++ QMimeData* data = new QMimeData;
++ const QUrl url(view()->contextMenuResult().linkUrl());
++ data->setText(url.path());
++ QApplication::clipboard()->setMimeData(data, QClipboard::Clipboard);
++ }
++#endif
++}
++
++void WebBrowserExtension::slotSaveLinkAs()
++{
++ if (view())
++ view()->triggerPageAction(QWebPage::DownloadLinkToDisk);
++}
++
++void WebBrowserExtension::slotViewDocumentSource()
++{
++ if (!view())
++ return;
++
++ const QUrl pageUrl (view()->url());
++ if (pageUrl.isLocalFile()) {
++ KRun::runUrl(pageUrl, QL1S("text/plain"), view(), false);
++ } else {
++ view()->page()->toHtml([this](const QString& html) {
++ QTemporaryFile tempFile;
++ tempFile.setFileTemplate(tempFile.fileTemplate() + QL1S(".html"));
++ tempFile.setAutoRemove(false);
++ if (tempFile.open()) {
++ tempFile.write(html.toUtf8());
++ KRun::runUrl(QUrl::fromLocalFile(tempFile.fileName()), QL1S("text/plain"), view(), true, false);
++ }
++ });
++ }
++}
++
++#if QTWEBKIT_VERSION >= QT_VERSION_CHECK(5, 602, 3)
++static bool isMultimediaElement(QWebContextMenuData::MediaType mediaType)
++{
++ switch(mediaType)
++ {
++ case QWebContextMenuData::MediaTypeVideo:
++ case QWebContextMenuData::MediaTypeAudio:
++ return true;
++ default:
++ return false;
++ }
++}
++#endif
++
++void WebBrowserExtension::slotLoopMedia()
++{
++#if QTWEBKIT_VERSION >= QT_VERSION_CHECK(5, 602, 3)
++ if (!view())
++ return;
++
++ QWebContextMenuData data = view()->contextMenuResult();
++ if (!isMultimediaElement( data.mediaType()))
++ return;
++ view()->page()->triggerAction(QWebPage::ToggleMediaLoop);
++#endif
++}
++
++void WebBrowserExtension::slotMuteMedia()
++{
++#if QTWEBKIT_VERSION >= QT_VERSION_CHECK(5, 602, 3)
++ if (!view())
++ return;
++
++ QWebContextMenuData data = view()->contextMenuResult();
++ if (!isMultimediaElement( data.mediaType()))
++ return;
++ view()->page()->triggerAction(QWebPage::ToggleMediaMute);
++#endif
++}
++
++void WebBrowserExtension::slotPlayMedia()
++{
++#if QTWEBKIT_VERSION >= QT_VERSION_CHECK(5, 602, 3)
++ if (!view())
++ return;
++
++ QWebContextMenuData data = view()->contextMenuResult();
++ if (!isMultimediaElement( data.mediaType()))
++ return;
++ view()->page()->triggerAction(QWebPage::ToggleMediaPlayPause);
++#endif
++}
++
++void WebBrowserExtension::slotShowMediaControls()
++{
++#if QTWEBKIT_VERSION >= QT_VERSION_CHECK(5, 602, 3)
++ if (!view())
++ return;
++
++ QWebContextMenuData data = view()->contextMenuResult();
++ if (!isMultimediaElement( data.mediaType()))
++ return;
++ view()->page()->triggerAction(QWebPage::ToggleMediaControls);
++#endif
++}
++
++#if 0
++static QUrl mediaUrlFrom(QWebElement& element)
++{
++ QWebFrame* frame = element.webFrame();
++ QString src = frame ? element.attribute(QL1S("src")) : QString();
++ if (src.isEmpty())
++ src = frame ? element.evaluateJavaScript(QL1S("this.src")).toString() : QString();
++
++ if (src.isEmpty())
++ return QUrl();
++
++ return QUrl(frame->baseUrl().resolved(QUrl::fromEncoded(QUrl::toPercentEncoding(src), QUrl::StrictMode)));
++}
++#endif
++
++void WebBrowserExtension::slotSaveMedia()
++{
++#if QTWEBKIT_VERSION >= QT_VERSION_CHECK(5, 602, 3)
++ if (!view())
++ return;
++
++ QWebContextMenuData data = view()->contextMenuResult();
++ if (!isMultimediaElement( data.mediaType()))
++ return;
++ emit saveUrl(data.mediaUrl());
++#endif
++}
++
++void WebBrowserExtension::slotCopyMedia()
++{
++#if QTWEBKIT_VERSION >= QT_VERSION_CHECK(5, 602, 3)
++ if (!view())
++ return;
++ QWebContextMenuData data = view()->contextMenuResult();
++ if (!isMultimediaElement( data.mediaType()))
++ return;
++
++ QUrl safeURL(data.mediaUrl());
++ if (!safeURL.isValid())
++ return;
++
++ safeURL.setPassword(QString());
++ // Set it in both the mouse selection and in the clipboard
++ QMimeData* mimeData = new QMimeData;
++//TODO: Porting: test
++ QList<QUrl> safeURLList;
++ safeURLList.append(safeURL);
++ mimeData->setUrls(safeURLList);
++ QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard);
++
++ mimeData = new QMimeData;
++ mimeData->setUrls(safeURLList);
++ QApplication::clipboard()->setMimeData(mimeData, QClipboard::Selection);
++#endif
++}
++
++void WebBrowserExtension::slotTextDirectionChanged()
++{
++ QAction* action = qobject_cast<QAction*>(sender());
++ if (action) {
++ bool ok = false;
++ const int value = action->data().toInt(&ok);
++ if (ok) {
++ view()->triggerPageAction(static_cast<QWebPage::WebAction>(value));
++ }
++ }
++}
++
++static QVariant execJScript(WebView* view, const QString& script)
++{
++#if 0
++ QWebElement element (view->contextMenuResult().element());
++ if (element.isNull())
++ return QVariant();
++ return element.evaluateJavaScript(script);
++#endif
++ return QVariant();
++}
++
++void WebBrowserExtension::slotCheckSpelling()
++{
++ const QString text (execJScript(view(), QL1S("this.value")).toString());
++
++ if ( text.isEmpty() ) {
++ return;
++ }
++
++ m_spellTextSelectionStart = 0;
++ m_spellTextSelectionEnd = 0;
++
++ Sonnet::BackgroundChecker *backgroundSpellCheck = new Sonnet::BackgroundChecker;
++ Sonnet::Dialog* spellDialog = new Sonnet::Dialog(backgroundSpellCheck, view());
++ backgroundSpellCheck->setParent(spellDialog);
++ spellDialog->setAttribute(Qt::WA_DeleteOnClose, true);
++ spellDialog->showSpellCheckCompletionMessage(true);
++ connect(spellDialog, SIGNAL(replace(QString,int,QString)), this, SLOT(spellCheckerCorrected(QString,int,QString)));
++ connect(spellDialog, SIGNAL(misspelling(QString,int)), this, SLOT(spellCheckerMisspelling(QString,int)));
++ spellDialog->setBuffer(text);
++ spellDialog->show();
++}
++
++void WebBrowserExtension::slotSpellCheckSelection()
++{
++ QString text (execJScript(view(), QL1S("this.value")).toString());
++
++ if ( text.isEmpty() ) {
++ return;
++ }
++
++ m_spellTextSelectionStart = qMax(0, execJScript(view(), QL1S("this.selectionStart")).toInt());
++ m_spellTextSelectionEnd = qMax(0, execJScript(view(), QL1S("this.selectionEnd")).toInt());
++ // kDebug() << "selection start:" << m_spellTextSelectionStart << "end:" << m_spellTextSelectionEnd;
++
++ Sonnet::BackgroundChecker *backgroundSpellCheck = new Sonnet::BackgroundChecker;
++ Sonnet::Dialog* spellDialog = new Sonnet::Dialog(backgroundSpellCheck, view());
++ backgroundSpellCheck->setParent(spellDialog);
++ spellDialog->setAttribute(Qt::WA_DeleteOnClose, true);
++ spellDialog->showSpellCheckCompletionMessage(true);
++ connect(spellDialog, SIGNAL(replace(QString,int,QString)), this, SLOT(spellCheckerCorrected(QString,int,QString)));
++ connect(spellDialog, SIGNAL(misspelling(QString,int)), this, SLOT(spellCheckerMisspelling(QString,int)));
++ connect(spellDialog, SIGNAL(done(QString)), this, SLOT(slotSpellCheckDone(QString)));
++ spellDialog->setBuffer(text.mid(m_spellTextSelectionStart, (m_spellTextSelectionEnd - m_spellTextSelectionStart)));
++ spellDialog->show();
++}
++
++void WebBrowserExtension::spellCheckerCorrected(const QString& original, int pos, const QString& replacement)
++{
++ // Adjust the selection end...
++ if (m_spellTextSelectionEnd > 0) {
++ m_spellTextSelectionEnd += qMax (0, (replacement.length() - original.length()));
++ }
++
++ const int index = pos + m_spellTextSelectionStart;
++ QString script(QL1S("this.value=this.value.substring(0,"));
++ script += QString::number(index);
++ script += QL1S(") + \"");
++ script += replacement;
++ script += QL1S("\" + this.value.substring(");
++ script += QString::number(index + original.length());
++ script += QL1S(")");
++
++ //kDebug() << "**** script:" << script;
++ execJScript(view(), script);
++}
++
++void WebBrowserExtension::spellCheckerMisspelling(const QString& text, int pos)
++{
++ // kDebug() << text << pos;
++ QString selectionScript (QL1S("this.setSelectionRange("));
++ selectionScript += QString::number(pos + m_spellTextSelectionStart);
++ selectionScript += QL1C(',');
++ selectionScript += QString::number(pos + text.length() + m_spellTextSelectionStart);
++ selectionScript += QL1C(')');
++ execJScript(view(), selectionScript);
++}
++
++void WebBrowserExtension::slotSpellCheckDone(const QString&)
++{
++ // Restore the text selection if one was present before we started the
++ // spell check.
++ if (m_spellTextSelectionStart > 0 || m_spellTextSelectionEnd > 0) {
++ QString script (QL1S("; this.setSelectionRange("));
++ script += QString::number(m_spellTextSelectionStart);
++ script += QL1C(',');
++ script += QString::number(m_spellTextSelectionEnd);
++ script += QL1C(')');
++ execJScript(view(), script);
++ }
++}
++
++
++void WebBrowserExtension::saveHistory()
++{
++ QWebHistory* history = (view() ? view()->history() : 0);
++
++ if (history && history->count() > 0) {
++ //kDebug() << "Current history: index=" << history->currentItemIndex() << "url=" << history->currentItem().url();
++ QByteArray histData;
++ QBuffer buff (&histData);
++ m_historyData.clear();
++ if (buff.open(QIODevice::WriteOnly)) {
++ QDataStream stream (&buff);
++ stream << *history;
++ m_historyData = qCompress(histData, 9);
++ }
++ QWidget* mainWidget = m_part ? m_part->widget() : 0;
++ QWidget* frameWidget = mainWidget ? mainWidget->parentWidget() : 0;
++ if (frameWidget) {
++ emit saveHistory(frameWidget, m_historyData);
++ // kDebug() << "# of items:" << history->count() << "current item:" << history->currentItemIndex() << "url:" << history->currentItem().url();
++ }
++ } else {
++ Q_ASSERT(false); // should never happen!!!
++ }
++}
++
++void WebBrowserExtension::slotPrintPreview()
++{
++#if 0
++ // Make it non-modal, in case a redirection deletes the part
++ QPointer<QPrintPreviewDialog> dlg (new QPrintPreviewDialog(view()));
++ connect(dlg.data(), SIGNAL(paintRequested(QPrinter*)),
++ view()->page()->currentFrame(), SLOT(print(QPrinter*)));
++ dlg->exec();
++ delete dlg;
++#endif
++}
++
++void WebBrowserExtension::slotOpenSelection()
++{
++ QAction *action = qobject_cast<QAction*>(sender());
++ if (action) {
++ KParts::BrowserArguments browserArgs;
++ browserArgs.frameName = QStringLiteral("_blank");
++ emit openUrlRequest(QUrl(action->data().toUrl()), KParts::OpenUrlArguments(), browserArgs);
++ }
++}
++
++void WebBrowserExtension::slotLinkInTop()
++{
++#if QTWEBKIT_VERSION >= QT_VERSION_CHECK(5, 602, 3)
++ if (!view())
++ return;
++
++ KParts::OpenUrlArguments uargs;
++ uargs.setActionRequestedByUser(true);
++
++ KParts::BrowserArguments bargs;
++ bargs.frameName = QL1S("_top");
++
++ const QUrl url(view()->contextMenuResult().linkUrl());
++
++ emit openUrlRequest(url, uargs, bargs);
++#endif
++}
++
++////
++
++WebTextExtension::WebTextExtension(WebKitPart* part)
++ : KParts::TextExtension(part)
++{
++ connect(part->view(), SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
++}
++
++WebKitPart* WebTextExtension::part() const
++{
++ return static_cast<WebKitPart*>(parent());
++}
++
++bool WebTextExtension::hasSelection() const
++{
++ return part()->view()->hasSelection();
++}
++
++QString WebTextExtension::selectedText(Format format) const
++{
++ switch(format) {
++ case PlainText:
++ return part()->view()->selectedText();
++ case HTML:
++ // PORTING_TODO selectedText might not be html
++ return part()->view()->selectedText();
++ }
++ return QString();
++}
++
++QString WebTextExtension::completeText(Format format) const
++{
++ // TODO David will hunt me down with a rusty spork if he sees this
++ QEventLoop ev;
++ QString str;
++ switch(format) {
++ case PlainText:
++ part()->view()->page()->toPlainText([&ev,&str](const QString& data) {
++ str = data;
++ ev.quit();
++ });
++ case HTML:
++ part()->view()->page()->toHtml([&ev,&str](const QString& data) {
++ str = data;
++ ev.quit();
++ });
++ }
++ ev.exec();
++ return QString();
++}
++
++////
++
++WebHtmlExtension::WebHtmlExtension(WebKitPart* part)
++ : KParts::HtmlExtension(part)
++{
++}
++
++
++QUrl WebHtmlExtension::baseUrl() const
++{
++ return part()->view()->page()->url();
++}
++
++bool WebHtmlExtension::hasSelection() const
++{
++ return part()->view()->hasSelection();
++}
++
++KParts::SelectorInterface::QueryMethods WebHtmlExtension::supportedQueryMethods() const
++{
++ return (KParts::SelectorInterface::EntireContent
++ | KParts::SelectorInterface::SelectedContent);
++}
++
++#if 0
++static KParts::SelectorInterface::Element convertWebElement(const QWebElement& webElem)
++{
++ KParts::SelectorInterface::Element element;
++ element.setTagName(webElem.tagName());
++ Q_FOREACH(const QString &attr, webElem.attributeNames()) {
++ element.setAttribute(attr, webElem.attribute(attr));
++ }
++ return element;
++}
++#endif
++
++static QString queryOne(const QString& query)
++{
++ QString jsQuery = QL1S("(function(query) { var element; var selectedElement = window.getSelection().getRangeAt(0).cloneContents().querySelector(\"");
++ jsQuery += query;
++ jsQuery += QL1S("\"); if (selectedElement && selectedElement.length > 0) { element = new Object; "
++ "element.tagName = String(selectedElements[0].tagName); element.href = String(selectedElements[0].href); } "
++ "return element; }())");
++ return jsQuery;
++}
++
++static QString queryAll(const QString& query)
++{
++ QString jsQuery = QL1S("(function(query) { var elements = []; var selectedElements = window.getSelection().getRangeAt(0).cloneContents().querySelectorAll(\"");
++ jsQuery += query;
++ jsQuery += QL1S("\"); var numSelectedElements = (selectedElements ? selectedElements.length : 0);"
++ "for (var i = 0; i < numSelectedElements; ++i) { var element = new Object; "
++ "element.tagName = String(selectedElements[i].tagName); element.href = String(selectedElements[i].href);"
++ "elements.push(element); } return elements; } ())");
++ return jsQuery;
++}
++
++static KParts::SelectorInterface::Element convertSelectionElement(const QVariant& variant)
++{
++ KParts::SelectorInterface::Element element;
++ if (!variant.isNull() && variant.type() == QVariant::Map) {
++ const QVariantMap elementMap (variant.toMap());
++ element.setTagName(elementMap.value(QL1S("tagName")).toString());
++ element.setAttribute(QL1S("href"), elementMap.value(QL1S("href")).toString());
++ }
++ return element;
++}
++
++static QList<KParts::SelectorInterface::Element> convertSelectionElements(const QVariant& variant)
++{
++ QList<KParts::SelectorInterface::Element> elements;
++ const QVariantList resultList (variant.toList());
++ Q_FOREACH(const QVariant& result, resultList) {
++ const QVariantMap elementMap = result.toMap();
++ KParts::SelectorInterface::Element element;
++ element.setTagName(elementMap.value(QL1S("tagName")).toString());
++ element.setAttribute(QL1S("href"), elementMap.value(QL1S("href")).toString());
++ elements.append(element);
++ }
++ return elements;
++}
++
++KParts::SelectorInterface::Element WebHtmlExtension::querySelector(const QString& query, KParts::SelectorInterface::QueryMethod method) const
++{
++ KParts::SelectorInterface::Element element;
++
++ // If the specified method is None, return an empty list...
++ if (method == KParts::SelectorInterface::None)
++ return element;
++
++ // If the specified method is not supported, return an empty list...
++ if (!(supportedQueryMethods() & method))
++ return element;
++
++#if 0
++ switch (method) {
++ case KParts::SelectorInterface::EntireContent: {
++ const QWebFrame* webFrame = part()->view()->page()->mainFrame();
++ element = convertWebElement(webFrame->findFirstElement(query));
++ break;
++ }
++ case KParts::SelectorInterface::SelectedContent: {
++ QWebFrame* webFrame = part()->view()->page()->mainFrame();
++ element = convertSelectionElement(webFrame->evaluateJavaScript(queryOne(query)));
++ break;
++ }
++ default:
++ break;
++ }
++#endif
++
++ return element;
++}
++
++QList<KParts::SelectorInterface::Element> WebHtmlExtension::querySelectorAll(const QString& query, KParts::SelectorInterface::QueryMethod method) const
++{
++ QList<KParts::SelectorInterface::Element> elements;
++
++ // If the specified method is None, return an empty list...
++ if (method == KParts::SelectorInterface::None)
++ return elements;
++
++ // If the specified method is not supported, return an empty list...
++ if (!(supportedQueryMethods() & method))
++ return elements;
++#if 0
++ switch (method) {
++ case KParts::SelectorInterface::EntireContent: {
++ const QWebFrame* webFrame = part()->view()->page()->mainFrame();
++ const QWebElementCollection collection = webFrame->findAllElements(query);
++ elements.reserve(collection.count());
++ Q_FOREACH(const QWebElement& element, collection)
++ elements.append(convertWebElement(element));
++ break;
++ }
++ case KParts::SelectorInterface::SelectedContent: {
++ QWebFrame* webFrame = part()->view()->page()->mainFrame();
++ elements = convertSelectionElements(webFrame->evaluateJavaScript(queryAll(query)));
++ break;
++ }
++ default:
++ break;
++ }
++#endif
++ return elements;
++}
++
++QVariant WebHtmlExtension::htmlSettingsProperty(KParts::HtmlSettingsInterface::HtmlSettingsType type) const
++{
++ QWebView* view = part() ? part()->view() : 0;
++ QWebPage* page = view ? view->page() : 0;
++ QWebSettings* settings = page ? page->settings() : 0;
++
++ if (settings) {
++ switch (type) {
++ case KParts::HtmlSettingsInterface::AutoLoadImages:
++ return settings->testAttribute(QWebSettings::AutoLoadImages);
++ case KParts::HtmlSettingsInterface::JavaEnabled:
++ return false; // settings->testAttribute(QWebSettings::JavaEnabled);
++ case KParts::HtmlSettingsInterface::JavascriptEnabled:
++ return settings->testAttribute(QWebSettings::JavascriptEnabled);
++ case KParts::HtmlSettingsInterface::PluginsEnabled:
++ return settings->testAttribute(QWebSettings::PluginsEnabled);
++ case KParts::HtmlSettingsInterface::DnsPrefetchEnabled:
++ return false; //settings->testAttribute(QWebSettings::DnsPrefetchEnabled);
++ case KParts::HtmlSettingsInterface::MetaRefreshEnabled:
++ return view->pageAction(QWebPage::Stop)->isEnabled();
++ case KParts::HtmlSettingsInterface::LocalStorageEnabled:
++ return settings->testAttribute(QWebSettings::LocalStorageEnabled);
++ case KParts::HtmlSettingsInterface::OfflineStorageDatabaseEnabled:
++ return false; //settings->testAttribute(QWebSettings::OfflineStorageDatabaseEnabled);
++ case KParts::HtmlSettingsInterface::OfflineWebApplicationCacheEnabled:
++ return false ;//settings->testAttribute(QWebSettings::OfflineWebApplicationCacheEnabled);
++ case KParts::HtmlSettingsInterface::PrivateBrowsingEnabled:
++ return false; //settings->testAttribute(QWebSettings::PrivateBrowsingEnabled);
++ case KParts::HtmlSettingsInterface::UserDefinedStyleSheetURL:
++ return false; //settings->userStyleSheetUrl();
++ default:
++ break;
++ }
++ }
++
++ return QVariant();
++}
++
++bool WebHtmlExtension::setHtmlSettingsProperty(KParts::HtmlSettingsInterface::HtmlSettingsType type, const QVariant& value)
++{
++ QWebView* view = part() ? part()->view() : 0;
++ QWebPage* page = view ? view->page() : 0;
++ QWebSettings* settings = page ? page->settings() : 0;
++
++ if (settings) {
++ switch (type) {
++ case KParts::HtmlSettingsInterface::AutoLoadImages:
++ settings->setAttribute(QWebSettings::AutoLoadImages, value.toBool());
++ return true;
++ case KParts::HtmlSettingsInterface::JavaEnabled:
++ //settings->setAttribute(QWebESettings::JavaEnabled, value.toBool());
++ return false;
++ case KParts::HtmlSettingsInterface::JavascriptEnabled:
++ settings->setAttribute(QWebSettings::JavascriptEnabled, value.toBool());
++ return true;
++ case KParts::HtmlSettingsInterface::PluginsEnabled:
++ settings->setAttribute(QWebSettings::PluginsEnabled, value.toBool());
++ return true;
++ case KParts::HtmlSettingsInterface::DnsPrefetchEnabled:
++// settings->setAttribute(QWebSettings::DnsPrefetchEnabled, value.toBool());
++ return false;
++ case KParts::HtmlSettingsInterface::MetaRefreshEnabled:
++ view->triggerPageAction(QWebPage::Stop);
++ return true;
++ case KParts::HtmlSettingsInterface::LocalStorageEnabled:
++ settings->setAttribute(QWebSettings::LocalStorageEnabled, value.toBool());
++ return false;
++ case KParts::HtmlSettingsInterface::OfflineStorageDatabaseEnabled:
++ //settings->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, value.toBool());
++ return false;
++ case KParts::HtmlSettingsInterface::OfflineWebApplicationCacheEnabled:
++ //settings->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled, value.toBool());
++ return false;
++ case KParts::HtmlSettingsInterface::PrivateBrowsingEnabled:
++ //settings->setAttribute(QWebEnngineSettings::PrivateBrowsingEnabled, value.toBool());
++ return false;
++ case KParts::HtmlSettingsInterface::UserDefinedStyleSheetURL:
++ //kDebug() << "Setting user style sheet for" << page << "to" << value.toUrl();
++ // settings->setUserStyleSheetUrl(value.toUrl());
++ return false;
++ default:
++ break;
++ }
++ }
++
++ return false;
++}
++
++WebKitPart* WebHtmlExtension::part() const
++{
++ return static_cast<WebKitPart*>(parent());
++}
++
++WebScriptableExtension::WebScriptableExtension(WebKitPart* part)
++ : ScriptableExtension(part)
++{
++}
++
++QVariant WebScriptableExtension::rootObject()
++{
++ return QVariant::fromValue(KParts::ScriptableExtension::Object(this, reinterpret_cast<quint64>(this)));
++}
++
++bool WebScriptableExtension::setException (KParts::ScriptableExtension* callerPrincipal, const QString& message)
++{
++ return KParts::ScriptableExtension::setException (callerPrincipal, message);
++}
++
++QVariant WebScriptableExtension::get (KParts::ScriptableExtension* callerPrincipal, quint64 objId, const QString& propName)
++{
++ //kDebug() << "caller:" << callerPrincipal << "id:" << objId << "propName:" << propName;
++ return callerPrincipal->get (0, objId, propName);
++}
++
++bool WebScriptableExtension::put (KParts::ScriptableExtension* callerPrincipal, quint64 objId, const QString& propName, const QVariant& value)
++{
++ return KParts::ScriptableExtension::put (callerPrincipal, objId, propName, value);
++}
++
++static QVariant exception(const char* msg)
++{
++ qWarning() << msg;
++ return QVariant::fromValue(KParts::ScriptableExtension::Exception(QString::fromLatin1(msg)));
++}
++
++QVariant WebScriptableExtension::evaluateScript (KParts::ScriptableExtension* callerPrincipal,
++ quint64 contextObjectId,
++ const QString& code,
++ KParts::ScriptableExtension::ScriptLanguage lang)
++{
++ Q_UNUSED(contextObjectId);
++ Q_UNUSED(code)
++ //kDebug() << "principal:" << callerPrincipal << "id:" << contextObjectId << "language:" << lang << "code:" << code;
++
++ if (lang != ECMAScript)
++ return exception("unsupported language");
++
++
++ KParts::ReadOnlyPart* part = callerPrincipal ? qobject_cast<KParts::ReadOnlyPart*>(callerPrincipal->parent()) : 0;
++ // QWebFrame* frame = part ? qobject_cast<QWebFrame*>(part->parent()) : 0;
++ // if (!frame)
++ return exception("failed to resolve principal");
++#if 0
++ QVariant result (frame->evaluateJavaScript(code));
++
++ if (result.type() == QVariant::Map) {
++ const QVariantMap map (result.toMap());
++ for (QVariantMap::const_iterator it = map.constBegin(), itEnd = map.constEnd(); it != itEnd; ++it) {
++ callerPrincipal->put(callerPrincipal, 0, it.key(), it.value());
++ }
++ } else {
++ const QString propName(code.contains(QLatin1String("__nsplugin")) ? QLatin1String("__nsplugin") : QString());
++ callerPrincipal->put(callerPrincipal, 0, propName, result.toString());
++ }
++
++ return QVariant::fromValue(ScriptableExtension::Null());
++#endif
++}
++
++bool WebScriptableExtension::isScriptLanguageSupported (KParts::ScriptableExtension::ScriptLanguage lang) const
++{
++ return (lang == KParts::ScriptableExtension::ECMAScript);
++}
++
++QVariant WebScriptableExtension::encloserForKid (KParts::ScriptableExtension* kid)
++{
++#if 0
++ KParts::ReadOnlyPart* part = kid ? qobject_cast<KParts::ReadOnlyPart*>(kid->parent()) : 0;
++ QWebFrame* frame = part ? qobject_cast<QWebFrame*>(part->parent()) : 0;
++ if (frame) {
++ return QVariant::fromValue(KParts::ScriptableExtension::Object(kid, reinterpret_cast<quint64>(kid)));
++ }
++#endif
++
++ return QVariant::fromValue(ScriptableExtension::Null());
++}
++
++WebKitPart* WebScriptableExtension::part()
++{
++ return qobject_cast<WebKitPart*>(parent());
++}
++
+diff --git b/webkitpart/src/webkitpart_ext.h b/webkitpart/src/webkitpart_ext.h
+new file mode 100644
+index 000000000..b375cede2
+--- /dev/null
++++ b/webkitpart/src/webkitpart_ext.h
+@@ -0,0 +1,201 @@
++/*
++ * This file is part of the KDE project.
++ *
++ * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
++ *
++ * 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 <http://www.gnu.org/licenses/>.
++ *
++ */
++
++#ifndef WEBKITPART_EXT_H
++#define WEBKITPART_EXT_H
++
++#include "kwebkitpartlib_export.h"
++
++#include <QPointer>
++
++#include <KParts/BrowserExtension>
++#include <KParts/TextExtension>
++#include <KParts/HtmlExtension>
++#include <KParts/HtmlSettingsInterface>
++#include <KParts/ScriptableExtension>
++#include <KParts/SelectorInterface>
++
++class QUrl;
++class WebPart;
++class WebView;
++class QPrinter;
++class KWEBKITPARTLIB_EXPORT WebBrowserExtension : public KParts::BrowserExtension
++{
++ Q_OBJECT
++
++public:
++ WebBrowserExtension(WebKitPart *parent, const QByteArray& cachedHistoryData);
++ ~WebBrowserExtension();
++
++ virtual int xOffset() override;
++ virtual int yOffset() override;
++ virtual void saveState(QDataStream &) override;
++ virtual void restoreState(QDataStream &) override;
++ void saveHistory();
++
++Q_SIGNALS:
++ void saveUrl(const QUrl &);
++ void saveHistory(QObject*, const QByteArray&);
++
++public Q_SLOTS:
++ void cut();
++ void copy();
++ void paste();
++ void print();
++
++ void slotSaveDocument();
++ void slotSaveFrame();
++ void searchProvider();
++ void reparseConfiguration();
++ void disableScrolling();
++
++ void zoomIn();
++ void zoomOut();
++ void zoomNormal();
++ void toogleZoomTextOnly();
++ void toogleZoomToDPI();
++ void slotSelectAll();
++
++ void slotSaveImageAs();
++ void slotSendImage();
++ void slotCopyImageURL();
++ void slotCopyImage();
++ void slotViewImage();
++ void slotBlockImage();
++ void slotBlockHost();
++
++ void slotCopyLinkURL();
++ void slotCopyLinkText();
++ void slotSaveLinkAs();
++ void slotCopyEmailAddress();
++
++ void slotViewDocumentSource();
++
++ void updateEditActions();
++ void updateActions();
++
++ void slotPlayMedia();
++ void slotMuteMedia();
++ void slotLoopMedia();
++ void slotShowMediaControls();
++ void slotSaveMedia();
++ void slotCopyMedia();
++ void slotTextDirectionChanged();
++ void slotCheckSpelling();
++ void slotSpellCheckSelection();
++ void slotSpellCheckDone(const QString&);
++ void spellCheckerCorrected(const QString&, int, const QString&);
++ void spellCheckerMisspelling(const QString&, int);
++ //void slotPrintRequested(QWebFrame*);
++ void slotPrintPreview();
++
++ void slotOpenSelection();
++ void slotLinkInTop();
++
++private Q_SLOTS:
++ void slotHandlePagePrinted(bool result);
++private:
++ WebView* view();
++ QPointer<WebPart> m_part;
++ QPointer<WebView> m_view;
++ quint32 m_spellTextSelectionStart;
++ quint32 m_spellTextSelectionEnd;
++ QByteArray m_historyData;
++ QPrinter *mCurrentPrinter;
++};
++
++/**
++ * @internal
++ * Implements the TextExtension interface
++ */
++class WebTextExtension : public KParts::TextExtension
++{
++ Q_OBJECT
++public:
++ WebTextExtension(WebKitPart* part);
++
++ bool hasSelection() const Q_DECL_OVERRIDE;
++ QString selectedText(Format format) const Q_DECL_OVERRIDE;
++ QString completeText(Format format) const Q_DECL_OVERRIDE;
++
++private:
++ WebKitPart* part() const;
++};
++
++/**
++ * @internal
++ * Implements the HtmlExtension interface
++ */
++class WebHtmlExtension : public KParts::HtmlExtension,
++ public KParts::SelectorInterface,
++ public KParts::HtmlSettingsInterface
++{
++ Q_OBJECT
++ Q_INTERFACES(KParts::SelectorInterface)
++ Q_INTERFACES(KParts::HtmlSettingsInterface)
++
++public:
++ WebHtmlExtension(WebKitPart* part);
++
++ // HtmlExtension
++ QUrl baseUrl() const Q_DECL_OVERRIDE;
++ bool hasSelection() const Q_DECL_OVERRIDE;
++
++ // SelectorInterface
++ QueryMethods supportedQueryMethods() const Q_DECL_OVERRIDE;
++ Element querySelector(const QString& query, KParts::SelectorInterface::QueryMethod method) const Q_DECL_OVERRIDE;
++ QList<Element> querySelectorAll(const QString& query, KParts::SelectorInterface::QueryMethod method) const Q_DECL_OVERRIDE;
++
++ // HtmlSettingsInterface
++ QVariant htmlSettingsProperty(HtmlSettingsType type) const Q_DECL_OVERRIDE;
++ bool setHtmlSettingsProperty(HtmlSettingsType type, const QVariant& value) Q_DECL_OVERRIDE;
++
++private:
++ WebKitPart* part() const;
++};
++
++class WebScriptableExtension : public KParts::ScriptableExtension
++{
++ Q_OBJECT
++
++public:
++ WebScriptableExtension(WebKitPart* part);
++
++ QVariant rootObject() Q_DECL_OVERRIDE;
++
++ QVariant get(ScriptableExtension* callerPrincipal, quint64 objId, const QString& propName) Q_DECL_OVERRIDE;
++
++ bool put(ScriptableExtension* callerPrincipal, quint64 objId, const QString& propName, const QVariant& value) Q_DECL_OVERRIDE;
++
++ bool setException(ScriptableExtension* callerPrincipal, const QString& message) Q_DECL_OVERRIDE;
++
++ QVariant evaluateScript(ScriptableExtension* callerPrincipal,
++ quint64 contextObjectId,
++ const QString& code,
++ ScriptLanguage language = ECMAScript) Q_DECL_OVERRIDE;
++
++ bool isScriptLanguageSupported(ScriptLanguage lang) const Q_DECL_OVERRIDE;
++
++private:
++ QVariant encloserForKid(KParts::ScriptableExtension* kid) Q_DECL_OVERRIDE;
++ WebKitPart* part();
++};
++
++#endif // WEBKITPART_EXT_H
+diff --git b/webkitpart/src/webkitpartfactory.cpp b/webkitpart/src/webkitpartfactory.cpp
+new file mode 100644
+index 000000000..1156db0e7
+--- /dev/null
++++ b/webkitpart/src/webkitpartfactory.cpp
+@@ -0,0 +1,65 @@
++/*
++ * This file is part of the KDE project.
++ *
++ * Copyright (C) 2008 Laurent Montel <montel@kde.org>
++ *
++ * 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 <http://www.gnu.org/licenses/>.
++ *
++ */
++
++#include "webkitpartfactory.h"
++#include "webkitpart_ext.h"
++#include "webkitpart.h"
++
++#include <QWidget>
++
++WebFactory::~WebFactory()
++{
++ // kDebug() << this;
++}
++
++QObject *WebFactory::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 QtWebKit's PORTING_TODO
++ // history management with any KParts based application.
++ QByteArray histData (m_historyBufContainer.value(parentWidget));
++ if (!histData.isEmpty()) histData = qUncompress(histData);
++ WebKitPart* part = new WebKitPart(parentWidget, parent, histData);
++ WebBrowserExtension* ext = qobject_cast<WebBrowserExtension*>(part->browserExtension());
++ if (ext) {
++ connect(ext, SIGNAL(saveHistory(QObject*,QByteArray)), this, SLOT(slotSaveHistory(QObject*,QByteArray)));
++ }
++ return part;
++}
++
++void WebFactory::slotSaveHistory(QObject* widget, const QByteArray& buffer)
++{
++ // kDebug() << "Caching history data from" << widget;
++ m_historyBufContainer.insert(widget, buffer);
++}
++
++void WebFactory::slotDestroyed(QObject* object)
++{
++ // kDebug() << "Removing cached history data of" << object;
++ m_historyBufContainer.remove(object);
++}
++
++K_EXPORT_PLUGIN(WebFactory)
+diff --git b/webkitpart/src/webkitpartfactory.h b/webkitpart/src/webkitpartfactory.h
+new file mode 100644
+index 000000000..f53ed41b7
+--- /dev/null
++++ b/webkitpart/src/webkitpartfactory.h
+@@ -0,0 +1,47 @@
++/*
++ * This file is part of the KDE project.
++ *
++ * Copyright (C) 2008 Laurent Montel <montel@kde.org>
++ *
++ * 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 <http://www.gnu.org/licenses/>.
++ *
++ */
++
++#ifndef WEBKITPARTFACTORY
++#define WEBKITPARTFACTORY
++
++#include <kpluginfactory.h>
++
++#include <QHash>
++
++class QWidget;
++
++class WebFactory : public KPluginFactory
++{
++ Q_OBJECT
++ Q_PLUGIN_METADATA(IID "org.kde.KPluginFactory" FILE "")
++ Q_INTERFACES(KPluginFactory)
++public:
++ virtual ~WebFactory();
++ QObject *create(const char* iface, QWidget *parentWidget, QObject *parent, const QVariantList& args, const QString &keyword) Q_DECL_OVERRIDE;
++
++private Q_SLOTS:
++ void slotDestroyed(QObject* object);
++ void slotSaveHistory(QObject* widget, const QByteArray&);
++
++private:
++ QHash<QObject*, QByteArray> m_historyBufContainer;
++};
++
++#endif // WEBKITPARTFACTORY
+diff --git b/webkitpart/src/webkitview.cpp b/webkitpart/src/webkitview.cpp
+new file mode 100644
+index 000000000..a106451d2
+--- /dev/null
++++ b/webkitpart/src/webkitview.cpp
+@@ -0,0 +1,594 @@
++/*
++ * This file is part of the KDE project.
++ *
++ * Copyright (C) 2007 Trolltech ASA
++ * Copyright (C) 2008 - 2010 Urs Wolfer <uwolfer @ kde.org>
++ * Copyright (C) 2008 Laurent Montel <montel@kde.org>
++ * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
++ *
++ * 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 <http://www.gnu.org/licenses/>.
++ *
++ */
++
++#include "webkitview.h"
++#include "webkitpage.h"
++#include "webkitpart.h"
++#include "settings/webkitsettings.h"
++
++#include <kio/global.h>
++#include <KAboutData>
++#include <KActionCollection>
++#include <KConfigGroup>
++#include <KService>
++#include <KUriFilter>
++#include <KActionMenu>
++#include <KIO/AccessManager>
++#include <KStringHandler>
++#include <KLocalizedString>
++
++#include <QTimer>
++#include <QMimeData>
++#include <QDropEvent>
++#include <QLabel>
++#include <QNetworkRequest>
++#include <QToolTip>
++#include <QCoreApplication>
++#include <unistd.h>
++#include <QMimeType>
++#include <QMimeDatabase>
++
++#define QL1S(x) QLatin1String(x)
++#define QL1C(x) QLatin1Char(x)
++
++#define ALTERNATE_DEFAULT_WEB_SHORTCUT QL1S("google")
++#define ALTERNATE_WEB_SHORTCUTS QStringList() << QL1S("google") << QL1S("wikipedia") << QL1S("webster") << QL1S("dmoz")
++
++WebView::WebView(WebKitPart* part, QWidget* parent)
++ :QWebView(parent),
++ m_actionCollection(new KActionCollection(this)),
++ m_part(part),
++ m_autoScrollTimerId(-1),
++ m_verticalAutoScrollSpeed(0),
++ m_horizontalAutoScrollSpeed(0)
++{
++ setAcceptDrops(true);
++
++ // Create the custom page...
++ setPage(new WebPage(part, this));
++
++ connect(this, SIGNAL(loadStarted()), this, SLOT(slotStopAutoScroll()));
++
++ if (WebSettings::self()->zoomToDPI())
++ setZoomFactor(logicalDpiY() / 96.0f);
++
++#ifndef HAVE_WEBCONTEXTMENUDATA
++ m_result = 0;
++#endif
++}
++
++WebView::~WebView()
++{
++ //kDebug();
++}
++
++void WebView::loadUrl(const QUrl& url, const KParts::OpenUrlArguments& args, const KParts::BrowserArguments& bargs)
++{
++ page()->setProperty("NavigationTypeUrlEntered", true);
++
++ if (args.reload() && url == this->url()) {
++ reload();
++ return;
++ }
++
++ QNetworkRequest request(url);
++ if (args.reload()) {
++ request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork);
++ }
++
++ if (bargs.postData.isEmpty()) {
++ QWebView::load(url);
++ } else {
++ // QWebView::load(url, QNetworkAccessManager::PostOperation, bargs.postData);
++ }
++}
++
++QWebContextMenuData WebView::contextMenuResult() const
++{
++ return m_result;
++}
++
++static void extractMimeTypeFor(const QUrl& url, QString& mimeType)
++{
++ const QString fname(url.fileName());
++
++ if (fname.isEmpty() || url.hasFragment() || url.hasQuery())
++ return;
++
++ QMimeType pmt = QMimeDatabase().mimeTypeForFile(fname);
++
++ // Further check for mime types guessed from the extension which,
++ // on a web page, are more likely to be a script delivering content
++ // of undecidable type. If the mime type from the extension is one
++ // of these, don't use it. Retain the original type 'text/html'.
++ if (pmt.isDefault() ||
++ pmt.inherits(QL1S("application/x-perl")) ||
++ pmt.inherits(QL1S("application/x-perl-module")) ||
++ pmt.inherits(QL1S("application/x-php")) ||
++ pmt.inherits(QL1S("application/x-python-bytecode")) ||
++ pmt.inherits(QL1S("application/x-python")) ||
++ pmt.inherits(QL1S("application/x-shellscript")))
++ return;
++
++ mimeType = pmt.name();
++}
++
++void WebView::contextMenuEvent(QContextMenuEvent* e)
++{
++#ifdef HAVE_WEBCONTEXTMENUDATA
++ m_result = page()->contextMenuData();
++
++ // Clear the previous collection entries first...
++ m_actionCollection->clear();
++
++ KParts::BrowserExtension::PopupFlags flags = KParts::BrowserExtension::DefaultPopupItems;
++ KParts::BrowserExtension::ActionGroupMap mapAction;
++ QString mimeType (QL1S("text/html"));
++ bool forcesNewWindow = false;
++
++ QUrl emitUrl;
++
++ if (m_result.isContentEditable()) {
++ flags |= KParts::BrowserExtension::ShowTextSelectionItems;
++ editableContentActionPopupMenu(mapAction);
++ } else if (m_result.mediaType() == QWebContextMenuData::MediaTypeVideo || m_result.mediaType() == QWebContextMenuData::MediaTypeAudio) {
++ multimediaActionPopupMenu(mapAction);
++ } else if (!m_result.linkUrl().isValid()) {
++ if (m_result.mediaType() == QWebContextMenuData::MediaTypeImage) {
++ emitUrl = m_result.mediaUrl();
++ extractMimeTypeFor(emitUrl, mimeType);
++ } else {
++ flags |= KParts::BrowserExtension::ShowBookmark;
++ emitUrl = m_part->url();
++
++ if (!m_result.selectedText().isEmpty()) {
++ flags |= KParts::BrowserExtension::ShowTextSelectionItems;
++ selectActionPopupMenu(mapAction);
++ }
++ }
++ partActionPopupMenu(mapAction);
++ } else {
++ flags |= KParts::BrowserExtension::ShowBookmark;
++ flags |= KParts::BrowserExtension::IsLink;
++ emitUrl = m_result.linkUrl();
++ linkActionPopupMenu(mapAction);
++ if (emitUrl.isLocalFile())
++ mimeType = QMimeDatabase().mimeTypeForUrl(emitUrl).name();
++ else
++ extractMimeTypeFor(emitUrl, mimeType);
++ partActionPopupMenu(mapAction);
++
++ // Show the OpenInThisWindow context menu item
++// forcesNewWindow = (page()->currentFrame() != m_result.linkTargetFrame());
++ }
++
++ if (!mapAction.isEmpty()) {
++ KParts::OpenUrlArguments args;
++ KParts::BrowserArguments bargs;
++ args.setMimeType(mimeType);
++ bargs.setForcesNewWindow(forcesNewWindow);
++ e->accept();
++ emit m_part->browserExtension()->popupMenu(e->globalPos(), emitUrl, static_cast<mode_t>(-1), args, bargs, flags, mapAction);
++ return;
++ }
++
++#endif
++ QWebView::contextMenuEvent(e);
++}
++
++void WebView::keyPressEvent(QKeyEvent* e)
++{
++ if (e && hasFocus()) {
++ const int key = e->key();
++ if (e->modifiers() & Qt::ShiftModifier) {
++ switch (key) {
++ case Qt::Key_Up:
++ /* if (!isEditableElement(page()))*/ {
++ m_verticalAutoScrollSpeed--;
++ if (m_autoScrollTimerId == -1)
++ m_autoScrollTimerId = startTimer(100);
++ e->accept();
++ return;
++ }
++ break;
++ case Qt::Key_Down:
++ /*if (!isEditableElement(page()))*/ {
++ m_verticalAutoScrollSpeed++;
++ if (m_autoScrollTimerId == -1)
++ m_autoScrollTimerId = startTimer(100);
++ e->accept();
++ return;
++ }
++ break;
++ case Qt::Key_Left:
++ /*if (!isEditableElement(page()))*/ {
++ m_horizontalAutoScrollSpeed--;
++ if (m_autoScrollTimerId == -1)
++ m_autoScrollTimerId = startTimer(100);
++ e->accept();
++ return;
++ }
++ break;
++ case Qt::Key_Right:
++ /*if (!isEditableElement(page()))*/ {
++ m_horizontalAutoScrollSpeed--;
++ if (m_autoScrollTimerId == -1)
++ m_autoScrollTimerId = startTimer(100);
++ e->accept();
++ return;
++ }
++ break;
++ default:
++ break;
++ }
++ } else if (m_autoScrollTimerId != -1) {
++ // kDebug() << "scroll timer id:" << m_autoScrollTimerId;
++ slotStopAutoScroll();
++ e->accept();
++ return;
++ }
++ }
++ QWebView::keyPressEvent(e);
++}
++
++void WebView::keyReleaseEvent(QKeyEvent *e)
++{
++ QWebView::keyReleaseEvent(e);
++}
++
++void WebView::mouseReleaseEvent(QMouseEvent* e)
++{
++ QWebView::mouseReleaseEvent(e);
++}
++
++void WebView::wheelEvent (QWheelEvent* e)
++{
++ QWebView::wheelEvent(e);
++}
++
++
++void WebView::timerEvent(QTimerEvent* e)
++{
++#if 0
++ if (e && e->timerId() == m_autoScrollTimerId) {
++ // do the scrolling
++ scroll(m_horizontalAutoScrollSpeed, m_verticalAutoScrollSpeed);
++ // check if we reached the end
++ const int y = page()->scrollPosition().y();
++ if (y == page()->currentFrame()->scrollBarMinimum(Qt::Vertical) ||
++ y == page()->currentFrame()->scrollBarMaximum(Qt::Vertical)) {
++ m_verticalAutoScrollSpeed = 0;
++ }
++
++ const int x = page()->scrollPosition().x();
++ if (x == page()->currentFrame()->scrollBarMinimum(Qt::Horizontal) ||
++ x == page()->currentFrame()->scrollBarMaximum(Qt::Horizontal)) {
++ m_horizontalAutoScrollSpeed = 0;
++ }
++
++ // Kill the timer once the max/min scroll limit is reached.
++ if (m_horizontalAutoScrollSpeed == 0 && m_verticalAutoScrollSpeed == 0) {
++ killTimer(m_autoScrollTimerId);
++ m_autoScrollTimerId = -1;
++ }
++ e->accept();
++ return;
++ }
++#endif
++ QWebView::timerEvent(e);
++}
++
++void WebView::editableContentActionPopupMenu(KParts::BrowserExtension::ActionGroupMap& partGroupMap)
++{
++ QList<QAction*> editableContentActions;
++
++ QActionGroup* group = new QActionGroup(this);
++ group->setExclusive(true);
++
++ QAction* action = new QAction(m_actionCollection);
++ action->setSeparator(true);
++ editableContentActions.append(action);
++
++ action = m_actionCollection->addAction(KStandardAction::Copy, QL1S("copy"), m_part->browserExtension(), SLOT(copy()));
++ action->setEnabled(pageAction(QWebPage::Copy)->isEnabled());
++ editableContentActions.append(action);
++
++ action = m_actionCollection->addAction(KStandardAction::Cut, QL1S("cut"), m_part->browserExtension(), SLOT(cut()));
++ action->setEnabled(pageAction(QWebPage::Cut)->isEnabled());
++ editableContentActions.append(action);
++
++ action = m_actionCollection->addAction(KStandardAction::Paste, QL1S("paste"), m_part->browserExtension(), SLOT(paste()));
++ action->setEnabled(pageAction(QWebPage::Paste)->isEnabled());
++ editableContentActions.append(action);
++
++ action = new QAction(m_actionCollection);
++ action->setSeparator(true);
++ editableContentActions.append(action);
++
++ editableContentActions.append(pageAction(QWebPage::SelectAll));
++ editableContentActions.append(pageAction(QWebPage::InspectElement));
++
++ partGroupMap.insert(QStringLiteral("editactions") , editableContentActions);
++}
++
++
++void WebView::partActionPopupMenu(KParts::BrowserExtension::ActionGroupMap& partGroupMap)
++{
++ QList<QAction*> partActions;
++
++#ifdef HAVE_WEBCONTEXTMENUDATA
++ if (m_result.mediaUrl().isValid()) {
++ QAction *action;
++ action = new QAction(i18n("Save Image As..."), this);
++ m_actionCollection->addAction(QL1S("saveimageas"), action);
++ connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotSaveImageAs()));
++ partActions.append(action);
++
++ action = new QAction(i18n("Send Image..."), this);
++ m_actionCollection->addAction(QL1S("sendimage"), action);
++ connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotSendImage()));
++ partActions.append(action);
++
++ action = new QAction(i18n("Copy Image URL"), this);
++ m_actionCollection->addAction(QL1S("copyimageurl"), action);
++ connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotCopyImageURL()));
++ partActions.append(action);
++
++#if 0
++ action = new QAction(i18n("Copy Image"), this);
++ m_actionCollection->addAction(QL1S("copyimage"), action);
++ connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotCopyImage()));
++ action->setEnabled(!m_result.pixmap().isNull());
++ partActions.append(action);
++#endif
++
++ action = new QAction(i18n("View Image (%1)", QUrl(m_result.mediaUrl()).fileName()), this);
++ m_actionCollection->addAction(QL1S("viewimage"), action);
++ connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotViewImage()));
++ partActions.append(action);
++
++ if (WebSettings::self()->isAdFilterEnabled()) {
++ action = new QAction(i18n("Block Image..."), this);
++ m_actionCollection->addAction(QL1S("blockimage"), action);
++ connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotBlockImage()));
++ partActions.append(action);
++
++ if (!m_result.mediaUrl().host().isEmpty() &&
++ !m_result.mediaUrl().scheme().isEmpty())
++ {
++ action = new QAction(i18n("Block Images From %1" , m_result.mediaUrl().host()), this);
++ m_actionCollection->addAction(QL1S("blockhost"), action);
++ connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotBlockHost()));
++ partActions.append(action);
++ }
++ }
++ }
++#endif
++
++ {
++ QAction *separatorAction = new QAction(m_actionCollection);
++ separatorAction->setSeparator(true);
++ partActions.append(separatorAction);
++ }
++
++ partActions.append(m_part->actionCollection()->action(QStringLiteral("viewDocumentSource")));
++
++ partActions.append(pageAction(QWebPage::InspectElement));
++
++ partGroupMap.insert(QStringLiteral("partactions"), partActions);
++}
++
++void WebView::selectActionPopupMenu(KParts::BrowserExtension::ActionGroupMap& selectGroupMap)
++{
++ QList<QAction*> selectActions;
++
++ QAction* copyAction = m_actionCollection->addAction(KStandardAction::Copy, QL1S("copy"), m_part->browserExtension(), SLOT(copy()));
++ copyAction->setText(i18n("&Copy Text"));
++ copyAction->setEnabled(m_part->browserExtension()->isActionEnabled("copy"));
++ selectActions.append(copyAction);
++
++ addSearchActions(selectActions, this);
++
++ KUriFilterData data (selectedText().simplified().left(256));
++ data.setCheckForExecutables(false);
++ if (KUriFilter::self()->filterUri(data, QStringList() << QStringLiteral("kshorturifilter") << QStringLiteral("fixhosturifilter")) &&
++ data.uri().isValid() && data.uriType() == KUriFilterData::NetProtocol) {
++ QAction *action = new QAction(QIcon::fromTheme(QStringLiteral("window-new")), i18nc("open selected url", "Open '%1'",
++ KStringHandler::rsqueeze(data.uri().url(), 18)), this);
++ m_actionCollection->addAction(QL1S("openSelection"), action);
++ action->setData(QUrl(data.uri()));
++ connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotOpenSelection()));
++ selectActions.append(action);
++ }
++
++ selectGroupMap.insert(QStringLiteral("editactions"), selectActions);
++}
++
++void WebView::linkActionPopupMenu(KParts::BrowserExtension::ActionGroupMap& linkGroupMap)
++{
++#ifdef HAVE_WEBCONTEXTMENUDATA
++ Q_ASSERT(!m_result.linkUrl().isEmpty());
++
++ const QUrl url(m_result.linkUrl());
++#else
++ const QUrl url;
++#endif
++
++ QList<QAction*> linkActions;
++
++ QAction* action;
++
++#ifdef HAVE_WEBCONTEXTMENUDATA
++ if (!m_result.selectedText().isEmpty()) {
++ action = m_actionCollection->addAction(KStandardAction::Copy, QL1S("copy"), m_part->browserExtension(), SLOT(copy()));
++ action->setText(i18n("&Copy Text"));
++ action->setEnabled(m_part->browserExtension()->isActionEnabled("copy"));
++ linkActions.append(action);
++ }
++#endif
++
++ if (url.scheme() == QLatin1String("mailto")) {
++#ifdef HAVE_WEBCONTEXTMENUDATA
++ action = new QAction(i18n("&Copy Email Address"), this);
++ m_actionCollection->addAction(QL1S("copylinklocation"), action);
++ connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotCopyEmailAddress()));
++ linkActions.append(action);
++#endif
++ } else {
++#ifdef HAVE_WEBCONTEXTMENUDATA
++ if (!m_result.linkText().isEmpty()) {
++ action = new QAction(QIcon::fromTheme(QStringLiteral("edit-copy")), i18n("Copy Link &Text"), this);
++ m_actionCollection->addAction(QL1S("copylinktext"), action);
++ connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotCopyLinkText()));
++ linkActions.append(action);
++ }
++#endif
++
++ action = new QAction(i18n("Copy Link &URL"), this);
++ m_actionCollection->addAction(QL1S("copylinkurl"), action);
++ connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotCopyLinkURL()));
++ linkActions.append(action);
++
++ action = new QAction(i18n("&Save Link As..."), this);
++ m_actionCollection->addAction(QL1S("savelinkas"), action);
++ connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(slotSaveLinkAs()));
++ linkActions.append(action);
++ }
++
++ linkGroupMap.insert(QStringLiteral("linkactions"), linkActions);
++}
++
++void WebView::multimediaActionPopupMenu(KParts::BrowserExtension::ActionGroupMap& mmGroupMap)
++{
++#ifdef HAVE_WEBCONTEXTMENUDATA
++ QList<QAction*> multimediaActions;
++
++ const bool isVideoElement = m_result.mediaType() == QWebContextMenuData::MediaTypeVideo;
++ const bool isAudioElement = m_result.mediaType() == QWebContextMenuData::MediaTypeAudio;
++
++ QAction* action = new QAction(i18n("&Play/Pause"), this);
++ m_actionCollection->addAction(QL1S("playmultimedia"), action);
++ connect(action, SIGNAL(triggered()), m_part->browserExtension(), SLOT(slotPlayMedia()));
++ multimediaActions.append(action);
++
++ action = new QAction(i18n("Un&mute/&Mute"), this);
++ m_actionCollection->addAction(QL1S("mutemultimedia"), action);
++ connect(action, SIGNAL(triggered()), m_part->browserExtension(), SLOT(slotMuteMedia()));
++ multimediaActions.append(action);
++
++ action = new QAction(i18n("Toggle &Loop"), this);
++ m_actionCollection->addAction(QL1S("loopmultimedia"), action);
++ connect(action, SIGNAL(triggered()), m_part->browserExtension(), SLOT(slotLoopMedia()));
++ multimediaActions.append(action);
++
++ action = new QAction(i18n("Toggle &Controls"), this);
++ m_actionCollection->addAction(QL1S("showmultimediacontrols"), action);
++ connect(action, SIGNAL(triggered()), m_part->browserExtension(), SLOT(slotShowMediaControls()));
++ multimediaActions.append(action);
++
++ action = new QAction(m_actionCollection);
++ action->setSeparator(true);
++ multimediaActions.append(action);
++
++ QString saveMediaText, copyMediaText;
++ if (isVideoElement) {
++ saveMediaText = i18n("Sa&ve Video As...");
++ copyMediaText = i18n("C&opy Video URL");
++ } else if (isAudioElement) {
++ saveMediaText = i18n("Sa&ve Audio As...");
++ copyMediaText = i18n("C&opy Audio URL");
++ } else {
++ saveMediaText = i18n("Sa&ve Media As...");
++ copyMediaText = i18n("C&opy Media URL");
++ }
++
++ action = new QAction(saveMediaText, this);
++ m_actionCollection->addAction(QL1S("savemultimedia"), action);
++ connect(action, SIGNAL(triggered()), m_part->browserExtension(), SLOT(slotSaveMedia()));
++ multimediaActions.append(action);
++
++ action = new QAction(copyMediaText, this);
++ m_actionCollection->addAction(QL1S("copymultimediaurl"), action);
++ connect(action, SIGNAL(triggered()), m_part->browserExtension(), SLOT(slotCopyMedia()));
++ multimediaActions.append(action);
++
++ mmGroupMap.insert(QStringLiteral("partactions"), multimediaActions);
++#endif
++}
++
++void WebView::slotStopAutoScroll()
++{
++ if (m_autoScrollTimerId == -1) {
++ return;
++ }
++
++ killTimer(m_autoScrollTimerId);
++ m_autoScrollTimerId = -1;
++ m_verticalAutoScrollSpeed = 0;
++ m_horizontalAutoScrollSpeed = 0;
++
++}
++
++void WebView::addSearchActions(QList<QAction*>& selectActions, QWebView* view)
++{
++ // search text
++ const QString selectedText = view->selectedText().simplified();
++ if (selectedText.isEmpty())
++ return;
++
++ KUriFilterData data;
++ data.setData(selectedText);
++ data.setAlternateDefaultSearchProvider(ALTERNATE_DEFAULT_WEB_SHORTCUT);
++ data.setAlternateSearchProviders(ALTERNATE_WEB_SHORTCUTS);
++
++ if (KUriFilter::self()->filterSearchUri(data, KUriFilter::NormalTextFilter)) {
++ const QString squeezedText = KStringHandler::rsqueeze(selectedText, 20);
++ QAction *action = new QAction(QIcon::fromTheme(data.iconName()),
++ i18nc("Search \"search provider\" for \"text\"", "Search %1 for '%2'",
++ data.searchProvider(), squeezedText), view);
++ action->setData(QUrl(data.uri()));
++ connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(searchProvider()));
++ m_actionCollection->addAction(QL1S("defaultSearchProvider"), action);
++ selectActions.append(action);
++
++
++ const QStringList preferredSearchProviders = data.preferredSearchProviders();
++ if (!preferredSearchProviders.isEmpty()) {
++ KActionMenu* providerList = new KActionMenu(i18nc("Search for \"text\" with",
++ "Search for '%1' with", squeezedText), view);
++ Q_FOREACH(const QString &searchProvider, preferredSearchProviders) {
++ if (searchProvider == data.searchProvider())
++ continue;
++
++ QAction *action = new QAction(QIcon::fromTheme(data.iconNameForPreferredSearchProvider(searchProvider)), searchProvider, view);
++ action->setData(data.queryForPreferredSearchProvider(searchProvider));
++ m_actionCollection->addAction(searchProvider, action);
++ connect(action, SIGNAL(triggered(bool)), m_part->browserExtension(), SLOT(searchProvider()));
++
++ providerList->addAction(action);
++ }
++ m_actionCollection->addAction(QL1S("searchProviderList"), providerList);
++ selectActions.append(providerList);
++ }
++ }
++}
+diff --git b/webkitpart/src/webkitview.h b/webkitpart/src/webkitview.h
+new file mode 100644
+index 000000000..2f846f073
+--- /dev/null
++++ b/webkitpart/src/webkitview.h
+@@ -0,0 +1,132 @@
++/*
++ * This file is part of the KDE project.
++ *
++ * Copyright (C) 2007 Trolltech ASA
++ * Copyright (C) 2008 Urs Wolfer <uwolfer @ kde.org>
++ * Copyright (C) 2008 Laurent Montel <montel@kde.org>
++ * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
++ *
++ * 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 <http://www.gnu.org/licenses/>.
++ *
++ */
++#ifndef WEBVIEW_H
++#define WEBVIEW_H
++
++#include <QPointer>
++#include <KParts/BrowserExtension>
++
++#include <QWebView>
++#include <QtWebKit/QtWebKitVersion>
++#if QTWEBKIT_VERSION >= QT_VERSION_CHECK(5, 602, 3)
++#define HAVE_WEBCONTEXTMENUDATA
++#include <QWebContextMenuData>
++#else
++typedef void* QWebContextMenuData;
++#endif
++
++class QUrl;
++class WebKitPart;
++
++class WebView : public QWebView
++{
++ Q_OBJECT
++public:
++ WebView(WebKitPart* part, QWidget* parent);
++ ~WebView();
++
++ /**
++ * Same as QWebPage::load, but with KParts style arguments instead.
++ *
++ * @see KParts::OpenUrlArguments, KParts::BrowserArguments.
++ *
++ * @param url the url to load.
++ * @param args reference to a OpenUrlArguments object.
++ * @param bargs reference to a BrowserArguments object.
++ */
++ void loadUrl(const QUrl& url, const KParts::OpenUrlArguments& args, const KParts::BrowserArguments& bargs);
++
++ QWebContextMenuData contextMenuResult() const;
++
++protected:
++ /**
++ * Reimplemented for internal reasons, the API is not affected.
++ *
++ * @see QWidget::contextMenuEvent
++ * @internal
++ */
++ void contextMenuEvent(QContextMenuEvent*) Q_DECL_OVERRIDE;
++
++ /**
++ * Reimplemented for internal reasons, the API is not affected.
++ *
++ * @see QWidget::keyPressEvent
++ * @internal
++ */
++ void keyPressEvent(QKeyEvent*) Q_DECL_OVERRIDE;
++
++ /**
++ * Reimplemented for internal reasons, the API is not affected.
++ *
++ * @see QWidget::keyReleaseEvent
++ * @internal
++ */
++ void keyReleaseEvent(QKeyEvent*) Q_DECL_OVERRIDE;
++
++ /**
++ * Reimplemented for internal reasons, the API is not affected.
++ *
++ * @see QWidget::mouseReleaseEvent
++ * @internal
++ */
++ void mouseReleaseEvent(QMouseEvent*) Q_DECL_OVERRIDE;
++
++ /**
++ * Reimplemented for internal reasons, the API is not affected.
++ *
++ * @see QObject::timerEvent
++ * @internal
++ */
++ void timerEvent(QTimerEvent*) Q_DECL_OVERRIDE;
++
++ /**
++ * Reimplemented for internal reasons, the API is not affected.
++ *
++ * @see QWidget::wheelEvent
++ * @internal
++ */
++ void wheelEvent(QWheelEvent*) Q_DECL_OVERRIDE;
++
++private Q_SLOTS:
++ void slotStopAutoScroll();
++
++private:
++ void editableContentActionPopupMenu(KParts::BrowserExtension::ActionGroupMap&);
++ void selectActionPopupMenu(KParts::BrowserExtension::ActionGroupMap&);
++ void linkActionPopupMenu(KParts::BrowserExtension::ActionGroupMap&);
++ void partActionPopupMenu(KParts::BrowserExtension::ActionGroupMap &);
++ void multimediaActionPopupMenu(KParts::BrowserExtension::ActionGroupMap&);
++ void addSearchActions(QList<QAction*>& selectActions, QWebView*);
++
++ KActionCollection* m_actionCollection;
++ QWebContextMenuData m_result;
++ QPointer<WebKitPart> m_part;
++
++ qint32 m_autoScrollTimerId;
++ qint32 m_verticalAutoScrollSpeed;
++ qint32 m_horizontalAutoScrollSpeed;
++
++ QHash<QString, QChar> m_duplicateLinkElements;
++};
++
++#endif // WEBVIEW_H
+diff --git b/webkitpart/src/websslinfo.cpp b/webkitpart/src/websslinfo.cpp
+new file mode 100644
+index 000000000..7960007d0
+--- /dev/null
++++ b/webkitpart/src/websslinfo.cpp
+@@ -0,0 +1,224 @@
++/*
++ * This file is part of the KDE project.
++ *
++ * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
++ *
++ * 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 <http://www.gnu.org/licenses/>.
++ *
++ */
++
++#include "websslinfo.h"
++
++#include <QVariant>
++
++
++class WebSslInfo::WebSslInfoPrivate
++{
++public:
++ WebSslInfoPrivate()
++ : usedCipherBits(0), supportedCipherBits(0) {}
++
++ QUrl url;
++ QString ciphers;
++ QString protocol;
++ QString certErrors;
++ QHostAddress peerAddress;
++ QHostAddress parentAddress;
++ QList<QSslCertificate> certificateChain;
++
++ int usedCipherBits;
++ int supportedCipherBits;
++};
++
++WebSslInfo::WebSslInfo()
++ :d(new WebSslInfo::WebSslInfoPrivate)
++{
++}
++
++WebSslInfo::WebSslInfo(const WebSslInfo& other)
++ :d(new WebSslInfo::WebSslInfoPrivate)
++{
++ *this = other;
++}
++
++WebSslInfo::~WebSslInfo()
++{
++ delete d;
++ d = 0;
++}
++
++bool WebSslInfo::isValid() const
++{
++ return (d ? !d->peerAddress.isNull() : false);
++}
++
++QUrl WebSslInfo::url() const
++{
++ return (d ? d->url : QUrl());
++}
++
++QHostAddress WebSslInfo::parentAddress() const
++{
++ return (d ? d->parentAddress : QHostAddress());
++}
++
++QHostAddress WebSslInfo::peerAddress() const
++{
++ return (d ? d->peerAddress : QHostAddress());
++}
++
++QString WebSslInfo::protocol() const
++{
++ return (d ? d->protocol : QString());
++}
++
++QString WebSslInfo::ciphers() const
++{
++ return (d ? d->ciphers : QString());
++}
++
++QString WebSslInfo::certificateErrors() const
++{
++ return (d ? d->certErrors : QString());
++}
++
++int WebSslInfo::supportedChiperBits () const
++{
++ return (d ? d->supportedCipherBits : 0);
++}
++
++int WebSslInfo::usedChiperBits () const
++{
++ return (d ? d->usedCipherBits : 0);
++}
++
++QList<QSslCertificate> WebSslInfo::certificateChain() const
++{
++ return (d ? d->certificateChain : QList<QSslCertificate>());
++}
++
++WebSslInfo& WebSslInfo::operator=(const WebSslInfo& other)
++{
++ if (d) {
++ d->ciphers = other.d->ciphers;
++ d->protocol = other.d->protocol;
++ d->certErrors = other.d->certErrors;
++ d->peerAddress = other.d->peerAddress;
++ d->parentAddress = other.d->parentAddress;
++ d->certificateChain = other.d->certificateChain;
++
++ d->usedCipherBits = other.d->usedCipherBits;
++ d->supportedCipherBits = other.d->supportedCipherBits;
++ d->url = other.d->url;
++ }
++
++ return *this;
++}
++
++bool WebSslInfo::saveTo(QMap<QString, QVariant>& data) const
++{
++ const bool ok = isValid();
++ if (ok) {
++ data.insert(QStringLiteral("ssl_in_use"), true);
++ data.insert(QStringLiteral("ssl_peer_ip"), d->peerAddress.toString());
++ data.insert(QStringLiteral("ssl_parent_ip"), d->parentAddress.toString());
++ data.insert(QStringLiteral("ssl_protocol_version"), d->protocol);
++ data.insert(QStringLiteral("ssl_cipher"), d->ciphers);
++ data.insert(QStringLiteral("ssl_cert_errors"), d->certErrors);
++ data.insert(QStringLiteral("ssl_cipher_used_bits"), d->usedCipherBits);
++ data.insert(QStringLiteral("ssl_cipher_bits"), d->supportedCipherBits);
++ QByteArray certChain;
++ Q_FOREACH(const QSslCertificate& cert, d->certificateChain)
++ certChain += cert.toPem();
++ data.insert(QStringLiteral("ssl_peer_chain"), certChain);
++ }
++
++ return ok;
++}
++
++void WebSslInfo::restoreFrom(const QVariant& value, const QUrl& url, bool reset)
++{
++ if (reset) {
++ *this = WebSslInfo();
++ }
++
++ if (value.isValid() && value.type() == QVariant::Map) {
++ QMap<QString,QVariant> metaData = value.toMap();
++ if (metaData.value(QStringLiteral("ssl_in_use"), false).toBool()) {
++ setCertificateChain(metaData.value(QStringLiteral("ssl_peer_chain")).toByteArray());
++ setPeerAddress(metaData.value(QStringLiteral("ssl_peer_ip")).toString());
++ setParentAddress(metaData.value(QStringLiteral("ssl_parent_ip")).toString());
++ setProtocol(metaData.value(QStringLiteral("ssl_protocol_version")).toString());
++ setCiphers(metaData.value(QStringLiteral("ssl_cipher")).toString());
++ setCertificateErrors(metaData.value(QStringLiteral("ssl_cert_errors")).toString());
++ setUsedCipherBits(metaData.value(QStringLiteral("ssl_cipher_used_bits")).toString());
++ setSupportedCipherBits(metaData.value(QStringLiteral("ssl_cipher_bits")).toString());
++ setUrl(url);
++ }
++ }
++}
++
++void WebSslInfo::setUrl (const QUrl &url)
++{
++ if (d)
++ d->url = url;
++}
++
++void WebSslInfo::setPeerAddress(const QString& address)
++{
++ if (d)
++ d->peerAddress = address;
++}
++
++void WebSslInfo::setParentAddress(const QString& address)
++{
++ if (d)
++ d->parentAddress = address;
++}
++
++void WebSslInfo::setProtocol(const QString& protocol)
++{
++ if (d)
++ d->protocol = protocol;
++}
++
++void WebSslInfo::setCertificateChain(const QByteArray& chain)
++{
++ if (d)
++ d->certificateChain = QSslCertificate::fromData(chain);
++}
++
++void WebSslInfo::setCiphers(const QString& ciphers)
++{
++ if (d)
++ d->ciphers = ciphers;
++}
++
++void WebSslInfo::setUsedCipherBits(const QString& bits)
++{
++ if (d)
++ d->usedCipherBits = bits.toInt();
++}
++
++void WebSslInfo::setSupportedCipherBits(const QString& bits)
++{
++ if (d)
++ d->supportedCipherBits = bits.toInt();
++}
++
++void WebSslInfo::setCertificateErrors(const QString& certErrors)
++{
++ if (d)
++ d->certErrors = certErrors;
++}
+diff --git b/webkitpart/src/websslinfo.h b/webkitpart/src/websslinfo.h
+new file mode 100644
+index 000000000..7c7d09ca7
+--- /dev/null
++++ b/webkitpart/src/websslinfo.h
+@@ -0,0 +1,70 @@
++/*
++ * This file is part of the KDE project.
++ *
++ * Copyright (C) 2009 Dawit Alemayehu <adawit@kde.org>
++ *
++ * 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 <http://www.gnu.org/licenses/>.
++ *
++ */
++#ifndef WEBSSLINFO_H
++#define WEBSSLINFO_H
++
++//#include <kdemacros.h>
++
++#include <QUrl>
++#include <QList>
++#include <QString>
++#include <QHostAddress>
++#include <QSslCertificate>
++
++class WebSslInfo
++{
++public:
++ WebSslInfo();
++ WebSslInfo(const WebSslInfo&);
++ virtual ~WebSslInfo();
++
++ bool isValid() const;
++ QUrl url() const;
++ QHostAddress peerAddress() const;
++ QHostAddress parentAddress() const;
++ QString ciphers() const;
++ QString protocol() const;
++ QString certificateErrors() const;
++ int supportedChiperBits () const;
++ int usedChiperBits () const;
++ QList<QSslCertificate> certificateChain() const;
++
++ bool saveTo(QMap<QString, QVariant>&) const;
++ void restoreFrom(const QVariant &, const QUrl& = QUrl(), bool reset = false);
++
++ void setUrl (const QUrl &url);
++ WebSslInfo& operator = (const WebSslInfo&);
++
++protected:
++ void setCiphers(const QString& ciphers);
++ void setProtocol(const QString& protocol);
++ void setPeerAddress(const QString& address);
++ void setParentAddress(const QString& address);
++ void setCertificateChain(const QByteArray& chain);
++ void setCertificateErrors(const QString& certErrors);
++ void setUsedCipherBits(const QString& bits);
++ void setSupportedCipherBits(const QString& bits);
++
++private:
++ class WebSslInfoPrivate;
++ WebSslInfoPrivate* d;
++};
++
++#endif // WEBSSLINFO_H
+diff --git b/webkitpart/testfiles/embed_tag_test.html b/webkitpart/testfiles/embed_tag_test.html
+new file mode 100644
+index 000000000..8afe2d611
+--- /dev/null
++++ b/webkitpart/testfiles/embed_tag_test.html
+@@ -0,0 +1,20 @@
++<html>
++<head>
++ <title> &lt;EMBED&gt; tests</title>
++</head>
++<body>
++ <h1>KDE e.V. Report 2011 Q2</h1>
++ <center>
++ <embed type="application/pdf" src="http://ev.kde.org/reports/ev-quarterly-2011_Q2.pdf" width="75%" height="400"/>
++ </center>
++ <p/>
++ <h1>KDE e.V. Report 2011 Q1</h1>
++ <center>
++ <embed type="application/pdf" src="http://ev.kde.org/reports/ev-quarterly-2011_Q1.pdf" width="75%" height="400"/>
++ </center>
++ <p/>
++ <center>
++ <video src="http://blip.tv/file/get/Sebasje-ThePlasmaDesktopShellInKDE42312.ogv" controls="controls" width="75%" height="450"/>
++ </center>
++</body>
++</html>
+diff --git b/webkitpart/testfiles/form_save_restore_test.html b/webkitpart/testfiles/form_save_restore_test.html
+new file mode 100644
+index 000000000..d1adaeb76
+--- /dev/null
++++ b/webkitpart/testfiles/form_save_restore_test.html
+@@ -0,0 +1,68 @@
++<html>
++<head>
++ <title>Form save restore test</title>
++</head>
++<body>
++
++<form name="testform">
++<label for="testedit">Enter text:</label>
++<input type="text" name="testinputtext" id="testedit">
++<br>
++<label>Check this box</label>
++<input type="checkbox" name="testinputcheckbox" value="checked">
++<br>
++<label>File to upload:</label>
++<input type="file" name="testinputfile">
++<br>
++<input type="radio" name="testinputradio" value="one">One</input>
++<br>
++<input type="radio" name="testinputradio" value="two">Two</input>
++<br>
++<input type="radio" name="testinputradio" value="three">Three</input>
++<br>
++</form>
++
++<p>
++Enter some text in the box below:<br/>
++<textarea name="testtextarea"></textarea>
++</p>
++
++<p>
++Disabled text area:<br/>
++<textarea name="testtextarea" disabled></textarea>
++</p>
++
++<p>
++Read only text area:<br/>
++<textarea name="testtextarea" readonly>This is a read only text area.</textarea>
++</p>
++
++<p>
++Text area with spell check disabled:<br/>
++<textarea name="testtextarea" spellcheck="false"></textarea>
++</p>
++
++<p>
++Choose one:
++<select name="testcombobox">
++<option>First</option>
++<option>Second</option>
++<option>Third</option>
++<option>Fourth</option>
++<option>Fifth</option>
++</select>
++</p><p/>
++
++<p>
++Select one or more items:<br/>
++<select name="testlist" multiple>
++<option>One</option>
++<option>Two</option>
++<option>Three</option>
++<option>Four</option>
++<option>Five</option>
++</select>
++</p>
++
++</body>
++</html>
+diff --git b/webkitpart/testfiles/frameset_test.html b/webkitpart/testfiles/frameset_test.html
+new file mode 100644
+index 000000000..25a295937
+--- /dev/null
++++ b/webkitpart/testfiles/frameset_test.html
+@@ -0,0 +1,9 @@
++<html>
++<head>
++<title>&lt;FRAMESET&gt; test</title>
++</head>
++<frameset cols="120,*">
++ <frame src="frametest/frame_navigation.html" />
++ <frame src="frametest/frame_a.html" name="showframe" />
++</frameset>
++</html>
+diff --git b/webkitpart/testfiles/frametest/frame_a.html b/webkitpart/testfiles/frametest/frame_a.html
+new file mode 100644
+index 000000000..0ea08f3f6
+--- /dev/null
++++ b/webkitpart/testfiles/frametest/frame_a.html
+@@ -0,0 +1,7 @@
++<html>
++<body bgcolor="#8F8FBD">
++
++<h3>Frame A</h3>
++
++</body>
++</html>
+diff --git b/webkitpart/testfiles/frametest/frame_b.html b/webkitpart/testfiles/frametest/frame_b.html
+new file mode 100644
+index 000000000..fe36a8d98
+--- /dev/null
++++ b/webkitpart/testfiles/frametest/frame_b.html
+@@ -0,0 +1,7 @@
++<html>
++<body bgcolor="#EBC79E">
++
++<h3>Frame B</h3>
++
++</body>
++</html>
+\ No newline at end of file
+diff --git b/webkitpart/testfiles/frametest/frame_c.html b/webkitpart/testfiles/frametest/frame_c.html
+new file mode 100644
+index 000000000..3ed0e0e67
+--- /dev/null
++++ b/webkitpart/testfiles/frametest/frame_c.html
+@@ -0,0 +1,7 @@
++<html>
++<body bgcolor="#FFFFCC">
++
++<h3>Frame C</h3>
++<a href="http://www.kde.org">Go to KDE website</a>
++</body>
++</html>
+\ No newline at end of file
+diff --git b/webkitpart/testfiles/frametest/frame_navigation.html b/webkitpart/testfiles/frametest/frame_navigation.html
+new file mode 100644
+index 000000000..3632a0d8b
+--- /dev/null
++++ b/webkitpart/testfiles/frametest/frame_navigation.html
+@@ -0,0 +1,9 @@
++<html>
++<body>
++<a href ="frame_a.html" target ="showframe">Frame a</a><br/>
++<a href ="frame_b.html" target ="showframe">Frame b</a><br/>
++<a href ="frame_c.html" target ="showframe">Frame c</a><br/>
++<a href ="frame_d.html" target ="showframe">Invalid frame</a><br/>
++<a href ="https://bugs.kde.org" target ="showframe">bugs.kde.org</a>
++</body>
++</html>
+\ No newline at end of file
+diff --git b/webkitpart/testfiles/js.html b/webkitpart/testfiles/js.html
+new file mode 100644
+index 000000000..4c03c3473
+--- /dev/null
++++ b/webkitpart/testfiles/js.html
+@@ -0,0 +1,52 @@
++<html>
++<head>
++<title>Javascript Link Tests</title>
++<script type="text/javascript">
++function resize()
++{
++ window.resizeTo(580, 420);
++}
++
++function move()
++{
++ window.moveTo(180, 120);
++}
++
++function promptAndAlertMessage()
++{
++ var message = prompt("Enter a message.", "");
++ alert(message);
++}
++
++function statusMessage()
++{
++ window.status = 'A new status message.';
++}
++
++function openWindow()
++{
++ window.open("about:blank", "NewWindowTest1", "width=300, height=400");
++}
++
++function openWindowFrameTest()
++{
++ var new_window = window.open('about:blank','testpage','width=800,height=600');
++ new_window.location="frameset_test.html";
++}
++
++</script>
++</head>
++<body>
++<script type="text/javascript">
++document.writeln("navigator.appName: " + navigator.appName + "<br />");
++document.writeln("navigator.appVersion: " + navigator.appVersion + "<br />");
++</script>
++<h1>Javascript Link Tests</h1>
++<a href="javascript:resize()">resizeTo</a><br />
++<a href="javascript:move()">moveTo</a><br />
++<a href="javascript:promptAndAlertMessage()">promptAndAlertMessage</a><br />
++<a href="javascript:statusMessage()">status</a><br />
++<a href="javascript:window.open('about:blank', 'NewWindowTest1', 'width=300, height=400')">JS open new window</a><br />
++<a href="javascript:openWindowFrameTest()">JS open new frameset</a><br />
++</body>
++</html>
+diff --git b/webkitpart/testfiles/link_tests.html b/webkitpart/testfiles/link_tests.html
+new file mode 100644
+index 000000000..f2d73007a
+--- /dev/null
++++ b/webkitpart/testfiles/link_tests.html
+@@ -0,0 +1,136 @@
++<html>
++<head>
++ <title>Link Tests</title>
++</head>
++<script type="text/javascript">
++ function delayedRedirect() {
++ setTimeout(window.open("http://kde-look.org/CONTENT/content-files/52338-kÃy.jpg"), 3000)
++ }
++ function openWin(url,name,features) {
++ url = url || ''
++ name = name || ''
++ features = features || 'width=200,height=100'
++ var myWindow = window.open(url,name,features);
++ if (!url) {
++ myWindow.document.write("<p>This is 'myWindow'</p>");
++ myWindow.focus();
++ }
++ }
++</script>
++<body>
++<h2>MAILTO Link Tests</h2>
++ <a href="mailto:joe@xyz.com&amp;CC=bob@xyz.com&amp;BCC=bob@xyz.com&amp;attach=%2Fetc%2Fpasswd&amp;subject=hello&amp;body=hello">Email link #1</a>
++ <br/>
++ <a href="mailto:joe@xyz.com">Email link #2</a>
++ <br/>
++<h2>FTP Link Tests</h2>
++ <a href="ftp://ftp.kde.org" target="_blank">FTP link #1 (new window)</a>
++ <br/>
++ <a href="ftp://ftp.kde.org/pub" target="_blank">FTP link #2 (new window)</a>
++ <br/>
++ <a href="ftp://upload.kde.org">FTP link #3</a>
++ <br/>
++ <a href="ftp://ftp.kde.org/pub/kde/README_UPLOAD">Text File Link</a>
++ <br/>
++ <a href="#fragments" target="_top">Anchor test</a>
++ <br/>
++ <a href="#fragments" target="_blank">Anchor test (new window)</a>
++ <br/>
++<h2>HTTP Link Tests</h2>
++ <a href="http://www.kde.org" target="_blank">Web site link (new window)</a>
++ <br/>
++ <a href="http://foo@www.kde.org">Web site link with bogus username</a>
++ <br/>
++ <a href="http://bar@www.kde.org">Web site link with different bogus username</a>
++ <br/>
++ <a href="http://ev.kde.org/reports/ev-quarterly-2012_Q1.pdf">PDF link</a>
++ <br/>
++ <a href="http://ev.kde.org/reports/ev-quarterly-2012_Q1.pdf" target="_blank">PDF link (new window)</a>
++ <br/>
++ <a href="http://ev.kde.org/reports/ev-quarterly-2012_Q1.pdf" target="_blank">Duplicate PDF link (new window)</a>
++ <br/>
++ <a href="http://blip.tv/file/get/Sebasje-WindowManagingFeaturesInKDEPlasma44222.ogg">Movie link</a>
++ <br/>
++ <a href="http://blip.tv/file/get/Sebasje-WindowManagingFeaturesInKDEPlasma44222.ogg" target="_blank">Movie link (new window)</a>
++ <br/>
++ <a href="http://www.ietf.org/rfc/rfc2344.txt">Text Document Link</a>
++ <br/>
++ <a href="http://www.microsoft.com%26item%3Dq209354rexsddiuyjkiuylkuryt2583453453fsesfsdfsfasfdfdsf@www.kde.org/">Bogus link</a>
++ <br/>
++<h2>Javascript Link Tests</h2>
++ <a href="javascript:openWin('http://www.kde.org','', 'width=600,height=600,statusbar=no,toolbar=no')">Open dialog like window link #1</a>
++ <br/>
++ <a href="javascript:openWin('file:///usr/local/src/KDE/git/extragear/kwebkitpart/tests/link_tests.html','','dialog','width=600,height=600,statusbar=no,toolbar=no')">Open dialog like window link #2</a>
++ <br/>
++ <a href="javascript:openWin('http://www.kde.org','', 'width=0,height=0')">Open new window link #2 (might be opened as Tab)</a>
++ <br/>
++ <a href="javascript:openWin('http://ev.kde.org/reports/ev-quarterly-2009Q1.pdf', '_blank', 'width=600,height=600,statusbar=no,toolbar=no')">Open PDF Document (new window)</a>
++ <br/>
++ <a href='empty.html' onclick="openWin('empty.html', 'dz_orders','toolbar=false,height=100,width=100,resizable=1,scrollbars=1')" target='dz_orders'>Javscript + Target test</a>
++ <br/>
++ <a href="javascript:window.close">Close window</a>
++ <br/>
++ <a href="" onmouseover="openWin()">On mouse over open window test</a>
++ <br/>
++ <a href="javascript:setTimeout(delayedRedirect(), 3000)" target="_blank">Redirect test</a>
++ <br/>
++<h2>KDE specific URL Tests</h2>
++ <a href="applications:/Internet/">Text Document Link</a>
++ <br/>
++<h2>Form Tests</h2>
++ <form action="mailto:someone@example.com?CC='bob@example.com&amp;attach=%2fetc%2fpasswd&amp;body=" method="post" enctype="application/x-www-form-urlencoded">
++ Choose file to upload:<br />
++ <input type="file" name="upload_file" size="20" /><br/>
++ <input type="submit" value="Send" />
++ <input type="reset" value="Reset" />
++ </form>
++ <br/>
++ <a name="fragments"><h2>URL Fragment Test</h2></a>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++ <br/>
++</body>
++</html>
+diff --git b/webkitpart/testfiles/meta_tag_refresh_test.html b/webkitpart/testfiles/meta_tag_refresh_test.html
+new file mode 100644
+index 000000000..4ea95a59c
+--- /dev/null
++++ b/webkitpart/testfiles/meta_tag_refresh_test.html
+@@ -0,0 +1,14 @@
++<html>
++<head>
++ <title>Meta redirect test</title>
++ <meta HTTP-EQUIV="Refresh" CONTENT="10;URL=http://kde.org">
++</head>
++<body>
++You will be redirected to <a href="http://www.kde.org">kde.org</a> in 10 seconds.<br/>
++<p>
++If the stop button is active (not disabled) after the page has completely loaded, it
++means the rendering engine allows you to cancel &lt;META&gt; based redirect requests.
++Otherwise, you are not able to stop redirects or refresh requests set by web pages.
++</p>
++</body>
++</html>
+\ No newline at end of file
+diff --git b/webkitpart/tests/CMakeLists.txt b/webkitpart/tests/CMakeLists.txt
+new file mode 100644
+index 000000000..85d8f12c6
+--- /dev/null
++++ b/webkitpart/tests/CMakeLists.txt
+@@ -0,0 +1,2 @@
++add_executable(webkitpart_tester webkitpart_tester.cpp)
++target_link_libraries(webkitpart_tester kwebkitpartlib Qt5::Core Qt5::Gui Qt5::Widgets Qt5::WebKitWidgets KF5::I18n KF5::KDELibs4Support)
+diff --git b/webkitpart/tests/webkitpart_tester.cpp b/webkitpart/tests/webkitpart_tester.cpp
+new file mode 100644
+index 000000000..e4c1e45f6
+--- /dev/null
++++ b/webkitpart/tests/webkitpart_tester.cpp
+@@ -0,0 +1,437 @@
++/*
++ * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
++ * Copyright (C) 2006 George Staikos <staikos@kde.org>
++ * Copyright (C) 2006 Dirk Mueller <mueller@kde.org>
++ * Copyright (C) 2006 Zack Rusin <zack@kde.org>
++ * Copyright (C) 2006 Simon Hausmann <hausmann@kde.org>
++ *
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ *
++ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
++ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
++ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
++ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
++ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
++ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#include <KApplication>
++#include <KAboutData>
++#include <KCmdLineArgs>
++#include <KDebug>
++#include <KIO/AccessManager>
++#include <KUriFilter>
++#include <KInputDialog>
++#include <KLineEdit>
++#include <webkitpart.h>
++
++#include <QInputDialog>
++
++//#include <QUiLoader>
++//#include <QWebPage>
++#include <QWebView>
++//#include <QWebFrame>
++#include <QWebSettings>
++//#include <QWebElement>
++//#include <QWebElementCollection>
++
++#if !defined(QT_NO_PRINTER)
++#include <QPrintPreviewDialog>
++#endif
++
++#include <QAction>
++#include <QCompleter>
++#include <QMainWindow>
++#include <QMenu>
++#include <QMenuBar>
++#include <QProgressBar>
++#include <QStatusBar>
++#include <QStringListModel>
++#include <QToolBar>
++#include <QToolTip>
++#include <QDir>
++#include <QFile>
++#include <QVector>
++#include <QTextStream>
++#include <QApplication>
++#include <KAboutData>
++#include <KLocalizedString>
++#include <QCommandLineParser>
++
++
++class MainWindow : public QMainWindow
++{
++ Q_OBJECT
++public:
++ MainWindow(const QString& url = QString()): currentZoom(100) {
++ view = new WebKitPart(this);
++ setCentralWidget(view->widget());
++
++ connect(view->view(), &QWebView::loadFinished,
++ this, &MainWindow::loadFinished);
++ connect(view->view(), SIGNAL(titleChanged(QString)),
++ this, SLOT(setWindowTitle(QString)));
++ connect(view->view()->page(), SIGNAL(linkHovered(QString)),
++ this, SLOT(showLinkHover(QString)));
++ connect(view->view()->page(), SIGNAL(windowCloseRequested()), this, SLOT(deleteLater()));
++
++ setupUI();
++
++ QUrl qurl(KUriFilter::self()->filteredUri(url, QStringList() << QStringLiteral("kshorturifilter")));
++ if (qurl.isValid()) {
++ urlEdit->setText(qurl.toEncoded());
++ view->openUrl(qurl);
++
++ // the zoom values are chosen to be like in Mozilla Firefox 3
++ zoomLevels << 30 << 50 << 67 << 80 << 90;
++ zoomLevels << 100;
++ zoomLevels << 110 << 120 << 133 << 150 << 170 << 200 << 240 << 300;
++ }
++ }
++
++ QWebPage* webPage() const {
++ return view->view()->page();
++ }
++
++ QWebView* webView() const {
++ return view->view();
++ }
++
++protected slots:
++
++ void changeLocation() {
++ QUrl url (KUriFilter::self()->filteredUri(urlEdit->text(), QStringList() << QStringLiteral("kshorturifilter")));
++ view->openUrl(url);
++ view->view()->setFocus(Qt::OtherFocusReason);
++ }
++
++ void loadFinished() {
++ urlEdit->setText(view->url().toString());
++
++ QUrl::FormattingOptions opts;
++ opts |= QUrl::RemoveScheme;
++ opts |= QUrl::RemoveUserInfo;
++ opts |= QUrl::StripTrailingSlash;
++ QString s = view->url().toString(opts);
++ s = s.mid(2);
++ if (s.isEmpty())
++ return;
++
++ if (!urlList.contains(s))
++ urlList += s;
++ urlModel.setStringList(urlList);
++ }
++
++ void showLinkHover(const QString &link) {
++ statusBar()->showMessage(link);
++ }
++
++ void zoomIn() {
++ int i = zoomLevels.indexOf(currentZoom);
++ Q_ASSERT(i >= 0);
++ if (i < zoomLevels.count() - 1)
++ currentZoom = zoomLevels[i + 1];
++
++ view->view()->setZoomFactor(qreal(currentZoom)/100.0);
++ }
++
++ void zoomOut() {
++ int i = zoomLevels.indexOf(currentZoom);
++ Q_ASSERT(i >= 0);
++ if (i > 0)
++ currentZoom = zoomLevels[i - 1];
++
++ view->view()->setZoomFactor(qreal(currentZoom)/100.0);
++ }
++
++ void resetZoom()
++ {
++ currentZoom = 100;
++ view->view()->setZoomFactor(1.0);
++ }
++
++ void toggleZoomTextOnly(bool b)
++ {
++// view->view()->page()->settings()->setAttribute(QWebSettings::ZoomTextOnly, b);
++ }
++
++ void print() {
++#if !defined(QT_NO_PRINTER)
++ QScopedPointer<QPrintPreviewDialog> dlg (new QPrintPreviewDialog(this));
++ connect(dlg.data(), SIGNAL(paintRequested(QPrinter*)),
++ view, SLOT(print(QPrinter*)));
++ dlg->exec();
++#endif
++ }
++
++ void setEditable(bool on) {
++// view->view()->page()->setContentEditable(on);
++ formatMenuAction->setVisible(on);
++ }
++
++ void dumpHtml() {
++ view->view()->page()->toHtml([](const QString& text) {
++ kDebug() << "HTML: " << text;
++ });
++ }
++
++ void selectElements() {
++ bool ok;
++ QString str = QInputDialog::getText(this, i18nc("input dialog window title for selecting html elements", "Select elements"),
++ i18nc("input dialog text for selecting html elements", "Choose elements"), QLineEdit::Normal,
++ QStringLiteral("a"), &ok);
++ if (ok && !str.isEmpty()) {
++ //QWebElementCollection collection = view->page()->mainFrame()->findAllElements(str);
++ //const int count = collection.count();
++ //for (int i=0; i < count; i++)
++ // collection.at(i).setStyleProperty("background-color", "yellow");
++ //statusBar()->showMessage(i18np("%1 element selected", "%1 elements selected", count), 5000);
++ }
++ }
++
++public slots:
++
++ void newWindow(const QString &url = QString()) {
++ MainWindow *mw = new MainWindow(url);
++ mw->show();
++ }
++
++private:
++
++ QVector<int> zoomLevels;
++ int currentZoom;
++
++ // create the status bar, tool bar & menu
++ void setupUI() {
++ progress = new QProgressBar(this);
++ progress->setRange(0, 100);
++ progress->setMinimumSize(100, 20);
++ progress->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
++ progress->hide();
++ statusBar()->addPermanentWidget(progress);
++
++ connect(view->view(), SIGNAL(loadProgress(int)), progress, SLOT(show()));
++ connect(view->view(), SIGNAL(loadProgress(int)), progress, SLOT(setValue(int)));
++ connect(view->view(), SIGNAL(loadFinished(bool)), progress, SLOT(hide()));
++
++ urlEdit = new KLineEdit(this);
++ urlEdit->setSizePolicy(QSizePolicy::Expanding, urlEdit->sizePolicy().verticalPolicy());
++ connect(urlEdit, SIGNAL(returnPressed()),
++ SLOT(changeLocation()));
++ QCompleter *completer = new QCompleter(this);
++ urlEdit->setCompleter(completer);
++ completer->setModel(&urlModel);
++
++ QToolBar *bar = addToolBar(QStringLiteral("Navigation"));
++ bar->addAction(view->view()->pageAction(QWebPage::Back));
++ bar->addAction(view->view()->pageAction(QWebPage::Forward));
++ bar->addAction(view->view()->pageAction(QWebPage::Reload));
++ bar->addAction(view->view()->pageAction(QWebPage::Stop));
++ bar->addWidget(urlEdit);
++
++ QMenu *fileMenu = menuBar()->addMenu(i18n("&File"));
++ QAction *newWindow = fileMenu->addAction(i18n("New Window"), this, SLOT(newWindow()));
++
++ fileMenu->addAction(i18n("Print"), this, SLOT(print()));
++ fileMenu->addAction(i18n("Close"), this, SLOT(close()));
++
++ QMenu *editMenu = menuBar()->addMenu(i18n("&Edit"));
++ editMenu->addAction(view->view()->pageAction(QWebPage::Undo));
++ editMenu->addAction(view->view()->pageAction(QWebPage::Redo));
++ editMenu->addSeparator();
++ editMenu->addAction(view->view()->pageAction(QWebPage::Cut));
++ editMenu->addAction(view->view()->pageAction(QWebPage::Copy));
++ editMenu->addAction(view->view()->pageAction(QWebPage::Paste));
++ editMenu->addSeparator();
++ QAction *setEditable = editMenu->addAction(i18n("Set Editable"), this, SLOT(setEditable(bool)));
++ setEditable->setCheckable(true);
++
++ QMenu *viewMenu = menuBar()->addMenu(i18n("&View"));
++ viewMenu->addAction(view->view()->pageAction(QWebPage::Stop));
++ viewMenu->addAction(view->view()->pageAction(QWebPage::Reload));
++ viewMenu->addSeparator();
++ QAction *zoomIn = viewMenu->addAction(i18n("Zoom &In"), this, SLOT(zoomIn()));
++ QAction *zoomOut = viewMenu->addAction(i18n("Zoom &Out"), this, SLOT(zoomOut()));
++ QAction *resetZoom = viewMenu->addAction(i18n("Reset Zoom"), this, SLOT(resetZoom()));
++ QAction *zoomTextOnly = viewMenu->addAction(i18n("Zoom Text Only"), this, SLOT(toggleZoomTextOnly(bool)));
++ zoomTextOnly->setCheckable(true);
++ zoomTextOnly->setChecked(false);
++ viewMenu->addSeparator();
++ viewMenu->addAction(i18n("Dump HTML"), this, SLOT(dumpHtml()));
++
++#if 0
++ QMenu *formatMenu = new QMenu(i18n("F&ormat"));
++ formatMenuAction = menuBar()->addMenu(formatMenu);
++ formatMenuAction->setVisible(false);
++ formatMenu->addAction(view->view()->pageAction(QWebPage::ToggleBold));
++ formatMenu->addAction(view->view()->pageAction(QWebPage::ToggleItalic));
++ formatMenu->addAction(view->view()->pageAction(QWebPage::ToggleUnderline));
++ QMenu *writingMenu = formatMenu->addMenu(i18n("Writing Direction"));
++ writingMenu->addAction(view->view()->pageAction(QWebPage::SetTextDirectionDefault));
++ writingMenu->addAction(view->view()->pageAction(QWebPage::SetTextDirectionLeftToRight));
++ writingMenu->addAction(view->view()->pageAction(QWebPage::SetTextDirectionRightToLeft));
++#endif
++ newWindow->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_N));
++ view->view()->pageAction(QWebPage::Back)->setShortcut(QKeySequence::Back);
++ view->view()->pageAction(QWebPage::Stop)->setShortcut(Qt::Key_Escape);
++ view->view()->pageAction(QWebPage::Forward)->setShortcut(QKeySequence::Forward);
++ view->view()->pageAction(QWebPage::Reload)->setShortcut(QKeySequence::Refresh);
++ view->view()->pageAction(QWebPage::Undo)->setShortcut(QKeySequence::Undo);
++ view->view()->pageAction(QWebPage::Redo)->setShortcut(QKeySequence::Redo);
++ view->view()->pageAction(QWebPage::Cut)->setShortcut(QKeySequence::Cut);
++ view->view()->pageAction(QWebPage::Copy)->setShortcut(QKeySequence::Copy);
++ view->view()->pageAction(QWebPage::Paste)->setShortcut(QKeySequence::Paste);
++ zoomIn->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Plus));
++ zoomOut->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Minus));
++ resetZoom->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_0));
++// view->view()->pageAction(QWebPage::ToggleBold)->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_B));
++// view->view()->pageAction(QWebPage::ToggleItalic)->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_I));
++// view->view()->pageAction(QWebPage::ToggleUnderline)->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_U));
++
++ QMenu *toolsMenu = menuBar()->addMenu(i18n("&Tools"));
++ toolsMenu->addAction(i18n("Select elements..."), this, SLOT(selectElements()));
++
++ }
++
++ WebKitPart *view;
++ KLineEdit *urlEdit;
++ QProgressBar *progress;
++
++ QAction *formatMenuAction;
++
++ QStringList urlList;
++ QStringListModel urlModel;
++};
++
++class URLLoader : public QObject
++{
++ Q_OBJECT
++public:
++ URLLoader(QWebView* view, const QString& inputFileName)
++ : m_view(view)
++ , m_stdOut(stdout)
++ {
++ init(inputFileName);
++ }
++
++public slots:
++ void loadNext()
++ {
++ QString qstr;
++ if (getUrl(qstr)) {
++ QUrl url(qstr, QUrl::StrictMode);
++ if (url.isValid()) {
++ m_stdOut << "Loading " << qstr << " ......" << endl;
++ m_view->load(url);
++ } else
++ loadNext();
++ } else
++ disconnect(m_view, 0, this, 0);
++ }
++
++private:
++ void init(const QString& inputFileName)
++ {
++ QFile inputFile(inputFileName);
++ if (inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
++ QTextStream stream(&inputFile);
++ QString line;
++ while (true) {
++ line = stream.readLine();
++ if (line.isNull())
++ break;
++ m_urls.append(line);
++ }
++ } else {
++ kDebug() << "Can't open list file";
++ exit(0);
++ }
++ m_index = 0;
++ inputFile.close();
++ }
++
++ bool getUrl(QString& qstr)
++ {
++ if (m_index == m_urls.size())
++ return false;
++
++ qstr = m_urls[m_index++];
++ return true;
++ }
++
++private:
++ QVector<QString> m_urls;
++ int m_index;
++ QWebView* m_view;
++ QTextStream m_stdOut;
++};
++
++
++int main(int argc, char **argv)
++{
++ KAboutData about(QStringLiteral("KDELauncher"), i18n("KDELauncher"), QStringLiteral("0.0000013"));
++ QApplication app(argc, argv);
++ QCommandLineParser parser;
++ KAboutData::setApplicationData(about);
++ parser.addVersionOption();
++ parser.addHelpOption();
++ //PORTING SCRIPT: adapt aboutdata variable if necessary
++ about.setupCommandLine(&parser);
++ parser.process(app);
++ about.processCommandLine(&parser);
++
++ QString url = QStringLiteral("%1/%2").arg(QDir::homePath()).arg(QStringLiteral("index.html"));
++
++// QWebSettings::globalSettings()->setMaximumPagesInCache(4);
++
++// QWebSettings::setObjectCacheCapacities((16*1024*1024) / 8, (16*1024*1024) / 8, 16*1024*1024);
++
++ QWebSettings::globalSettings()->setAttribute(QWebSettings::PluginsEnabled, true);
++// QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
++
++ const QStringList args = app.arguments();
++
++ if (args.contains(QStringLiteral("-r"))) {
++ // robotized
++ QString listFile = args.at(2);
++ if (!(args.count() == 3) && QFile::exists(listFile)) {
++ kDebug() << "Usage: KDELauncher -r listfile";
++ exit(0);
++ }
++ MainWindow window;
++ QWebView *view = window.webView();
++ URLLoader loader(view, listFile);
++ QObject::connect(view, SIGNAL(loadFinished(bool)), &loader, SLOT(loadNext()));
++ loader.loadNext();
++ window.show();
++ return app.exec();
++ } else {
++ if (args.count() > 1)
++ url = args.at(1);
++
++ MainWindow window(url);
++
++ // Opens every given urls in new windows
++ for (int i = 2; i < args.count(); i++)
++ window.newWindow(args.at(i));
++
++ window.show();
++ return app.exec();
++ }
++}
++
++#include "webkitpart_tester.moc"
+diff --git b/webkitpart/webkitpart.lsm b/webkitpart/webkitpart.lsm
+new file mode 100644
+index 000000000..1b94c5a24
+--- /dev/null
++++ b/webkitpart/webkitpart.lsm
+@@ -0,0 +1,18 @@
++Begin3
++Title: webkitpart
++Version: 1.2.0
++Entered-date: 06APR2011
++Description: A WebKit browser component for KDE (KPart)
++Keywords: webkit, webkitpart
++Author: Trolltech ASA
++ Urs Wolfer <uwolfer @ kde.org>
++ Laurent Montel <montel@kde.org>
++ Dawit Alemayehu <adawit@kde.org>
++ Sune Vuorela <sune@kde.org>
++Maintained-by: Sune Vuorela <sune@kde.org>
++Primary-site:
++Home-Page:
++Original-site: None
++Platforms: KF5 and higher
++Copying-policy: LGPL
++End