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