diff --git a/resources/rssguard.qrc b/resources/rssguard.qrc
index 664e2cb00..b43cf2970 100644
--- a/resources/rssguard.qrc
+++ b/resources/rssguard.qrc
@@ -9,6 +9,7 @@
text/COPYING_GNU_LGPL_21
text/COPYING_QT
+ scripts/builtin_js/observer.js
scripts/web_ui/rssguard.html
sounds/boing.wav
diff --git a/src/librssguard/definitions/definitions.h b/src/librssguard/definitions/definitions.h
index ec2d818c0..3bf71dc26 100644
--- a/src/librssguard/definitions/definitions.h
+++ b/src/librssguard/definitions/definitions.h
@@ -362,6 +362,9 @@
#define APP_SQL_PATH QSL(":/sql")
#define APP_INFO_PATH QSL(":/text")
+#define BUILTIN_JS_FOLDER QSL(":/scripts/builtin_js")
+#define OBSERVER_JS_FILE QSL("observer.js")
+
#define WEB_UI_FOLDER QSL(":/scripts/web_ui")
#define WEB_UI_FILE QSL("rssguard.html")
diff --git a/src/librssguard/gui/webviewers/webengine/webengineviewer.cpp b/src/librssguard/gui/webviewers/webengine/webengineviewer.cpp
index f3b14c83d..73cce39cc 100644
--- a/src/librssguard/gui/webviewers/webengine/webengineviewer.cpp
+++ b/src/librssguard/gui/webviewers/webengine/webengineviewer.cpp
@@ -15,6 +15,7 @@
#include "network-web/webfactory.h"
#include
+#include
#include
#include
#include
@@ -201,6 +202,36 @@ QUrl WebEngineViewer::url() const {
return QWebEngineView::url();
}
+QByteArray WebEngineViewer::getJsEnabledHtml(QObject* parent, const QString& url) {
+ QByteArray res;
+
+ QMetaObject::invokeMethod(
+ qApp,
+ [&] {
+ QGraphicsScene* scene = new QGraphicsScene(parent);
+ QGraphicsView* view = new QGraphicsView(scene, qApp->mainFormWidget());
+
+ WebEngineViewer* viewer = new WebEngineViewer(qApp->mainFormWidget());
+ WebEnginePage* page = new WebEnginePage(viewer);
+
+ scene->addWidget(viewer);
+
+ viewer->resize(3800, 2100);
+ view->show();
+ viewer->setPage(page);
+
+ res = page->pageHtml(url).toUtf8();
+
+ delete scene;
+ // delete view;
+ // delete viewer;
+ // delete viewer;
+ },
+ Qt::ConnectionType::BlockingQueuedConnection);
+
+ return res;
+}
+
ContextMenuData WebEngineViewer::provideContextMenuData(QContextMenuEvent* event) const {
#if QT_VERSION_MAJOR == 6
auto* menu_pointer = lastContextMenuRequest();
diff --git a/src/librssguard/gui/webviewers/webengine/webengineviewer.h b/src/librssguard/gui/webviewers/webengine/webengineviewer.h
index 022c7ab2f..0d9e027e2 100644
--- a/src/librssguard/gui/webviewers/webengine/webengineviewer.h
+++ b/src/librssguard/gui/webviewers/webengine/webengineviewer.h
@@ -37,6 +37,8 @@ class WebEngineViewer : public QWebEngineView, public WebViewer {
virtual QString html() const;
virtual QUrl url() const;
+ static QByteArray getJsEnabledHtml(QObject* parent, const QString& url);
+
signals:
void pageTitleChanged(const QString& new_title);
void pageUrlChanged(const QUrl& url);
diff --git a/src/librssguard/network-web/webengine/webenginepage.cpp b/src/librssguard/network-web/webengine/webenginepage.cpp
index 614417c54..d975ddc49 100644
--- a/src/librssguard/network-web/webengine/webenginepage.cpp
+++ b/src/librssguard/network-web/webengine/webenginepage.cpp
@@ -34,16 +34,20 @@ WebEngineViewer* WebEnginePage::view() const {
QString WebEnginePage::pageHtml(const QString& url) {
QEventLoop loop;
QString html;
- QTimer tmr;
- tmr.setInterval(15000);
-
- connect(&tmr, &QTimer::timeout, &loop, &QEventLoop::quit);
- connect(this, &WebEnginePage::loadFinished, &tmr, QOverload<>::of(&QTimer::start));
+ // Load initial DOM/page.
+ connect(this, &WebEnginePage::loadFinished, &loop, &QEventLoop::quit);
+ connect(this, &WebEnginePage::domIsIdle, &loop, &QEventLoop::quit);
load(url);
loop.exec();
+ // Page is loaded. Send artificial scroll-to-bottom and wait for changes to end.
+
+ runJavaScript("window.resizeTo(3800, 2100);");
+ runJavaScript(IOFactory::readFile(BUILTIN_JS_FOLDER + QL1C('/') + OBSERVER_JS_FILE));
+ loop.exec();
+
toHtml([&](const QString& htm) {
html = htm;
loop.exit();
@@ -100,4 +104,8 @@ void WebEnginePage::javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level
Q_UNUSED(level)
qWarningNN << LOGSEC_JS << message << QSL(" (source: %1:%2)").arg(source_id, QString::number(line_number));
+
+ if (message.contains(QSL("iiddllee"))) {
+ emit domIsIdle();
+ }
}
diff --git a/src/librssguard/network-web/webengine/webenginepage.h b/src/librssguard/network-web/webengine/webenginepage.h
index 343230fc3..4add531a8 100644
--- a/src/librssguard/network-web/webengine/webenginepage.h
+++ b/src/librssguard/network-web/webengine/webenginepage.h
@@ -15,6 +15,9 @@ class WebEnginePage : public QWebEnginePage {
WebEngineViewer* view() const;
+ signals:
+ void domIsIdle();
+
public slots:
QString pageHtml(const QString& url);
diff --git a/src/librssguard/services/standard/standardfeed.cpp b/src/librssguard/services/standard/standardfeed.cpp
index 82b631a5b..7fcaf553b 100644
--- a/src/librssguard/services/standard/standardfeed.cpp
+++ b/src/librssguard/services/standard/standardfeed.cpp
@@ -205,7 +205,7 @@ QString StandardFeed::sourceTypeToString(StandardFeed::SourceType type) {
return tr("Local file");
case StandardFeed::SourceType::EmbeddedBrowser:
- return tr("Built-in web browser");
+ return tr("Built-in web browser with JavaScript support");
default:
return tr("Unknown");
@@ -297,17 +297,7 @@ StandardFeed* StandardFeed::guessFeed(StandardFeed::SourceType source_type,
}
else if (source_type == StandardFeed::SourceType::EmbeddedBrowser) {
#if defined(NO_LITE)
- WebEnginePage page;
- WebEngineViewer viewer;
-
- // NOTE: Viewer must be present or JavaScript just does not run.
- viewer.setPage(&page);
- viewer.setAttribute(Qt::WA_DontShowOnScreen);
- viewer.show();
-
- feed_contents = page.pageHtml(source).toUtf8();
-
- // IOFactory::writeFile("a.html", feed_contents);
+ feed_contents = WebEngineViewer::getJsEnabledHtml(qApp, source);
#else
throw ApplicationException(tr("this source type cannot be used on 'lite' %1 build").arg(QSL(APP_NAME)));
#endif
diff --git a/src/librssguard/services/standard/standardserviceroot.cpp b/src/librssguard/services/standard/standardserviceroot.cpp
index a36048f4e..df1f03214 100644
--- a/src/librssguard/services/standard/standardserviceroot.cpp
+++ b/src/librssguard/services/standard/standardserviceroot.cpp
@@ -257,9 +257,20 @@ QList StandardServiceRoot::obtainNewMessages(Feed* feed,
page->moveToThread(qApp->thread());
viewer->setPage(page);
- viewer->setAttribute(Qt::WA_DontShowOnScreen);
+ viewer->setAttribute(Qt::WidgetAttribute::WA_DontShowOnScreen, true);
+ viewer->setAttribute(Qt::WidgetAttribute::WA_DontShowOnScreen, true);
+ viewer->setAttribute(Qt::WidgetAttribute::WA_DeleteOnClose, true);
- QMetaObject::invokeMethod(viewer, "show", Qt::ConnectionType::BlockingQueuedConnection);
+ // QMetaObject::invokeMethod(viewer, "show", Qt::ConnectionType::BlockingQueuedConnection);
+
+ QMetaObject::invokeMethod(
+ viewer,
+ [&] {
+ viewer->show();
+ viewer->resize(3800, 2100);
+ // viewer->hide();
+ },
+ Qt::ConnectionType::BlockingQueuedConnection);
QString html;
QMetaObject::invokeMethod(page,
@@ -271,7 +282,8 @@ QList StandardServiceRoot::obtainNewMessages(Feed* feed,
feed_contents = html.toUtf8();
page->deleteLater();
- viewer->deleteLater();
+ viewer->close();
+ // viewer->deleteLater();
#else
throw ApplicationException(tr("this source type cannot be used on 'lite' %1 build").arg(QSL(APP_NAME)));
#endif