Better profile support, only 1 web server per context, multiple windows per context
This commit is contained in:
@@ -26,7 +26,6 @@
|
||||
#define COMMAND_FILE_OPEN 20
|
||||
#define COMMAND_FILE_SAVE 21
|
||||
#define COMMAND_SET_OU_TOKEN 22
|
||||
#define COMMAND_SET_CERTIFICATE 23
|
||||
|
||||
class Command
|
||||
{
|
||||
|
||||
@@ -22,7 +22,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
rkt_webview_init();
|
||||
|
||||
wv1 = rkt_webview_create(0, eventCb, nullptr);
|
||||
int context = rkt_webview_new_context("console.log('boilerplate!');", nullptr);
|
||||
|
||||
wv1 = rkt_webview_create(context, 0, eventCb);
|
||||
|
||||
rkt_webview_move(wv1, 200, 300);
|
||||
rkt_webview_resize(wv1, 800, 600);
|
||||
@@ -57,7 +59,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
|
||||
if (i == 10) {
|
||||
wv2 = rkt_webview_create(wv1, eventCb, nullptr);
|
||||
wv2 = rkt_webview_create(context, wv1, eventCb);
|
||||
rkt_webview_move(wv2, 400, 200);
|
||||
rkt_webview_resize(wv2, 800, 600);
|
||||
rkt_webview_set_url(wv2, "https://127.0.0.1");
|
||||
|
||||
@@ -32,10 +32,17 @@ void rkt_webview_init()
|
||||
}
|
||||
}
|
||||
|
||||
int rkt_webview_create(rktwebview_t parent, event_cb_t js_event_cb, const char *optional_server_cert_pem)
|
||||
|
||||
rkt_wv_context_t rkt_webview_new_context(const char *boilerplate_js, const char *optional_server_cert_pem)
|
||||
{
|
||||
rkt_webview_init();
|
||||
return handler->rktWebViewCreate(parent, js_event_cb, optional_server_cert_pem);
|
||||
return handler->newContext(boilerplate_js, optional_server_cert_pem);
|
||||
}
|
||||
|
||||
int rkt_webview_create(rkt_wv_context_t context, rktwebview_t parent, event_cb_t js_event_cb)
|
||||
{
|
||||
rkt_webview_init();
|
||||
return handler->rktWebViewCreate(context, parent, js_event_cb);
|
||||
}
|
||||
|
||||
void rkt_webview_close(rktwebview_t wv)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
extern "C" {
|
||||
|
||||
typedef int rktwebview_t;
|
||||
typedef int rkt_wv_context_t;
|
||||
|
||||
typedef struct {
|
||||
rktwebview_t wv;
|
||||
@@ -81,12 +82,12 @@ typedef void (*event_cb_t)(rkt_data_t *);
|
||||
|
||||
RKTWEBVIEW_QT_EXPORT void rkt_webview_init();
|
||||
RKTWEBVIEW_QT_EXPORT void rkt_webview_process_events(int for_ms);
|
||||
|
||||
RKTWEBVIEW_QT_EXPORT void rkt_webview_free_data(rkt_data_t *d);
|
||||
|
||||
RKTWEBVIEW_QT_EXPORT rkt_data_t *rkt_webview_version();
|
||||
|
||||
RKTWEBVIEW_QT_EXPORT int rkt_webview_create(rktwebview_t parent, event_cb_t js_event_cb, const char *optional_server_cert_pem);
|
||||
RKTWEBVIEW_QT_EXPORT rkt_wv_context_t rkt_webview_new_context(const char *boilerplate_js, const char *optional_server_cert_pem);
|
||||
|
||||
RKTWEBVIEW_QT_EXPORT int rkt_webview_create(rkt_wv_context_t context, rktwebview_t parent, event_cb_t js_event_cb);
|
||||
RKTWEBVIEW_QT_EXPORT void rkt_webview_close(rktwebview_t wv);
|
||||
RKTWEBVIEW_QT_EXPORT bool rkt_webview_valid(rktwebview_t wv);
|
||||
RKTWEBVIEW_QT_EXPORT result_t rkt_webview_set_title(rktwebview_t wv, const char *title);
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QAbstractEventDispatcher>
|
||||
#include <QWebEngineProfile>
|
||||
#include <QWebEngineProfileBuilder>
|
||||
#include <QWebEngineScriptCollection>
|
||||
#include <QWebEngineScript>
|
||||
#include "command.h"
|
||||
#include <QFileDialog>
|
||||
|
||||
@@ -29,14 +33,12 @@ void Rktwebview_qt::processCommand(Command *cmd)
|
||||
}
|
||||
break;
|
||||
case COMMAND_CREATE: {
|
||||
int parent = cmd->args[0].toInt();
|
||||
rkt_wv_context_t context = cmd->args[0].toInt();
|
||||
rktwebview_t parent = cmd->args[1].toInt();
|
||||
|
||||
void *f = cmd->args[1].value<void *>();
|
||||
void *f = cmd->args[2].value<void *>();
|
||||
event_cb_t js_event_cb = reinterpret_cast <event_cb_t>(f);
|
||||
|
||||
bool has_scp = cmd->args[2].toBool();
|
||||
QByteArray scp_pem = cmd->args[3].toByteArray();
|
||||
|
||||
WebviewWindow *p;
|
||||
if (_views.contains(parent)) {
|
||||
p = _views[parent];
|
||||
@@ -44,22 +46,28 @@ void Rktwebview_qt::processCommand(Command *cmd)
|
||||
p = nullptr;
|
||||
}
|
||||
|
||||
WebviewWindow *w = new WebviewWindow(p, has_scp, scp_pem);
|
||||
WebViewQt *view = new WebViewQt(nextHandle(), w);
|
||||
w->addView(view, this);
|
||||
if (!_contexts.contains(context)) {
|
||||
cmd->result = -1;
|
||||
cmd->done = true;
|
||||
} else {
|
||||
QWebEngineProfile *profile = _contexts[context];
|
||||
WebviewWindow *w = new WebviewWindow(profile, p);
|
||||
WebViewQt *view = new WebViewQt(nextHandle(), w);
|
||||
w->addView(view, this);
|
||||
|
||||
int id = view->id();
|
||||
int id = view->id();
|
||||
|
||||
_views[id] = w;
|
||||
_view_js_callbacks[id] = js_event_cb;
|
||||
_views[id] = w;
|
||||
_view_js_callbacks[id] = js_event_cb;
|
||||
|
||||
w->show();
|
||||
while(!w->windowCreated()) {
|
||||
doEvents();
|
||||
w->show();
|
||||
while(!w->windowCreated()) {
|
||||
doEvents();
|
||||
}
|
||||
|
||||
cmd->result = id;
|
||||
cmd->done = true;
|
||||
}
|
||||
|
||||
cmd->result = id;
|
||||
cmd->done = true;
|
||||
}
|
||||
break;
|
||||
case COMMAND_CLOSE: {
|
||||
@@ -370,17 +378,68 @@ int Rktwebview_qt::nextHandle()
|
||||
return h;
|
||||
}
|
||||
|
||||
int Rktwebview_qt::rktWebViewCreate(int parent, event_cb_t js_evt_cb, const char *optional_server_cert_pem)
|
||||
rkt_wv_context_t Rktwebview_qt::newContext(const char *boilerplate_js, const char *optional_server_cert_pem)
|
||||
{
|
||||
QWebEngineProfileBuilder b;
|
||||
if (optional_server_cert_pem != nullptr) {
|
||||
QByteArray scp = QByteArray(optional_server_cert_pem);
|
||||
QList<QSslCertificate> certs;
|
||||
QSslCertificate cert(scp);
|
||||
certs.append(cert);
|
||||
b.setAdditionalTrustedCertificates(certs);
|
||||
}
|
||||
_context_counter += 1;
|
||||
QString name = QString::asprintf("profile-%d", _context_counter);
|
||||
|
||||
QString code = "if (window.rkt_event_queue === undefined) { window.rkt_event_queue = []; }\n"
|
||||
"window.rkt_send_event = function(obj) {\n"
|
||||
" console.log('Sending event: ' + obj);\n"
|
||||
" window.rkt_event_queue.push(obj);\n"
|
||||
"};\n"
|
||||
"window.rkt_get_events = function() {\n"
|
||||
" let q = window.rkt_event_queue;\n"
|
||||
" window.rkt_event_queue = [];\n"
|
||||
" let json_q = JSON.stringify(q);\n"
|
||||
" return json_q;\n"
|
||||
"};\n"
|
||||
"";
|
||||
|
||||
QList<QWebEngineScript> scripts;
|
||||
QWebEngineProfile *p = b.createProfile(name);
|
||||
QWebEngineScriptCollection *col = p->scripts();
|
||||
QWebEngineScript s1;
|
||||
s1.setInjectionPoint(QWebEngineScript::InjectionPoint::DocumentReady);
|
||||
s1.setName("eventing");
|
||||
s1.setSourceCode(code);
|
||||
s1.setWorldId(QWebEngineScript::MainWorld);
|
||||
scripts.append(s1);
|
||||
|
||||
QWebEngineScript s2;
|
||||
s2.setInjectionPoint(QWebEngineScript::InjectionPoint::DocumentReady);
|
||||
s2.setName("boilerplate");
|
||||
s2.setSourceCode(boilerplate_js);
|
||||
s2.setWorldId(QWebEngineScript::MainWorld);
|
||||
scripts.append(s2);
|
||||
|
||||
col->insert(scripts);
|
||||
|
||||
QWebEngineScriptCollection *c = p->scripts();
|
||||
QList<QWebEngineScript> l = c->toList();
|
||||
printf("%d\n", l.size());
|
||||
|
||||
_contexts[_context_counter] = p;
|
||||
|
||||
return _context_counter;
|
||||
}
|
||||
|
||||
int Rktwebview_qt::rktWebViewCreate(rkt_wv_context_t context, rktwebview_t parent, event_cb_t js_evt_cb)
|
||||
{
|
||||
Command c(COMMAND_CREATE);
|
||||
c.args.push_back(context);
|
||||
c.args.push_back(parent);
|
||||
void *function = reinterpret_cast<void *>(js_evt_cb);
|
||||
QVariant f(QVariant::fromValue(function));
|
||||
c.args.push_back(f);
|
||||
bool has_scp = (optional_server_cert_pem != nullptr);
|
||||
c.args.push_back(has_scp);
|
||||
QByteArray scp = (optional_server_cert_pem == nullptr) ? QByteArray("") : QByteArray(optional_server_cert_pem);
|
||||
c.args.push_back(scp);
|
||||
|
||||
postCommand(&c);
|
||||
|
||||
@@ -659,7 +718,7 @@ void Rktwebview_qt::onPageLoad(rktwebview_t w)
|
||||
|
||||
void Rktwebview_qt::pageLoaded(rktwebview_t w, bool ok)
|
||||
{
|
||||
runJs(w,
|
||||
/*runJs(w,
|
||||
"if (window.rkt_event_queue === undefined) { window.rkt_event_queue = []; }\n"
|
||||
"window.rkt_send_event = function(obj) {\n"
|
||||
" console.log('Sending event: ' + obj);\n"
|
||||
@@ -672,6 +731,20 @@ void Rktwebview_qt::pageLoaded(rktwebview_t w, bool ok)
|
||||
" return json_q;\n"
|
||||
"};\n"
|
||||
);
|
||||
*/
|
||||
|
||||
if (!ok) {
|
||||
// Inject code of the profile to this page
|
||||
WebviewWindow *win = _views[w];
|
||||
QWebEngineProfile *p = win->profile();
|
||||
QWebEngineScriptCollection *col = p->scripts();
|
||||
QList<QWebEngineScript> l = col->toList();
|
||||
int i;
|
||||
for(i = 0; i < l.size(); i++) {
|
||||
runJs(w, l[i].sourceCode().toUtf8().constData());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// trigger page loaded.
|
||||
EventContainer e("page-loaded");
|
||||
@@ -775,6 +848,8 @@ Rktwebview_qt::Rktwebview_qt(Rktwebview_qt **handler) :
|
||||
_argc = 1;
|
||||
_argv[0] = const_cast<char *>("Rktwebview_qt");
|
||||
|
||||
_context_counter = 0;
|
||||
|
||||
|
||||
_current_handle = 0;
|
||||
_handler = handler;
|
||||
@@ -800,3 +875,19 @@ Rktwebview_qt::Rktwebview_qt(Rktwebview_qt **handler) :
|
||||
|
||||
*_handler = nullptr;
|
||||
}
|
||||
|
||||
Rktwebview_qt::~Rktwebview_qt()
|
||||
{
|
||||
QList<int> win_keys = _views.keys();
|
||||
int i, N;
|
||||
for(i = 0, N = win_keys.size(); i < N; i++) {
|
||||
WebviewWindow *w = _views[win_keys[i]];
|
||||
delete w;
|
||||
}
|
||||
|
||||
QList<int> c_keys = _contexts.keys();
|
||||
for(i = 0, N = c_keys.size(); i < N; i++) {
|
||||
QWebEngineProfile *p = _contexts[c_keys[i]];
|
||||
delete p;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,8 +26,11 @@ class RKTWEBVIEW_QT_EXPORT Rktwebview_qt : public QObject
|
||||
private:
|
||||
QApplication *_app;
|
||||
rktwebview_t _current_handle;
|
||||
|
||||
int _context_counter;
|
||||
QHash<int, QWebEngineProfile *> _contexts;
|
||||
QHash<int, WebviewWindow *> _views;
|
||||
QHash<int, event_cb_t> _view_js_callbacks;
|
||||
QHash<int, event_cb_t> _view_js_callbacks;
|
||||
|
||||
QTimer _process_events;
|
||||
|
||||
@@ -64,7 +67,8 @@ public:
|
||||
public:
|
||||
int nextHandle();
|
||||
public:
|
||||
int rktWebViewCreate(int parent, event_cb_t js_evt_cb, const char *optional_server_cert_pem);
|
||||
rkt_wv_context_t newContext(const char *boilerplate_js, const char *optional_server_cert_pem);
|
||||
int rktWebViewCreate(rkt_wv_context_t context, rktwebview_t parent, event_cb_t js_evt_cb);
|
||||
void rktWebViewClose(int wv);
|
||||
void rktSetOUToken(rktwebview_t wv, const char *ou_token);
|
||||
void rktQuit();
|
||||
@@ -110,6 +114,7 @@ public:
|
||||
|
||||
public:
|
||||
Rktwebview_qt(Rktwebview_qt **handler);
|
||||
~Rktwebview_qt();
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ WebViewQt::WebViewQt(int id, WebviewWindow *window)
|
||||
_window = window;
|
||||
}
|
||||
|
||||
|
||||
int WebViewQt::id() const
|
||||
{
|
||||
return _id;
|
||||
|
||||
@@ -23,7 +23,6 @@ signals:
|
||||
|
||||
public:
|
||||
WebViewQt(int id, WebviewWindow *window);
|
||||
|
||||
};
|
||||
|
||||
#endif // WEBVIEWQT_H
|
||||
|
||||
@@ -36,7 +36,7 @@ static void displ1(QSslCertificate &cert, QList<QSslCertificate::SubjectInfo > l
|
||||
};
|
||||
*/
|
||||
|
||||
WebviewWindow::WebviewWindow(WebviewWindow *parent, bool has_scp, QByteArray scp_pem)
|
||||
WebviewWindow::WebviewWindow(QWebEngineProfile *profile, WebviewWindow *parent)
|
||||
: QMainWindow{parent}
|
||||
{
|
||||
static int profile_nr = 0;
|
||||
@@ -51,21 +51,7 @@ WebviewWindow::WebviewWindow(WebviewWindow *parent, bool has_scp, QByteArray scp
|
||||
_moved = 0;
|
||||
_resized = 0;
|
||||
|
||||
QWebEngineProfileBuilder b;
|
||||
if (has_scp) {
|
||||
profile_nr += 1;
|
||||
char buf[100];
|
||||
sprintf(buf, "profile-%d", profile_nr);
|
||||
QString name(buf);
|
||||
QSslCertificate cert(scp_pem);
|
||||
|
||||
QList<QSslCertificate> certs;
|
||||
certs.append(cert);
|
||||
b.setAdditionalTrustedCertificates(certs);
|
||||
_profile = b.createProfile(name);
|
||||
} else {
|
||||
_profile = QWebEngineProfile::defaultProfile();
|
||||
}
|
||||
_profile = profile;
|
||||
|
||||
if (parent != nullptr) {
|
||||
setWindowModality(Qt::WindowModality::WindowModal);
|
||||
@@ -78,7 +64,9 @@ WebviewWindow::WebviewWindow(WebviewWindow *parent, bool has_scp, QByteArray scp
|
||||
|
||||
void WebviewWindow::navigationRequested(QWebEngineNavigationRequest &req)
|
||||
{
|
||||
if (req.navigationType() == QWebEngineNavigationRequest::NavigationType::TypedNavigation) {
|
||||
QWebEngineNavigationRequest::NavigationType t = req.navigationType();
|
||||
if (t == QWebEngineNavigationRequest::NavigationType::TypedNavigation ||
|
||||
t == QWebEngineNavigationRequest::RedirectNavigation) {
|
||||
req.accept();
|
||||
} else {
|
||||
EventContainer e("navigation-request");
|
||||
@@ -226,8 +214,9 @@ void WebviewWindow::addView(WebViewQt *v, Rktwebview_qt *c)
|
||||
_view = v;
|
||||
this->setCentralWidget(v);
|
||||
|
||||
QWebEnginePage *page;
|
||||
QWebEnginePage *page = _view->page();
|
||||
|
||||
/*
|
||||
if (_profile == nullptr) {
|
||||
page = _view->page();
|
||||
} else {
|
||||
@@ -255,6 +244,7 @@ void WebviewWindow::addView(WebViewQt *v, Rktwebview_qt *c)
|
||||
);
|
||||
evt_script.setWorldId(QWebEngineScript::ApplicationWorld);
|
||||
//col.insert(evt_script);
|
||||
*/
|
||||
|
||||
connect(page, &QWebEnginePage::loadFinished, this, [this](bool ok) {
|
||||
_container->pageLoaded(_view->id(), ok);
|
||||
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
void openDevTools();
|
||||
|
||||
public:
|
||||
explicit WebviewWindow(WebviewWindow *parent, bool has_scp, QByteArray scp_pem);
|
||||
explicit WebviewWindow(QWebEngineProfile *profile, WebviewWindow *parent);
|
||||
|
||||
private slots:
|
||||
void triggerResize();
|
||||
|
||||
Reference in New Issue
Block a user