]> matita.cs.unibo.it Git - helm.git/blob - matitaB/matita/matitaweb.js
Matitaweb: goto bottom can now be undone step by step and also reports errors
[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 var lockedbackup = "";
19 var matita;
20
21 function text_of_html(h)
22 {
23   if(document.all) {
24      return h.innerText;
25   } else {
26      return h.textContent;
27   }
28 }
29
30 function unescape_html(s)
31 {
32   u = document.getElementById("unescape");
33   u.innerHTML = s;
34   return text_of_html(u)
35 }
36
37 function filterByClass (elements,cname){
38   var itemsfound = new Array;
39   for(var i=0;i<elements.length;i++){
40     if(elements[i].className == cname){
41       itemsfound.push(elements[i]);
42     }
43   }
44   return itemsfound;
45 }
46
47 function initialize()
48 {
49   if (readCookie("session") == null) {
50     window.location = "/login.html"
51   } else {
52     body = document.body;
53     titlebar = document.getElementById("titlebar");
54     matitaTitle = document.getElementById("matitaTitle");
55     apparea = document.getElementById("matitaapparea");
56     locked = document.getElementById("locked");
57     unlocked = document.getElementById("unlocked");
58     toparea = document.getElementById("toparea");
59     workarea = document.getElementById("workarea");
60     scriptcell = document.getElementById("scriptcell");
61     sidearea = document.getElementById("sidearea");
62     disambcell = document.getElementById("disambcell");
63     goalcell = document.getElementById("goalcell");
64     goals = document.getElementById("goals");
65     goalview = document.getElementById("goalview");
66     filename = document.getElementById("filename");
67     logarea = document.getElementById("logarea");
68     advanceButton = document.getElementById("advance");
69     retractButton = document.getElementById("retract");
70     cursorButton = document.getElementById("cursor");
71     bottomButton = document.getElementById("bottom");
72     dialogBox = document.getElementById("dialogBox");
73     uploadBox = document.getElementById("uploadBox");
74     dialogTitle = document.getElementById("dialogTitle");
75     dialogContent = document.getElementById("dialogContent");
76
77     matita = new Object();
78     matita.disambMode = matita.proofMode = false;
79
80     // hide sequent view at start
81     initializeLayout();
82     updateSide();
83
84     changeFile("test.ma");
85
86     // initialize keyboard events in the unlocked script
87     init_keyboard(unlocked);
88
89     init_autotraces();
90
91   }
92 }
93
94 function init_autotraces() {
95     $("#unlocked .autotactic").tooltip({ 
96       delay: 0, 
97       showURL: false, 
98       bodyHandler: function() { 
99         return (trace_of($(this)[0])); 
100       }
101     });
102     $("#locked .autotactic").tooltip({ 
103       delay: 0, 
104       showURL: false, 
105       bodyHandler: function() { 
106         return (trace_of($(this)[0]));
107       }
108     });
109 }
110
111 function trace_of(node) {
112   return text_of_html(filterByClass(node.childNodes,"autotrace")[0]);
113 }
114
115 function changeFile(name) {
116     current_fname = name;
117     matitaTitle.innerHTML = "Matita - cic:/matita/" + name;
118 }
119
120 function init_keyboard(target)
121 {
122     if (target.addEventListener)
123     {
124 //       target.addEventListener("keydown",keydown,false);
125        target.addEventListener("keypress",keypress,false);
126 //       target.addEventListener("keyup",keyup,false);
127 //       target.addEventListener("textInput",textinput,false);
128     }
129     else if (target.attachEvent)
130     {
131 //       target.attachEvent("onkeydown", keydown);
132        target.attachEvent("onkeypress", keypress);
133 //       target.attachEvent("onkeyup", keyup);
134 //       target.attachEvent("ontextInput", textinput);
135     }
136     else
137     {
138 //       target.onkeydown= keydown;
139        target.onkeypress= keypress;
140 //       target.onkeyup= keyup;
141 //       target.ontextinput= textinput;   // probably doesn't work
142     }
143  
144 }
145
146 function keyval(n)
147 {
148     if (n == null) return 'undefined';
149     var s= '' + n;
150     if (n >= 32 && n < 127) s+= ' (' + String.fromCharCode(n) + ')';
151     while (s.length < 9) s+= ' ';
152     return s;
153 }
154  
155 function string_of_key(n)
156 {
157     if (n == null) return 'undefined';
158     return String.fromCharCode(n);
159 }
160
161 function pressmesg(w,e)
162 {
163    debug(w + '  keyCode=' + keyval(e.keyCode) +
164                  ' which=' + keyval(e.which) +
165                  ' charCode=' + keyval(e.charCode) +
166                  '\n          shiftKey='+e.shiftKey
167               + ' ctrlKey='+e.ctrlKey
168               + ' altKey='+e.altKey
169               + ' metaKey='+e.metaKey);
170 }
171  
172 function suppressdefault(e,flag)
173 {
174    if (flag)
175    {
176        if (e.preventDefault) e.preventDefault();
177        if (e.stopPropagation) e.stopPropagation();
178    }
179    return !flag;
180 }
181
182 function restoreSelection(r) {
183     unlocked.focus();
184     if (r != null) {
185         if (window.getSelection)//non IE and there is already a selection
186         {
187             var s = window.getSelection();
188             if (s.rangeCount > 0) 
189                 s.removeAllRanges();
190             s.addRange(r);
191         }
192         else 
193             if (document.createRange)//non IE and no selection
194             {
195                 window.getSelection().addRange(r);
196             }
197             else 
198                 if (document.selection)//IE
199                 {
200                     r.select();
201                 }
202     }
203 }
204
205 function lookup_tex(texmacro)
206 {
207   texmacro = texmacro.substring(1);
208   return unescape(macro2utf8[texmacro]);
209 }
210
211 function strip_tags(tagname,classname) 
212 {
213     var tags = unlocked.getElementsByTagName(tagname);
214     if (is_defined(classname)) {
215         tags = filterByClass(tags,classname);
216     }
217     for (i = 0; i < tags.length; i++) {
218         var children = tags[i].childNodes;
219         for (j = 0; j < children.length; j++) {
220             tags[i].parentNode.insertBefore(children[j],tags[i]);
221         }
222     }
223     while (tags.length > 0) {
224       tags[0].parentNode.removeChild(tags[0]);
225     }
226 }
227
228 function strip_interpr() {
229         strip_tags("A");
230         alert("strip_interpr ended");
231 }
232  
233 function keypress(e)
234 {
235    if (!e) e= event;
236    pressmesg('keypress',e);
237    var s = string_of_key(e.charCode);
238    strip_tags("span","error");
239    if (s == " ") {
240         j = getCursorPos();
241         i = unlocked.innerHTML.html_to_matita().lastIndexOf('\\',j);
242         if (i >= 0) {
243           match = unlocked.innerHTML.html_to_matita().substring(i,j);
244           sym = unescape_html(lookup_tex(match));
245           if (sym != "undefined") {
246              if (window.getSelection) { // non IE
247                 savedRange.setStart(savedsc,savedso - (j-i));
248                 savedRange.deleteContents();
249                 savedRange.insertNode(document.createTextNode(sym));
250                 savedsc.parentNode.normalize();
251                 if (savedRange.collapsed) { // Mozilla
252                   savedRange.setEnd(savedsc,savedRange.endOffset + sym.length);
253                 }
254                 savedRange.collapse(false);
255              } else {
256                 savedRange.moveStart(i-j);
257                 savedRange.text(sym);
258                 savedRange.collapse(false);
259              }
260              restoreSelection(savedRange); 
261              return suppressdefault(e,true);
262           }
263           else {
264              // restoreSelection(0); 
265              return suppressdefault(e,false);
266           }
267         }
268         else return suppressdefault(e,false);
269    } else {
270         return suppressdefault(e,false);
271    }
272 }
273  
274 var logtxt = "";
275
276 function debug(txt)
277 {
278         // internet explorer (v.9) doesn't work with innerHTML
279         // but google chrome's innerText is, in a sense, "write only"
280         // what should we do?
281         // logarea.innerText = txt + "\n" + logarea.innerText;
282         logtxt = /* logtxt + "\n" +*/ txt;
283 }
284
285 function showLog() {
286   logWin = window.open( "", "Matita Log",
287      "width=600,height=450,status,scrollbars,resizable,screenX=20,screenY=40,left=20,top=40");
288   logWin.document.write('<html><head><title>Matita Log' + '</title></head>');   
289   logWin.document.write('<body><textarea style="width:100%;height:100%;">' +
290     logtxt + '</textarea></body></html>');
291   logWin.document.close(); 
292 }
293
294 function listhd(l)
295 {
296         ar = l.split("#");
297         debug("hd of '" + l + "' = '" + ar[0] + "'");
298         return (ar[0]);
299 }
300
301 function listtl(l)
302 {
303         i = l.indexOf("#");
304         tl = l.substr(i+1);
305         debug("tl of '" + l + "' = '" + tl + "'");
306         return (tl);
307 }
308
309 function listcons(x,l)
310 {
311         debug("cons '" + x + "' on '" + l + "'");
312         return (x + "#" + l);
313 }
314
315 function listnil()
316 {
317         return ("");
318 }
319
320 function list_append(l1,l2)
321 { return (l1 + l2) }
322
323 function is_nil(l)
324 {
325         return (l == "");
326 }
327
328 function fold_left (f,acc,l)
329 {
330         if (is_nil(l))
331            { debug("'" + l + "' is fold end");
332            return (acc); }
333         else
334            { debug("'" + l + "' is fold cons");
335              return(fold_left (f,f(acc,(listhd(l))),listtl(l))); }
336 }
337
338 function listiter (f,l)
339 {
340         if (is_nil(l))
341         { debug("'" + l + "' is nil");
342            return;
343         }
344         else
345         {
346            debug("'" + l + "' is not nil");
347            f(listhd(l));
348            listiter(f,listtl(l));
349         }
350 }
351
352 function listmap (f,l)
353 {
354         debug("listmap on " + l);
355         if (is_nil(l)) 
356            { debug("returning listnil");
357              return(listnil());
358            }
359         else 
360            { debug("cons f(hd) map(f,tl)");
361              return(f(listhd(l)) + "#" + listmap(f,listtl(l)));
362            }
363 }
364
365 var statements = listnil();
366
367 var goalarray;
368 var metalist = listnil();
369
370 function pairmap (f,p)
371 {
372   debug("pairmap of '" + p + "'");
373   ar = p.split("|");
374   return (f(ar[0],ar[1])); 
375 }
376
377 function tripletmap (f,p)
378 {
379   debug("tripletmap of '" + p + "'");
380   ar = p.split("|");
381   return (f(ar[0],ar[1],ar[2])); 
382 }
383
384 function fst (p)
385 {
386   debug("fst");
387   return (pairmap (function (a,b) { return (a); }, p));
388 }
389
390 function p13 (p)
391 {
392   debug("p13");
393   return (tripletmap (function (a,b,c) { return (a); }, p));
394 }
395
396 function p23 (p)
397 {
398   debug("p23");
399   return (tripletmap (function (a,b,c) { return (b); }, p));
400 }
401
402 function p33 (p)
403 {
404   debug("f33");
405   return (tripletmap (function (a,b,c) { return (c); }, p));
406 }
407
408 function populate_goalarray(menv)
409 {
410   debug("metasenv.length = " + menv.length);
411   if (menv.length == 0) {
412       try {
413           hideSequent();
414       } catch (err) { };
415   } else {
416       showSequent();
417       goalarray = new Array();
418       metalist = listnil();
419       var tmp_goallist = "";
420       for (i = 0; i < menv.length; i++) {
421         metano = menv[i].getAttribute("number");
422         metaname = menv[i].childNodes[0].childNodes[0].data;
423         goal = menv[i].childNodes[1].childNodes[0].data;
424         debug ("found meta n. " + metano);
425         debug ("found goal\nBEGIN" + goal + "\nEND");
426         goalarray[metano] = goal;
427         tmp_goallist = " <A href=\"javascript:switch_goal(" + metano + ")\">" + metaname + "</A>" + tmp_goallist;
428         metalist = listcons(metano,metalist);
429         debug ("goalarray[\"" + metano + "\"] = " + goalarray[metano]); 
430       }
431       goals.innerHTML = tmp_goallist;
432       debug("new metalist is '" + metalist + "'");
433       if (is_nil(metalist)) {
434         switch_goal();
435       }
436       else {
437         switch_goal(listhd(metalist));
438       }
439   }
440 }
441
442 function switch_goal(meta)
443 {
444   if (typeof meta == "undefined") {
445     goalview.innerHTML = "";
446   }
447   else {
448     debug("switch_goal " + meta + "\n" + goalarray[meta]);
449     goalview.innerHTML = "<B>Goal ?" + meta + ":</B>\n\n" + goalarray[meta];
450   }
451 }
452
453 // the following is used to avoid escaping unicode, which results in 
454 // the server being unable to unescape the string
455 String.prototype.sescape = function() {
456         var patt1 = /%/gi;
457         var patt2 = /=/gi;
458         var patt3 = /&/gi;
459         var patt4 = /\+/gi;
460         var result = this;
461         result = result.replace(patt1,"%25");
462         result = result.replace(patt2,"%3D");
463         result = result.replace(patt3,"%26");
464         result = result.replace(patt4,"%2B");
465         return (result);
466 }
467
468 String.prototype.html_to_matita = function()
469 {
470         var patt1 = /<br(\/|)>/gi;
471         var patt2 = /</gi
472         var patt3 = />/gi
473         var patt4 = /&lt;/gi;
474         var patt5 = /&gt;/gi;
475         var patt6 = /&nbsp;/gi;
476         var result = this;
477         result = result.replace(patt1,"\n");
478         result = result.replace(patt2,"\005");
479         result = result.replace(patt3,"\006");
480         result = result.replace(patt4,"<");
481         result = result.replace(patt5,">");
482         result = result.replace(patt6," ");
483         return (unescape(result));
484 }
485
486 String.prototype.matita_to_html = function()
487 {
488         var patt1 = /</gi
489         var patt2 = />/gi
490         var patt3 = /\005/gi;
491         var patt4 = /\006/gi;
492         var result = this;
493         result = result.replace(patt1,"&lt;");
494         result = result.replace(patt2,"&gt;");
495         result = result.replace(patt3,"<");
496         result = result.replace(patt4,">");
497         return (unescape(result));
498 }
499
500 function pause()
501 {
502         advanceButton.disabled = true;
503         retractButton.disabled = true;
504         cursorButton.disabled = true;
505         bottomButton.disabled = true;
506 }
507
508 function resume()
509 {
510         advanceButton.disabled = false;
511         retractButton.disabled = false;
512         cursorButton.disabled = false;
513         bottomButton.disabled = false;
514 }
515
516 function is_defined(x)
517 {
518         return (typeof x != "undefined");
519 }
520
521 /* servicename: name of the service being called
522  * reqbody: text of the request
523  * processResponse: processes the server response
524  *     (takes the response text in input, undefined in case of error)
525  */
526 function callServer(servicename,processResponse,reqbody)
527 {
528         var req = null; 
529         // pause();
530         if (window.XMLHttpRequest)
531         {
532                 req = new XMLHttpRequest();
533         } 
534         else if (window.ActiveXObject) 
535         {
536                 try {
537                                 req = new ActiveXObject("Msxml2.XMLHTTP");
538                 } catch (e)
539                 {
540                         try {
541                                 req = new ActiveXObject("Microsoft.XMLHTTP");
542                                 } catch (e) {}
543                 }
544         }
545         req.onreadystatechange = function()
546         { 
547
548                 rs = req.readyState;
549
550                 if(rs == 4)
551                 {
552                         stat = req.status;
553                         stxt = req.statusText;
554                         if(stat == 200)
555                         {
556                           debug(req.responseText);
557                           if (window.DOMParser) {
558                             parser=new DOMParser();
559                             xmlDoc=parser.parseFromString(req.responseText,"text/xml");
560                           }
561                           else // Internet Explorer
562                           {
563                             xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
564                             xmlDoc.async="false";
565                             xmlDoc.loadXML(req.responseText);
566                           }     
567                           processResponse(xmlDoc);
568                         } else {
569                           processResponse();
570                         }
571                 } 
572         };
573         req.open("POST", servicename); // + escape(unlocked.innerHTML), true);
574         req.setRequestHeader("Content-type","application/x-www-form-urlencoded");       
575         if (reqbody) {
576                 req.send(reqbody); 
577         } else {
578                 req.send();
579         }
580   
581 }
582
583 function advanceForm1()
584 {
585         processor = function(xml) {
586                 if (is_defined(xml)) {
587                         var parsed = xml.getElementsByTagName("parsed")[0];
588                         var ambiguity = xml.getElementsByTagName("ambiguity")[0];
589                         if (is_defined(parsed)) {
590                         // debug("advance: received response\nBEGIN\n" + req.responseText + "\nEND");
591                             var len = parseInt(parsed.getAttribute("length"));
592                             // len0 = unlocked.innerHTML.length;
593                             var unescaped = unlocked.innerHTML.html_to_matita();
594                             var parsedtxt = parsed.childNodes[0].wholeText;
595                             //parsedtxt = unescaped.substr(0,len); 
596                             var unparsedtxt = unescaped.substr(len);
597                             lockedbackup += parsedtxt;
598                             locked.innerHTML = lockedbackup;
599                             unlocked.innerHTML = unparsedtxt.matita_to_html();
600                             // len1 = unlocked.innerHTML.length;
601                             // len2 = len0 - len1;
602                             var len2 = parsedtxt.length;
603                             var metasenv = xml.getElementsByTagName("meta");
604                             populate_goalarray(metasenv);
605                             init_autotraces();
606                             statements = listcons(len2,statements);
607                             unlocked.scrollIntoView(true);
608                         }
609                         else if (is_defined(ambiguity)) {
610                             var start = parseInt(ambiguity.getAttribute("start"));
611                             var stop = parseInt(ambiguity.getAttribute("stop"));
612                             var choices = xml.getElementsByTagName("choice");
613
614                             matita.ambiguityStart = start;
615                             matita.ambiguityStop = stop;
616                             matita.unlockedbackup = unlocked.innerHTML.html_to_matita();
617                             matita.interpretations = [];
618                         
619                             var unlockedtxt = unlocked.innerHTML.html_to_matita();
620                             var pre = unlockedtxt.substring(0,start).matita_to_html();
621                             var mid = unlockedtxt.substring(start,stop).matita_to_html();
622                             var post = unlockedtxt.substring(stop).matita_to_html();
623                             unlocked.innerHTML = pre + 
624                                     "<span class=\"error\" title=\"disambiguation error\">" +
625                                     mid + "</span>" + post;
626
627                             var title = "<H3>Ambiguous input</H3>";
628                             disambcell.innerHTML = title;
629                             for (i = 0;i < choices.length;i++) {
630                                 matita.interpretations[i] = new Object();
631
632                                 var href = choices[i].getAttribute("href");
633                                 var title = choices[i].getAttribute("title");
634                                 var desc = choices[i].childNodes[0].nodeValue;
635
636                                 matita.interpretations[i].href = href;
637                                 matita.interpretations[i].title = title;
638                                 matita.interpretations[i].desc = desc;
639                                 
640                                 var choice = document.createElement("input");
641                                 choice.setAttribute("type","radio");
642                                 choice.setAttribute("name","interpr");
643                                 choice.setAttribute("href",href);
644                                 choice.setAttribute("title",title);
645                                 if (i == 0) choice.setAttribute("checked","");
646                                 
647                                 disambcell.appendChild(choice);
648                                 disambcell.appendChild(document.createTextNode(desc));
649                                 disambcell.appendChild(document.createElement("br"));
650                             }
651
652                             var okbutton = document.createElement("input");
653                             okbutton.setAttribute("type","button");
654                             okbutton.setAttribute("value","OK");
655                             okbutton.setAttribute("onclick","do_disambiguate()");
656                             var cancelbutton = document.createElement("input");
657                             cancelbutton.setAttribute("type","button");
658                             cancelbutton.setAttribute("value","Cancel");
659                             cancelbutton.setAttribute("onclick","cancel_disambiguate()");
660
661                             disambcell.appendChild(okbutton);
662                             disambcell.appendChild(cancelbutton);
663
664                             disable_toparea();
665
666                             matita.disambMode = true;
667                             updateSide();
668                         }
669                         else {
670                             var error = xml.getElementsByTagName("error")[0]; 
671                             unlocked.innerHTML = error.childNodes[0].wholeText;
672                             // debug(xml.childNodes[0].nodeValue);
673                         }
674                 } else {
675                         debug("advance failed");
676                 }
677                 resume();
678         };
679         pause();
680         callServer("advance",processor,"body=" + (unlocked.innerHTML.html_to_matita()).sescape());
681   
682 }
683
684 function gotoBottom()
685 {
686         processor = function(xml) {
687                 if (is_defined(xml)) {
688                         // debug("goto bottom: received response\nBEGIN\n" + req.responseText + "\nEND");
689                         var parsed = xml.getElementsByTagName("parsed");
690                         var localized = xml.getElementsByTagName("localized")[0];
691                         var ambiguity = xml.getElementsByTagName("ambiguity")[0];
692                         var generic_err = xml.getElementsByTagName("error")[0];
693                         for (var i = 0;i < parsed.length; i++) {
694                           var len = parsed[i].getAttribute("length");
695                           // len0 = unlocked.innerHTML.length;
696                           var unescaped = unlocked.innerHTML.html_to_matita();
697                           // the browser may decide to split textnodes: use wholeText!
698                           var parsedtxt = parsed[i].childNodes[0].wholeText;
699                           //parsedtxt = unescaped.substr(0,len); 
700                           var unparsedtxt = unescaped.substr(len);
701                           lockedbackup += parsedtxt;
702                           locked.innerHTML = lockedbackup; //.matita_to_html();
703                           unlocked.innerHTML = unparsedtxt.matita_to_html();
704                           // len1 = unlocked.innerHTML.length;
705                           var len2 = parsedtxt.length;
706                           statements = listcons(len2,statements);
707                         }
708                         unlocked.scrollIntoView(true);
709                         metasenv = xml.getElementsByTagName("meta");
710                         init_autotraces();
711                         populate_goalarray(metasenv);
712
713                         if (is_defined(ambiguity)) {
714                             var start = parseInt(ambiguity.getAttribute("start"));
715                             var stop = parseInt(ambiguity.getAttribute("stop"));
716                             var choices = xml.getElementsByTagName("choice");
717
718                             matita.ambiguityStart = start;
719                             matita.ambiguityStop = stop;
720                             matita.unlockedbackup = unlocked.innerHTML.html_to_matita();
721                             matita.interpretations = [];
722                         
723                             var unlockedtxt = unlocked.innerHTML.html_to_matita();
724                             var pre = unlockedtxt.substring(0,start).matita_to_html();
725                             var mid = unlockedtxt.substring(start,stop).matita_to_html();
726                             var post = unlockedtxt.substring(stop).matita_to_html();
727                             unlocked.innerHTML = pre + 
728                                     "<span class=\"error\" title=\"disambiguation error\">" +
729                                     mid + "</span>" + post;
730
731                             var title = "<H3>Ambiguous input</H3>";
732                             disambcell.innerHTML = title;
733                             for (i = 0;i < choices.length;i++) {
734                                 matita.interpretations[i] = new Object();
735
736                                 var href = choices[i].getAttribute("href");
737                                 var title = choices[i].getAttribute("title");
738                                 var desc = choices[i].childNodes[0].nodeValue;
739
740                                 matita.interpretations[i].href = href;
741                                 matita.interpretations[i].title = title;
742                                 matita.interpretations[i].desc = desc;
743                                 
744                                 var choice = document.createElement("input");
745                                 choice.setAttribute("type","radio");
746                                 choice.setAttribute("name","interpr");
747                                 choice.setAttribute("href",href);
748                                 choice.setAttribute("title",title);
749                                 if (i == 0) choice.setAttribute("checked","");
750                                 
751                                 disambcell.appendChild(choice);
752                                 disambcell.appendChild(document.createTextNode(desc));
753                                 disambcell.appendChild(document.createElement("br"));
754                             }
755
756                             var okbutton = document.createElement("input");
757                             okbutton.setAttribute("type","button");
758                             okbutton.setAttribute("value","OK");
759                             okbutton.setAttribute("onclick","do_disambiguate()");
760                             var cancelbutton = document.createElement("input");
761                             cancelbutton.setAttribute("type","button");
762                             cancelbutton.setAttribute("value","Cancel");
763                             cancelbutton.setAttribute("onclick","cancel_disambiguate()");
764
765                             disambcell.appendChild(okbutton);
766                             disambcell.appendChild(cancelbutton);
767
768                             disable_toparea();
769
770                             matita.disambMode = true;
771                             updateSide();
772                         }
773                         if (is_defined(localized)) {
774                             unlocked.innerHTML = localized.wholeText;
775                         }
776                         if (is_defined(generic_err)) {
777                             debug("Unmanaged error:\n" ^ generic_err.wholeText);
778                         }
779                 } else {
780                         debug("goto bottom failed");
781                 } 
782                 resume();
783         };
784         pause();
785         callServer("bottom",processor,"body=" + (unlocked.innerHTML.html_to_matita()).sescape());
786 }
787
788
789 function gotoTop()
790 {
791         processor = function(xml) {
792                 if (is_defined(xml)) {
793                   if (xml.childNodes[0].textContent != "ok") {
794                      debug("goto top failed");
795                   }
796                   else
797                         statements = listnil();
798                         /*
799                         lockedlen = locked.innerHTML.length - statementlen;
800                         statement = locked.innerHTML.substr(lockedlen, statementlen);
801                         locked.innerHTML = locked.innerHTML.substr(0,lockedlen);
802                         unlocked.innerHTML = statement + unlocked.innerHTML;
803                         */
804                         unlocked.innerHTML = lockedbackup + unlocked.innerHTML;
805                         lockedbackup = "";
806                         locked.innerHTML = lockedbackup;
807                         init_autotraces();
808                         hideSequent();
809                         unlocked.scrollIntoView(true);
810                 } else {
811                         debug("goto top failed");
812                 } 
813                 resume();
814         };
815         pause();
816         callServer("top",processor,"body=" + (unlocked.innerHTML.html_to_matita()).sescape());
817   
818 }
819 function gotoPos(offset)
820 {
821         if (!is_defined(offset)) {
822                 offset = getCursorPos();
823         }
824         processor = function(xml) {
825                 if (is_defined(xml)) {
826                         parsed = xml.getElementsByTagName("parsed")[0];
827                         len = parseInt(parsed.getAttribute("length"));
828                         // len0 = unlocked.innerHTML.length;
829                         unescaped = unlocked.innerHTML.html_to_matita();
830                         parsedtxt = parsed.childNodes[0].wholeText;
831                         //parsedtxt = unescaped.substr(0,len); 
832                         unparsedtxt = unescaped.substr(len);
833                         lockedbackup += parsedtxt;
834                         locked.innerHTML = lockedbackup; //.matita_to_html();
835                         unlocked.innerHTML = unparsedtxt.matita_to_html();
836                         // len1 = unlocked.innerHTML.length;
837                         len2 = parsedtxt.length;
838                         metasenv = xml.getElementsByTagName("meta");
839                         // populate_goalarray(metasenv);
840                         statements = listcons(len2,statements);
841                         unlocked.scrollIntoView(true);
842                         // la populate non andrebbe fatta a ogni passo
843                         if (offset <= len) {
844                                 init_autotraces();
845                                 populate_goalarray(metasenv);
846                                 resume();
847                         } else {
848                                 gotoPos(offset - len);
849                         }
850                 } else {
851                         init_autotraces();
852                         unlocked.scrollIntoView(true);
853                         populate_goalarray(metasenv);
854                         resume();
855                 }
856         }
857         pause();
858         callServer("advance",processor,"body=" + (unlocked.innerHTML.html_to_matita()).sescape());
859 }
860
861 function retract()
862 {
863         processor = function(xml) {
864                 if (typeof xml != "undefined") {
865                         // debug("advance: received response\nBEGIN\n" + req.responseText + "\nEND");
866                         statementlen = parseInt(listhd(statements));
867                         statements = listtl(statements);
868                         /*
869                         lockedlen = locked.innerHTML.length - statementlen;
870                         statement = locked.innerHTML.substr(lockedlen, statementlen);
871                         locked.innerHTML = locked.innerHTML.substr(0,lockedlen);
872                         unlocked.innerHTML = statement + unlocked.innerHTML;
873                         */
874                         lockedlen = lockedbackup.length - statementlen;
875                         statement = lockedbackup.substr(lockedlen, statementlen);
876                         lockedbackup = lockedbackup.substr(0,lockedlen);
877                         locked.innerHTML = lockedbackup;
878                         unlocked.innerHTML = statement + unlocked.innerHTML;
879                         metasenv = xml.getElementsByTagName("meta");
880                         init_autotraces();
881                         populate_goalarray(metasenv);
882                         unlocked.scrollIntoView(true);
883                 } else {
884                         debug("retract failed");
885                 }
886                 resume();
887         };
888         debug("retract 1");
889         pause();
890         callServer("retract",processor);
891         debug("retract 2");
892 }
893
894 function openFile()
895
896         processor = function(xml)
897         {
898                 if (is_defined(xml)) {  
899                         lockedbackup = "";
900                         locked.innerHTML = lockedbackup;
901                         unlocked.innerHTML = xml.documentElement.wholeText;
902                 } else {
903                         debug("file open failed");
904                 }
905         };
906         callServer("open",processor,"file=" + escape(filename.value)); 
907 }
908
909 function retrieveFile(thefile)
910
911         processor = function(xml)
912         {
913                 if (is_defined(xml)) {  
914                         changeFile(thefile);
915                         lockedbackup = ""
916                         locked.innerHTML = lockedbackup;
917                         // code originally used in google chrome (problems with mozilla)
918                         // debug(xml.getElementsByTagName("file")[0].childNodes[0].nodeValue);
919                         // unlocked.innerHTML = xml.getElementsByTagName("file")[0].childNodes[0].nodeValue;
920                         debug(xml.childNodes[0].textContent);
921                         if (document.all) { // IE
922                           unlocked.innerHTML = xml.childNodes[0].text;
923                         } else {
924                           unlocked.innerHTML = xml.childNodes[0].textContent;
925                         }
926                         init_autotraces();
927
928                 } else {
929                         debug("file open failed");
930                 }
931         };
932         abortDialog();
933         callServer("open",processor,"file=" + escape(thefile)); 
934 }
935
936 function showLibrary(title,callback,reloadDialog)
937
938         var req = null;
939         dialogBox.reload = reloadDialog; 
940         // pause();
941         if (window.XMLHttpRequest)
942         {
943                 req = new XMLHttpRequest();
944         } 
945         else if (window.ActiveXObject) 
946         {
947                 try {
948                                 req = new ActiveXObject("Msxml2.XMLHTTP");
949                 } catch (e)
950                 {
951                         try {
952                                 req = new ActiveXObject("Microsoft.XMLHTTP");
953                                 } catch (e) {}
954                 }
955         }
956         req.onreadystatechange = function()
957         { 
958
959                 rs = req.readyState;
960
961                 if(rs == 4)
962                 {
963                         stat = req.status;
964                         stxt = req.statusText;
965                         if(stat == 200)
966                         {
967                           debug(req.responseText);
968                           showDialog("<H2>" + title + "</H2>",req.responseText, callback);
969                         } 
970                 } 
971         };
972         req.open("POST", "viewlib"); // + escape(unlocked.innerHTML), true);
973         req.setRequestHeader("Content-type","application/x-www-form-urlencoded");       
974         req.send();
975   
976 }
977
978 function uploadDialog()
979 {  
980         uploadBox.style.display = "block";
981 }
982
983 function uploadOK()
984 {   
985    var file = document.getElementById("uploadFilename").files[0];
986    if (file) { 
987        var filecontent = file.getAsText("UTF-8");
988        locked.innerHTML = lockedbackup;
989        unlocked.innerHTML = filecontent;
990        uploadBox.style.display = "none";
991    }
992 //   if (file) { 
993 //      var reader = new FileReader();
994 //      reader.readAsText(file, "UTF-8");
995 //       reader.onloadend = function (evt) {
996 //         lockedbackup = "";
997 //           locked.innerHTML = lockedbackup
998 //           unlocked.innerHTML = evt.target.result;
999 //           uploadBox.style.display = "none";
1000 //       }
1001 //       reader.onerror = function (evt) {
1002 //         debug("file open failed");
1003 //           uploadBox.style.display = "none";
1004 //      }
1005 //   }
1006 }
1007
1008 function openDialog()
1009 {  
1010         callback = function (fname) { retrieveFile(fname); };
1011         showLibrary("Open file", callback, openDialog);
1012 }
1013
1014 function saveDialog()
1015 {  
1016         callback = function (fname) { 
1017           abortDialog();
1018           saveFile(fname,
1019                    (locked.innerHTML.html_to_matita()).sescape(),
1020                    (unlocked.innerHTML.html_to_matita()).sescape(),
1021                    false,saveDialog); 
1022         };
1023         showLibrary("Save file as", callback, saveDialog);
1024 }
1025
1026 function newDialog()
1027 {
1028         callback = function (fname) { 
1029           abortDialog();
1030           saveFile(fname,"","",false,newDialog,true);
1031         };
1032         showLibrary("Create new file", callback, newDialog);
1033 }
1034
1035
1036 function saveFile(fname,lockedtxt,unlockedtxt,force,reloadDialog,reloadFile)
1037 {
1038         if (!is_defined(reloadFile)) { reloadFile = true };
1039         if (!is_defined(fname)) {
1040             fname = current_fname;
1041             lockedtxt = (locked.innerHTML.html_to_matita()).sescape();
1042             unlockedtxt = (unlocked.innerHTML.html_to_matita()).sescape();
1043             force = true;
1044             // when force is true, reloadDialog is not needed 
1045         }
1046         processor = function(xml) {
1047                 if (is_defined(xml)) {
1048                   if (xml.childNodes[0].textContent != "ok") {
1049                     if (confirm("File already exists. All existing data will be lost.\nDo you want to proceed anyway?")) {
1050                        saveFile(fname,lockedtxt,unlockedtxt,true,reloadDialog,reloadFile);
1051                     } else {
1052                       reloadDialog();
1053                     }
1054                   } else {
1055                     changeFile(fname);
1056                     debug("file saved!");
1057                     if (reloadFile) { retrieveFile(fname); }
1058                   }
1059                 } else {
1060                         debug("save file failed");
1061                 }
1062                 resume();
1063         };
1064         if (is_defined(fname)) {
1065           pause();
1066           callServer("save",processor,"file=" + escape(fname) + 
1067                                     "&locked=" + lockedtxt +
1068                                     "&unlocked=" + unlockedtxt +
1069                                     "&force=" + force);
1070         }
1071         else { debug("no file selected"); }
1072 }
1073
1074 function createDir() {
1075    abortDialog();
1076    dirname = prompt("New directory name:\ncic:/matita/","newdir");
1077    if (dirname != null) {
1078         processor = function(xml) {
1079                 if (is_defined(xml)) {
1080                   if (xml.childNodes[0].textContent != "ok") {
1081                       alert("An error occurred :-(");
1082                   }
1083                 } else {
1084                       alert("An error occurred :-(");
1085                 }
1086                 dialogBox.reload();
1087         };
1088         pause();
1089         callServer("save",processor,"file=" + escape(dirname) + 
1090                                     "&locked=&unlocked=&force=false&dir=true");
1091    } else {
1092       dialogBox.reload();
1093    }
1094 }
1095
1096 function commitAll()
1097 {
1098         processor = function(xml) {
1099                 if (is_defined(xml)) {
1100                         debug(xml.getElementsByTagName("details")[0].textContent);
1101                         alert("Commit executed: see details in the log.\n\n" +
1102                               "NOTICE: this message does NOT imply (yet) that the commit was successful.");
1103                 } else {
1104                         alert("Commit failed!");
1105                 }
1106                 resume();
1107         };
1108         pause();
1109         callServer("commit",processor);
1110 }
1111
1112 function updateAll()
1113 {
1114         processor = function(xml) {
1115                 if (is_defined(xml)) {
1116                         alert("Update executed.\n\n" +
1117                               "Details:\n" +
1118                               xml.getElementsByTagName("details")[0].textContent);
1119                 } else {
1120                         alert("Update failed!");
1121                 }
1122                 resume();
1123         };
1124         pause();
1125         callServer("update",processor);
1126 }
1127
1128 var goalcell;
1129
1130 function hideSequent() {
1131         matita.proofMode = false;
1132         updateSide();
1133 }
1134
1135 function showSequent() {
1136         matita.proofMode = true;
1137         updateSide();
1138 }
1139
1140 function showDialog(title,content,callback) {
1141   dialogTitle.innerHTML = title;
1142   dialogContent.innerHTML = content;
1143   dialogBox.callback = callback;
1144
1145   //Get the screen height and width
1146   var maskHeight = $(document).height();
1147   var maskWidth = $(window).width();
1148   
1149   //Set heigth and width to mask to fill up the whole screen
1150   $('#mask').css({'width':maskWidth,'height':maskHeight});
1151   
1152   //transition effect           
1153   $('#mask').fadeIn(100);       
1154   $('#mask').fadeTo(200,0.8);   
1155   
1156   //Get the window height and width
1157   var winH = $(window).height();
1158   var winW = $(window).width();
1159   
1160   //Set the popup window to center
1161   $('#dialogBox').css('top',  winH/2-$('#dialogBox').height()/2);
1162   $('#dialogBox').css('left', winW/2-$('#dialogBox').width()/2);
1163   
1164   //transition effect
1165   $('#dialogBox').fadeIn(200); 
1166
1167   dialogBox.style.display = "block";
1168 }
1169
1170 function abortDialog(dialog) {
1171   $('#mask').hide();
1172   dialogBox.style.display = "none";
1173 }
1174
1175 function removeElement(id) {
1176   var element = document.getElementById(id);
1177   element.parentNode.removeChild(element);
1178
1179
1180 var savedsc;
1181 var savedso;
1182
1183 function getCursorPos() {
1184   var cursorPos;
1185   if (window.getSelection) {
1186     var selObj = window.getSelection();
1187     savedRange = selObj.getRangeAt(0);
1188     savedsc = savedRange.startContainer;
1189     savedso = savedRange.startOffset;
1190     //cursorPos =  findNode(selObj.anchorNode.parentNode.childNodes, selObj.anchorNode) + selObj.anchorOffset;
1191     cursorPos =  findNode(unlocked.childNodes, selObj.anchorNode,0) + selObj.anchorOffset;
1192     /* FIXME the following works wrong in Opera when the document is longer than 32767 chars */
1193     return(cursorPos);
1194   }
1195   else if (document.selection) {
1196     savedRange = document.selection.createRange();
1197     var bookmark = savedRange.getBookmark();
1198     /* FIXME the following works wrong when the document is longer than 65535 chars */
1199     cursorPos = bookmark.charCodeAt(2) - 11; /* Undocumented function [3] */
1200     return(cursorPos);
1201   }
1202 }
1203
1204 function findNode(list, node, acc) {
1205   for (var i = 0; i < list.length; i++) {
1206     if (list[i] == node) {
1207    //   debug("success " + i);
1208       return acc;
1209     }
1210     if (list[i].hasChildNodes()) {
1211        try {
1212    //      debug("recursion on node " + i);
1213          return (findNode(list[i].childNodes,node,acc))
1214        }
1215        catch (e) { /* debug("recursion failed"); */ }
1216     }
1217     sandbox = document.getElementById("sandbox");
1218     dup = list[i].cloneNode(true);
1219     sandbox.appendChild(dup);
1220 //    debug("fail " + i + ": " + sandbox.innerHTML);
1221     acc += sandbox.innerHTML.html_to_matita().length;
1222     sandbox.removeChild(dup);
1223   }
1224   throw "not found";
1225 }
1226
1227 function test () {
1228   debug("cursor test: " + unlocked.innerHTML.substr(0,getCursorPos()));
1229 }
1230
1231 function get_checked_index(name) {
1232         var radios = document.getElementsByName(name);
1233         for (i = 0; i < radios.length; i++) {
1234             if (radios[i].checked) {
1235                     return i;
1236             }
1237         }
1238         return null;
1239 }
1240
1241 function cancel_disambiguate() {
1242         matita.disambMode = false;
1243         $('#whitemask').hide();
1244         updateSide();
1245 }
1246
1247 function do_disambiguate() {
1248         var i = get_checked_index("interpr");
1249         if (i != null) {
1250             var pre = matita.unlockedbackup
1251                       .substring(0,matita.ambiguityStart).matita_to_html();
1252             var mid = matita.unlockedbackup
1253                       .substring(matita.ambiguityStart,matita.ambiguityStop)
1254                       .matita_to_html();
1255             var post = matita.unlockedbackup
1256                        .substring(matita.ambiguityStop).matita_to_html();
1257
1258             var href = matita.interpretations[i].href;
1259             var title = matita.interpretations[i].title;
1260
1261             if (is_defined(title)) {
1262                 mid = "<A href=\"" + href + "\" title=\"" + title + "\">" + mid + "</A>";
1263             } else {
1264                 mid = "<A href=\"" + href + "\">" + mid + "</A>";
1265             }
1266
1267             unlocked.innerHTML = pre + mid + post;
1268
1269             matita.disambMode = false;
1270             $('#whitemask').hide();
1271             updateSide();
1272         }
1273 }
1274
1275 function readCookie(name) {
1276         var nameEQ = name + "=";
1277         var ca = document.cookie.split(';');
1278         for(var i=0;i < ca.length;i++) {
1279                 var c = ca[i];
1280                 while (c.charAt(0)==' ') c = c.substring(1,c.length);
1281                 if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
1282         }
1283         return null;
1284 }
1285
1286 function delete_cookie ( cookie_name )
1287 {
1288   var cookie_date = new Date();  // current date & time
1289   cookie_date.setTime ( cookie_date.getTime() - 1 );
1290   document.cookie = cookie_name += "=; expires=" + cookie_date.toGMTString();
1291 }
1292
1293 function delete_session()
1294 {
1295         delete_cookie("session");
1296 }
1297
1298 function disable_toparea() {
1299         var offset = $('#toparea').offset();
1300         $('#whitemask').css('top',offset.top);
1301         $('#whitemask').css('left',offset.left);
1302         $('#whitemask').css('width',$('#toparea').outerWidth() + "px");
1303         $('#whitemask').css('height',$('#toparea').outerHeight() + "px");
1304         $('#whitemask').fadeTo('fast',0.7);
1305 }