diff --git a/inc/liquidappconfigwindow.hpp b/inc/liquidappconfigwindow.hpp index 7e44562..517d65d 100644 --- a/inc/liquidappconfigwindow.hpp +++ b/inc/liquidappconfigwindow.hpp @@ -57,6 +57,7 @@ public slots: // JavaScript tab QCheckBox* enableJavaScriptCheckBox; + QCheckBox* enableLocalStorageCheckBox; QLabel* additionalJsLabel; QPlainTextEdit* additionalJsTextArea; diff --git a/inc/liquidappwebpage.hpp b/inc/liquidappwebpage.hpp index 1f411ee..d7e8f81 100644 --- a/inc/liquidappwebpage.hpp +++ b/inc/liquidappwebpage.hpp @@ -27,6 +27,7 @@ class LiquidAppWebPage : public QWebEnginePage void javaScriptAlert(const QUrl& securityOrigin, const QString& msg) override; bool javaScriptConfirm(const QUrl& securityOrigin, const QString& msg) override; bool javaScriptPrompt(const QUrl& securityOrigin, const QString& msg, const QString& defaultValue, QString* result) override; + // TODO: windowCloseRequested QWebEngineProfile* liquidAppWebProfile = Q_NULLPTR; LiquidAppWindow* liquidAppWindow = Q_NULLPTR; diff --git a/inc/lqd.h b/inc/lqd.h index cb6a8b2..452fc68 100644 --- a/inc/lqd.h +++ b/inc/lqd.h @@ -50,6 +50,8 @@ #define LQD_CFG_KEY_NAME_LOCK_WIN_GEOM "LockWindowGeometry" // boolean, defaults to FALSE #define LQD_CFG_KEY_NAME_MUTE_AUDIO "MuteAudio" // boolean, defaults to FALSE #define LQD_CFG_KEY_NAME_NOTES "Notes" // text +#define LQD_CFG_KEY_NAME_PRESERVE_COOKIES "PreserveCookies" // boolean, defaults to FALSE +#define LQD_CFG_KEY_NAME_PRESERVE_LOCAL_STORAGE "PreserveLocalStorage" // boolean, defaults to FALSE #define LQD_CFG_KEY_NAME_PROXY_HOST LQD_CFG_GROUP_NAME_PROXY "/" "Host" // text #define LQD_CFG_KEY_NAME_PROXY_PORT LQD_CFG_GROUP_NAME_PROXY "/" "Port" // number #define LQD_CFG_KEY_NAME_PROXY_USE_AUTH LQD_CFG_GROUP_NAME_PROXY "/" "UseAuthentication" // boolean, defaults to FALSE diff --git a/src/liquidappconfigwindow.cpp b/src/liquidappconfigwindow.cpp index 60a34b4..a507ab1 100644 --- a/src/liquidappconfigwindow.cpp +++ b/src/liquidappconfigwindow.cpp @@ -425,20 +425,55 @@ LiquidAppConfigDialog::LiquidAppConfigDialog(QWidget* parent, QString liquidAppN jsTabWidget->setLayout(jsTabWidgetLayout); tabWidget->addTab(jsTabWidget, tr("JavaScript")); - // Enable JavaScript checkbox + // Enable JavaScript & enable local storage checkboxes { - enableJavaScriptCheckBox = new QCheckBox(tr("Enable JavaScript"), this); - enableJavaScriptCheckBox->setCursor(Qt::PointingHandCursor); + // Enable JavaScript checkbox + { + enableJavaScriptCheckBox = new QCheckBox(tr("Enable JavaScript"), this); + enableJavaScriptCheckBox->setCursor(Qt::PointingHandCursor); - if (isEditingExistingBool) { - bool isChecked = existingLiquidAppConfig->value(LQD_CFG_KEY_NAME_ENABLE_JS).toBool(); - enableJavaScriptCheckBox->setChecked(isChecked); - } else { - // Checked by default (when creating new Liquid app) - enableJavaScriptCheckBox->setChecked(true); + if (isEditingExistingBool) { + bool isChecked = existingLiquidAppConfig->value(LQD_CFG_KEY_NAME_ENABLE_JS).toBool(); + enableJavaScriptCheckBox->setChecked(isChecked); + } else { + // Checked by default (when creating new Liquid app) + enableJavaScriptCheckBox->setChecked(true); + } + + jsTabWidgetLayout->addWidget(enableJavaScriptCheckBox); } - jsTabWidgetLayout->addWidget(enableJavaScriptCheckBox); + // Enable local storage checkbox + { + QHBoxLayout* enableLocalStorageLayout = new QHBoxLayout(); + enableLocalStorageLayout->setContentsMargins(LQD_UI_MARGIN, 0, 0, 0); + + enableLocalStorageCheckBox = new QCheckBox(tr("Save and restore local storage data"), this); + enableLocalStorageCheckBox->setCursor(Qt::PointingHandCursor); + + if (isEditingExistingBool) { + bool isChecked = existingLiquidAppConfig->value(LQD_CFG_KEY_NAME_PRESERVE_LOCAL_STORAGE).toBool(); + enableLocalStorageCheckBox->setChecked(isChecked); + } else { + // Checked by default (when creating new Liquid app) + enableLocalStorageCheckBox->setChecked(true); + } + + enableLocalStorageLayout->addWidget(enableLocalStorageCheckBox); + + connect(enableJavaScriptCheckBox, &QCheckBox::toggled, [&](const bool isOn){ + if (!isOn) { + enableLocalStorageCheckBox->setChecked(false); + } + }); + connect(enableLocalStorageCheckBox, &QCheckBox::toggled, [&](const bool isOn){ + if (isOn) { + enableJavaScriptCheckBox->setChecked(isOn); + } + }); + + jsTabWidgetLayout->addLayout(enableLocalStorageLayout); + } } // Additonal JavaScript code text area @@ -821,6 +856,11 @@ void LiquidAppConfigDialog::save() tempLiquidAppConfig->setValue(LQD_CFG_KEY_NAME_ENABLE_JS, enableJavaScriptCheckBox->isChecked()); } + // Preserve local storage + { + tempLiquidAppConfig->setValue(LQD_CFG_KEY_NAME_PRESERVE_LOCAL_STORAGE, enableLocalStorageCheckBox->isChecked()); + } + // Allow cookies { tempLiquidAppConfig->setValue(LQD_CFG_KEY_NAME_ALLOW_COOKIES, allowCookiesCheckBox->isChecked()); diff --git a/src/liquidappwebpage.cpp b/src/liquidappwebpage.cpp index a7ba28d..83f94c2 100644 --- a/src/liquidappwebpage.cpp +++ b/src/liquidappwebpage.cpp @@ -175,7 +175,7 @@ void LiquidAppWebPage::setWebSettingsToDefault(QWebEngineSettings* webSettings) webSettings->setAttribute(QWebEngineSettings::JavascriptCanPaste, false); #endif webSettings->setAttribute(QWebEngineSettings::JavascriptEnabled, false); - webSettings->setAttribute(QWebEngineSettings::LocalStorageEnabled, true); + webSettings->setAttribute(QWebEngineSettings::LocalStorageEnabled, false); #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0) webSettings->setAttribute(QWebEngineSettings::PdfViewerEnabled, false); #endif diff --git a/src/liquidappwindow.cpp b/src/liquidappwindow.cpp index db0bdac..8510764 100644 --- a/src/liquidappwindow.cpp +++ b/src/liquidappwindow.cpp @@ -547,26 +547,35 @@ void LiquidAppWindow::loadLiquidAppConfig(void) } // Toggle JavaScript on if enabled in application config - if (liquidAppConfig->contains(LQD_CFG_KEY_NAME_ENABLE_JS)) { - settings()->setAttribute( - QWebEngineSettings::JavascriptEnabled, - liquidAppConfig->value(LQD_CFG_KEY_NAME_ENABLE_JS).toBool() - ); + if (liquidAppConfig->value(LQD_CFG_KEY_NAME_ENABLE_JS).toBool()) { + settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, true); + settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true); + + // Restore HTML5 local storage data if preservation is enabled in this Liquid App's config + if (liquidAppConfig->value(LQD_CFG_KEY_NAME_PRESERVE_LOCAL_STORAGE).toBool()) { + const QString js = QString("(()=>{"\ + "localStorage.setItem('zkey', 134143);"\ + "alert(JSON.stringify(Object.entries(localStorage)));"\ + "})()"); + QWebEngineScript script; + script.setInjectionPoint(QWebEngineScript::DocumentCreation); // NOTE: this will run every time + script.setRunsOnSubFrames(false); // XXX: this probably should be true + script.setSourceCode(js); + script.setWorldId(QWebEngineScript::ApplicationWorld); + liquidAppWebPage->scripts().insert(script); + } } #if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) // Hide scrollbars - if (liquidAppConfig->contains(LQD_CFG_KEY_NAME_HIDE_SCROLLBARS)) { - settings()->setAttribute( - QWebEngineSettings::ShowScrollBars, - !liquidAppConfig->value(LQD_CFG_KEY_NAME_HIDE_SCROLLBARS).toBool() - ); + if (liquidAppConfig->value(LQD_CFG_KEY_NAME_HIDE_SCROLLBARS).toBool()) { + settings()->setAttribute(QWebEngineSettings::ShowScrollBars, false); } #endif // Mute audio if muted in application config - if (liquidAppConfig->contains(LQD_CFG_KEY_NAME_MUTE_AUDIO)) { - page()->setAudioMuted(liquidAppConfig->value(LQD_CFG_KEY_NAME_MUTE_AUDIO).toBool()); + if (liquidAppConfig->value(LQD_CFG_KEY_NAME_MUTE_AUDIO).toBool()) { + page()->setAudioMuted(true); } // Restore web view zoom level @@ -605,7 +614,7 @@ void LiquidAppWindow::loadLiquidAppConfig(void) "})()").arg(additionalCss.replace("\n", " ").replace("'", "\\'")); QWebEngineScript script; script.setInjectionPoint(QWebEngineScript::DocumentReady); - script.setRunsOnSubFrames(false); + script.setRunsOnSubFrames(false); // XXX: should it be true? script.setSourceCode(js); script.setWorldId(QWebEngineScript::ApplicationWorld); liquidAppWebPage->scripts().insert(script); @@ -689,7 +698,7 @@ void LiquidAppWindow::saveLiquidAppConfig(void) } // Save icon data as base64 string - { + if (iconToSave.availableSizes().size() > 0) { QBuffer buffer; buffer.open(QIODevice::WriteOnly); iconToSave.pixmap(iconToSave.availableSizes()[0]).save(&buffer, "PNG"); @@ -708,6 +717,18 @@ void LiquidAppWindow::saveLiquidAppConfig(void) } } + // Save LocalStorage data if preservation is enabled in application config + if (liquidAppConfig->value(LQD_CFG_KEY_NAME_PRESERVE_LOCAL_STORAGE).toBool()) { + // Restore localStorage items from this Liquid App's config file + const QString js = QString("(()=>{"\ + "return JSON.stringify(localStorage);"\ + "})()"); + page()->runJavaScript(js, QWebEngineScript::ApplicationWorld, [&](const QVariant& res){ + qDebug().noquote() << res.toString(); + }); + Liquid::sleep(100); // Give time for the lambda callback to fire up + } + liquidAppConfig->sync(); }