Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for HTML5 local storage #99

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions inc/liquidappconfigwindow.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public slots:

// JavaScript tab
QCheckBox* enableJavaScriptCheckBox;
QCheckBox* enableLocalStorageCheckBox;
QLabel* additionalJsLabel;
QPlainTextEdit* additionalJsTextArea;

Expand Down
1 change: 1 addition & 0 deletions inc/liquidappwebpage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions inc/lqd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
60 changes: 50 additions & 10 deletions src/liquidappconfigwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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());
Expand Down
2 changes: 1 addition & 1 deletion src/liquidappwebpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
49 changes: 35 additions & 14 deletions src/liquidappwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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");
Expand All @@ -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();
}

Expand Down