diff --git a/example/index.html b/example/index.html index 516491d..c8ba0ea 100644 --- a/example/index.html +++ b/example/index.html @@ -13,6 +13,10 @@ Please press this for something to happen.

Some input text:

+

+Some input date: +

+

Hi there! Click here to load this page again

To page 2

diff --git a/example/page2.html b/example/page2.html index 2d223c8..649e9e7 100644 --- a/example/page2.html +++ b/example/page2.html @@ -10,6 +10,16 @@

Hi there! Click here to load this main page again

+ + + + + + + + + +
LabelValue
Hi! One10
Ohw!12
Oh no!1330
Right102
Left1013
FLOP33
diff --git a/js/boilerplate.js b/js/boilerplate.js index 87ec3dd..bc4124b 100644 --- a/js/boilerplate.js +++ b/js/boilerplate.js @@ -44,7 +44,33 @@ window.rkt_event_info = function(e, id, evt) { return obj; }; -window.rkt_bind_evt_ids = function(win_nr, selector, event_kind) { +window.rkt_bounds = new Map(); + +window.rkt_get_evt_handler = function(event_kind, el_id, selector, win_nr) +{ + let handler_key = "h-" + event_kind + "-" + el_id + "-" + selector + "-" + win_nr; + if (window.rkt_bounds.has(handler_key)) { + return window.rkt_bounds.get(handler_key); + } else { + let handler = { + handleEvent: function(e) { + let obj = {evt: event_kind, id: el_id, selector: selector, window: win_nr, + js_evt: window.rkt_event_info(event_kind, el_id, e) }; + window.rkt_put_evt(obj); + } + }; + window.rkt_bounds.set(handler_key, handler); + return handler; + } +} + +window.rkt_rm_evt_handler = function(event_kind, el_id, selector, win_nr) +{ + let handler_key = "h-" + event_kind + "-" + el_id + "-" + selector + "-" + win_nr; + window.rkt_bounds.delete(handler_key); +} + +window.rkt_bind_evt_ids = function(win_nr, selector, event_kinds) { try { let nodelist = document.querySelectorAll(selector); if (nodelist === undefined || nodelist === null) { @@ -57,15 +83,48 @@ window.rkt_bind_evt_ids = function(win_nr, selector, event_kind) { let el_type = el.getAttribute('type'); if (el_type === null) { el_type = ''; } if (el_id !== null) { - el.addEventListener(event_kind, - function(e) { - let obj = {evt: event_kind, id: el_id, selector: selector, window: win_nr, - js_evt: window.rkt_event_info(event_kind, el_id, e) }; - window.rkt_put_evt(obj); - } - ); - let info = [ el_id, el_tag, el_type ]; - ids.push(info); + if (event_kinds.length > 0) { + let i; + for(i = 0; i < event_kinds.length; i++) { + let event_kind = event_kinds[i]; + el.addEventListener(event_kind, window.rkt_get_evt_handler(event_kind, el_id, selector, win_nr)); + } + let info = [ el_id, el_tag, el_type ]; + ids.push(info); + } + } + }); + return ids; + } catch(e) { + return []; + } +}; + +window.rkt_unbind_evt_ids = function(win_nr, selector, event_kinds) { + console.log("unbind: " + selector); + console.log(event_kinds); + try { + let nodelist = document.querySelectorAll(selector); + if (nodelist === undefined || nodelist === null) { + return []; + } + let ids = []; + nodelist.forEach(function(el) { + let el_id = el.getAttribute('id'); + let el_tag = el.nodeName; + let el_type = el.getAttribute('type'); + if (el_type === null) { el_type = ''; } + if (el_id !== null) { + if (event_kinds.length > 0) { + let i; + for(i = 0; i < event_kinds.length; i++) { + let event_kind = event_kinds[i]; + el.removeEventListener(event_kind, window.rkt_get_evt_handler(event_kind, el_id, selector, win_nr)); + window.rkt_rm_evt_handler(event_kind, el_id, selector, win_nr); + } + let info = [ el_id, el_tag, el_type ]; + ids.push(info); + } } }); return ids; diff --git a/private/racket-webview.rkt b/private/racket-webview.rkt index 1e7b6ef..3b2f2d6 100644 --- a/private/racket-webview.rkt +++ b/private/racket-webview.rkt @@ -59,6 +59,7 @@ wv-list-of-permitted-exts? webview-bind! + webview-unbind! webview-set-url! webview-navigate! @@ -156,7 +157,7 @@ (if (eq? cookie-header #f) #f (let ((cookies (c:cookie-header->alist (header-value cookie-header)))) - (displayln (format "Cookies: ~a" cookies)) + ;(displayln (format "Cookies: ~a" cookies)) (let ((sec-token (findf (λ (c) (eq? (string->symbol (format "~a" (car c))) @@ -169,7 +170,6 @@ (define (make-sec-header sec-cache) (let ((tok (make-security-token))) (lru-add! sec-cache tok) - (displayln (format "new sec-token: ~a" tok)) (make-header #"Set-Cookie" (string->bytes/utf-8 (format "rkt-webview-token=~a" tok))) @@ -264,8 +264,10 @@ (f1 (build-path cert-path (format "self-signed-~a.cert" window-nr))) (f2 (build-path cert-path (format "self-signed-~a.key" window-nr))) ) - (delete-file f1) - (delete-file f2) + (when (file-exists? f1) + (delete-file f1)) + (when (file-exists? f2) + (delete-file f2)) ) ) @@ -275,7 +277,10 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (define (util-parse-event evt) - (let ((wv-d0 (with-input-from-string evt read-json))) + (let ((wv-d0 (hash-copy (with-input-from-string evt read-json)))) + (hash-set! wv-d0 'event + (string->symbol + (format "~a" (hash-ref wv-d0 'event 'nil)))) wv-d0)) (define (webview-call-js-result? x) @@ -530,13 +535,32 @@ 'oke)) (define/contract (webview-bind! wv selector event) - (-> wv? (or/c symbol? string?) symbol? list?) - (let ((sel (if (symbol? selector) + (-> wv? (or/c symbol? string?) (or/c symbol? list-of-symbol?) list?) + (let* ((sel (if (symbol? selector) + (format "#~a" selector) + selector)) + (event* (if (symbol? event) (list event) event)) + (evt (format "[ ~a ]" (string-join + (map (λ (e) (format "'~a'" e)) event*) ", "))) + ) + (let ((r (webview-call-js wv + (format "return window.rkt_bind_evt_ids(~a, '~a', ~a)" + (wv-window-nr wv) sel evt)))) + (map (λ (el) + (list (string->symbol (car el)) (cadr el) (caddr el))) + r)))) + +(define/contract (webview-unbind! wv selector event) + (-> wv? (or/c symbol? string?) (or/c symbol? list-of-symbol?) list?) + (let* ((sel (if (symbol? selector) (format "#~a" selector) selector)) - (evt (format "~a" event))) + (event* (if (symbol? event) (list event) event)) + (evt (format "[ ~a ]" (string-join + (map (λ (e) (format "'~a'" e)) event*) ", "))) + ) (let ((r (webview-call-js wv - (format "return window.rkt_bind_evt_ids(~a, '~a', '~a')" + (format "return window.rkt_unbind_evt_ids(~a, '~a', ~a)" (wv-window-nr wv) sel evt)))) (map (λ (el) (list (string->symbol (car el)) (cadr el) (caddr el))) diff --git a/private/racket-wv.rkt b/private/racket-wv.rkt index 0042a33..62bfb95 100644 --- a/private/racket-wv.rkt +++ b/private/racket-wv.rkt @@ -2,36 +2,18 @@ (require "racket-webview.rkt" racket/class + simple-ini/class + "wv-window.rkt" ) -(provide wv-window% +(provide (all from out "wv-window.rkt") ) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Classes +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define wv-window% +(define wv-element% (class object% - - (init-field profile - base-dir - [settings #f] - [parent #f] - [title "Racket Webview Window"] - [file-not-found-handler (λ (file base-path path) path)] - ) - - (define wv #f) - - (define (event-handler wv evt) - (displayln evt)) - - (super-new) - - (begin - (set! wv (webview-create - profile - (webview-standard-file-getter base-dir - file-not-found-handler) - event-handler))) - ) - ) - \ No newline at end of file + (init-field element-id + \ No newline at end of file