aboutsummaryrefslogtreecommitdiff
path: root/src/webengine/webprofile.h
blob: 894463f86cb5400b95885f124098e40f44d3d587 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
/*
 * This file is part of smolbote. It's copyrighted by the contributors recorded
 * in the version control history of the file, available from its original
 * location: https://neueland.iserlohn-fortress.net/gitea/aqua/smolbote
 *
 * SPDX-License-Identifier: GPL-3.0
 */

#ifndef SMOLBOTE_WEBENGINEPROFILE_H
#define SMOLBOTE_WEBENGINEPROFILE_H

#include <QMap>
#include <QNetworkCookie>
#include <QSettings>
#include <QString>
#include <QUrl>
#include <QVariant>
#include <QVector>
#include <QWebEngineCookieStore>
#include <QWebEngineProfile>
#include <QWebEngineSettings>

class UrlRequestInterceptor;
class WebProfile : public QWebEngineProfile
{
    friend class UrlRequestInterceptor;

    Q_OBJECT

    Q_PROPERTY(QString id READ getId CONSTANT)
    Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
    Q_PROPERTY(QString search READ search WRITE setSearch NOTIFY searchChanged)
    Q_PROPERTY(QUrl homepage READ homepage WRITE setHomepage NOTIFY homepageChanged)
    Q_PROPERTY(QUrl newtab READ newtab WRITE setNewtab NOTIFY newtabChanged)

    // QWebEngineProfile should-be properties
    Q_PROPERTY(QString cachePath READ cachePath WRITE setCachePath NOTIFY propertyChanged)
    Q_PROPERTY(QString persistentStoragePath READ persistentStoragePath WRITE setPersistentStoragePath NOTIFY propertyChanged)
    Q_PROPERTY(int persistentCookiesPolicy READ persistentCookiesPolicy WRITE setPersistentCookiesPolicy NOTIFY propertyChanged)

    Q_PROPERTY(QString httpAcceptLanguage READ httpAcceptLanguage WRITE setHttpAcceptLanguage NOTIFY propertyChanged)
    Q_PROPERTY(int httpCacheMaximumSize READ httpCacheMaximumSize WRITE setHttpCacheMaximumSize NOTIFY propertyChanged)
    Q_PROPERTY(int httpCacheType READ httpCacheType WRITE setHttpCacheType NOTIFY propertyChanged)
    Q_PROPERTY(QString httpUserAgent READ httpUserAgent WRITE setHttpUserAgent NOTIFY propertyChanged)

    Q_PROPERTY(bool spellCheckEnabled READ isSpellCheckEnabled WRITE setSpellCheckEnabled NOTIFY propertyChanged)

    // more custom properties
    Q_PROPERTY(QList<QVariant> cookies READ cookies WRITE setCookies NOTIFY cookiesChanged)
    Q_PROPERTY(QMap<QString, QVariant> headers READ headers WRITE setHeaders NOTIFY headersChanged)

signals:
    void nameChanged(const QString &name);
    void searchChanged(const QString &url);
    void homepageChanged(const QUrl &url);
    void newtabChanged(const QUrl &url);

    void propertyChanged(const QString &name, const QVariant &value);
    void attributeChanged(QWebEngineSettings::WebAttribute attribute, bool value);

    void cookiesChanged();
    void headersChanged();
    void headerChanged(const QString &name, const QString &value);
    void headerRemoved(const QString &name);

public:
    [[nodiscard]] static QSettings *load(const QString &path, const QString &search = QString(), const QUrl &homepage = QUrl(), const QUrl &newtab = QUrl());
    [[nodiscard]] static WebProfile *load(const QString &id, QSettings *settings, bool isOffTheRecord = true);

    WebProfile(const WebProfile &) = delete;
    WebProfile &operator=(const WebProfile &) = delete;
    WebProfile(WebProfile &&) = delete;
    WebProfile &operator=(WebProfile &&) = delete;

    static WebProfile *defaultProfile();
    static void setDefaultProfile(WebProfile *profile);

    ~WebProfile() override = default;

    [[nodiscard]] QString getId() const
    {
        return m_id;
    }
    [[nodiscard]] QString name() const
    {
        return m_name;
    }
    void setName(const QString &name)
    {
        m_name = name;
        emit nameChanged(name);
    }

    [[nodiscard]] QList<QVariant> cookies() const
    {
        QList<QVariant> r;
        for(const auto &cookie : m_cookies) {
            r.append(cookie.toRawForm());
        }
        return r;
    }

    [[nodiscard]] QString search() const
    {
        return m_search;
    }
    void setSearch(const QString &url)
    {
        m_search = url;
        emit searchChanged(m_search);
    }

    [[nodiscard]] QUrl homepage() const
    {
        return m_homepage;
    }
    void setHomepage(const QUrl &url)
    {
        m_homepage = url;
        emit homepageChanged(m_homepage);
    }

    [[nodiscard]] QUrl newtab() const
    {
        return m_newtab;
    }
    void setNewtab(const QUrl &url)
    {
        m_newtab = url;
        emit newtabChanged(m_newtab);
    }

    void setCachePath(const QString &path)
    {
        QWebEngineProfile::setCachePath(path);
        emit propertyChanged("cachePath", path);
    }
    void setPersistentStoragePath(const QString &path)
    {
        QWebEngineProfile::setPersistentStoragePath(path);
        emit propertyChanged("persistentStoragePath", path);
    }
    void setPersistentCookiesPolicy(int policy)
    {
        QWebEngineProfile::setPersistentCookiesPolicy(static_cast<QWebEngineProfile::PersistentCookiesPolicy>(policy));
        emit propertyChanged("persistentCookiesPolicy", policy);
    }

    void setHttpAcceptLanguage(const QString &httpAcceptLanguage)
    {
        QWebEngineProfile::setHttpAcceptLanguage(httpAcceptLanguage);
        emit propertyChanged("httpAcceptLanguage", httpAcceptLanguage);
    }
    void setHttpCacheMaximumSize(int maxSize)
    {
        QWebEngineProfile::setHttpCacheMaximumSize(maxSize);
        emit propertyChanged("httpCacheMaximumSize", maxSize);
    }
    void setHttpCacheType(int type)
    {
        QWebEngineProfile::setHttpCacheType(static_cast<QWebEngineProfile::HttpCacheType>(type));
        emit propertyChanged("httpCacheType", type);
    }
    void setHttpUserAgent(const QString &userAgent)
    {
        QWebEngineProfile::setHttpUserAgent(userAgent);
        emit propertyChanged("httpUserAgent", userAgent);
    }
    void setHttpHeader(const QString &name, const QString &value)
    {
        m_headers[name.toLatin1()] = value.toLatin1();
        emit headerChanged(name, value);
    }
    void removeHttpHeader(const QString &name)
    {
        if(m_headers.contains(name.toLatin1())) {
            m_headers.remove(name.toLatin1());
            emit headerRemoved(name);
        }
    }
    [[nodiscard]] QMap<QString, QVariant> headers() const
    {
        QMap<QString, QVariant> r;
        auto it = m_headers.constBegin();
        while(it != m_headers.constEnd()) {
            r.insert(QString(it.key()), QVariant(it.value()));
            ++it;
        }
        return r;
    }
    void setSpellCheckEnabled(bool enable)
    {
        QWebEngineProfile::setSpellCheckEnabled(enable);
        emit propertyChanged("spellCheckEnabed", enable);
    }

    void setUrlRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
    {
        m_filters.append(interceptor);
    }

public slots:
    void setCookies(const QList<QVariant> &cookies)
    {
        auto *store = cookieStore();
        store->deleteAllCookies();
        for(const auto &data : cookies) {
            for(auto &cookie : QNetworkCookie::parseCookies(data.toByteArray())) {
                store->setCookie(cookie);
            }
        }
        emit cookiesChanged();
    }
    void setHeaders(const QMap<QString, QVariant> &headers)
    {
        m_headers.clear();
        auto it = headers.constBegin();
        while(it != headers.constEnd()) {
            m_headers.insert(it.key().toLatin1(), it.value().toByteArray());
            ++it;
        }
        emit headersChanged();
    }

protected:
    // off-the-record constructor
    explicit WebProfile(const QString &id, QObject *parent = nullptr);
    // default constructor
    explicit WebProfile(const QString &id, const QString &storageName, QObject *parent = nullptr);

    const QString m_id;
    QString m_name;
    QString m_search = QString("about:blank");
    QUrl m_homepage = QUrl("about:blank");
    QUrl m_newtab = QUrl("about:blank");

    QVector<QWebEngineUrlRequestInterceptor *> m_filters;
    QList<QNetworkCookie> m_cookies;
    QMap<QByteArray, QByteArray> m_headers;
};

#endif // SMOLBOTE_WEBENGINEPROFILE_H