Dateiverwaltung für die WebBox
ulrich
2021-01-14 ebc1f371409171987dee6a782145189e25cc4d56
commit | author | age
05e9c4 1 function AppVorlage() {
U 2   var self = this;
41ab37 3   this.appMenu;
U 4   this.vorlagen;
5   this.api;
6   this.userid;
7   this.pfad = '';
8   this.loc;
9   this.modus = 'kacheln';
ebc1f3 10   this.cm;
U 11   this.tinymce;
41ab37 12   this.PERS_DIR = "Persoenlich";
U 13   this.PUB_DIR = "Oeffentlich";
14   this.DAV_DIR = "Austausch";
15   this.BASE_DIR = "$basis";
16   this.DATA_DIR = "$daten";
17   this.WWW_DIR = "www";
f002d9 18   this.openEditor;
U 19   this.openFileName;
41ab37 20   this.cache = {}; // mustache template cache
05e9c4 21
94b871 22   this.datei_neuer_text = function () {
ebc1f3 23     //self.meldung_mit_timeout("Neuer Text", 1500);
U 24     self.fm_text_edit('Neue Datei');
25   };
26   
27   this.datei_neuer_ordner = function() {
28     
05e9c4 29   };
U 30
31   /* Funktionen aus App-Vorlage */
94b871 32
U 33   this.init = function () {
f002d9 34     
U 35     // Hide and show an element by changing "display" to block and none
36     document.querySelector(".codeeditor-space").style.display = "none";
37     document.querySelector(".code-editor-container").style.display = "none";
38     document.querySelector("#mce-editor").style.display = "none";
39     //document.querySelector(".box").style.display = "block";
40     
41ab37 41     //self.vorlagen = new Vorlagen();
05e9c4 42     self.appMenu = new AppMenu();
U 43     self.appMenu.init(
94b871 44             "data/menu/",
U 45             "hauptmenue.json",
46             "data/tpl/app-menu.tpl",
47             ".west",
48             "8em");
49     document.querySelector('.hamburger').addEventListener('click', function (e) {
05e9c4 50       self.menue_umschalten();
U 51     });
58bcbd 52     self.fm_get_login();
41ab37 53     
U 54     var parsedUrl = new URL(window.location.href);
55     var wunschPfad = parsedUrl.searchParams.get("pfad");
56
57     if(wunschPfad !== null && wunschPfad.length > 0) {
58       self.pfad = wunschPfad;
59       self.fm_get_list(wunschPfad);
60     } else {
61       self.fm_get_list('');
62     }
ebc1f3 63     
U 64     self.seitenleiste_umschalten();
41ab37 65     //fm_init_uploader();
58bcbd 66     self.loc = window.location.protocol + '//' + window.location.host;
41ab37 67     
U 68     //self.fm_get_list('');
69     //self.loc = window.location.protocol + '//' + window.location.host;
05e9c4 70   };
U 71
58bcbd 72   this.login_zeigen = function() {
U 73     self.meldung_mit_timeout("Benutzer: " + self.userid, 1500);
74   };
75   
94b871 76   this.menue_umschalten = function () {
05e9c4 77     var ham = document.querySelector(".hamburger");
U 78     ham.classList.toggle("is-active"); // hamburger-icon umschalten
79     self.appMenu.toggle(); // menue oeffnen/schliessen
80   };
81
94b871 82   this.info_dialog_zeigen = function () {
05e9c4 83     self.dialog_laden_und_zeigen('data/tpl/dlg-info.tpl', '');
U 84     self.menue_umschalten();
85   };
86
94b871 87   this.seitenleiste_umschalten = function () {
05e9c4 88     var ostDiv = document.querySelector('.ost');
94b871 89     if (ostDiv.classList.contains('ost-open')) {
05e9c4 90       ostDiv.classList.remove('ost-open');
94b871 91       ostDiv.style.flexBasis = '0em';
05e9c4 92     } else {
94b871 93       ostDiv.classList.add('ost-open');
U 94       ostDiv.style.flexBasis = '6em';
05e9c4 95     }
ebc1f3 96     //self.menue_umschalten();
05e9c4 97   };
U 98
94b871 99   this.fusszeile_umschalten = function () {
05e9c4 100     var suedDiv = document.querySelector('.sued');
94b871 101     if (suedDiv.classList.contains('sued-open')) {
05e9c4 102       suedDiv.classList.remove('sued-open');
94b871 103       suedDiv.style.height = '0';
05e9c4 104     } else {
U 105       suedDiv.classList.add('sued-open');
94b871 106       suedDiv.style.height = '1.5em';
05e9c4 107     }
U 108     self.menue_umschalten();
109   };
110
94b871 111   this.meldung_mit_timeout = function (meldung, timeout) {
05e9c4 112     var s = document.querySelector('.sued');
U 113     s.textContent = meldung;
94b871 114     setTimeout(function () {
05e9c4 115       s.textContent = 'Bereit.';
94b871 116       setTimeout(function () {
05e9c4 117         var suedDiv = document.querySelector('.sued');
94b871 118         if (suedDiv.classList.contains('sued-open')) {
U 119           suedDiv.classList.remove('sued-open');
120           suedDiv.style.height = '0';
05e9c4 121         }
U 122       }, 500);
123     }, timeout);
124   };
ebc1f3 125   
U 126   this.fm_menu_datei_schliessen = function() {
127     if(self.openEditor === 'text') {
128       if(!self.cm.getDoc().isClean()) {
129         self.fm_ask_for_save();
130       } else {
131         self.fm_do_close();
132       }
133     } else {
134       if(self.tinymce.activeEditor.undoManager.hasUndo()) {
135         self.fm_ask_for_save();
136       } else {
137         self.fm_do_close();
138       }
139     }
140   };  
141
142   this.fm_ask_for_save = function() {
143     self.dialog_laden_und_zeigen('data/tpl/dlg-ask-save.tpl', '', function() {
144       // wenn dialog da ist, hier events verknuepfen
145       document.querySelector('#cancel-btn').addEventListener('click', function() {
146         self.fm_do_close();
147         self.dialog_schliessen();
148       });
149       document.querySelector('#speichern-btn').addEventListener('click', function() {
150         self.fm_menu_datei_speichern(function() {
151           self.fm_do_close();
152           self.dialog_schliessen();
153         });
154       });
155     });
156   };
157
158   this.fm_menu_datei_speichern = function(callback) {
159     //var fname = $('.datei-gewaehlt').text();
160     var fname = self.openFileName;
161     if(fname !== undefined && fname !== '') {
162       self.fm_save_file(fname, 'saveTextFile', callback);
163     } else {
164       self.fm_menu_datei_speichern_unter(callback);
165     }
166   };
167   
168   this.fm_menu_datei_speichern_unter = function(callback) {  
169     self.dialog_laden_und_zeigen('data/tpl/dlg-save-as.tpl', '', function() {
170
171     });    
172     
173     
174     /*
175     $('#modal_ok').click(function() {
176       $('#modal_ok').attr('onclick','').unbind('click');
177       // hier speichern
178       fm_save_file($('#dateiname').val(), 'saveTextFileAs', callback);
179     });
180     $('#saveModalTitle').text('Datei speichern');
181     $('#dialogfrage').text("Dateiname?");
182
183     var fname = $('.datei-gewaehlt').text();
184     if(fname !== undefined) {
185       $('#dateiname').val(fname);
186     } else {
187       $('#dateiname').val('');
188     }
189     $('#dateiname').attr('placeholder', 'Dateiname');
190     $('#saveModal').modal({
191       keyboard: false,
192       show: true
193     });
194     */
195   };
196
197
05e9c4 198
U 199   /* Dialog-Funktionen */
200
201   /*
94b871 202    Einen Dialog aus Vorlagen erzeugen
U 203    
204    vurl - URL zur Dialogvorlage
205    msgTpl - URL mit einer Vorlage eines Mitteilungstextes (optional)
206    */
ebc1f3 207   this.dialog_laden_und_zeigen = function (vurl, msgTpl, cb) {
U 208     var vorlage = self.cache[vurl];
209     if(vorlage === undefined) {
210       self.fm_get(vurl, "text", function(antwort) {
211         self.cache[vurl] = antwort;
212         self.dialog_zeigen(vurl, antwort, cb);
213         //self.vorlage_fuellen(vurl, inhalt, cb);
94b871 214       });
05e9c4 215     } else {
ebc1f3 216       self.dialog_zeigen(vurl, vorlage, cb);
05e9c4 217     }
U 218   };
219
ebc1f3 220   this.dialog_zeigen = function (vurl, inhalt, cb) {
05e9c4 221     var dlg = document.querySelector(".dialog");
ebc1f3 222     self.html_erzeugen(
94b871 223             vurl,
U 224             inhalt,
225             function (html) {
226               //dlg.html(html);
227               dlg.style.height = '5em';
228               dlg.innerHTML = html;
229               document.querySelector('.close-btn').addEventListener('click', self.dialog_schliessen);
230               //dlg.slideDown(300);
ebc1f3 231               if(typeof(cb) !== 'function') {
U 232                 // ..
233               } else {
234                 cb();
235               }
94b871 236             });
05e9c4 237   };
U 238
58bcbd 239   this.dialog_schliessen = function () {
05e9c4 240     document.querySelector('.close-btn').removeEventListener('click', self.dialog_schliessen);
U 241     //$('.dialog').slideUp(300);
242     var dlg = document.querySelector('.dialog');
243     //dlg.style.display = "none";
244     dlg.style.height = '0';
245     dlg.innerHTML = '';
246   };
6648a8 247  
U 248   this.fm_dateiwahl = function(ev) {
249     var elem = ev.target;
250     if(self.modus == 'kacheln') {
251       // Kacheln
252       if(elem.classList.contains("icon-folder")) {
253         if(/*ev.shiftKey || */ ev.ctrlKey) {
4f01b8 254           var par = elem.parentElement;
U 255           par.querySelector('.dateiname').classList.add('datei-gewaehlt');
6648a8 256         } else {
U 257           var ordner = elem.parentElement.querySelector('.dateiname').textContent.trim();
258           if(self.pfad.length > 0) {
259             self.pfad = self.pfad + '/' + ordner;
260           } else {
261             self.pfad = ordner;
262           }
263           self.fm_get_list(self.pfad);
264         }
265       } else if(elem.classList.contains('datei')) {
266         if(/*ev.shiftKey || */ ev.ctrlKey) {
267           // mehrere Dateien sollen gewaehlt werden
268         } else {
269           var gew = document.querySelector('.datei-gewaehlt');
270           if(gew != undefined) {
271             gew.classList.remove('datei-gewaehlt');
272           }        
273         }
274         var par = elem.parentElement;
275         par.querySelector('.dateiname').classList.add('datei-gewaehlt');
276       } else {
277         //console.log('kein folder oder file...');
278       }
279     } else {
4f01b8 280       // Liste
U 281       var pElem = elem.closest('.datei-zeile');
282       var dElem = pElem.querySelector('.datei-elem');
283       if(dElem.getElementsByTagName("i")[0].classList.contains('icon-doc-text-inv')) {
6648a8 284         // Datei
U 285         if(/*ev.shiftKey || */ ev.ctrlKey) {
286           // mehrere Dateien sollen gewaehlt werden
287         } else {
4f01b8 288           var ti = document.querySelector('.table-info');
U 289           if(ti !== null) {
290             ti.classList.remove('table-info');
291           }
292           var dg = document.querySelector('.datei-gewaehlt');
293           if(dg !== null) {
294             dg.classList.remove('datei-gewaehlt');
295           }
6648a8 296         }
4f01b8 297         pElem.classList.add('table-info');
U 298         pElem.querySelector('.dateiname').classList.add('datei-gewaehlt');
6648a8 299       } else {
U 300         // Ordner
301         if(/*ev.shiftKey || */ ev.ctrlKey) {
4f01b8 302           //elem.children[0].classList.add('datei-gewaehlt');
U 303           pElem.querySelector('.dateiname').classList.add('datei-gewaehlt');
6648a8 304         } else {
4f01b8 305           var ordner = pElem.querySelector('.dateiname').textContent;
6648a8 306           if(self.pfad.length > 0) {
U 307             self.pfad = self.pfad + '/' + ordner;
308           } else {
309             self.pfad = ordner;
310           }
4f01b8 311           self.fm_get_list(self.pfad);
6648a8 312         }
U 313       }   
314     }
315   };
316  
41ab37 317   
58bcbd 318   this.fm_render_list = function (fl) {
4f01b8 319     if (self.modus === 'kacheln') {
58bcbd 320       // Kachelansicht
6648a8 321       self.html_erzeugen("data/tpl/kacheln.tpl", fl, function(html) {
U 322         var elem = document.querySelector('#dateien');
323         elem.innerHTML = html;
324         self.addEvtListener('.figure', 'click', self.fm_dateiwahl);
325       });
58bcbd 326     } else {
U 327       // Listenansicht
4f01b8 328       self.html_erzeugen("data/tpl/liste.tpl", fl, function(html) {
U 329         var elem = document.querySelector('#dateien');
330         elem.innerHTML = html;
331         self.addEvtListener('.datei-zeile', 'click', self.fm_dateiwahl);
332       });
58bcbd 333     }
U 334   };
335   
336   this.fm_get_path = function (uid) {
337     var restdir;
338     if (self.pfad.indexOf(self.PUB_DIR) > -1) {
339       restdir = self.pfad.substr(self.PUB_DIR.length);
340     } else if (self.pfad.indexOf(self.PERS_DIR) > -1) {
341       restdir = self.pfad.substr(self.PERS_DIR.length);
342     } else if (self.pfad.indexOf(self.BASE_DIR) > -1) {
343       restdir = self.pfad.substr(self.BASE_DIR.length);
344     } else if (self.pfad.indexOf(self.DATA_DIR) > -1) {
345       restdir = self.pfad.substr(self.DATA_DIR.length);
346     } else if (self.pfad.indexOf(self.DAV_DIR) > -1) {
347       restdir = self.pfad.substr(self.DAV_DIR.length);
348     }
349     if (restdir !== undefined && restdir.startsWith('/')) {
350       restdir = restdir.substr(1);
351       if (restdir.indexOf(self.WWW_DIR) > -1) {
352         restdir = restdir.replace(self.WWW_DIR, 'data');
353       }
354     }
41ab37 355     var pdir = self.fm_get_base(uid);
58bcbd 356     if (restdir.length > 1) {
U 357       return pdir + "/" + restdir;
358     } else {
359       return pdir;
360     }
361   };
362
363   this.fm_get_base = function (uid) {
364     var pdir;
365     if (self.pfad.indexOf(self.PUB_DIR) > -1) {
366       pdir = '/data/' + uid;
367     } else if (self.pfad.indexOf(self.PERS_DIR) > -1) {
368       pdir = '/home/' + uid;
369     } else if (self.pfad.indexOf(self.BASE_DIR) > -1) {
370       pdir = '';
371     } else if (self.pfad.indexOf(self.DATA_DIR) > -1) {
372       pdir = '';
373     }
374     return pdir;
375   };
2864b2 376   
U 377   /**
378    * Aus einem relativen Pfad ein Array aus BcrFile Objekten 
379    * machen
380    * 
381    * @param {String} relPfad  der relative Pfad
382    * @returns {Array}  die BcrFile-Objekte zum Pfad als Array
383    */
384   this.fm_buildBreadcrumb = function(relPfad) {
385     var rp = '';
386     var dirList = new Array();
387     dirList.push(new BcrFile(rp, 'Home'));
388     if(relPfad.length > 1) {
389       var dirs = relPfad.split('/');
390       for(var i = 0; i < dirs.length; i++) {
391         if(rp.length > 0 ) {
392           // weitere Einträge
393           dirList.push(new BcrFile(rp + '/' + dirs[i], dirs[i]));
394           rp = rp + '/' + dirs[i];
395         } else {
396           // erster Eintrag
397           dirList.push(new BcrFile(dirs[i], dirs[i]));
398           rp = dirs[i];
399         }
400       }
401     }
402     return dirList;
403   };
404   
4f01b8 405   /*
U 406    * icon-th-large
407    * icon-th-list
408    * @returns {undefined}
409    */
410   this.fm_ansicht_umschalten = function() {
411     var elem = document.querySelector('#ansicht');
412     var iElem = elem.getElementsByTagName("i")[0];
413     if(iElem.classList.contains('icon-th-list')) {
414       iElem.classList.add('icon-th-large');
415       iElem.classList.remove('icon-th-list');
416       self.modus = 'liste';
417     } else {
418       iElem.classList.add('icon-th-list');
419       iElem.classList.remove('icon-th-large');
420       self.modus = 'kacheln';
421     }
422     self.fm_get_list(self.pfad);    
423   };
424
425   this.fm_set_modus = function() {
426     var elem = document.querySelector('#ansicht');
427     var iElem = elem.getElementsByTagName("i")[0];
428     if(self.modus === 'kacheln') {
429       iElem.classList.add('icon-th-list');    
430       iElem.classList.remove('icon-th-large');
431     } else {
432       iElem.classList.add('icon-th-large');
433       iElem.classList.remove('icon-th-list');
434     }    
435   };
436
437   
2864b2 438   /**
U 439    * Der letzte Eintrag in dirs ist der aktuelle Ordner und 
440    * deshalb ausgegraut.
441    * 
442    * Wenn nur ein Ordner in dirs enthalten ist, dann sind wir 
443    * an der obersten Ebene (Home).
444    * 
445    * @param {Array} dirList ein Array aus BcrFile-Objekten
446    * @returns nichts 
447    */
448   this.fm_renderBreadcrumb = function(dirList) {
449     var elem = document.querySelector('.breadcrumb');
450     if(dirList.length > 1) {
451       var last = dirList.pop();
452       var bcList = new BcrFiles(dirList);
4f01b8 453       
2864b2 454       self.html_erzeugen("data/tpl/bcr.tpl", bcList, function(html) {
4f01b8 455         var htmlGesamt = html;
2864b2 456         self.html_erzeugen("data/tpl/bcr2.tpl", last, function(html) {
4f01b8 457           htmlGesamt += html;          
U 458           self.html_erzeugen("data/tpl/bcr3.tpl", dirList[0], function(html) {
459             htmlGesamt += html;
460             elem.innerHTML = htmlGesamt;
461             self.addEvtListener('.bc-link', 'click', self.fm_bc_click);
462             self.addEvtListener('#ansicht', 'click', self.fm_ansicht_umschalten);
463             self.fm_set_modus();
464           });
465           
2864b2 466         });                  
U 467       });            
468     } else {
469       // oberste Ebene
4f01b8 470       var htmla;
U 471       var htmlb;
2864b2 472       self.html_erzeugen("data/tpl/bcr2.tpl", dirList[0], function(html) {
4f01b8 473         htmla = html;        
U 474         self.html_erzeugen("data/tpl/bcr3.tpl", dirList[0], function(html) {
475           htmlb = html;
476           elem.innerHTML = htmla + htmlb;
477           self.addEvtListener('.bc-link', 'click', self.fm_bc_click);
478           self.addEvtListener('#ansicht', 'click', self.fm_ansicht_umschalten);
479           self.fm_set_modus();
480         });
2864b2 481       });            
U 482     }
483   };
484   
485   /**
486    * Auf den Klick auf ein Breadcrumb-Element reagieren:
487    * Den Ordner-Inhalt des geklickten Elements anzeigen
488    * @returns nichts
489    */
490   this.fm_bc_click = function() {
491     var elem = this;
492     var bcPfad = elem.getAttribute("rpath");
493     if(bcPfad !== undefined) {
494       self.pfad = bcPfad;
495       self.fm_get_list(bcPfad);
496     } else {
497       pfad = '';
498       self.fm_get_list('');
499     }
500   };
501
94b871 502   /* API functions */
05e9c4 503
94b871 504   // http://localhost:8079/file-cms/svc?c=de.uhilger.filecms.api.FileMgr&f=JSONNICE&m=list&p=
U 505   this.fm_get_list = function (relPfad) {
506     var m = '?c=de.uhilger.filecms.api.FileMgr&m=list&p=' + relPfad;
507     var u = '../svc' + m;
58bcbd 508     self.fm_get(u, "json", function (respText) {
U 509       var resp = JSON.parse(respText);
94b871 510       if (resp.List[0].FileRef !== undefined) {
U 511         var files = new Array();
512         if (resp.List[0].FileRef instanceof Array) {
513           for (var i = 0; i < resp.List[0].FileRef.length; i++) {
514             files.push(new FileRef(resp.List[0].FileRef[i]));
05e9c4 515           }
U 516         } else {
94b871 517           files.push(new FileRef(resp.List[0].FileRef));
05e9c4 518         }
94b871 519         var fl = new FileList(files);
58bcbd 520         self.fm_render_list(fl);
94b871 521       } else {
58bcbd 522         // #dateien leeren
8ba358 523         var elem = document.querySelector("#dateien");
U 524         elem.innerHTML = '';
94b871 525       }
8ba358 526       
U 527       // Breadcrumb
528       
2864b2 529       var dirList = self.fm_buildBreadcrumb(relPfad);
4f01b8 530       self.fm_renderBreadcrumb(dirList);     
94b871 531     });
U 532   };
f002d9 533   
ebc1f3 534   this.fm_edit_as_text = function() {
U 535     self.fm_get_file_content('text');
536   };
537   
f002d9 538   this.fm_get_file_content = function(typ) {
U 539     var gewaehlte = document.querySelector('.datei-gewaehlt');
540     //var fname = $(gewaehlte).find('.dateiname').text();
541
542     var fname = gewaehlte.textContent;
ebc1f3 543     //console.log('fname: ' + fname);
f002d9 544     self.openFileName = fname;
U 545     var m = '?c=de.uhilger.filecms.api.FileMgr&m=getCode&p=' + self.pfad + '&p=' + fname;
546     var u = '../svc' + m;
547     self.fm_get(u, "text", function(resp) {
548       if(typ === 'text') {
549         var mode = "text/x-java";
550         if(fname.endsWith('js')) {
551           mode = 'javascript';
552         } else if(fname.endsWith('xml')) {
553           mode = 'xml';
554         } else if(fname.endsWith('properties')) {
555           mode = 'xml';
556         } else if(fname.endsWith('adoc')) {
557           mode = 'text/x-markdown';
558         }
559         self.fm_text_edit(resp, mode);
560       } else {
561         self.fm_dok_edit(resp);
562       }
563     });
564   };
565
ebc1f3 566   this.fm_save_file = function(saveFileName, method, callback) {
U 567     var content;
568     if(self.openEditor === 'text') {
569       content = self.cm.getValue();
570       self.cm.getDoc().markClean();
571     } else {
572       content = ed.getContent();
573       tinymce.activeEditor.undoManager.clear();
574     }
575     var m = '?c=de.uhilger.filecms.api.FileMgr&m=' + method;
576     var u = '../svc'; // + m;
577     //var data = [self.pfad, saveFileName, content];
578     //var data = "p=" + self.serialisieren(self.pfad);
579     //data += "&p=" + self.serialisieren(saveFileName);
580     //data += "&p=" + self.serialisieren(content);
581     var data = 'c=de.uhilger.filecms.api.FileMgr&m=' + method + '&p=' + self.pfad + '&p=' + saveFileName + 'p3=' + content;
582     self.http_post(u, data, function(resp) {
583       // hier scheint nichts zurueckzukommen..
584     });
585     /*
586     self.fm_post(u, {p: self.pfad, p: saveFileName, p: content}, '', function(resp) {
587       // hier scheint nichts zurueckzukommen..
588     });
589     */
590     self.openFileName = saveFileName;
591     if(typeof (callback) !== 'function') {
592
593     } else {
594       callback();
595     }
596   };
597
598
f002d9 599
U 600 /* ---- codemirror editor handling -------- */
601
602   /*
603   function htmlDecode(value){ 
604     return $('<div/>').html(value).text(); 
605   }
606   */
607
608   this.fm_code_edit = function(content, m) {
ebc1f3 609     //console.log('fm_code_edit content: ' + content.substring(0,30));
U 610     self.cm = CodeMirror.fromTextArea(document.getElementById("editspace"), {
f002d9 611       lineNumbers: true,
U 612       lineWrapping: true,
613       gutters: ["CodeMirror-linenumbers", "breakpoints"],
614       mode: m,
615       viewportMargin : Infinity,
616       tabSize: 2,
617       extraKeys: {
618           "F9": function(cm) {
619           cm.setOption("fullScreen", !cm.getOption("fullScreen"));
620         },
621           "Esc": function(cm) {
622           if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
623         },
624           ".": function(cm) {
625           console.log('dot pressed: perhaps look up class or method name');
626           /*
627            * Hier kann man eine Funktion ausloesen, die fuer das 
628            * Wort vor dem Punkt (Name der Klasse) eine Liste mit 
629            * Vorschlaegen fuer Methodennamen einblendet.
630            */
631
632           /*
633            * CodeMirror.Pass laesst das Zeichen zum Editorinhalt durch, 
634            * verhindert aber das Ausloesen von 'keyHandled'
635            */
636           return CodeMirror.Pass; 
637         }
638       }
639     });
640     //cm.setValue(htmlDecode(content));
641     //cm.setValue(content);
ebc1f3 642     self.cm.setValue(self.unescapeHtml(content));
U 643     self.cm.getDoc().markClean();
644     self.cm.on("gutterClick", function(theEditor, lineNumber) {
f002d9 645       var info = theEditor.lineInfo(lineNumber);
U 646       //--lineNumber;
647       //console.log(info.gutterMarkers.breakpoints.message);
648       //var marker = info.gutterMarkers.breakpoints;
649       //$(marker).tooltip('toggle');
650     });
651     /*
652     cm.on("keyHandled", function(theEditor, keyName, event){
653       console.log('cm.keyHandled keyName: ' + keyName + ', event.type: ' + event.type);    
654     });
655     */
656   };
657
658   this.makeMarker = function(msg) {
659     var marker = document.createElement("div");
660     marker.style.color = "#822";
661     marker.innerHTML = "●";
662     //marker.message = msg;
663     $(marker).tooltip({
664       placement: 'right',
665       title: msg,
666       offset: '0 -30'
667     });
668     return marker;
669   };
670
671   
672   /* -------- Editoren --------- */
673   
674   this.fm_text_edit = function(content, mode) {
675     document.querySelector(".codeeditor-space").style.display = "block";
676     document.querySelector(".code-editor-container").style.display = "block";
ebc1f3 677     document.querySelector(".zentrum-behaelter").style.display = "none";
f002d9 678     self.fm_code_edit(content, mode);  
U 679     self.openEditor = 'text';
680   };
681
682   this.fm_dok_edit = function(content) {
683     //fm_filectls_hide();
684     fm_dok_editor_init(userid);
685     $("#mce-editor").show();
686
687     window.clearTimeout(tmo2);
688     tmo2 = window.setTimeout(function () {
689       try {
690         ed.setContent(content);
691         openEditor = 'dok';  
692       } catch (err) {
693       }
694     }, 200);
695   };
ebc1f3 696   
U 697   this.fm_do_close = function() {
698     document.querySelector(".codeeditor-space").style.display = "none";
699     document.querySelector(".code-editor-container").style.display = "none";
700     document.querySelector(".zentrum-behaelter").style.display = "block";
701     if(self.cm !== undefined) {
702       self.cm.toTextArea();
703     }
704     self.openFileName = '';
705     self.openEditor = '';
706     self.fm_get_list(self.pfad);
707   };
05e9c4 708
94b871 709   /* -------- An- und Abmelden ------------- */
05e9c4 710
94b871 711   this.fm_get_login = function() {
U 712     var m = '?c=de.uhilger.filecms.pub.SessionManager&m=getSessionUser';
713     var u = '../pub' + m;
714     self.fm_get(u, "text", function (resp) {
715       self.userid = resp;
58bcbd 716       self.login_zeigen();
U 717       //document.querySelector("#userMenu").textContent = resp;
94b871 718     });
U 719   };
05e9c4 720
94b871 721   this.fm_logout = function() {
U 722     var m = '?c=de.uhilger.filecms.pub.SessionManager&m=expireSession';
723     var u = '../pub' + m;
724     self.fm_get(u, "text", function (resp) {
725       //$('#userMenu').text('nicht angemeldet');
726       window.location.href = '../logout.html';
727     });
728   };
41ab37 729   
6648a8 730   /* ----- Hilfsfunktionen ----- */
U 731
732   this.serialisieren = function(obj) {
733     return '{"' + obj.constructor.name + '":' + JSON.stringify(obj) + '}';
734   };
735   
736   this.addEvtListener = function(selector, eventName, func) {
737     document.querySelectorAll(selector).forEach(elem => { elem.addEventListener(eventName, func); });
738   };
739   
740   this.removeAllListeners = function(id) {
741     var el = document.getElementById(id);
742     elClone = el.cloneNode(true);
743     el.parentNode.replaceChild(elClone, el);
744   }; // https://stackoverflow.com/questions/19469881/remove-all-event-listeners-of-specific-type
745
ebc1f3 746   this.escapeHtml = function(text) {
U 747     text = text.replace(/\u228/g,'&auml;');
748     text = text.replace(/\u246/g,'&ouml;');
749     text = text.replace(/\u252/g,'&uuml;');
750     text = text.replace(/\u196/g,'&Auml;');
751     text = text.replace(/\u214/g,'&Ouml;');
752     text = text.replace(/\u220/g,'&Uuml;');
753     text = text.replace(/\u223/g,'&szlig;');
754     text = text.replace(/\u26/g,'&amp;');
755     return text;
756   };
757
758   this.unescapeHtml = function(text) {
759     text = text.replace(/&auml;/g, String.fromCharCode(228));
760     text = text.replace(/&ouml;/g, String.fromCharCode(246));
761     text = text.replace(/&uuml;/g, String.fromCharCode(252));
762     text = text.replace(/&Auml;/g, String.fromCharCode(196));
763     text = text.replace(/&Ouml;/g, String.fromCharCode(214));
764     text = text.replace(/&Uuml;/g, String.fromCharCode(220));
765     text = text.replace(/&szlig;/g, String.fromCharCode(223));
766     text = text.replace(/&amp;/g, String.fromCharCode(26));
767     return text;
768   };
769
41ab37 770   /* ---- Vorlagen ---- */
U 771
772   this.html_erzeugen = function(vurl, inhalt, cb) {
773     var vorlage = self.cache[vurl];
774     if(vorlage === undefined) {
775       self.vorlage_laden_und_fuellen(vurl, inhalt, cb);
776     } else {
777       self.vorlage_fuellen(vurl, inhalt, cb);
778     }
779   };
780
781   this.vorlage_fuellen = function(vurl, inhalt, cb) {
782     cb(Mustache.render(self.cache[vurl], inhalt));
783   };
784
785   this.vorlage_laden_und_fuellen = function(vurl, inhalt, cb) {
786     self.fm_get(vurl, "text", function(antwort) {
787       self.cache[vurl] = antwort;
788       self.vorlage_fuellen(vurl, inhalt, cb);
789     });
790   };
94b871 791
U 792   /* -------- ajax helper functions ----------- */
793
58bcbd 794   this.fm_get = function (u, dtype, scallback) {    
U 795     var xmlhttp = new XMLHttpRequest();
796     var url = u;
797     xmlhttp.onreadystatechange = function() {
798       if (this.readyState == 4 && this.status == 200) {
799         scallback(this.responseText);
94b871 800       }
58bcbd 801     };
U 802     xmlhttp.open("GET", url, true);
803     xmlhttp.send();
94b871 804   };
ebc1f3 805   
U 806   self.fm_post = function(u, d, dtype, scallback) {
807     var xmlhttp = new XMLHttpRequest();
808     var url = u;
809     xmlhttp.onreadystatechange = function() {
810       if (this.readyState == 4 && this.status == 200) {
811         scallback(this.responseText);
812       }
813     };
814     xmlhttp.open("POST", url, true);
815     xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
816     //xmlhttp.send(d);
817     xmlhttp.send(self.serialisieren(d));
818
819     /*
820     $.ajax({
821       url: u,
822       data: d,
823       type: "POST",
824       dataType: dtype,
825       success: scallback,
826       error: function (xhr, status, errorThrown) {
827         $('#fehler').html("Error: " + errorThrown + " Status: " + status);
828       },
829       complete: function (xhr, status) {
830         //alert( "The request is complete!" );
831       }
832     });
833      */
834   };
835
836   this.http_get = function(u, cb)  {
837     self.http_call('GET', u, null, cb);
838   };
839   
840   this.http_post = function(u, data, cb) {
841     self.http_call('POST', u, data, cb);
842   };
843
844   this.http_call = function (method, u, data, scallback) {    
845     var xhr = new XMLHttpRequest();
846     var url = u;
847     xhr.onreadystatechange = function() {
848       if (this.readyState === 4 && this.status === 200) {
849         scallback(this.responseText);
850       }
851     };
852     xhr.open(method, url);
853     if(method === 'GET')  {
854       xhr.send();
855     } else if(method === 'POST' || method === 'PUT') {
856       xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
857       xhr.send(data);
858     }
859   };
860   
861
94b871 862
05e9c4 863 }