]> matita.cs.unibo.it Git - helm.git/blob - matitaB/matita/matitaweb.js
e4b0efdba98cc4f72e3d9b22c8fca2519fc8a398
[helm.git] / matitaB / matita / matitaweb.js
1 var locked;
2 var unlocked;
3 var workarea;
4 var scriptcell;
5 var goalcell;
6 var goals;
7 var goalview;
8 var filename;
9 var logarea;
10 var advanceButton;
11 var retractButton;
12 var cursorButton;
13 var bottomButton;
14 var dialogBox;
15 var dialogTitle;
16 var dialogContent;
17 var metasenv = "";
18
19 function initialize()
20 {
21   if (readCookie("session") == null) {
22     window.location = "/login.html"
23   } else {
24     locked = document.getElementById("locked");
25     unlocked = document.getElementById("unlocked");
26     workarea = document.getElementById("workarea");
27     scriptcell = document.getElementById("scriptcell");
28     goalcell = document.getElementById("goalcell");
29     goals = document.getElementById("goals");
30     goalview = document.getElementById("goalview");
31     filename = document.getElementById("filename");
32     logarea = document.getElementById("logarea");
33     advanceButton = document.getElementById("advance");
34     retractButton = document.getElementById("retract");
35     cursorButton = document.getElementById("cursor");
36     bottomButton = document.getElementById("bottom");
37     dialogBox = document.getElementById("dialogBox");
38     dialogTitle = document.getElementById("dialogTitle");
39     dialogContent = document.getElementById("dialogContent");
40   
41     // hide sequent view at start
42     hideSequent();
43
44     // initialize keyboard events in the unlocked script
45     init_keyboard(unlocked);
46   }
47 }
48
49 function init_keyboard(target)
50 {
51     if (target.addEventListener)
52     {
53 //       target.addEventListener("keydown",keydown,false);
54        target.addEventListener("keypress",keypress,false);
55 //       target.addEventListener("keyup",keyup,false);
56 //       target.addEventListener("textInput",textinput,false);
57     }
58     else if (target.attachEvent)
59     {
60 //       target.attachEvent("onkeydown", keydown);
61        target.attachEvent("onkeypress", keypress);
62 //       target.attachEvent("onkeyup", keyup);
63 //       target.attachEvent("ontextInput", textinput);
64     }
65     else
66     {
67 //       target.onkeydown= keydown;
68        target.onkeypress= keypress;
69 //       target.onkeyup= keyup;
70 //       target.ontextinput= textinput;   // probably doesn't work
71     }
72  
73 }
74
75 function keyval(n)
76 {
77     if (n == null) return 'undefined';
78     var s= '' + n;
79     if (n >= 32 && n < 127) s+= ' (' + String.fromCharCode(n) + ')';
80     while (s.length < 9) s+= ' ';
81     return s;
82 }
83  
84 function string_of_key(n)
85 {
86     if (n == null) return 'undefined';
87     return String.fromCharCode(n);
88 }
89
90 function pressmesg(w,e)
91 {
92    debug(w + '  keyCode=' + keyval(e.keyCode) +
93                  ' which=' + keyval(e.which) +
94                  ' charCode=' + keyval(e.charCode) +
95                  '\n          shiftKey='+e.shiftKey
96               + ' ctrlKey='+e.ctrlKey
97               + ' altKey='+e.altKey
98               + ' metaKey='+e.metaKey);
99 }
100  
101 function suppressdefault(e,flag)
102 {
103    if (flag)
104    {
105        if (e.preventDefault) e.preventDefault();
106        if (e.stopPropagation) e.stopPropagation();
107    }
108    return !flag;
109 }
110
111 function restoreSelection(adjust) {
112     unlocked.focus();
113     if (savedRange != null) {
114         if (window.getSelection)//non IE and there is already a selection
115         {
116             var s = window.getSelection();
117             if (s.rangeCount > 0) 
118                 s.removeAllRanges();
119             range = document.createRange();
120             range.setStart(savedsc,savedso + adjust);
121             range.collapse(true);
122             s.addRange(range);
123         }
124         else 
125             if (document.createRange)//non IE and no selection
126             {
127                 window.getSelection().addRange(savedRange);
128             }
129             else 
130                 if (document.selection)//IE
131                 {
132                     savedRange.select();
133                 }
134     }
135 }
136
137 function lookup_tex(texmacro)
138 {
139   texmacro = texmacro.substring(1);
140   return unescape(macro2utf8[texmacro]);
141 }
142  
143 function keypress(e)
144 {
145    if (!e) e= event;
146    pressmesg('keypress',e);
147    var s = string_of_key(e.charCode);
148    if (s == " ") {
149         j = getCursorPos();
150         i = unlocked.innerHTML.lastIndexOf('\\',j);
151         if (i >= 0) {
152           match = unlocked.innerHTML.substring(i,j);
153           pre = unlocked.innerHTML.substring(0,i);
154           post = unlocked.innerHTML.substring(j);
155           
156           sym = lookup_tex(match);
157           if (typeof sym != "undefined") {
158              len1 = unlocked.innerText.length;
159              unlocked.innerHTML = pre + sym + post;
160              len2 = unlocked.innerText.length;
161              restoreSelection(len2 - len1); 
162              return suppressdefault(e,true);
163           }
164           else {
165              // restoreSelection(0); 
166              return suppressdefault(e,false);
167           }
168         }
169         else return suppressdefault(e,false);
170    } else {
171         return suppressdefault(e,false);
172    }
173 }
174  
175 function debug(txt)
176 {
177         // internet explorer (v.9) doesn't work with innerHTML
178         // but google chrome's innerText is, in a sense, "write only"
179         // what should we do?
180         logarea.innerText = txt + "\n" + logarea.innerText;
181 }
182
183 function listhd(l)
184 {
185         ar = l.split("#");
186         debug("hd of '" + l + "' = '" + ar[0] + "'");
187         return (ar[0]);
188 }
189
190 function listtl(l)
191 {
192         i = l.indexOf("#");
193         tl = l.substr(i+1);
194         debug("tl of '" + l + "' = '" + tl + "'");
195         return (tl);
196 }
197
198 function listcons(x,l)
199 {
200         debug("cons '" + x + "' on '" + l + "'");
201         return (x + "#" + l);
202 }
203
204 function listnil()
205 {
206         return ("");
207 }
208
209 function is_nil(l)
210 {
211         return (l == "");
212 }
213
214 function fold_left (f,acc,l)
215 {
216         if (is_nil(l))
217            { debug("'" + l + "' is fold end");
218            return (acc); }
219         else
220            { debug("'" + l + "' is fold cons");
221              return(fold_left (f,f(acc,(listhd(l))),listtl(l))); }
222 }
223
224 function listiter (f,l)
225 {
226         if (is_nil(l))
227         { debug("'" + l + "' is nil");
228            return;
229         }
230         else
231         {
232            debug("'" + l + "' is not nil");
233            f(listhd(l));
234            listiter(f,listtl(l));
235         }
236 }
237
238 function listmap (f,l)
239 {
240         debug("listmap on " + l);
241         if (is_nil(l)) 
242            { debug("returning listnil");
243              return(listnil());
244            }
245         else 
246            { debug("cons f(hd) map(f,tl)");
247              return(f(listhd(l)) + "#" + listmap(f,listtl(l)));
248            }
249 }
250
251 var statements = listnil();
252
253 var goalarray;
254 var metalist = listnil();
255
256 function pairmap (f,p)
257 {
258   debug("pairmap of '" + p + "'");
259   ar = p.split("|");
260   return (f(ar[0],ar[1])); 
261 }
262
263 function tripletmap (f,p)
264 {
265   debug("tripletmap of '" + p + "'");
266   ar = p.split("|");
267   return (f(ar[0],ar[1],ar[2])); 
268 }
269
270 function fst (p)
271 {
272   debug("fst");
273   return (pairmap (function (a,b) { return (a); }, p));
274 }
275
276 function p13 (p)
277 {
278   debug("p13");
279   return (tripletmap (function (a,b,c) { return (a); }, p));
280 }
281
282 function p23 (p)
283 {
284   debug("p23");
285   return (tripletmap (function (a,b,c) { return (b); }, p));
286 }
287
288 function p33 (p)
289 {
290   debug("f33");
291   return (tripletmap (function (a,b,c) { return (c); }, p));
292 }
293
294 function populate_goalarray(menv)
295 {
296   debug("metasenv.length = " + menv.length);
297   if (menv.length == 0) {
298       try {
299           hideSequent();
300       } catch (err) { };
301   } else {
302       showSequent();
303       goalarray = new Array();
304       metalist = listnil();
305       var tmp_goallist = "";
306       for (i = 0; i < menv.length; i++) {
307         metano = menv[i].getAttribute("number");
308         metaname = menv[i].childNodes[0].childNodes[0].data;
309         goal = menv[i].childNodes[1].childNodes[0].data;
310         debug ("found meta n. " + metano);
311         debug ("found goal\nBEGIN" + goal + "\nEND");
312         goalarray[metano] = goal;
313         tmp_goallist = " <A href=\"javascript:switch_goal(" + metano + ")\">" + metaname + "</A>" + tmp_goallist;
314         metalist = listcons(metano,metalist);
315         debug ("goalarray[\"" + metano + "\"] = " + goalarray[metano]); 
316       }
317       goals.innerHTML = tmp_goallist;
318       debug("new metalist is '" + metalist + "'");
319       if (is_nil(metalist)) {
320         switch_goal();
321       }
322       else {
323         switch_goal(listhd(metalist));
324       }
325   }
326 }
327
328 function switch_goal(meta)
329 {
330   if (typeof meta == "undefined") {
331     goalview.innerHTML = "";
332   }
333   else {
334     debug("switch_goal " + meta + "\n" + goalarray[meta]);
335     goalview.innerHTML = "<B>Goal ?" + meta + ":</B>\n\n" + goalarray[meta];
336   }
337 }
338
339 String.prototype.sescape = function() {
340         var patt1 = /%/gi;
341         var patt2 = /=/gi;
342         var patt3 = /&/gi;
343         var patt4 = /\+/gi;
344         var result = this;
345         result = result.replace(patt1,"%25");
346         result = result.replace(patt2,"%3D");
347         result = result.replace(patt3,"%26");
348         result = result.replace(patt4,"%2B");
349         return (result);
350 }
351
352 String.prototype.unescapeHTML = function()
353 {
354         var patt1 = /<br(\/|)>/gi;
355         var patt2 = /&lt;/gi;
356         var patt3 = /&gt;/gi;
357         var result = this;
358         result = result.replace(patt1,"\n");
359         result = result.replace(patt2,"<");
360         result = result.replace(patt3,">");
361         return (unescape(result));
362 }
363
364 function pause()
365 {
366         advanceButton.disabled = true;
367         retractButton.disabled = true;
368         cursorButton.disabled = true;
369         bottomButton.disabled = true;
370 }
371
372 function resume()
373 {
374         advanceButton.disabled = false;
375         retractButton.disabled = false;
376         cursorButton.disabled = false;
377         bottomButton.disabled = false;
378 }
379
380 function is_defined(x)
381 {
382         return (typeof x != "undefined");
383 }
384
385 /* servicename: name of the service being called
386  * reqbody: text of the request
387  * processResponse: processes the server response
388  *     (takes the response text in input, undefined in case of error)
389  */
390 function callServer(servicename,processResponse,reqbody)
391 {
392         var req = null; 
393         // pause();
394         if (window.XMLHttpRequest)
395         {
396                 req = new XMLHttpRequest();
397         } 
398         else if (window.ActiveXObject) 
399         {
400                 try {
401                                 req = new ActiveXObject("Msxml2.XMLHTTP");
402                 } catch (e)
403                 {
404                         try {
405                                 req = new ActiveXObject("Microsoft.XMLHTTP");
406                                 } catch (e) {}
407                 }
408         }
409         req.onreadystatechange = function()
410         { 
411
412                 rs = req.readyState;
413
414                 if(rs == 4)
415                 {
416                         stat = req.status;
417                         stxt = req.statusText;
418                         if(stat == 200)
419                         {
420                           debug(req.responseText);
421                           if (window.DOMParser) {
422                             parser=new DOMParser();
423                             xmlDoc=parser.parseFromString(req.responseText,"text/xml");
424                           }
425                           else // Internet Explorer
426                           {
427                             xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
428                             xmlDoc.async="false";
429                             xmlDoc.loadXML(req.responseText);
430                           }     
431                           processResponse(xmlDoc);
432                         } else {
433                           processResponse();
434                         }
435                 } 
436         };
437         req.open("POST", servicename); // + escape(unlocked.innerHTML), true);
438         req.setRequestHeader("Content-type","application/x-www-form-urlencoded");       
439         if (reqbody) {
440                 req.send(reqbody); 
441         } else {
442                 req.send();
443         }
444   
445 }
446
447 function advanceForm1()
448 {
449         processor = function(xml) {
450                 if (is_defined(xml)) {
451                         // debug("advance: received response\nBEGIN\n" + req.responseText + "\nEND");
452                         len = parseInt(xml.getElementsByTagName("parsed")[0].getAttribute("length"));
453                         len0 = unlocked.innerHTML.length;
454                         unescaped = unlocked.innerHTML.unescapeHTML();
455                         parsedtxt = unescaped.substr(0,len); 
456                         unparsedtxt = unescaped.substr(len);
457                         locked.innerHTML = locked.innerHTML + parsedtxt;
458                         unlocked.innerHTML = unparsedtxt;
459                         len1 = unlocked.innerHTML.length;
460                         len2 = len0 - len1;
461                         metasenv = xml.getElementsByTagName("meta");
462                         populate_goalarray(metasenv);
463                         statements = listcons(len2,statements);
464                         unlocked.scrollIntoView(true);
465                 } else {
466                         debug("advance failed");
467                 }
468                 resume();
469         };
470         pause();
471         callServer("advance",processor,"body=" + (unlocked.innerHTML.unescapeHTML()).sescape());
472   
473 }
474
475 function gotoBottom()
476 {
477         processor = function(xml) {
478                 if (is_defined(xml)) {
479                         // debug("goto bottom: received response\nBEGIN\n" + req.responseText + "\nEND");
480                         len = parseInt(xml.getElementsByTagName("parsed")[0].getAttribute("length"));
481                         len0 = unlocked.innerHTML.length;
482                         unescaped = unlocked.innerHTML.unescapeHTML();
483                         parsedtxt = unescaped.substr(0,len); 
484                         unparsedtxt = unescaped.substr(len);
485                         locked.innerHTML = locked.innerHTML + parsedtxt;
486                         unlocked.innerHTML = unparsedtxt;
487                         len1 = unlocked.innerHTML.length;
488                         len2 = len0 - len1;
489                         metasenv = xml.getElementsByTagName("meta");
490                         populate_goalarray(metasenv);
491                         statements = listcons(len2,statements);
492                         unlocked.scrollIntoView(true);
493                 } else {
494                         debug("goto bottom failed");
495                 } 
496                 resume();
497         };
498         pause();
499         callServer("bottom",processor,"body=" + (unlocked.innerHTML.unescapeHTML()).sescape());
500   
501 }
502
503
504 function gotoPos(offset)
505 {
506         if (!is_defined(offset)) {
507                 offset = getCursorPos();
508         }
509         processor = function(xml) {
510                 if (is_defined(xml)) {
511                         // debug("goto pos: received response\nBEGIN\n" + req.responseText + "\nEND");
512                         len = parseInt(xml.getElementsByTagName("parsed")[0].getAttribute("length"));
513                         len0 = unlocked.innerHTML.length;
514                         unescaped = unlocked.innerHTML.unescapeHTML();
515                         parsedtxt = unescaped.substr(0,len); 
516                         unparsedtxt = unescaped.substr(len);
517                         locked.innerHTML = locked.innerHTML + parsedtxt;
518                         unlocked.innerHTML = unparsedtxt;
519                         len1 = unlocked.innerHTML.length;
520                         len2 = len0 - len1;
521                         metasenv = xml.getElementsByTagName("meta");
522                         // populate_goalarray(metasenv);
523                         statements = listcons(len2,statements);
524                         unlocked.scrollIntoView(true);
525                         // la populate non andrebbe fatta a ogni passo
526                         if (offset <= len) {
527                                 populate_goalarray(metasenv);
528                                 resume();
529                         } else {
530                                 gotoPos(offset - len);
531                         }
532                 } else {
533                         unlocked.scrollIntoView(true);
534                         populate_goalarray(metasenv);
535                         resume();
536                 }
537         }
538         pause();
539         callServer("advance",processor,"body=" + (unlocked.innerHTML.unescapeHTML()).sescape());
540 }
541
542 function retract()
543 {
544         processor = function(xml) {
545                 if (typeof xml != "undefined") {
546                         // debug("advance: received response\nBEGIN\n" + req.responseText + "\nEND");
547                         statementlen = parseInt(listhd(statements));
548                         statements = listtl(statements);
549                         lockedlen = locked.innerHTML.length - statementlen;
550                         statement = locked.innerHTML.substr(lockedlen, statementlen);
551                         locked.innerHTML = locked.innerHTML.substr(0,lockedlen);
552                         unlocked.innerHTML = statement + unlocked.innerHTML;
553                         metasenv = xml.getElementsByTagName("meta");
554                         populate_goalarray(metasenv);
555                         unlocked.scrollIntoView(true);
556                 } else {
557                         debug("retract failed");
558                 }
559                 resume();
560         };
561         debug("retract 1");
562         pause();
563         callServer("retract",processor);
564         debug("retract 2");
565 }
566
567 function openFile()
568
569         processor = function(xml)
570         {
571                 if (is_defined(xml)) {  
572                         locked.innerHTML = "";
573                         unlocked.innerHTML = xml.documentElement.textContent;
574                 } else {
575                         debug("file open failed");
576                 }
577         };
578         callServer("open",processor,"file=" + escape(filename.value)); 
579 }
580
581 function retrieveFile(thefile)
582
583         processor = function(xml)
584         {
585                 if (is_defined(xml)) {  
586                         locked.innerHTML = "";
587                         unlocked.innerHTML = xml.documentElement.textContent;
588                 } else {
589                         debug("file open failed");
590                 }
591         };
592         dialogBox.style.display = "none";
593         callServer("open",processor,"file=" + escape(thefile)); 
594 }
595
596 function showLibrary()
597
598         var req = null; 
599         // pause();
600         if (window.XMLHttpRequest)
601         {
602                 req = new XMLHttpRequest();
603         } 
604         else if (window.ActiveXObject) 
605         {
606                 try {
607                                 req = new ActiveXObject("Msxml2.XMLHTTP");
608                 } catch (e)
609                 {
610                         try {
611                                 req = new ActiveXObject("Microsoft.XMLHTTP");
612                                 } catch (e) {}
613                 }
614         }
615         req.onreadystatechange = function()
616         { 
617
618                 rs = req.readyState;
619
620                 if(rs == 4)
621                 {
622                         stat = req.status;
623                         stxt = req.statusText;
624                         if(stat == 200)
625                         {
626                           debug(req.responseText);
627                           showDialog("<H2>Library</H2>",req.responseText);
628                         } 
629                 } 
630         };
631         req.open("POST", "viewlib"); // + escape(unlocked.innerHTML), true);
632         req.setRequestHeader("Content-type","application/x-www-form-urlencoded");       
633         req.send();
634   
635 }
636
637 var goalcell;
638
639 function hideSequent() {
640   goalcell.parentNode.removeChild(goalcell);
641   scriptcell.setAttribute("colspan","2");
642 }
643
644 function showSequent() {
645   scriptcell.setAttribute("colspan","1");
646   workarea.appendChild(goalcell);
647 }
648
649 function showDialog(title,content) {
650   dialogTitle.innerHTML = title;
651   dialogContent.innerHTML = content;
652   dialogBox.style.display = "block";
653 }
654
655 function removeElement(id) {
656   var element = document.getElementById(id);
657   element.parentNode.removeChild(element);
658
659
660 var savedsc;
661 var savedso;
662
663 function getCursorPos() {
664   var cursorPos;
665   if (window.getSelection) {
666     var selObj = window.getSelection();
667     savedRange = selObj.getRangeAt(0);
668     savedsc = savedRange.startContainer;
669     savedso = savedRange.startOffset;
670     //cursorPos =  findNode(selObj.anchorNode.parentNode.childNodes, selObj.anchorNode) + selObj.anchorOffset;
671     cursorPos =  findNode(unlocked.childNodes, selObj.anchorNode,0) + selObj.anchorOffset;
672     /* FIXME the following works wrong in Opera when the document is longer than 32767 chars */
673     return(cursorPos);
674   }
675   else if (document.selection) {
676     savedRange = document.selection.createRange();
677     var bookmark = savedRange.getBookmark();
678     /* FIXME the following works wrong when the document is longer than 65535 chars */
679     cursorPos = bookmark.charCodeAt(2) - 11; /* Undocumented function [3] */
680     return(cursorPos);
681   }
682 }
683
684 function findNode(list, node, acc) {
685   for (var i = 0; i < list.length; i++) {
686     if (list[i] == node) {
687    //   debug("success " + i);
688       return acc;
689     }
690     if (list[i].hasChildNodes()) {
691        try {
692    //      debug("recursion on node " + i);
693          return (findNode(list[i].childNodes,node,acc))
694        }
695        catch (e) { /* debug("recursion failed"); */ }
696     }
697     sandbox = document.getElementById("sandbox");
698     dup = list[i].cloneNode(true);
699     sandbox.appendChild(dup);
700 //    debug("fail " + i + ": " + sandbox.innerHTML);
701     acc += sandbox.innerHTML.length;
702     sandbox.removeChild(dup);
703   }
704   throw "not found";
705 }
706
707 function test () {
708   debug("cursor test: " + unlocked.innerHTML.substr(0,getCursorPos()));
709 }
710
711 function readCookie(name) {
712         var nameEQ = name + "=";
713         var ca = document.cookie.split(';');
714         for(var i=0;i < ca.length;i++) {
715                 var c = ca[i];
716                 while (c.charAt(0)==' ') c = c.substring(1,c.length);
717                 if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
718         }
719         return null;
720 }
721
722 function delete_cookie ( cookie_name )
723 {
724   var cookie_date = new Date();  // current date & time
725   cookie_date.setTime ( cookie_date.getTime() - 1 );
726   document.cookie = cookie_name += "=; expires=" + cookie_date.toGMTString();
727 }
728
729 function delete_session()
730 {
731         delete_cookie("session");
732 }