diff --git a/private/racket-webview-qt.rkt b/private/racket-webview-qt.rkt
index 053b7a7..8db1e5a 100644
--- a/private/racket-webview-qt.rkt
+++ b/private/racket-webview-qt.rkt
@@ -21,6 +21,7 @@
rkt-webview-set-url!
rkt-webview-set-html!
rkt-webview-run-js
+ rkt-webview-call-js
rkt-webview-move
rkt-webview-resize
rkt-webview-exit
@@ -200,6 +201,9 @@
(define (rkt-webview-run-js wv js)
(rkt_webview_run_js (rkt-wv-win wv) js))
+(define (rkt-webview-call-js wv js)
+ (rkt_webview_call_js (rkt-wv-win wv) js))
+
(define (rkt-webview-resize wv w h)
(rkt_webview_resize (rkt-wv-win wv) w h))
diff --git a/private/racket-webview.rkt b/private/racket-webview.rkt
index e7d301e..a11ec6d 100644
--- a/private/racket-webview.rkt
+++ b/private/racket-webview.rkt
@@ -18,10 +18,12 @@
webview-devtools
webview-close
webview-run-js
+ webview-call-js
webview-move
webview-resize
webview-bind!
webview-standard-file-getter
+
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -113,7 +115,7 @@
#:parent [p 0])
(let* ((h (make-wv #f current-servlet-port -1 file-getter bj #f))
(server (let ((s (start-web-server h)))
- (sleep 1)
+ (sleep 1) ;;; TODO: Check if web server is up.
s))
(event-processor (λ (wv evt)
(event-callback h (util-parse-event evt))))
@@ -166,9 +168,9 @@
(on-not-exist file base-path p)
p)))))
-;(define (webview-call-js wv js)
-; (let ((result (rkt_webview_call_js (wv-handle wv) js)))
-; result))
+(define (webview-call-js wv js)
+ (let ((result (rkt_webview_call_js (wv-handle wv) js)))
+ result))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; testing
diff --git a/private/web-racket.rkt b/private/web-racket.rkt
index 64484a8..17a29d9 100644
--- a/private/web-racket.rkt
+++ b/private/web-racket.rkt
@@ -79,6 +79,18 @@
(set! _std_x 50))
)))
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ ;; Storage
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+ (define windows (make-hash))
+
+ (define (ww-debug msg)
+ (displayln (format "DBG: ~a" msg)))
+
+ (define (ww-error msg)
+ (displayln (format "ERR: ~a" msg)))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Class representing an element in the HTML page
;; each element is identified by an id.
@@ -94,9 +106,9 @@
(define/public (get-id)
id)
- (define/public (win)
- (let ((w (hash-ref windows (ww-win-id win-id) #f)))
- w))
+ ;(define/public (win)
+ ; (let ((w (hash-ref windows (ww-win-id win-id) #f)))
+ ; w))
(define connected-callbacks (make-hash))
@@ -110,7 +122,7 @@
(apply cb args)))))
(define/public (exec-js js)
- (ww-exec-js win-id js))
+ (webview-run-js win-id js))
(define/public (connect evt func)
(hash-set! connected-callbacks evt func))
@@ -119,34 +131,34 @@
(hash-remove! connected-callbacks evt))
(define/public (add-style! st)
- (ww-add-style win-id id st))
+ (webview-add-style win-id id st))
(define/public (set-style! st)
- (ww-set-style win-id id st))
+ (webview-set-style win-id id st))
(define/public (style)
- (ww-get-style win-id id))
+ (webview-get-style win-id id))
(define/public (get-attr a)
- (ww-get-attr win-id id a))
+ (webview-get-attr win-id id a))
(define/public (set-attr! a val)
- (ww-set-attr win-id id a val))
+ (webview-set-attr win-id id a val))
(define/public (del-attr a)
- (ww-del-attr win-id id a))
+ (webview-del-attr win-id id a))
(define/public (get-attrs)
- (ww-get-attrs win-id id))
+ (webview-get-attrs win-id id))
(define/public (add-class! cl)
- (ww-add-class win-id id cl))
+ (webview-add-class win-id id cl))
(define/public (remove-class! cl)
- (ww-remove-class win-id id cl))
+ (webview-remove-class win-id id cl))
(define/public (has-class? cl)
- (ww-has-class? win-id id cl))
+ (webview-has-class? win-id id cl))
(define/public (enable)
(send this remove-class! 'disabled))
@@ -175,7 +187,7 @@
(define/public (set-inner-html! html-or-sexpr)
(if (string? html-or-sexpr)
- (ww-set-inner-html win-id id html-or-sexpr)
+ (webview-set-inner-html! win-id id html-or-sexpr)
(set-inner-html! (xexpr->html5 html-or-sexpr))))
(super-new)
@@ -345,6 +357,8 @@
[height (if (eq? settings #f) _std_h (send settings get 'window-height _std_h))]
[icon #f]
[menu #f]
+ [base-path (build-path ".")]
+ [on-not-exist (λ (file base-path path) path)]
[html-file #f]
)
@@ -525,10 +539,10 @@
(ww-get-elements win-id selector))
(define/public (move x y)
- (ww-move win-id x y))
+ (webview-move win-id x y))
(define/public (resize x y)
- (ww-resize win-id x y))
+ (webview-resize win-id x y))
(define/public (get-x) x)
(define/public (get-y) y)
@@ -731,14 +745,17 @@
; (ww-new profile use-browser)
; (ww-new profile use-browser parent-id)))
(set! win-id (webview-create
- (λ (file) file)
+ (webview-standard-file-getter base-path
+ #:not-exist not-exist)
+ event-handler))
+
(when (eq? win-id #f)
(error "Window could not be constructed"))
- (hash-set! windows-evt-handlers (ww-win-id win-id) event-handler)
+ ;(hash-set! windows-evt-handlers (ww-win-id win-id) event-handler)
(hash-set! windows (ww-win-id win-id) this)
- (ww-resize win-id width height)
+ (webview-resize win-id width height)
(when parent
(let* ((parent-width (send parent get-width))
@@ -750,7 +767,7 @@
(set! y (+ parent-y (/ (- parent-height height) 2)))
)
)
- (ww-move win-id x y)
+ (webview-move win-id x y)
(send this set-title! title)
diff --git a/rktwebview_qt/main.cpp b/rktwebview_qt/main.cpp
index fdf00f8..4702f46 100644
--- a/rktwebview_qt/main.cpp
+++ b/rktwebview_qt/main.cpp
@@ -32,6 +32,22 @@ int main(int argc, char *argv[])
rkt_webview_open_devtools(wv1);
}
+ if (i == 3) {
+ rkt_js_result_t *r = rkt_webview_call_js(wv1, "{ let a = 7 * 6; console.log('a = ' + a); return a; }");
+ printf("rkt_js_result: %d: %s\n", r->result, r->value);
+ }
+
+ if (i == 4) {
+ rkt_js_result_t *r = rkt_webview_call_js(wv1, "let el = document.getElementById('hi');el.value = '10';");
+ printf("rkt_js_result: %d: %s\n", r->result, r->value);
+ }
+
+ if (i == 6) {
+ rkt_js_result_t *r = rkt_webview_call_js(wv1, "document.body.innerHTML = '
Hi!
'; return document.body.innerHTML;");
+ printf("rkt_js_result: %d: %s\n", r->result, r->value);
+ }
+
+
if (i == 10) {
wv2 = rkt_webview_create(0, eventCb);
}
diff --git a/rktwebview_qt/rktutils.h b/rktwebview_qt/rktutils.h
index ef3ac0f..acedce0 100644
--- a/rktwebview_qt/rktutils.h
+++ b/rktwebview_qt/rktutils.h
@@ -15,4 +15,21 @@ public:
QString mkEventJson(const EventContainer &kv);
+class Command
+{
+public:
+ int cmd;
+ QVector args;
+ QVariant result;
+ bool done;
+ bool js_result_ok;
+public:
+ Command(int _cmd) {
+ cmd = _cmd;
+ done = false;
+ js_result_ok = true;
+ }
+};
+
+
#endif
diff --git a/rktwebview_qt/rktwebview.cpp b/rktwebview_qt/rktwebview.cpp
index c887b4e..ac8ea8b 100644
--- a/rktwebview_qt/rktwebview.cpp
+++ b/rktwebview_qt/rktwebview.cpp
@@ -66,6 +66,14 @@ result_t rkt_webview_run_js(rktwebview_t wv, const char *js)
return r;
}
+rkt_js_result_t *rkt_webview_call_js(rktwebview_t wv, const char *js)
+{
+ rkt_webview_init();
+ rkt_js_result_t *r = handler->rktCallJs(wv, js);
+ return r;
+}
+
+
result_t rkt_webview_open_devtools(rktwebview_t wv)
{
@@ -95,6 +103,14 @@ result_t rkt_webview_destroy_event(rkt_event_t *e)
return result_t::oke;
}
+result_t rkt_webview_destroy_js_result(rkt_js_result_t *r)
+{
+ free(r->value);
+ free(r);
+ return result_t::oke;
+}
+
+
result_t rkt_webview_move(rktwebview_t wv, int x, int y)
{
rkt_webview_init();
@@ -118,3 +134,5 @@ bool rkt_webview_valid(rktwebview_t wv)
rkt_webview_init();
return handler->rktValid(wv);
}
+
+
diff --git a/rktwebview_qt/rktwebview.h b/rktwebview_qt/rktwebview.h
index 47c1626..7faa013 100644
--- a/rktwebview_qt/rktwebview.h
+++ b/rktwebview_qt/rktwebview.h
@@ -32,6 +32,13 @@ typedef enum {
resize_failed = 13
} result_t;
+typedef struct {
+ result_t result;
+ char *value;
+} rkt_js_result_t;
+
+
+
RKTWEBVIEW_QT_EXPORT void rkt_webview_init();
RKTWEBVIEW_QT_EXPORT void rkt_webview_process_events(int for_ms);
@@ -44,6 +51,9 @@ RKTWEBVIEW_QT_EXPORT result_t rkt_webview_set_url(rktwebview_t wv, const char *u
RKTWEBVIEW_QT_EXPORT result_t rkt_webview_set_html(rktwebview_t wv, const char *html);
RKTWEBVIEW_QT_EXPORT result_t rkt_webview_run_js(rktwebview_t wv, const char *js);
+RKTWEBVIEW_QT_EXPORT rkt_js_result_t *rkt_webview_call_js(rktwebview_t wv, const char *js);
+RKTWEBVIEW_QT_EXPORT result_t rkt_webview_destroy_js_result(rkt_js_result_t *r);
+
RKTWEBVIEW_QT_EXPORT result_t rkt_webview_open_devtools(rktwebview_t wv);
RKTWEBVIEW_QT_EXPORT result_t rkt_webview_destroy_event(rkt_event_t *e);
diff --git a/rktwebview_qt/rktwebview_qt.cpp b/rktwebview_qt/rktwebview_qt.cpp
index 4c44b59..b453338 100644
--- a/rktwebview_qt/rktwebview_qt.cpp
+++ b/rktwebview_qt/rktwebview_qt.cpp
@@ -18,20 +18,7 @@
#define COMMAND_DEV_TOOLS 7
#define COMMAND_MOVE 8
#define COMMAND_RESIZE 9
-
-class Command
-{
-public:
- int cmd;
- QVector args;
- QVariant result;
- bool done;
-public:
- Command(int _cmd) {
- cmd = _cmd;
- done = false;
- }
-};
+#define COMMAND_CALL_JS 10
void Rktwebview_qt::processCommands()
{
@@ -127,6 +114,19 @@ void Rktwebview_qt::processCommands()
cmd->done = true;
}
break;
+ case COMMAND_CALL_JS: {
+ int wv = cmd->args[0].toInt();
+ QString js = cmd->args[1].toString();
+ if (_views.contains(wv)) {
+ WebviewWindow *w = _views[wv];
+ w->callJs(js, cmd);
+ } else {
+ cmd->result = false;
+ cmd->js_result_ok = false;
+ cmd->done = true;
+ }
+ }
+ break;
case COMMAND_DEV_TOOLS: {
int wv = cmd->args[0].toInt();
if (_views.contains(wv)) {
@@ -260,6 +260,22 @@ result_t Rktwebview_qt::rktSetHtml(rktwebview_t wv, const char *html)
return r ? result_t::oke : result_t::set_navigate_failed;
}
+rkt_js_result_t *Rktwebview_qt::rktCallJs(rktwebview_t wv, const char *js)
+{
+ Command c(COMMAND_CALL_JS);
+ QString _js(js);
+ c.args.push_back(wv);
+ c.args.push_back(_js);
+ _command_queue.enqueue(&c);
+ while(!c.done) { doEvents(); }
+
+ rkt_js_result_t *r = static_cast(malloc(sizeof(rkt_js_result_t)));
+ r->result = c.js_result_ok ? result_t::oke : result_t::eval_js_failed;
+ r->value = strdup(c.result.toString().toUtf8());
+
+ return r;
+}
+
result_t Rktwebview_qt::rktRunJs(rktwebview_t wv, const char *js)
{
Command c(COMMAND_RUN_JS);
diff --git a/rktwebview_qt/rktwebview_qt.h b/rktwebview_qt/rktwebview_qt.h
index 0cf6ccf..5aece18 100644
--- a/rktwebview_qt/rktwebview_qt.h
+++ b/rktwebview_qt/rktwebview_qt.h
@@ -57,6 +57,7 @@ public:
result_t rktSetUrl(rktwebview_t wv, const char *url);
result_t rktSetHtml(rktwebview_t wv, const char *html);
result_t rktRunJs(rktwebview_t wv, const char *js);
+ rkt_js_result_t *rktCallJs(rktwebview_t wv, const char *js);
result_t rktMove(rktwebview_t wv, int x, int y);
result_t rktResize(rktwebview_t wv, int w, int h);
bool rktValid(rktwebview_t wv);
diff --git a/rktwebview_qt/webviewwindow.cpp b/rktwebview_qt/webviewwindow.cpp
index 9e5f118..e5356b3 100644
--- a/rktwebview_qt/webviewwindow.cpp
+++ b/rktwebview_qt/webviewwindow.cpp
@@ -129,6 +129,31 @@ void WebviewWindow::runJs(const QString &js)
p->runJavaScript(js);
}
+void WebviewWindow::callJs(const QString &js, Command *c)
+{
+ QWebEnginePage *p = _view->page();
+ QString _js = QString("{\n") +
+ " let f = function() {\n" +
+ " " + js + "\n" +
+ " };\n" +
+ " try {\n" +
+ " let obj = { oke: true, result: f(), exn: false };\n" +
+ " obj;\n" +
+ " } catch(e) {\n" +
+ " let obj = { oke: false, result: false, exn: e.message };\n" +
+ " obj;\n" +
+ " }\n" +
+ "}";
+ p->runJavaScript(_js, [c](const QVariant &v) {
+ c->result = v;
+ QJsonObject obj = v.toJsonObject();
+ bool ok = obj["oke"].toBool();
+ c->js_result_ok = ok;
+ c->result = QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::JsonFormat::Compact));
+ c->done = true;
+ });
+}
+
void WebviewWindow::openDevTools()
{
_devtools = new QMainWindow(this);
diff --git a/rktwebview_qt/webviewwindow.h b/rktwebview_qt/webviewwindow.h
index 4e48520..cf266d8 100644
--- a/rktwebview_qt/webviewwindow.h
+++ b/rktwebview_qt/webviewwindow.h
@@ -6,6 +6,7 @@
class WebViewQt;
class Rktwebview_qt;
+class Command;
class WebviewWindow : public QMainWindow
{
@@ -39,6 +40,7 @@ public:
public:
void runJs(const QString &js);
+ void callJs(const QString &js, Command *c);
void openDevTools();
public: