-
Notifications
You must be signed in to change notification settings - Fork 2
/
dw.lisp
121 lines (101 loc) · 4.03 KB
/
dw.lisp
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
(in-package #:plot-window)
;;;; Our Javascript code module DW
(declare-javascript-library jquery ()
:url "//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"
:loaded-p (boundp j-query))
(declare-javascript-library jquery-json (jquery)
:url "/jquery.json-2.4.js"
:loaded-p (boundp (@ j-query to-j-s-o-n)))
(declare-javascript-library graceful-web-socket (jquery)
:url "/jquery.gracefulWebSocket.js"
:loaded-p (boundp (@ j-query graceful-web-socket)))
(define-javascript-code-module dw ()
:requires (graceful-web-socket jquery-json))
(defun-javascript (dw lg) (msg)
(send-ws-message (create :type "page-log" :message msg))
(chain console (log msg)))
(defun-javascript (dw make-element-inserter) (how location)
(create 'how how 'location location))
(defvar-javascript (dw *inserter*) ($ (lambda () (setf (@ dw *inserter*) (make-element-inserter :prepend ($ "body"))))))
(defun-javascript (dw insert-element) (new-element continuation &optional (element-inserter (@ dw *inserter*)))
(let* ((loc (@ element-inserter location)))
(unless (= 1 (length loc))
(throw
(new (-error
(interpolate
"{Selector \"$[place]\" found $[(length loc)] elements, must result in exactly one.}")))))
(case (@ element-inserter how)
(:before
(chain new-element (hide))
(chain loc (before new-element))
(chain new-element (slide-down 1000 continuation)))
(:after
(chain new-element (hide))
(chain loc (after new-element))
(chain new-element (slide-down 1000 continuation)))
(:append
(chain new-element (hide) (fade-in 1000 continuation))
(chain loc (append new-element)))
(:prepend
(chain new-element (hide))
(chain loc (prepend new-element))
(chain new-element (slide-down 1000 continuation)))
(:replace-content
(cprogn (continuation)
(progn
(chain ($ (chain loc (children))) (wrap-all "<div/>"))
(chain loc (children) (fade-out 400 next)))
(progn
(chain loc (empty))
(chain new-element (hide) (fade-in 400 next))
(chain loc (prepend new-element))))))))
(defvar-javascript (dw ws) 1)
(defun-javascript (dw on-message) (e)
(let* ((msg (chain $ (parse-j-s-o-n (@ e data))))
(target (@ msg target))
(selection (if target
(j-query (@ msg target))
j-query))
(event (@ msg event))
(argument (if (@ msg argument)
(@ msg argument)
msg)))
(lg (concatenate 'string "Got: " (chain -J-S-O-N (stringify msg))))
(funcall (aref selection event) argument)))
(defun-javascript (dw initialize) ()
;;; establish dw.ws
(let ((x (chain $ (graceful-web-socket (websocket-url)))))
(flet ((ws-error (e)
(chain console (log "ws hd an error.")))
(ws-open (e)
;; This next line sets *last-websocket-client* over
;; on the lisp side. This should be done in a more
;; fastidious manner.
(lg "websocket has opened")))
(setf (@ dw ws) x)
(setf (@ x onerror) #'ws-error)
(setf (@ x onopen) #'ws-open)
(setf (@ x onmessage) #'on-message)))
(chain console (log "dw module has initialized")))
(defun-javascript (dw send-ws-message) (data)
(cond
((and (boundp (@ this dw))
(boundp (@ dw ws))
(eql (typeof (@ dw ws)) :object)
(not (eql null (@ dw ws))))
(cond
((eql (@ dw ws ready-state) 1)
(chain dw ws (send (chain $ (to-J-S-O-N data)))))
(t
(chain console (log "dw.ws is not open")))))
(t
(chain console (log "dw.ws is unavailable")))))
(defun-javascript (dw clear-screen) ()
(chain ($ :body) (empty)))
(defun clear-display-window ()
(ps-eval-in-client (chain dw (clear-screen))))
#+nil
(defun-javascript (dw create) (prototype-object)
(flet ((-f () (create)))
(setf (@ -f prototype) o)
(new -f)))