103a3c8a930359ddefb652b92bff8b11cf275535
[nit.git] / src / examples / nitlight_as_a_service.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # This is an example of a client of the frontend without command-line processing.
16 #
17 # It offers a simple nitcorn web server that offers a textarea and nitpick and nitlignt it.
18 module nitlight_as_a_service
19
20 import frontend
21 import highlight
22 import nitcorn
23 import nitcorn::log
24 import template
25 import json::serialization_write
26
27 # Nitcorn service to hightlight code
28 #
29 # It's a single stand-alone page that has to form to itself.
30 class HighlightAction
31 super Action
32
33 redef fun answer(http_request, turi)
34 do
35 var hl = new HighlightVisitor
36 var page = new Template
37
38 # There is code? Process it
39 var code = http_request.post_args.get_or_null("code")
40 var hlcode = null
41 if code != null then hlcode = hightlightcode(hl, code)
42
43 if http_request.post_args.get_or_null("json") == "true" and hlcode != null then
44 var response = new HttpResponse(200)
45 response.header["Content-Type"] = "text/json"
46 response.body = hlcode.to_json
47 return response
48 end
49
50 if http_request.post_args.get_or_null("ajax") == "true" and hlcode != null then
51 page.add hlcode.code_mirror_update
52 page.add """
53 document.getElementById("lightcode").innerHTML = "{{{hl.html.write_to_string.escape_to_c}}}";
54 nitmessage();
55 """
56
57 var response = new HttpResponse(200)
58 response.header["Content-Type"] = "application/javascript"
59 response.body = page.write_to_string
60 return response
61 end
62
63 page.add """
64 <!doctype html><html><head>{{{hl.head_content}}}
65 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.16.0/codemirror.css">
66 <style>
67 {{{hl.css_content}}}
68 textarea {width:100%;}
69 .lint-error {font-family: arial; font-size: 70%; background: #ffa; color: #a00; padding: 2px 5px 3px; }
70 .lint-error-icon {color: red; padding: 0 3px; margin-right: 7px;}
71 </style></head><body>
72 """
73 # Add the form+textarea
74 page.add """
75 <form action="#light" method=post><textarea id=code name=code rows=10>{{{code or else ""}}}</textarea><br><input type=submit></form>
76 """
77
78 if hlcode != null then
79 # Inject highlight
80 page.add "<pre id=light><code id=lightcode>"
81 page.add hl.html.write_to_string
82 page.add "</code></pre><hr>"
83 page.add "<ul>"
84
85 # List messages
86 for m in hlcode.source.messages do
87 page.add "<li>{m.location.as(not null)}: {m.text}</li>"
88 end
89 page.add "</ul>"
90 else
91 page.add "<pre id=light><code id=lightcode></code></pre>"
92 end
93
94 page.add hl.foot_content
95
96 # Call codemirror
97 page.add """
98 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.16.0/codemirror.min.js"></script>
99 <script>
100 var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
101 lineNumbers: true
102 });
103 """
104
105 # Callback to update codemirror messages
106 if hlcode != null then
107 page.add hlcode.code_mirror_update
108 else
109 page.add "function nitmessage()\{\}"
110 end
111 page.add """
112 var widgets = [];
113 nitmessage();
114
115 function updatePage() {
116 $.post("", { ajax: true, code: editor.getValue()}, function(data) {
117 eval(data);
118 $(".popupable").popover({html:true, placement:'top'});
119 });
120 }
121
122 var waiting;
123 editor.on("change", function() {
124 clearTimeout(waiting);
125 waiting = setTimeout(updatePage, 500);
126 });
127 waiting = setTimeout(updatePage, 500);
128
129 </script>
130 </body></html>
131 """
132
133 var response = new HttpResponse(200)
134 response.header["Content-Type"] = "text/html"
135 response.body = page.write_to_string
136 return response
137 end
138 end
139
140 var host = "localhost:8080"
141 if args.length > 0 then host = args.first
142
143 var vh = new VirtualHost(host)
144 vh.routes.add new Route("/", new HighlightAction)
145 var factory = new HttpFactory.and_libevent
146 factory.config.virtual_hosts.add vh
147 factory.run