0
|
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["&","&"]]Replace["<", "<"]]Replace[">", ">"]
|
|
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 }
|