comparison framework.rhope @ 0:76568becd6d6

Rhope Alpha 2a source import
author Mike Pavone <pavone@retrodev.com>
date Tue, 28 Apr 2009 23:06:07 +0000
parents
children b3f71490858c
comparison
equal deleted inserted replaced
-1:000000000000 0:76568becd6d6
1 Import webserver.rhope
2
3 Framework Handler[con,path,request type,queryvars,headers,handler,title,use session]
4 {
5 page <- New@Page[title, path, use session, queryvars, headers]
6 out list <- [handler]Do[ [[New@List[]]Append[page]]Append[path] ]
7 handler page <- [out list]Index[0]
8 If[[request type] = ["POST"]]
9 {
10 final page <- Process POST[handler page, con, headers]
11 }{
12 final page <- Val[handler page]
13 }
14 string,out headers <- [final page]Render
15
16 [HTTP OK[con, Get Content Type[".html"], [string]Length, out headers]
17 ]Put String[string]
18 }
19
20 Handler Fixer[handler:out]
21 {
22 If[[Type Of[handler]] = ["List"]]
23 {
24 out <- [[["Framework Handler"]Set Input[5, [handler]Index[0]]]Set Input[6, [handler]Index[1]]]Set Input[7, [handler]Index[2]]
25 }{
26 out <- handler
27 }
28 }
29
30 Start Web[handlers]
31 {
32 Print["Starting Rhope Web Server"]
33 Init Sessions[]
34 { Listen on Port[80,["Connection Start"]Set Input[1, Map[handlers,"Handler Fixer"]]] }
35 Wait Forever[]
36 }
37
38 Get Class[container:class]
39 {
40 If[[[[container]Class >>]Length] > [0]]
41 {
42 class <- [[" class=\""]Append[[container]Class >>]]Append["\""]
43 }{
44 class <- ""
45 }
46 }
47
48 Blueprint Web Event
49 {
50 Event Name
51 Origin
52 Data
53 }
54
55 New@Web Event[name,origin,data:out]
56 {
57 out <- [[[Build["Web Event"]]Event Name <<[name]]Origin <<[origin]]Data <<[data]
58 }
59
60 Blueprint Web Container
61 {
62 Tag Name
63 Class
64 Propagate Events
65 Children
66 Handlers
67 Named Children
68 Session
69 Use Session
70 }
71
72 New@Web Container[class:out]
73 {
74 out <- [[[[[[[Build["Web Container"]
75 ]Tag Name <<["div"]
76 ]Class <<[class]
77 ]Propagate Events <<[No]
78 ]Children <<[New@List[]]
79 ]Named Children <<[New@Dictionary[]]
80 ]Handlers <<[New@Dictionary[]]
81 ]Use Session <<[No]
82 }
83
84 Name@Web Container[cont:out,none]
85 {
86 none <- cont
87 }
88
89 Render Child[start,container:out]
90 {
91 out <- [start]Append[[container]Render]
92 }
93
94 Set Session@Web Container[container,session:out]
95 {
96 out <- [
97 [
98 [container]Use Session <<[Yes]
99 ]Session <<[session]
100 ]Children <<[ Map[ [container]Children >>, ["Set Session"]Set Input[1, session] ] ]
101 }
102
103 Set Handler@Web Container[container,event name,handler:out]
104 {
105 out <- [container]Handlers <<[ [[container]Handlers >> ]Set[event name, handler] ]
106 }
107
108 Render@Web Container[container:out,headers]
109 {
110 out <- [[[[[[["<"]Append[ [container]Tag Name >> ]
111 ]Append[Get Class[container]]
112 ]Append[">\n\t"]
113 ]Append[Fold[["Render Child"]<String@Worker, "", [container]Children >>]]
114 ]Append["\n</"]
115 ]Append[ [container]Tag Name >> ]
116 ]Append[">\n"]
117 }
118
119 Container Event Handler[container,events,index:cont,out events]
120 {
121 event <- [events]Index[index]
122 [[container]Handlers >>]Index[ [event]Event Name >>]
123 {
124 result list <- [~]Do[
125 [[New@List[]]Append[container]]Append[event]
126 ]
127 new container <- [result list]Index[0]
128 [result list]Index[1]
129 {
130 out events <- [result events]Append[~]
131 }{
132 out events <- Val[result events]
133 }
134 }{
135 new container <- container
136 out events <- Val[result events]
137 }
138
139 [events]Next[index]
140 {
141 cont, result events <- Container Event Handler[new container, events, ~]
142 }{
143 cont <- Val[new container]
144 result events <- New@List[]
145 }
146 }
147
148 Container Postback Helper[container,post data,index,events:out,out events]
149 {
150 ,current events <- [[[container]Children >>]Index[index]]Postback[post data]
151 {
152 new container <- [container]Children <<[[[container]Children >>]Set[index, ~]]
153 }
154 combined events <- Concatenate[events, current events]
155 [[new container]Children >>]Next[index]
156 {
157 out, out events <- Container Postback Helper[new container, post data, ~, combined events]
158 }{
159 [combined events]First
160 {
161 out, newevents <- Container Event Handler[new container, combined events, ~]
162 out events <- Concatenate[combined events, newevents]
163 }{
164 out <- Val[new container]
165 out events <- Val[combined events]
166 }
167 }
168 }
169
170 Postback@Web Container[container,post data:out,events]
171 {
172 [[container]Children >>]First
173 {
174 out, postback events <- Container Postback Helper[container, post data, ~, New@List[]]
175 If[[container]Propagate Events >>]
176 {
177 events <- Val[postback events]
178 }{
179 events <- New@List[]
180 }
181 }{
182 out <- container
183 events <- New@List[]
184 }
185 }
186
187 Add Child[cont,child:out]
188 {
189 If[[cont]Use Session >>]
190 {
191 prepped child <- [child]Set Session[[cont]Session >>]
192 }{
193 prepped child <- Val[child]
194 }
195 with child <- [cont]Children <<[ [[cont]Children >>]Append[prepped child] ]
196
197 [prepped child]Name
198 {
199 out <- [with child]Named Children <<[ [[with child]Named Children >>]Set[~, [[[with child]Children >>]Length] - [1]] ]
200 }{
201 out <- Val[with child]
202 }
203 }
204
205 Get Child By Name[container,name:out,not found]
206 {
207 ,not found <- [[container]Named Children >>]Index[name]
208 {
209 out <- [[container]Children >>]Index[~]
210 }
211 }
212
213 Blueprint Page
214 {
215 Title
216 URL
217 CSS
218 Children
219 Named Children
220 Handlers
221 Use Session
222 Session
223 Session ID
224 }
225
226 Set Handler@Page[container,event name,handler:out]
227 {
228 out <- [container]Handlers <<[ [[container]Handlers >> ]Set[event name, handler] ]
229 }
230
231 New@Page[title,url,use session,queryvars,headers:out]
232 {
233 page <- [[[[[[[Build["Page"]
234 ]Title <<[title]
235 ]URL <<[url]
236 ]CSS <<[[New@List[]]Append["/default.css"]]
237 ]Children <<[New@List[]]
238 ]Named Children <<[New@Dictionary[]]
239 ]Handlers <<[New@Dictionary[]]
240 ]Use Session <<[use session]
241
242 If[use session]
243 {
244 Load@Session[queryvars, headers]
245 {
246 out <- [[page]Session <<[~]]Session ID <<[ [~]Session ID>>]
247 }
248 }{
249 out <- Val[page]
250 }
251 }
252
253 Get Action@Page[page:out]
254 {
255 If[[page]Use Session>>]
256 {
257 [[page]Session >>]Get Link Params
258 {
259 out <- [[[page]URL >>]Append["?"]]Append[~]
260 }{
261 out <- [page]URL >>
262 }
263 }{
264 out <- [page]URL >>
265 }
266 }
267
268 Render@Page[page:out,headers]
269 {
270 out <- [[[[[[["<html>\n\t<head>\n\t\t<title>"]Append[[page]Title >>]
271 ]Append["</title>\n\t\t<link rel=\"stylesheet\" href=\""]
272 ]Append[[[page]CSS >>]Join["\">\n\t\t<link rel=\"stylesheet\" href=\""]]
273 ]Append["\">\n\t</head>\n\t<body>\n\t<form method=\"POST\" action=\""]
274 ]Append[[[page]Get Action]Append["\">\n"]]
275 ]Append[Fold[["Render Child"]<String@Worker, "", [page]Children >>]]
276 ]Append["\t</form>\n\t</body>\n</html>"]
277 If[[page]Use Session>>]
278 {
279 headers <- [[page]Session >>]Finalize[New@Dictionary[]]
280 }{
281 headers <- New@Dictionary[]
282 }
283 }
284
285 Clear Children[page:out]
286 {
287 out <- [[page]Children <<[New@List[]]]Named Children <<[New@Dictionary[]]
288 }
289
290 Set@Page[page,key,val:out]
291 {
292 out <- [page]Session <<[ [[page]Session >>]Set[key, val] ]
293 }
294
295 Index@Page[page,key:out,not found]
296 {
297 out,not found <- [[page]Session >>]Index[key]
298 }
299
300 First@Page[page:first,not found]
301 {
302 first,not found <- [[page]Session >>]First
303 }
304
305 Next@Page[page,last:next,not found]
306 {
307 next,not found <- [[page]Session >>]Next[last]
308 }
309
310 Add CSS@Page[page,css:out]
311 {
312 out <- [page]CSS <<[ [[page]CSS >>]Append[css] ]
313 }
314
315 Clear CSS@Page[page:out]
316 {
317 out <- [page]CSS <<[New@List[]]
318 }
319
320 Decode Helper Decode[list,destlist,index:out]
321 {
322 code,rest <- [[list]Index[index]]Slice[2]
323 newlist <- [destlist]Set[index, [[""]Put Byte[From Hex@Whole Number[code]]]Append[rest]]
324 [list]Next[index]
325 {
326 out <- Decode Helper Straight[list, newlist, ~]
327 }{
328 out <- Val[newlist]
329 }
330 }
331
332 Decode Helper Straight[list,destlist,index:out]
333 {
334 newlist <- [destlist]Set[index, [list]Index[index]]
335 [list]Next[index]
336 {
337 out <- Decode Helper Decode[list, newlist, ~]
338 }{
339 out <- Val[newlist]
340 }
341 }
342
343 URL Decode[val:out]
344 {
345 parts <- [val]Split["%"]
346 [parts]First
347 {
348 out <- [Decode Helper Straight[parts, New@List[], ~]]Join[""]
349 }{
350 out <- val
351 }
352 }
353
354 URL Encode Path[string:out]
355 {
356 out <- [[[[string]Replace["%","%25"]]Replace[" ","%20"]]Replace["/","%2F"]]Replace["?","%3F"]
357 }
358
359 Decode Pair[val,key:oval,okey]
360 {
361 oval <- URL Decode[val]
362 okey <- URL Decode[key]
363 }
364
365 Process POST[page,con,headers:out]
366 {
367 [con]Get FString[[headers]Index["Content-Length"]] {}
368 {
369 post string <- [~]Replace["+"," "]
370 }
371 post data <- Key Value Map[Dict Split[post string, "=", "&"], ["Decode Pair"]<String@Worker]
372 out <- [page]Postback[post data]
373 }
374
375 Postback@Page[page,post data:out,events]
376 {
377 [[page]Children >>]First
378 {
379 out, events <- Container Postback Helper[page, post data, ~, New@List[]]
380 }{
381 out <- page
382 }
383 events <- New@List[]
384 }
385
386 Blueprint Web Text
387 {
388 Text
389 Enclosing Tag
390 }
391
392 New@Web Text[text,tag:out]
393 {
394 out <- [[Build["Web Text"]]Text <<[text]]Enclosing Tag <<[tag]
395 }
396
397 Name@Web Text[text:out,none]
398 {
399 none <- text
400 }
401
402 Escape HTML Text[string:out]
403 {
404 out <- [[[string]Replace["&","&amp;"]]Replace["<", "&lt;"]]Replace[">", "&gt;"]
405 }
406
407 Render@Web Text[text:out,headers]
408 {
409 processed text <- [Escape HTML Text[[text]Text >>]]Replace["\n","<br>\n\t"]
410 If[[[[text]Enclosing Tag >>]Length] = [0]]
411 {
412 out <- Val[processed text]
413 }{
414 out <- [[[["<"]Append[[text]Enclosing Tag >>]]Append[">"]]Append[processed text]]Append[[["</"]Append[[text]Enclosing Tag >>]]Append[">"]]
415 }
416 }
417
418 Postback@Web Text[text,post data:out,events]
419 {
420 out <- text
421 events <- New@List[]
422 }
423
424 Set Session@Web Text[text,session:out]
425 {
426 out <- session
427 }
428
429 Render@String[string:out,headers]
430 {
431 out <- [New@Web Text[string,""]]Render
432 }
433
434 Name@String[string:out,none]
435 {
436 none <- string
437 }
438
439 Postback@String[in,post data:out,events]
440 {
441 out <- in
442 events <- New@List[]
443 }
444
445 Set Session@String[in,session:out]
446 {
447 out <- in
448 }
449
450 Blueprint Web Field
451 {
452 Name
453 Value
454 Type
455 Class
456 }
457
458 Name@Web Field[field:name,none]
459 {
460 name <- [field]Name >>
461 }
462
463 New@Web Field[name,value,type:out]
464 {
465 out <- [[[[Build["Web Field"]]Name <<[name]]Value <<[value]]Type <<[type]]Class <<[""]
466 }
467
468 Set Session@Web Field[in,session:out]
469 {
470 out <- in
471 }
472
473 Render@Web Field[field:out,headers]
474 {
475 If[[[field]Type >>] = ["multiline"]]
476 {
477 out <- [[[[[["<textarea name=\""]Append[[field]Name >>]]Append["\""]]Append[Get Class[field]]]Append[">"]]Append[[field]Value >>]]Append["</textarea>"]
478 }{
479 out <- [[[[[[[["<input type=\""]Append[[field]Type >>]]Append["\" name=\""]]Append[[field]Name >>]]Append["\""]]Append[Get Class[field]]]Append[" value=\""]]Append[[field]Value >>]]Append["\">"]
480 }
481
482 }
483
484 Postback@Web Field[field,post data:out,event]
485 {
486 [post data]Index[[field]Name >>]
487 {
488 out <- [field]Value <<[~]
489
490 If[[[field]Value >>] = [~]]
491 {
492 event <- New@List[]
493 }{
494 event <- [New@List[]]Append[ New@Web Event["change", [field]Name >>, [field]Value >>] ]
495 }
496 }{
497 out <- field
498 event <- New@List[]
499 }
500 }
501
502 Blueprint Web Button
503 {
504 Name
505 Label
506 Class
507 }
508
509 New@Web Button[name,label:out]
510 {
511 out <- [[[Build["Web Button"]]Name <<[name]]Label <<[label]]Class <<[""]
512 }
513
514 Name@Web Button[button:name,none]
515 {
516 name <- [button]Name >>
517 }
518
519 Set Session@Web Button[in,session:out]
520 {
521 out <- in
522 }
523
524 Postback@Web Button[button,post data:out,events]
525 {
526 out <- button
527 [post data]Index[[button]Name >>]
528 {
529 events <- [New@List[]]Append[ New@Web Event["click", [button]Name >>, 0] ]
530 }{
531 events <- New@List[]
532 }
533 }
534
535 Render@Web Button[button:out,headers]
536 {
537 out <- [[[[[["<input type=\"submit\" name=\""]Append[[button]Name >>]]Append["\""]]Append[Get Class[button]]]Append[" value=\""]]Append[[button]Label >>]]Append["\">"]
538 }
539
540 Blueprint Session
541 {
542 Session ID
543 IP Address
544 Use Cookies
545 Data
546 }
547
548 Get Unique ID[:out] uses Session
549 {
550 out <- [[[::ID]<Whole Number@String]Append["_"]]Append[Random[]]
551 ::ID <- [::ID]+[1]
552 }
553
554 New@Session[:out]
555 {
556 out <- [[[Build["Session"]]Session ID <<[Get Unique ID[]]]Use Cookies <<[No]]Data <<[New@Dictionary[]]
557 }
558
559 Load@Session[queryvars,headers:out] uses Session
560 {
561 ,checkquery <- [headers]Index["Cookie"]
562 {
563 parts <- Dict Split[~, "=", "; "]
564 ,checkquery <- [parts]Index["session_id"]
565 {
566 ,checkquery <- [::Sessions]Index[~]
567 {
568 out <- [~]Use Cookies <<[Yes]
569 }
570 }
571 }
572
573
574 Val[checkquery]
575 {
576 ,makenew <- [queryvars]Index["session_id"]
577 {
578 out, makenew <- [::Sessions]Index[~]
579 }
580 }
581
582 Val[makenew]
583 {
584 out <- New@Session[]
585 }
586 }
587
588 Get Link Params@Session[session:out,no params]
589 {
590 If[[session]Use Cookies >>]
591 {
592 no params <- No
593 }{
594 out <- ["session_id="]Append[[session]Session ID >>]
595 }
596 }
597
598 Set@Session[session,key,val:out]
599 {
600 out <- [session]Data <<[ [[session]Data >>]Set[key, val] ]
601 }
602
603 Index@Session[session,key:out,not found]
604 {
605 out,not found <- [[session]Data >>]Index[key]
606 }
607
608 First@Session[session:first,not found]
609 {
610 first,not found <- [[session]Data >>]First
611 }
612
613 Next@Session[session,last:next,not found]
614 {
615 next,not found <- [[session]Data >>]Next[last]
616 }
617
618 Init Sessions[:out] uses Session
619 {
620 ::ID <- 1
621 ::Sessions <- New@Dictionary[]
622 out <- 0
623 }
624
625 Finalize@Session[session,headers:out headers] uses Session
626 {
627 ::Sessions <- [::Sessions]Set[[session]Session ID >>, session]
628 out headers <- [headers]Set["Set-Cookie", ["session_id="]Append[[session]Session ID >>]]
629 }
630
631 Blueprint Web Link
632 {
633 Text
634 Target
635 Class
636 Query Params
637 }
638
639 New@Web Link[text,target:out]
640 {
641 out <- [[[[Build["Web Link"]]Text <<[text]]Target <<[target]]Class <<[""]]Query Params <<[New@Dictionary[]]
642 }
643
644
645 With Session@Web Link[text,target,session:out]
646 {
647 New@Web Link[text, target]
648 {
649 out <- [~]Query Params <<[[[~]Query Params >>]Set["session_id", [session]Session ID >>]]
650 }
651 }
652
653 Render@Web Link[link:out,headers]
654 {
655 [[link]Query Params>>]First
656 {
657 queryvars <- ["?"]Append[Key Value Join[[link]Query Params>>, "=","&"]]
658 }{
659 queryvars <- ""
660 }
661 out <- [[[[[[["<a href=\""]Append[[link]Target>>]]Append[queryvars]]Append["\""]
662 ]Append[Get Class[link]]]Append[">"]]Append[Escape HTML Text[[link]Text>>]]]Append["</a>"]
663 }
664
665 Postback@Web Link[in,post data:out,events]
666 {
667 out <- in
668 events <- New@List[]
669 }
670
671 Name@Web Link[link:name,none]
672 {
673 none <- link
674 }
675
676 Set Session@Web Link[link,session:out]
677 {
678 If[[[[link]Target >>]Slice[7]] = ["http://"]]
679 {
680 out <- link
681 }{
682 If[[session]Use Cookies >>]
683 {
684 out <- link
685 }{
686 out <- [link]Query Params <<[[[link]Query Params >>]Set["session_id", [session]Session ID>>]]
687 }
688 }
689 }
690
691 Blueprint Web Table
692 {
693 Headers
694 Data
695 }
696
697 New@Web Table[headers,data:out]
698 {
699 out <- [[Build["Web Table"]]Headers <<[headers]]Data <<[data]
700 }
701
702 Name@Web Table[link:name,none]
703 {
704 none <- link
705 }
706
707 Set Session@Web Table[in,session:out]
708 {
709 out <- in
710 }
711
712 Postback@Web Table[table,post data:out,events]
713 {
714 out <- table
715 events <- ()
716 }
717
718 Make Header Row[string,header:out]
719 {
720 out <- [[[string]Append["\t\t\t<th>"]]Append[header]]Append["</th>\n"]
721 }
722
723 Get Header Row@Web Table[table:out]
724 {
725 If[[[[table]Headers >>]Length] > [0]]
726 {
727 out <- [Fold[["Make Header Row"]<String@Worker, "\t\t<tr>\n", [table]Headers >>]]Append["\t\t</tr>\n"]
728 }{
729 out <- ""
730 }
731 }
732
733 Make Table Cell[string,cell:out]
734 {
735 out <- [[[string]Append["\t\t\t<td>"]]Append[[cell]Render]]Append["</td>\n"]
736 }
737
738 Make Table Row[string,row:out]
739 {
740 out <- [Fold[["Make Table Cell"]<String@Worker, [string]Append["\t\t<tr>\n"], row]]Append["\t\t</tr>"]
741 }
742
743 Render@Web Table[table:out,headers]
744 {
745 out <- [
746 [
747 ["\t<table>\n"]Append[[table]Get Header Row]
748 ]Append[ Fold[["Make Table Row"]<String@Worker, "", [table]Data >>] ]
749 ]Append["\t</table>\n"]
750 }