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