Dateiverwaltung für die WebBox
ulrich
2021-01-21 8cab6e94514c38151b2e0c53c9df47c6e1682e28
commit | author | age
05e9c4 1 function AppVorlage() {
U 2   var self = this;
41ab37 3   this.appMenu;
4e450e 4   //this.vorlagen;
41ab37 5   this.api;
U 6   this.userid;
7   this.pfad = '';
8   this.loc;
9   this.modus = 'kacheln';
ebc1f3 10   this.cm;
4e450e 11   //this.tinymce;
U 12   this.ed;
13   this.tmo;
14   this.tmo2;
41ab37 15   this.PERS_DIR = "Persoenlich";
U 16   this.PUB_DIR = "Oeffentlich";
17   this.DAV_DIR = "Austausch";
18   this.BASE_DIR = "$basis";
19   this.DATA_DIR = "$daten";
20   this.WWW_DIR = "www";
f002d9 21   this.openEditor;
U 22   this.openFileName;
beb124 23   this.cutCopyOperation;
U 24   this.cutCopySrcDir;
25   this.cutCopyFiles;
9350c9 26   this.fm_slideshow = false;
820953 27   this.dateien;
41ab37 28   this.cache = {}; // mustache template cache
05e9c4 29
94b871 30   this.datei_neuer_text = function () {
ebc1f3 31     //self.meldung_mit_timeout("Neuer Text", 1500);
U 32     self.fm_text_edit('Neue Datei');
33   };
34   
05e9c4 35   /* Funktionen aus App-Vorlage */
94b871 36
4e450e 37   this.init = function () {    
f002d9 38     document.querySelector(".codeeditor-space").style.display = "none";
U 39     document.querySelector("#mce-editor").style.display = "none";
05e9c4 40     self.appMenu = new AppMenu();
U 41     self.appMenu.init(
94b871 42             "data/menu/",
U 43             "hauptmenue.json",
44             "data/tpl/app-menu.tpl",
45             ".west",
46             "8em");
47     document.querySelector('.hamburger').addEventListener('click', function (e) {
05e9c4 48       self.menue_umschalten();
U 49     });
f32042 50     document.querySelector('#top-neuer-text-btn').addEventListener('click', self.datei_neuer_text);
U 51     document.querySelector('#top-neuer-ordner-btn').addEventListener('click', self.datei_neuer_ordner);
52     document.querySelector('#top-close-btn').addEventListener('click', self.fm_menu_datei_schliessen);
58bcbd 53     self.fm_get_login();
41ab37 54     
U 55     var parsedUrl = new URL(window.location.href);
56     var wunschPfad = parsedUrl.searchParams.get("pfad");
57
58     if(wunschPfad !== null && wunschPfad.length > 0) {
59       self.pfad = wunschPfad;
60       self.fm_get_list(wunschPfad);
61     } else {
62       self.fm_get_list('');
63     }
ebc1f3 64     
U 65     self.seitenleiste_umschalten();
820953 66     self.fm_init_uploader();
58bcbd 67     self.loc = window.location.protocol + '//' + window.location.host;
05e9c4 68   };
820953 69   
U 70   /* ----- Uploader Anfang ----------*/
71
72   this.fm_init_uploader = function() {
73     //console.log('init_uploader');
74     self.dateien = new Array();
8e238e 75     var dropzone = document.getElementById("upload-target");  
820953 76     dropzone.ondragover = dropzone.ondragenter = function(event) {  
U 77       event.stopPropagation();  
78       event.preventDefault();  
79     };
80
81     dropzone.ondrop = function(event) {  
82       //console.log('dateien ondrop');
83       event.stopPropagation();  
84       event.preventDefault();  
85       var fileList = event.dataTransfer.files;  
86       for (var i=0; i<fileList.length; i++) {  
87         self.dateien.push(fileList[i]);
88         //console.log('upload ' + fileList[i]);
89       }
90       self.sendFile(self.dateien.pop());
91     };
92   };
93
94   /* ----- Uploader Ende --------------- */  
05e9c4 95
58bcbd 96   this.login_zeigen = function() {
U 97     self.meldung_mit_timeout("Benutzer: " + self.userid, 1500);
98   };
99   
b20b74 100   this.fm_neuer_reiter = function() {
U 101     window.open('/file-cms/ui2/?pfad=' + self.pfad, '_blank');
102   };
820953 103   
U 104   this.fm_hilfe = function() {
105     window.open('/data/dok/wbx-doku.html#wbx-bedienung', '_blank');
106   };
9350c9 107   
U 108   this.fm_toggle_show_slideshow = function() {
109     if(self.fm_slideshow) {
110       //$('#m-toggle-slideshow').text('Diashow einschalten');
111       self.fm_slideshow = false;
112     } else {
113       //$('#m-toggle-slideshow').text('Diashow ausschalten');
114       self.fm_slideshow = true;
115     }
116   };
117   
820953 118   this.fm_view_slideshow = function() {
U 119
120     // https://localhost:8443/file-cms/fotos/?o=ulrich/bilder/diashow/ordnername
121
122
123     var userid = self.userid; // $('#userMenu').text();
124     //var gewaehlte = $('.datei-gewaehlt');
125     //var gewaehlte = document.querySelector('.datei-gewaehlt');
126     //var fname = gewaehlte.textContent;
127
128     var path = self.fm_get_path(userid);
129     var restdir = path;
130     if(path.indexOf('/data/') > -1) {
131       restdir = path.substr('/data/'.length);
132     }
133
134     //window.open('/file-cms/fotos/?o=' + userid + '/' + path + '/' + fname, '_blank');
135     window.open('/file-cms/fotos/?o=' + restdir + '/' /*+ fname*/, '_blank');
136   };
137
122cf8 138   this.fm_menu_datei_entpacken = function() {
U 139     //var gewaehlte = $('.datei-gewaehlt');
140     //var fname = $(gewaehlte[0]).text();
141     var gewaehlte = document.querySelector('.datei-gewaehlt');
142     var fname = gewaehlte.textContent;
143     self.fm_unzip_file(fname);
144   };
145
94b871 146   this.menue_umschalten = function () {
05e9c4 147     var ham = document.querySelector(".hamburger");
U 148     ham.classList.toggle("is-active"); // hamburger-icon umschalten
149     self.appMenu.toggle(); // menue oeffnen/schliessen
150   };
151
94b871 152   this.info_dialog_zeigen = function () {
05e9c4 153     self.dialog_laden_und_zeigen('data/tpl/dlg-info.tpl', '');
e342e0 154     //self.menue_umschalten();
05e9c4 155   };
U 156
94b871 157   this.seitenleiste_umschalten = function () {
05e9c4 158     var ostDiv = document.querySelector('.ost');
94b871 159     if (ostDiv.classList.contains('ost-open')) {
05e9c4 160       ostDiv.classList.remove('ost-open');
94b871 161       ostDiv.style.flexBasis = '0em';
05e9c4 162     } else {
94b871 163       ostDiv.classList.add('ost-open');
U 164       ostDiv.style.flexBasis = '6em';
05e9c4 165     }
ebc1f3 166     //self.menue_umschalten();
05e9c4 167   };
U 168
94b871 169   this.fusszeile_umschalten = function () {
05e9c4 170     var suedDiv = document.querySelector('.sued');
94b871 171     if (suedDiv.classList.contains('sued-open')) {
05e9c4 172       suedDiv.classList.remove('sued-open');
94b871 173       suedDiv.style.height = '0';
05e9c4 174     } else {
U 175       suedDiv.classList.add('sued-open');
94b871 176       suedDiv.style.height = '1.5em';
05e9c4 177     }
U 178     self.menue_umschalten();
179   };
122cf8 180
U 181   this.fm_fusszeile_zeigen = function() {
182     var suedDiv = document.querySelector('.sued');
183     suedDiv.classList.add('sued-open');
e3cec2 184     suedDiv.style.height = '7em';
122cf8 185     //$('.sued').show();
U 186   };
187
05e9c4 188
94b871 189   this.meldung_mit_timeout = function (meldung, timeout) {
05e9c4 190     var s = document.querySelector('.sued');
U 191     s.textContent = meldung;
85ba85 192     s.classList.add('sued-open');
U 193     s.style.height = '1.5em';
94b871 194     setTimeout(function () {
05e9c4 195       s.textContent = 'Bereit.';
94b871 196       setTimeout(function () {
05e9c4 197         var suedDiv = document.querySelector('.sued');
94b871 198         if (suedDiv.classList.contains('sued-open')) {
U 199           suedDiv.classList.remove('sued-open');
200           suedDiv.style.height = '0';
05e9c4 201         }
U 202       }, 500);
203     }, timeout);
204   };
ebc1f3 205   
U 206   this.fm_menu_datei_schliessen = function() {
207     if(self.openEditor === 'text') {
208       if(!self.cm.getDoc().isClean()) {
209         self.fm_ask_for_save();
210       } else {
211         self.fm_do_close();
212       }
213     } else {
4e450e 214       if(tinymce.activeEditor.undoManager.hasUndo()) {
ebc1f3 215         self.fm_ask_for_save();
U 216       } else {
217         self.fm_do_close();
218       }
219     }
220   };  
221
222   this.fm_ask_for_save = function() {
223     self.dialog_laden_und_zeigen('data/tpl/dlg-ask-save.tpl', '', function() {
224       // wenn dialog da ist, hier events verknuepfen
225       document.querySelector('#cancel-btn').addEventListener('click', function() {
226         self.fm_do_close();
227         self.dialog_schliessen();
228       });
229       document.querySelector('#speichern-btn').addEventListener('click', function() {
230         self.fm_menu_datei_speichern(function() {
231           self.fm_do_close();
232           self.dialog_schliessen();
233         });
234       });
235     });
236   };
237
238   this.fm_menu_datei_speichern = function(callback) {
239     //var fname = $('.datei-gewaehlt').text();
240     var fname = self.openFileName;
241     if(fname !== undefined && fname !== '') {
242       self.fm_save_file(fname, 'saveTextFile', callback);
03be8f 243       self.meldung_mit_timeout(fname + ' gespeichert.', 1500);
ebc1f3 244     } else {
U 245       self.fm_menu_datei_speichern_unter(callback);
246     }
247   };
248   
249   this.fm_menu_datei_speichern_unter = function(callback) {  
250     self.dialog_laden_und_zeigen('data/tpl/dlg-save-as.tpl', '', function() {
5b4d03 251       document.querySelector('#cancel-btn').addEventListener('click', function() {
U 252         //self.fm_do_close();
253         self.dialog_schliessen();
254       });
255       document.querySelector('#speichern-btn').addEventListener('click', function() {
1a9589 256         //self.fm_menu_datei_speichern(function() {
U 257           //console.log(document.querySelector('#datei-name-in').value);
03be8f 258           var fname = document.querySelector('#datei-name-in').value;
U 259           self.fm_save_file(fname, 'saveTextFileAs', callback);
260           self.meldung_mit_timeout(fname + ' gespeichert.', 1500);
4e450e 261           if(typeof(callback) !== 'function') {
03be8f 262             //self.fm_do_close();
4e450e 263             self.dialog_schliessen();
U 264           }
1a9589 265         //});
5b4d03 266       });
ebc1f3 267     });    
4e450e 268   };
U 269   
270   this.fm_menu_neues_dokument = function() {
271     self.fm_dok_edit('');
ebc1f3 272   };
05e9c4 273
U 274   /* Dialog-Funktionen */
275
276   /*
94b871 277    Einen Dialog aus Vorlagen erzeugen
U 278    
279    vurl - URL zur Dialogvorlage
280    msgTpl - URL mit einer Vorlage eines Mitteilungstextes (optional)
281    */
ebc1f3 282   this.dialog_laden_und_zeigen = function (vurl, msgTpl, cb) {
U 283     var vorlage = self.cache[vurl];
284     if(vorlage === undefined) {
285       self.fm_get(vurl, "text", function(antwort) {
286         self.cache[vurl] = antwort;
287         self.dialog_zeigen(vurl, antwort, cb);
288         //self.vorlage_fuellen(vurl, inhalt, cb);
94b871 289       });
05e9c4 290     } else {
ebc1f3 291       self.dialog_zeigen(vurl, vorlage, cb);
05e9c4 292     }
U 293   };
294
ebc1f3 295   this.dialog_zeigen = function (vurl, inhalt, cb) {
05e9c4 296     var dlg = document.querySelector(".dialog");
ebc1f3 297     self.html_erzeugen(
94b871 298             vurl,
U 299             inhalt,
300             function (html) {
301               //dlg.html(html);
1a9589 302               dlg.style.height = '7em';
94b871 303               dlg.innerHTML = html;
U 304               document.querySelector('.close-btn').addEventListener('click', self.dialog_schliessen);
305               //dlg.slideDown(300);
ebc1f3 306               if(typeof(cb) !== 'function') {
U 307                 // ..
308               } else {
309                 cb();
310               }
94b871 311             });
05e9c4 312   };
U 313
58bcbd 314   this.dialog_schliessen = function () {
05e9c4 315     document.querySelector('.close-btn').removeEventListener('click', self.dialog_schliessen);
U 316     //$('.dialog').slideUp(300);
317     var dlg = document.querySelector('.dialog');
318     //dlg.style.display = "none";
319     dlg.style.height = '0';
320     dlg.innerHTML = '';
5b4d03 321     self.removeAllListeners('#cancel-btn');
U 322     self.removeAllListeners('#speichern-btn');
05e9c4 323   };
39e714 324   
U 325   this.fm_auswahl_marke_entfernen = function() {
326     var gew = document.querySelector('.datei-gewaehlt');
327     if(gew !== null) {
328       gew.classList.remove('datei-gewaehlt');
329     }        
330   };
0783c5 331   
U 332   this.fm_view_file = function() {
333     var fname = document.querySelector('.datei-gewaehlt').textContent;
334     var path = self.fm_get_path(self.userid);
335     window.open(path + '/' + fname, '_blank');
336   };
39e714 337
0783c5 338   this.datei_ansehen_oder_bearbeiten = function(dateiname) {
U 339     if(dateiname.endsWith('htmi')) {
340       self.fm_get_file_content('doc', dateiname);
341     } else if(dateiname.endsWith('jpg') || dateiname.endsWith('png') || 
98f80c 342             dateiname.endsWith('gif') || dateiname.endsWith('pdf') ) {
U 343       self.fm_view_file();
0783c5 344     } else {
U 345       self.fm_get_file_content('text', dateiname);      
346     }
39e714 347   };
U 348   
349   /**
85ba85 350    * Hier werden die folgenden Faelle einer Datei- 
U 351    * bzw. Ordnerauswahl ausgefuehrt:
352    * 
353    * geklickt, nicht gewaehlt: 
354    *    auswaehlen, evtl. bestehende andere Auswahl entfernen
355    *    
356    * geklickt, ausgewaehlt: 
357    *    Datei ansehen oder oeffnen bzw. Ordner oeffnen
358    *    
359    * geklickt mit [Strg], nicht gewahlt: 
360    *    auswaehlen, bestehende Auswahl beibehalten (Mehrfachauswahl)
361    *    
362    * geklickt mit [Strg], gewaehlt: 
363    *    Auswahl bei diesem Element entfernen
39e714 364    * 
U 365    * Diese Fälle sind unterteilt in 
85ba85 366    *    1. Kachel-Modus
U 367    *    2. Listenmodus
39e714 368    * 
85ba85 369    * @param {type} ev Klick-Event
U 370    * @returns {undefined} nichts 
39e714 371    */
6648a8 372   this.fm_dateiwahl = function(ev) {
U 373     var elem = ev.target;
374     if(self.modus == 'kacheln') {
375       // Kacheln
9350c9 376       //var par = elem.parentElement;
U 377       var par = elem.closest('.datei-figure');
0783c5 378       var dElem = par.querySelector('.dateiname');
6648a8 379       if(elem.classList.contains("icon-folder")) {
39e714 380         // Ordner
0783c5 381         //var par = elem.parentElement;
U 382         var istGewaehlt = dElem.classList.contains('datei-gewaehlt');
39e714 383         if(istGewaehlt) {
U 384           if(/*ev.shiftKey || */ ev.ctrlKey) {
385             // mehrere Ordner sind gewaehlt, diese eine wieder entfernen
0783c5 386             dElem.classList.remove('datei-gewaehlt');
6648a8 387           } else {
39e714 388             // Ordner oeffnen
0783c5 389             var ordner = dElem.textContent.trim();
39e714 390             if(self.pfad.length > 0) {
U 391               self.pfad = self.pfad + '/' + ordner;
392             } else {
393               self.pfad = ordner;
394             }
395             self.fm_get_list(self.pfad);
6648a8 396           }
39e714 397         } else {
U 398           // Ordner auswaehlen
399           if(/*ev.shiftKey || */ ev.ctrlKey) {
400             // Mehrfachauswahl
401           } else {
402             self.fm_auswahl_marke_entfernen();
403           }
0783c5 404           dElem.classList.add('datei-gewaehlt');
6648a8 405         }
U 406       } else if(elem.classList.contains('datei')) {
39e714 407         // Datei
0783c5 408         //var par = elem.parentElement;
U 409         //var dElem = par.querySelector('.dateiname');
410         var istGewaehlt = dElem.classList.contains('datei-gewaehlt');
39e714 411         if(istGewaehlt) {
U 412           if(/*ev.shiftKey || */ ev.ctrlKey) {
413             // mehrere Dateien sind gewaehlt, diese eine wieder entfernen
0783c5 414             dElem.classList.remove('datei-gewaehlt');
39e714 415           } else {
U 416             // Datei zum Bearbeiten oeffnen
0783c5 417             self.datei_ansehen_oder_bearbeiten(dElem.textContent);
39e714 418           }
U 419         } else {
420           if(/*ev.shiftKey || */ ev.ctrlKey) {
421             // mehrere Dateien sollen gewaehlt werden
422           } else {
423             self.fm_auswahl_marke_entfernen();
424           }
0783c5 425           dElem.classList.add('datei-gewaehlt');
39e714 426         }
6648a8 427       } else {
U 428         //console.log('kein folder oder file...');
429       }
430     } else {
4f01b8 431       // Liste
U 432       var pElem = elem.closest('.datei-zeile');
433       var dElem = pElem.querySelector('.datei-elem');
0783c5 434       var dnElem = pElem.querySelector('.dateiname');
U 435       var istGewaehlt = dnElem.classList.contains('datei-gewaehlt');
4f01b8 436       if(dElem.getElementsByTagName("i")[0].classList.contains('icon-doc-text-inv')) {
6648a8 437         // Datei
39e714 438         if(istGewaehlt) {
U 439           if(/*ev.shiftKey || */ ev.ctrlKey) {
440             // mehrere Dateien sind gewaehlt, diese eine wieder entfernen
0783c5 441             dnElem.classList.remove('datei-gewaehlt');
39e714 442           } else {
U 443             // gewaehlte Datei ohne [Strg] geklickt: ansehen oder oeffnen
0783c5 444             self.datei_ansehen_oder_bearbeiten(dnElem.textContent);
39e714 445           }
6648a8 446         } else {
39e714 447           if(/*ev.shiftKey || */ ev.ctrlKey) {
U 448             // mehrere Dateien sollen gewaehlt werden, Auswahl ist weiter unten
449           } else {
450             var ti = document.querySelector('.table-info');
451             if(ti !== null) {
452               ti.classList.remove('table-info');
453             }
454             self.fm_auswahl_marke_entfernen();
4f01b8 455           }
39e714 456           pElem.classList.add('table-info');
0783c5 457           dnElem.classList.add('datei-gewaehlt');
6648a8 458         }
U 459       } else {
460         // Ordner
39e714 461         if(istGewaehlt) {
U 462           if(/*ev.shiftKey || */ ev.ctrlKey) {
463             // ein gewaehlter Ordner ist mit [Strg] geklickt, Auswahl entfernen
0783c5 464             dnElem.classList.remove('datei-gewaehlt');
6648a8 465           } else {
39e714 466             // Ordner oeffnen
0783c5 467             var ordner = dnElem.textContent;
39e714 468             if(self.pfad.length > 0) {
U 469               self.pfad = self.pfad + '/' + ordner;
470             } else {
471               self.pfad = ordner;
472             }
473             self.fm_get_list(self.pfad);
6648a8 474           }
39e714 475         } else {
U 476           if(/*ev.shiftKey || */ ev.ctrlKey) {
477             // nicht gewaehlter Ordner und [Strg]: zu Mehrfachauswahl hinzufuegen
478           } else {
479             // nicht gewaehlter Ordner ohne [Strg]: andere Auswhalen entfernen und weiter unten Ordner auswaehlen
480             self.fm_auswahl_marke_entfernen();
481           }
0783c5 482           dnElem.classList.add('datei-gewaehlt');
6648a8 483         }
U 484       }   
485     }
486   };
487  
41ab37 488   
58bcbd 489   this.fm_render_list = function (fl) {
4f01b8 490     if (self.modus === 'kacheln') {
58bcbd 491       // Kachelansicht
6648a8 492       self.html_erzeugen("data/tpl/kacheln.tpl", fl, function(html) {
U 493         var elem = document.querySelector('#dateien');
494         elem.innerHTML = html;
495         self.addEvtListener('.figure', 'click', self.fm_dateiwahl);
496       });
58bcbd 497     } else {
U 498       // Listenansicht
4f01b8 499       self.html_erzeugen("data/tpl/liste.tpl", fl, function(html) {
U 500         var elem = document.querySelector('#dateien');
501         elem.innerHTML = html;
502         self.addEvtListener('.datei-zeile', 'click', self.fm_dateiwahl);
503       });
58bcbd 504     }
U 505   };
506   
507   this.fm_get_path = function (uid) {
508     var restdir;
509     if (self.pfad.indexOf(self.PUB_DIR) > -1) {
510       restdir = self.pfad.substr(self.PUB_DIR.length);
511     } else if (self.pfad.indexOf(self.PERS_DIR) > -1) {
512       restdir = self.pfad.substr(self.PERS_DIR.length);
513     } else if (self.pfad.indexOf(self.BASE_DIR) > -1) {
514       restdir = self.pfad.substr(self.BASE_DIR.length);
515     } else if (self.pfad.indexOf(self.DATA_DIR) > -1) {
516       restdir = self.pfad.substr(self.DATA_DIR.length);
517     } else if (self.pfad.indexOf(self.DAV_DIR) > -1) {
518       restdir = self.pfad.substr(self.DAV_DIR.length);
519     }
520     if (restdir !== undefined && restdir.startsWith('/')) {
521       restdir = restdir.substr(1);
522       if (restdir.indexOf(self.WWW_DIR) > -1) {
523         restdir = restdir.replace(self.WWW_DIR, 'data');
524       }
525     }
41ab37 526     var pdir = self.fm_get_base(uid);
58bcbd 527     if (restdir.length > 1) {
U 528       return pdir + "/" + restdir;
529     } else {
530       return pdir;
531     }
532   };
533
534   this.fm_get_base = function (uid) {
535     var pdir;
536     if (self.pfad.indexOf(self.PUB_DIR) > -1) {
537       pdir = '/data/' + uid;
538     } else if (self.pfad.indexOf(self.PERS_DIR) > -1) {
539       pdir = '/home/' + uid;
540     } else if (self.pfad.indexOf(self.BASE_DIR) > -1) {
541       pdir = '';
542     } else if (self.pfad.indexOf(self.DATA_DIR) > -1) {
543       pdir = '';
544     }
545     return pdir;
546   };
2864b2 547   
U 548   /**
549    * Aus einem relativen Pfad ein Array aus BcrFile Objekten 
550    * machen
551    * 
552    * @param {String} relPfad  der relative Pfad
553    * @returns {Array}  die BcrFile-Objekte zum Pfad als Array
554    */
555   this.fm_buildBreadcrumb = function(relPfad) {
556     var rp = '';
557     var dirList = new Array();
558     dirList.push(new BcrFile(rp, 'Home'));
559     if(relPfad.length > 1) {
560       var dirs = relPfad.split('/');
561       for(var i = 0; i < dirs.length; i++) {
562         if(rp.length > 0 ) {
563           // weitere Einträge
564           dirList.push(new BcrFile(rp + '/' + dirs[i], dirs[i]));
565           rp = rp + '/' + dirs[i];
566         } else {
567           // erster Eintrag
568           dirList.push(new BcrFile(dirs[i], dirs[i]));
569           rp = dirs[i];
570         }
571       }
572     }
573     return dirList;
574   };
575   
4f01b8 576   /*
U 577    * icon-th-large
578    * icon-th-list
579    * @returns {undefined}
580    */
581   this.fm_ansicht_umschalten = function() {
582     var elem = document.querySelector('#ansicht');
583     var iElem = elem.getElementsByTagName("i")[0];
584     if(iElem.classList.contains('icon-th-list')) {
585       iElem.classList.add('icon-th-large');
586       iElem.classList.remove('icon-th-list');
587       self.modus = 'liste';
588     } else {
589       iElem.classList.add('icon-th-list');
590       iElem.classList.remove('icon-th-large');
591       self.modus = 'kacheln';
592     }
593     self.fm_get_list(self.pfad);    
594   };
595
596   this.fm_set_modus = function() {
597     var elem = document.querySelector('#ansicht');
598     var iElem = elem.getElementsByTagName("i")[0];
599     if(self.modus === 'kacheln') {
600       iElem.classList.add('icon-th-list');    
601       iElem.classList.remove('icon-th-large');
602     } else {
603       iElem.classList.add('icon-th-large');
604       iElem.classList.remove('icon-th-list');
605     }    
606   };
607
608   
2864b2 609   /**
U 610    * Der letzte Eintrag in dirs ist der aktuelle Ordner und 
611    * deshalb ausgegraut.
612    * 
613    * Wenn nur ein Ordner in dirs enthalten ist, dann sind wir 
614    * an der obersten Ebene (Home).
615    * 
616    * @param {Array} dirList ein Array aus BcrFile-Objekten
617    * @returns nichts 
618    */
619   this.fm_renderBreadcrumb = function(dirList) {
620     var elem = document.querySelector('.breadcrumb');
621     if(dirList.length > 1) {
622       var last = dirList.pop();
623       var bcList = new BcrFiles(dirList);
4f01b8 624       
2864b2 625       self.html_erzeugen("data/tpl/bcr.tpl", bcList, function(html) {
4f01b8 626         var htmlGesamt = html;
2864b2 627         self.html_erzeugen("data/tpl/bcr2.tpl", last, function(html) {
4f01b8 628           htmlGesamt += html;          
U 629           self.html_erzeugen("data/tpl/bcr3.tpl", dirList[0], function(html) {
630             htmlGesamt += html;
631             elem.innerHTML = htmlGesamt;
632             self.addEvtListener('.bc-link', 'click', self.fm_bc_click);
633             self.addEvtListener('#ansicht', 'click', self.fm_ansicht_umschalten);
634             self.fm_set_modus();
635           });
636           
2864b2 637         });                  
U 638       });            
639     } else {
640       // oberste Ebene
4f01b8 641       var htmla;
U 642       var htmlb;
2864b2 643       self.html_erzeugen("data/tpl/bcr2.tpl", dirList[0], function(html) {
4f01b8 644         htmla = html;        
U 645         self.html_erzeugen("data/tpl/bcr3.tpl", dirList[0], function(html) {
646           htmlb = html;
647           elem.innerHTML = htmla + htmlb;
648           self.addEvtListener('.bc-link', 'click', self.fm_bc_click);
649           self.addEvtListener('#ansicht', 'click', self.fm_ansicht_umschalten);
650           self.fm_set_modus();
651         });
2864b2 652       });            
U 653     }
654   };
655   
656   /**
657    * Auf den Klick auf ein Breadcrumb-Element reagieren:
658    * Den Ordner-Inhalt des geklickten Elements anzeigen
659    * @returns nichts
660    */
661   this.fm_bc_click = function() {
662     var elem = this;
663     var bcPfad = elem.getAttribute("rpath");
664     if(bcPfad !== undefined) {
665       self.pfad = bcPfad;
666       self.fm_get_list(bcPfad);
667     } else {
668       pfad = '';
669       self.fm_get_list('');
670     }
671   };
672
beb124 673   /* ------- Dateifunktionen Start ----------- */
U 674
675   this.fm_menu_cut = function() {
676     console.log('fm_menu_cut');
677     self.fm_cut_files();
678   };
39e714 679   this.fm_menu_copy = function() {
03be8f 680     //console.log('fm_menu_kopie');
beb124 681     self.fm_copy_files();
U 682   };
683   this.fm_menu_paste = function() {
684     console.log('fm_menu_paste');
685     self.fm_paste_files();
686   };
687   this.fm_menu_delete = function() {
688     self.dialog_laden_und_zeigen('data/tpl/dlg-ask-del.tpl', '', function() {
689       // wenn dialog da ist, hier events verknuepfen
690       document.querySelector('#cancel-btn').addEventListener('click', function() {
691         //self.fm_do_close();
692         self.dialog_schliessen();
693       });
694       document.querySelector('#speichern-btn').addEventListener('click', function() {
39e714 695         //self.fm_menu_datei_speichern(function() {
beb124 696           self.fm_del_files();
U 697           self.dialog_schliessen();
39e714 698         //});
beb124 699       });
U 700     });
701   };
702   
703   /*
704    * Hier merkt sich die Dateiverwalting die markierten Dateien fuer 
705    * eine Dateioperation. Bei cut wird in der 'paste' Operation auf dem Server 
706    * fuer die 'gemerkten' Dateien ein Move gemacht. Die Dateien werden 
707    * vom gewaehlten Ort zum Zielort verschoben.
708    * 
709    * @returns {undefined}
710    */
711   this.fm_cut_files = function() {
712     console.log('fm_cut_files');
713     self.cutCopySrcDir = self.pfad;
714     self.cutCopyFiles = self.fm_gewaehlte_dateien();
715     self.cutCopyOperation = 'cut';
03be8f 716     self.meldung_mit_timeout('zum Ausschneiden in Zwischenablage', 1500);
beb124 717   };
U 718
719   /*
720    * Hier merkt sich die Dateiverwalting die markierten Dateien fuer 
721    * eine Dateioperation. Bei copy wird in der 'paste' Operation auf dem Server 
722    * fuer die 'gemerkten' Dateien eine Kopie gemacht. Die Dateien werden 
723    * am gewaehlten Ort behalten und am Zielort wird eine Kopier der 
724    * gewaehlten DAteien erstellt
725    * 
726    * @returns {undefined}
727    */
728   this.fm_copy_files = function() {
03be8f 729     //console.log('fm_copy_files');
beb124 730     self.cutCopySrcDir = self.pfad;
U 731     self.cutCopyFiles = self.fm_gewaehlte_dateien();
732     self.cutCopyOperation = 'copy';
03be8f 733     self.meldung_mit_timeout('in Zwischenablage kopiert', 1500);
beb124 734   };
U 735   
736   
737
738   /*
739    * Gewaehlte Dateien feststellen
740    * 
741    * @returns {String} eine per JSON.stringify schon vorbereitete List zum 
742    * Absenden als Parameter an den Server
743    */
744   this.fm_gewaehlte_dateien = function() {
745     var gewaehlte = document.querySelectorAll('.datei-gewaehlt');
746     return self.fm_dateiliste_bilden(gewaehlte);
747   };
748
749   this.fm_dateiliste_bilden = function(gewaehlte) {
750     var fnames = new Array();
751     var i = 0;
752     while(i < gewaehlte.length) {
753       var str = { "java.lang.String": gewaehlte[i].innerText};
754       fnames.push(str);
755       //console.log('loeschen ' + pfad + ' ' + $(gewaehlte[i]).text());
756       //i += 2;
757       i++;
758     }
759     var liste = '{"List":' + JSON.stringify(fnames) + '}';
760     // 'liste' enthaelt:
761     // {"List":[{"java.lang.String":"test3.txt"},{"java.lang.String":"Test1.txt"},{"java.lang.String":"Test2.txt"}]}
762     // und wird auf dem Server zu einer List[ArrayList<String>] bei der jede ArrayList<String> nur ein Element hat 
e3cec2 763     //console.log(liste);
beb124 764     return liste;
U 765   };
766
98f80c 767   this.fm_menu_datei_umbenennen = function() {
U 768     //var gewaehlte = $('.datei-gewaehlt');
769     var gewaehlte = document.querySelector('.datei-gewaehlt');
770     var fname = gewaehlte.textContent;
771     
772     self.dialog_laden_und_zeigen('data/tpl/dlg-rename.tpl', '', function() {
773       document.querySelector('#cancel-btn').addEventListener('click', function() {
774         self.dialog_schliessen();
775       });
776       document.querySelector('#speichern-btn').addEventListener('click', function() {
777         self.fm_rename_file(fname, self.pfad, document.querySelector('#datei-name-in').value);
778         self.dialog_schliessen();
779       });
780     });    
781   };
782   
beb124 783   this.fm_menu_html_export = function() {
U 784     self.fm_export_html();
785   };
786
787   /* --------- Dateifunktionen Ende ---------- */
788
94b871 789   /* API functions */
05e9c4 790
94b871 791   // http://localhost:8079/file-cms/svc?c=de.uhilger.filecms.api.FileMgr&f=JSONNICE&m=list&p=
U 792   this.fm_get_list = function (relPfad) {
793     var m = '?c=de.uhilger.filecms.api.FileMgr&m=list&p=' + relPfad;
794     var u = '../svc' + m;
58bcbd 795     self.fm_get(u, "json", function (respText) {
U 796       var resp = JSON.parse(respText);
94b871 797       if (resp.List[0].FileRef !== undefined) {
U 798         var files = new Array();
799         if (resp.List[0].FileRef instanceof Array) {
800           for (var i = 0; i < resp.List[0].FileRef.length; i++) {
801             files.push(new FileRef(resp.List[0].FileRef[i]));
05e9c4 802           }
U 803         } else {
94b871 804           files.push(new FileRef(resp.List[0].FileRef));
05e9c4 805         }
94b871 806         var fl = new FileList(files);
58bcbd 807         self.fm_render_list(fl);
94b871 808       } else {
58bcbd 809         // #dateien leeren
8ba358 810         var elem = document.querySelector("#dateien");
U 811         elem.innerHTML = '';
94b871 812       }
8ba358 813       
U 814       // Breadcrumb
815       
2864b2 816       var dirList = self.fm_buildBreadcrumb(relPfad);
4f01b8 817       self.fm_renderBreadcrumb(dirList);     
94b871 818     });
U 819   };
f002d9 820   
1a9589 821   this.datei_neuer_ordner = function() {
U 822     self.dialog_laden_und_zeigen('data/tpl/dlg-ask-folder.tpl', '', function() {
823       document.querySelector('#cancel-btn').addEventListener('click', function() {
824         self.dialog_schliessen();
825       });
826       document.querySelector('#speichern-btn').addEventListener('click', function() {
827         var m = '?c=de.uhilger.filecms.api.FileMgr&m=newFolder&p=' + 
828                 self.pfad + 
829                 '&p=' + document.querySelector('#folder-name-in').value;
830         var u = '../svc' + m;
831         self.fm_get(u, "json", function(resp) {
832           self.dialog_schliessen();
833           self.fm_get_list(self.pfad);
834         });
835       });
836     });    
837   };
03be8f 838   
U 839   this.fm_open_file = function() {
840     var gewaehlte = document.querySelector('.datei-gewaehlt');
841     var fname = gewaehlte.textContent;
e342e0 842     self.datei_ansehen_oder_bearbeiten(fname);
03be8f 843   };
1a9589 844
0783c5 845   this.fm_get_file_content = function(typ, fname) {
f002d9 846     self.openFileName = fname;
U 847     var m = '?c=de.uhilger.filecms.api.FileMgr&m=getCode&p=' + self.pfad + '&p=' + fname;
848     var u = '../svc' + m;
849     self.fm_get(u, "text", function(resp) {
850       if(typ === 'text') {
851         var mode = "text/x-java";
852         if(fname.endsWith('js')) {
853           mode = 'javascript';
854         } else if(fname.endsWith('xml')) {
855           mode = 'xml';
856         } else if(fname.endsWith('properties')) {
857           mode = 'xml';
858         } else if(fname.endsWith('adoc')) {
859           mode = 'text/x-markdown';
860         }
861         self.fm_text_edit(resp, mode);
862       } else {
863         self.fm_dok_edit(resp);
864       }
865     });
866   };
867
ebc1f3 868   this.fm_save_file = function(saveFileName, method, callback) {
U 869     var content;
870     if(self.openEditor === 'text') {
871       content = self.cm.getValue();
872       self.cm.getDoc().markClean();
873     } else {
4e450e 874       content = self.ed.getContent();
ebc1f3 875       tinymce.activeEditor.undoManager.clear();
U 876     }
877     var m = '?c=de.uhilger.filecms.api.FileMgr&m=' + method;
5b4d03 878     var u = '../svc' + m;
c79727 879     var data = '&p=' + self.pfad + '&p=' + saveFileName + '&p=' + 
U 880             encodeURIComponent(content);
5b4d03 881     self.fm_post(u, data, "text", function(resp) {
U 882       // ...
ebc1f3 883     });
U 884     self.openFileName = saveFileName;
885     if(typeof (callback) !== 'function') {
886
887     } else {
888       callback();
889     }
890   };
891
beb124 892   /*
U 893    * Hier wird fuer eine zuvor markierte Liste von Dateien, fuer die 
894    * Cut oder Copy gewaehlt wurde, die Operations ausgefuehrt (move oder copy)
895    * @returns {undefined}
896    */
897   this.fm_paste_files = function() {
898     var m;
899     if(self.cutCopyOperation === 'cut') {
900       //m = '?c=de.uhilger.filecms.api.FileMgr&m=moveFiles'; //&p=' + cutCopySrcDir + '&p=' + pfad + '&p=' + encodeURIComponent(liste);
901       m = '?c=de.uhilger.filecms.api.FileMgr&m=moveFiles&p=' + self.cutCopySrcDir + '&p=' + self.pfad + '&p=' + encodeURIComponent(self.cutCopyFiles);
902     } else {
903       //m = '?c=de.uhilger.filecms.api.FileMgr&m=copyFiles'; //&p=' + cutCopySrcDir + '&p=' + pfad + '&p=' + encodeURIComponent(liste);
904       m = '?c=de.uhilger.filecms.api.FileMgr&m=copyFiles&p=' + self.cutCopySrcDir + '&p=' + self.pfad + '&p=' + encodeURIComponent(self.cutCopyFiles);
905     }
906     var u = '../svc' + m;  
907     self.fm_get(u, "text", function(resp) {
908       // console.log('deleteFiles gab folgendes zurueck: ' + resp);
909       self.fm_get_list(self.pfad);
910     });
911   };
ebc1f3 912
beb124 913   this.fm_del_files = function() {
U 914     var liste = self.fm_gewaehlte_dateien();
915     var m = '?c=de.uhilger.filecms.api.FileMgr&m=deleteFiles&p=' + self.pfad + '&p=' + encodeURIComponent(liste);
916     var u = '../svc' + m;
917     self.fm_get(u, "text", function(resp) {
918       // console.log('deleteFiles gab folgendes zurueck: ' + resp);
919       self.fm_get_list(self.pfad);
920     });
921   };
f002d9 922
98f80c 923   this.fm_rename_file = function(fn, p, neuerName) {
U 924     var m = '?c=de.uhilger.filecms.api.FileMgr&m=renameFile';
925     m = m + '&p=' + p; 
926     m = m + '&p=' + fn; 
927     m = m + '&p=' + neuerName; 
928     var u = '../svc' + m;
929     self.fm_get(u, "text", function(resp) {
930       self.fm_get_list(self.pfad);
931     });  
932   };
122cf8 933   
U 934   this.fm_unzip_file = function(fn) {
935     var m = '?c=de.uhilger.filecms.api.FileMgr&m=extractZipfile';
936     m = m + '&p=' + self.pfad; 
937     m = m + '&p=' + fn; 
938     var u = '../svc' + m;
939     self.fm_get(u, "text", function(resp) {
e3cec2 940       var mtx = new Meldung('Rueckmeldung vom Entpacken: ' + resp);
U 941       //console.log(mtx);
942       self.html_erzeugen("data/tpl/fuss.tpl", mtx, function(html) {
943         //console.log(html);
944         var elem = document.querySelector('.sued');
945         elem.innerHTML = html;
946         document.querySelector('.close-btn-fuss').addEventListener('click', function(){
947           var suedDiv = document.querySelector('.sued');
948           document.querySelector('.close-btn-fuss').removeEventListener('click', this);
949           suedDiv.classList.remove('sued-open');
950           suedDiv.style.height = '0';
951         });
952         self.fm_fusszeile_zeigen();
953         self.fm_get_list(self.pfad);
954       });
122cf8 955     });  
U 956   };
98f80c 957
820953 958   /* -------- upload ----------- */
U 959
960   this.sendFile = function(datei) {
961     //console.log('sendFile ' + datei);
962     var uri = "../api/upload";
963     var xhr = new XMLHttpRequest();  
964     var fd = new FormData();  
965     xhr.open("POST", uri, true);  
966     xhr.onreadystatechange = function() {  
967       if (xhr.readyState === 4 && xhr.status === 200) {  
968         self.fm_get_list(self.pfad);
969         if(self.dateien.length > 0) {
970           self.sendFile(self.dateien.pop());
971         }
972       }  
973     };  
974     fd.append('dateiauswahlfeld', datei);  
975     fd.append('pfad', self.pfad);
976     xhr.send(fd);          
977   };
978
979   /* ---- codemirror editor handling -------- */
f002d9 980
U 981   /*
982   function htmlDecode(value){ 
983     return $('<div/>').html(value).text(); 
984   }
985   */
986
987   this.fm_code_edit = function(content, m) {
ebc1f3 988     //console.log('fm_code_edit content: ' + content.substring(0,30));
U 989     self.cm = CodeMirror.fromTextArea(document.getElementById("editspace"), {
f002d9 990       lineNumbers: true,
U 991       lineWrapping: true,
992       gutters: ["CodeMirror-linenumbers", "breakpoints"],
993       mode: m,
994       viewportMargin : Infinity,
995       tabSize: 2,
996       extraKeys: {
997           "F9": function(cm) {
998           cm.setOption("fullScreen", !cm.getOption("fullScreen"));
999         },
1000           "Esc": function(cm) {
1001           if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
1002         },
1003           ".": function(cm) {
1004           console.log('dot pressed: perhaps look up class or method name');
1005           /*
1006            * Hier kann man eine Funktion ausloesen, die fuer das 
1007            * Wort vor dem Punkt (Name der Klasse) eine Liste mit 
1008            * Vorschlaegen fuer Methodennamen einblendet.
1009            */
1010
1011           /*
1012            * CodeMirror.Pass laesst das Zeichen zum Editorinhalt durch, 
1013            * verhindert aber das Ausloesen von 'keyHandled'
1014            */
1015           return CodeMirror.Pass; 
1016         }
1017       }
1018     });
1019     //cm.setValue(htmlDecode(content));
c79727 1020     //self.cm.setValue(content);
ebc1f3 1021     self.cm.setValue(self.unescapeHtml(content));
U 1022     self.cm.getDoc().markClean();
1023     self.cm.on("gutterClick", function(theEditor, lineNumber) {
f002d9 1024       var info = theEditor.lineInfo(lineNumber);
U 1025       //--lineNumber;
1026       //console.log(info.gutterMarkers.breakpoints.message);
1027       //var marker = info.gutterMarkers.breakpoints;
1028       //$(marker).tooltip('toggle');
1029     });
1030     /*
1031     cm.on("keyHandled", function(theEditor, keyName, event){
1032       console.log('cm.keyHandled keyName: ' + keyName + ', event.type: ' + event.type);    
1033     });
1034     */
1035   };
1036
1037   this.makeMarker = function(msg) {
1038     var marker = document.createElement("div");
1039     marker.style.color = "#822";
1040     marker.innerHTML = "●";
1041     //marker.message = msg;
1042     $(marker).tooltip({
1043       placement: 'right',
1044       title: msg,
1045       offset: '0 -30'
1046     });
1047     return marker;
1048   };
1049
4e450e 1050   /* ---- TinyMCE editor handling -------- */
U 1051
1052   this.fm_dok_editor_init = function(uid) {
1053     var base = self.fm_get_path(uid);
1054     //var edCount = 0;
1055     //console.log("fm_dok_editor_init calling tinymce.init with base: " + base + "/");
1056
1057     /*
1058      * vgl.
1059      * http://stackoverflow.com/questions/4651676/how-do-i-remove-tinymce-and-then-re-add-it
1060      */
1061     //tinymce.EditorManager.execCommand('mceRemoveControl',true, 'textarea.text-editor');
1062     //tinymce.EditorManager.execCommand('mceAddControl',true, editor_id);
1063     if(self.ed !== undefined) {
1064       self.ed.destroy();
1065     }
1066     if(tinymce !== undefined) {
1067       tinymce.remove('textarea.text-editor');
1068       tinymce.EditorManager.editors = []; 
1069     }
1070
1071     /*
1072      * Konfiguration TinyMCE
1073      */
1074     tinymce.init({
1075       content_css : "/file-cms/ui/mce.css",
1076       //content_css: "/jslib/bootstrap/css/bootstrap.min.css",
1077       selector: "textarea.text-editor",
1078       statusbar: false,
1079       menubar: false,
1080       plugins: 'advlist charmap code image link lists media table print preview save table textcolor importcss',
1081       toolbar: 'undo redo | styleselect | image table | link unlink | bullist numlist | outdent indent | code',
1082       /*
1083       menu: {
1084         file: {title: 'File', items: 'savevers | exit'},
1085         edit: {title: 'Edit', items: 'undo redo | cut copy paste pastetext | selectall'},
1086         view: {title: 'View', items: 'visualaid | code | link image media | template hr'},
1087       },
1088       */
1089       resize: 'both',
1090       importcss_append: true,
1091       width: "100%",
1092       height: '100%',
1093       relative_urls : true, 
1094       convert_urls : false, 
1095       document_base_url : base + "/",
1096       setup: function (editor) {
1097         self.ed = editor;
1098       }
1099     });
1100
1101     window.addEventListener('resize', self.fm_resize_editor);
1102     //$(window).on('resize', self.fm_resize_editor);
1103     self.fm_resize_editor();
1104   };
1105
1106   this.fm_resize_editor = function() {
1107     window.clearTimeout(self.tmo);
1108     self.tmo = window.setTimeout(function () {
1109       try {
1110         var myHeight = document.querySelector('.inhalt').offsetHeight - 
1111                 document.querySelector('.nord').offsetHeight + 2; // - 4;
1112         //console.log('myHeight: ' + myHeight);
1113         self.ed.theme.resizeTo('100%', myHeight);  // sets the dimensions of the editable area
1114       } catch (err) {
1115       }
1116     }, 200);
1117   };
1118
1119
f002d9 1120   
U 1121   /* -------- Editoren --------- */
1122   
1123   this.fm_text_edit = function(content, mode) {
1124     document.querySelector(".codeeditor-space").style.display = "block";
5b4d03 1125     //document.querySelector(".code-editor-container").style.display = "block";
U 1126     //document.querySelector(".zentrum-behaelter").style.display = "none";
1127     document.querySelector(".breadcrumb").style.display = "none";
1128     document.querySelector(".zentrum").style.display = "none";
f002d9 1129     self.fm_code_edit(content, mode);  
U 1130     self.openEditor = 'text';
1131   };
1132
1133   this.fm_dok_edit = function(content) {
1134     //fm_filectls_hide();
4e450e 1135     self.fm_dok_editor_init(self.userid);
U 1136     document.querySelector("#mce-editor").style.display = "block";
1137     //$("#mce-editor").show();
1138     document.querySelector(".breadcrumb").style.display = "none";
1139     document.querySelector(".zentrum").style.display = "none";
f002d9 1140
4e450e 1141     window.clearTimeout(self.tmo2);
U 1142     self.tmo2 = window.setTimeout(function () {
f002d9 1143       try {
4e450e 1144         self.ed.setContent(content);
U 1145         self.openEditor = 'dok';  
f002d9 1146       } catch (err) {
U 1147       }
1148     }, 200);
1149   };
ebc1f3 1150   
U 1151   this.fm_do_close = function() {
1152     document.querySelector(".codeeditor-space").style.display = "none";
4e450e 1153     document.querySelector("#mce-editor").style.display = "none";
U 1154     // $("#mce-editor").hide();
5b4d03 1155     //document.querySelector(".code-editor-container").style.display = "none";
U 1156     //document.querySelector(".zentrum-behaelter").style.display = "block";
1157     document.querySelector(".breadcrumb").style.display = "block";
1158     document.querySelector(".zentrum").style.display = "block";
ebc1f3 1159     if(self.cm !== undefined) {
U 1160       self.cm.toTextArea();
1161     }
1162     self.openFileName = '';
1163     self.openEditor = '';
1164     self.fm_get_list(self.pfad);
1165   };
05e9c4 1166
94b871 1167   /* -------- An- und Abmelden ------------- */
05e9c4 1168
94b871 1169   this.fm_get_login = function() {
U 1170     var m = '?c=de.uhilger.filecms.pub.SessionManager&m=getSessionUser';
1171     var u = '../pub' + m;
1172     self.fm_get(u, "text", function (resp) {
1173       self.userid = resp;
58bcbd 1174       self.login_zeigen();
U 1175       //document.querySelector("#userMenu").textContent = resp;
94b871 1176     });
U 1177   };
05e9c4 1178
94b871 1179   this.fm_logout = function() {
U 1180     var m = '?c=de.uhilger.filecms.pub.SessionManager&m=expireSession';
1181     var u = '../pub' + m;
1182     self.fm_get(u, "text", function (resp) {
1183       //$('#userMenu').text('nicht angemeldet');
1184       window.location.href = '../logout.html';
1185     });
1186   };
41ab37 1187   
6648a8 1188   /* ----- Hilfsfunktionen ----- */
U 1189
1190   this.serialisieren = function(obj) {
1191     return '{"' + obj.constructor.name + '":' + JSON.stringify(obj) + '}';
1192   };
1193   
1194   this.addEvtListener = function(selector, eventName, func) {
1195     document.querySelectorAll(selector).forEach(elem => { elem.addEventListener(eventName, func); });
1196   };
1197   
1198   this.removeAllListeners = function(id) {
1199     var el = document.getElementById(id);
5b4d03 1200     if(el !== null) {
U 1201       elClone = el.cloneNode(true);
1202       el.parentNode.replaceChild(elClone, el);
1203     }
6648a8 1204   }; // https://stackoverflow.com/questions/19469881/remove-all-event-listeners-of-specific-type
U 1205
ebc1f3 1206   this.escapeHtml = function(text) {
U 1207     text = text.replace(/\u228/g,'&auml;');
1208     text = text.replace(/\u246/g,'&ouml;');
1209     text = text.replace(/\u252/g,'&uuml;');
1210     text = text.replace(/\u196/g,'&Auml;');
1211     text = text.replace(/\u214/g,'&Ouml;');
1212     text = text.replace(/\u220/g,'&Uuml;');
1213     text = text.replace(/\u223/g,'&szlig;');
1214     text = text.replace(/\u26/g,'&amp;');
1215     return text;
1216   };
1217
1218   this.unescapeHtml = function(text) {
1219     text = text.replace(/&auml;/g, String.fromCharCode(228));
1220     text = text.replace(/&ouml;/g, String.fromCharCode(246));
1221     text = text.replace(/&uuml;/g, String.fromCharCode(252));
1222     text = text.replace(/&Auml;/g, String.fromCharCode(196));
1223     text = text.replace(/&Ouml;/g, String.fromCharCode(214));
1224     text = text.replace(/&Uuml;/g, String.fromCharCode(220));
1225     text = text.replace(/&szlig;/g, String.fromCharCode(223));
1226     text = text.replace(/&amp;/g, String.fromCharCode(26));
1227     return text;
1228   };
1229
41ab37 1230   /* ---- Vorlagen ---- */
U 1231
1232   this.html_erzeugen = function(vurl, inhalt, cb) {
1233     var vorlage = self.cache[vurl];
1234     if(vorlage === undefined) {
1235       self.vorlage_laden_und_fuellen(vurl, inhalt, cb);
1236     } else {
1237       self.vorlage_fuellen(vurl, inhalt, cb);
1238     }
1239   };
1240
1241   this.vorlage_fuellen = function(vurl, inhalt, cb) {
1242     cb(Mustache.render(self.cache[vurl], inhalt));
1243   };
1244
1245   this.vorlage_laden_und_fuellen = function(vurl, inhalt, cb) {
1246     self.fm_get(vurl, "text", function(antwort) {
1247       self.cache[vurl] = antwort;
1248       self.vorlage_fuellen(vurl, inhalt, cb);
1249     });
1250   };
94b871 1251
U 1252   /* -------- ajax helper functions ----------- */
1253
58bcbd 1254   this.fm_get = function (u, dtype, scallback) {    
U 1255     var xmlhttp = new XMLHttpRequest();
1256     var url = u;
1257     xmlhttp.onreadystatechange = function() {
5b4d03 1258       if (this.readyState === 4 && this.status === 200) {
58bcbd 1259         scallback(this.responseText);
94b871 1260       }
58bcbd 1261     };
U 1262     xmlhttp.open("GET", url, true);
1263     xmlhttp.send();
94b871 1264   };
ebc1f3 1265   
U 1266   self.fm_post = function(u, d, dtype, scallback) {
1267     var xmlhttp = new XMLHttpRequest();
1268     var url = u;
1269     xmlhttp.onreadystatechange = function() {
5b4d03 1270       if (this.readyState === 4 && this.status === 200) {
ebc1f3 1271         scallback(this.responseText);
U 1272       }
1273     };
1274     xmlhttp.open("POST", url, true);
c79727 1275     xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=utf-8');
5b4d03 1276     xmlhttp.send(d);
ebc1f3 1277   };
U 1278
5b4d03 1279   /*
ebc1f3 1280   this.http_get = function(u, cb)  {
U 1281     self.http_call('GET', u, null, cb);
1282   };
1283   
1284   this.http_post = function(u, data, cb) {
1285     self.http_call('POST', u, data, cb);
1286   };
1287
1288   this.http_call = function (method, u, data, scallback) {    
1289     var xhr = new XMLHttpRequest();
1290     var url = u;
1291     xhr.onreadystatechange = function() {
1292       if (this.readyState === 4 && this.status === 200) {
1293         scallback(this.responseText);
1294       }
1295     };
5b4d03 1296     xhr.open(method, url, false);
ebc1f3 1297     if(method === 'GET')  {
U 1298       xhr.send();
1299     } else if(method === 'POST' || method === 'PUT') {
1300       xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
1301       xhr.send(data);
1302     }
1303   };
5b4d03 1304   */
ebc1f3 1305
94b871 1306
05e9c4 1307 }