1// Copyright (C) 2018 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qwebviewfactory_p.h"
5#include "qwebviewplugin_p.h"
6#include <private/qfactoryloader_p.h>
7#include <QtCore/qglobal.h>
8
9QT_BEGIN_NAMESPACE
10
11Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, (QWebViewPluginInterface_iid, QLatin1String("/webview")))
12
13static QString getPluginName()
14{
15 static const QString name = !qEnvironmentVariableIsEmpty(varName: "QT_WEBVIEW_PLUGIN")
16 ? QString::fromLatin1(ba: qgetenv(varName: "QT_WEBVIEW_PLUGIN"))
17#ifdef Q_OS_MACOS
18 : QStringLiteral("webengine");
19#else
20 : QStringLiteral("native");
21#endif // Q_OS_MACOS
22 return name;
23}
24
25class QNullWebViewSettings : public QAbstractWebViewSettings
26{
27public:
28 explicit QNullWebViewSettings(QObject *p) : QAbstractWebViewSettings(p) {}
29 bool localStorageEnabled() const override { return false; }
30 bool javascriptEnabled() const override { return false; }
31 bool localContentCanAccessFileUrls() const override { return false; }
32 bool allowFileAccess() const override { return false; }
33 void setLocalContentCanAccessFileUrls(bool) override {}
34 void setJavascriptEnabled(bool) override {}
35 void setLocalStorageEnabled(bool) override {}
36 void setAllowFileAccess(bool) override {}
37};
38
39class QNullWebView : public QAbstractWebView
40{
41public:
42 explicit QNullWebView(QObject *p = nullptr)
43 : QAbstractWebView(p)
44 , m_settings(new QNullWebViewSettings(this))
45 {}
46 void setParentView(QObject *view) override { Q_UNUSED(view); }
47 QObject *parentView() const override { return nullptr; }
48 void setGeometry(const QRect &geometry) override { Q_UNUSED(geometry); }
49 void setVisibility(QWindow::Visibility visibility) override { Q_UNUSED(visibility); }
50 void setVisible(bool visible) override { Q_UNUSED(visible); }
51
52 QString httpUserAgent() const override { return QString(); }
53 void setHttpUserAgent(const QString &userAgent) override { Q_UNUSED(userAgent); }
54 QUrl url() const override { return QUrl(); }
55 void setUrl(const QUrl &url) override { Q_UNUSED(url); }
56 bool canGoBack() const override { return false; }
57 bool canGoForward() const override { return false; }
58 QString title() const override { return QString(); }
59 int loadProgress() const override { return 0; }
60 bool isLoading() const override { return false; }
61 void goBack() override { }
62 void goForward() override { }
63 void stop() override { }
64 void reload() override { }
65 void loadHtml(const QString &html, const QUrl &baseUrl) override
66 { Q_UNUSED(html); Q_UNUSED(baseUrl); }
67 void runJavaScriptPrivate(const QString &script, int callbackId) override
68 { Q_UNUSED(script); Q_UNUSED(callbackId); }
69 void setCookie(const QString &domain, const QString &name, const QString &value) override
70 { Q_UNUSED(domain); Q_UNUSED(name); Q_UNUSED(value); }
71 void deleteCookie(const QString &domain, const QString &name) override
72 { Q_UNUSED(domain); Q_UNUSED(name); }
73 void deleteAllCookies() override {}
74
75protected:
76 QAbstractWebViewSettings *getSettings() const override
77 {
78 return m_settings;
79 }
80
81private:
82 QNullWebViewSettings *m_settings = nullptr;
83};
84
85QAbstractWebView *QWebViewFactory::createWebView()
86{
87 QAbstractWebView *wv = nullptr;
88 QWebViewPlugin *plugin = getPlugin();
89 if (plugin)
90 wv = plugin->create(QStringLiteral("webview"));
91
92 if (!wv || !plugin) {
93 qWarning(msg: "No WebView plug-in found!");
94 wv = new QNullWebView;
95 }
96
97 return wv;
98}
99
100bool QWebViewFactory::requiresExtraInitializationSteps()
101{
102 const QString pluginName = getPluginName();
103 const int index = pluginName.isEmpty() ? 0 : qMax<int>(a: 0, b: loader->indexOf(needle: pluginName));
104
105 const QList<QPluginParsedMetaData> metaDataList = loader->metaData();
106 if (metaDataList.isEmpty())
107 return false;
108
109 const auto &pluginMetaData = metaDataList.at(i: index);
110 Q_ASSERT(pluginMetaData.value(QtPluginMetaDataKeys::IID) == QLatin1String(QWebViewPluginInterface_iid));
111 const auto metaDataObject = pluginMetaData.value(k: QtPluginMetaDataKeys::MetaData).toMap();
112 return metaDataObject.value(key: QLatin1String("RequiresInit")).toBool();
113}
114
115QWebViewPlugin *QWebViewFactory::getPlugin()
116{
117 // Plugin loading logic:
118 // 1. Get plugin name - plugin name is either user specified or "native"
119 // - Exception: macOS, which will default to using "webengine" until the native plugin is matured.
120 // 2. If neither a user specified or "default" plugin exists, then the first available is used.
121 const QString pluginName = getPluginName();
122 const int index = pluginName.isEmpty() ? 0 : qMax<int>(a: 0, b: loader->indexOf(needle: pluginName));
123 return qobject_cast<QWebViewPlugin *>(object: loader->instance(index));
124}
125
126QT_END_NAMESPACE
127

source code of qtwebview/src/webview/qwebviewfactory.cpp