Persoenliche Mediazentrale
ulrich
2021-04-10 0e9cd39f81a9635dffd31e1d72229e6ca75d5f84
commit | author | age
b379f5 1 function Mediazentrale() {
cfa858 2   var self = this;
U 3   var appMenu;
4   var cache; // mustache templates
86bbf7 5   var ortPfad;
U 6   var mediaPfad;
e60cff 7   var katUrl;
U 8   var selTitel;
f45e20 9
U 10   this.init = function () {
11     self.mediaPfad = '/';
12     self.ortPfad = '/';
13     self.cache = new Array();
14     self.appMenu = new AppMenu();
15     self.appMenu.init(
16             "data/menu/",
17             "hauptmenue.json",
18             "data/tpl/app-menu.tpl",
19             ".west",
20             "8em");
21
22     document.querySelector('.hamburger').addEventListener('click', function (e) {
23       self.menue_umschalten();
24     });
25     
26     self.addEvtListener('#mi-katalog', 'click', self.media_liste);
27     self.addEvtListener('#mi-orte', 'click', self.ablageort_liste);
28     self.addEvtListener('#mi-prefs', 'click', self.prefs_liste);
29     self.addEvtListener('#mi-player', 'click', self.abspieler_liste);
8d7d35 30     self.addEvtListener('#mi-listen', 'click', self.abspielliste_liste);
U 31     self.addEvtListener('#mi-list', 'click', self.titel_liste);
f45e20 32     
U 33     self.fusszeile_umschalten();
34     self.seitenleiste_umschalten();
35     self.dialog_unten_zeigen();
36   };
37   
8d7d35 38   /* ---------------- Entitaets-Listen ----------------- */
U 39
86bbf7 40   // auf der obersten Ebene werden die Kataloge angezeigt,
U 41   // darunter der Inhalt des aktuellen Pfades
42   this.media_liste = function() {
8d7d35 43     self.reset_top_buttons();
86bbf7 44     if(self.ortPfad === '/') {
U 45       // Kataloge listen
f45e20 46       self.http_get('../api/store/Ablageort/liste/', function (responseText) {
8d7d35 47         //document.querySelector('#top-up-btn').removeEventListener('click', self.media_liste_herauf);
86bbf7 48         self.vorlage_laden_und_fuellen("data/tpl/katalog_root_liste.tpl", JSON.parse(responseText), function (html) {
U 49           document.querySelector(".zentraler-inhalt").innerHTML = html;
50           self.addEvtListener('.entity-eintrag', 'click', function (event) {
51             var t = event.target;
52             self.http_get('../api/store/Ablageort/' + t.textContent, function(responseText) {
53               var ablageort = JSON.parse(responseText);
54               self.ortPfad = ablageort.url;
55               self.media_liste();
56             });
57           });
58         });
59       });
60     } else {
3271f1 61       var url = '..' + self.ortPfad + self.mediaPfad;
U 62       if(!url.endsWith('/')) {
63         url = url + '/';
64       }
65       self.http_get(url, function(responseText) {
86bbf7 66         self.vorlage_laden_und_fuellen("data/tpl/katalog_inhalt_liste.tpl", JSON.parse(responseText), function (html) {
U 67           document.querySelector(".zentraler-inhalt").innerHTML = html;
68           self.addEvtListener('.entity-eintrag', 'click', function (event) {
69             var t = event.target;
3271f1 70             var tx = t.textContent;
86bbf7 71             if(t.classList.contains("entity-typ-folder")) {
3271f1 72               if(self.mediaPfad.endsWith('/')) {
U 73                 self.mediaPfad = self.mediaPfad + tx;                
74               } else {
75                 self.mediaPfad = self.mediaPfad + '/' + tx;
76               }
86bbf7 77               self.media_liste();
U 78             } else {
37eadf 79               if(t.classList.contains('selected')) {
U 80                 self.addSelectedTitel();
81               } else {
82                 self.removeClassMulti('selected');
83                 t.classList.add('selected');
84               }
e60cff 85               //self.selTitel = new Titel(t.textContent, self.ortPfad);       
86bbf7 86             }
U 87           });
8d7d35 88           self.addEvtListener('#top-up-btn', 'click', function(event) {
86bbf7 89             if(self.mediaPfad === '/') {
U 90               self.ortPfad = '/';              
91             } else {
92               var pos = self.mediaPfad.lastIndexOf('/');
3271f1 93               var parent;
U 94               if(pos > 1) {
95                 parent = self.mediaPfad.substring(0, pos);
96               } else {
97                 parent = '/';
98               }
86bbf7 99               self.mediaPfad = parent;
U 100             }
101             self.media_liste();
8d7d35 102           });
86bbf7 103         });
U 104       });
105     }
e60cff 106   };
245ac1 107   
a43e1a 108   this.ablageort_liste = function() {
e44ed0 109     self.entitaet_liste('../api/store/Ablageort/liste/', 
U 110       "data/tpl/ablageort_liste.tpl", '../api/store/Ablageort/', 
111       "self.ablageort_form", function(responseText) {
112         var ablageort = JSON.parse(responseText);
113         self.ablageort_form(ablageort);
114       });
cf6509 115   };
U 116
117   this.prefs_liste = function() {
e44ed0 118     self.entitaet_liste('../api/store/Einstellung/liste/', 
U 119       "data/tpl/einstellung_liste.tpl", '../api/store/Einstellung/', 
120       "self.prefs_form", function(responseText) {
121         var einstellung = JSON.parse(responseText);
122         self.prefs_form(einstellung);
123       });
cf6509 124   };
U 125
3d4bca 126   this.abspieler_liste = function() {
e44ed0 127     self.entitaet_liste('../api/store/Abspieler/liste/', 
U 128       "data/tpl/abspieler_liste.tpl", '../api/store/Abspieler/', 
129       "self.abspieler_form", function(responseText) {
130         var abspieler = JSON.parse(responseText);
131         self.abspieler_form(abspieler);
132       });
8d7d35 133   };
U 134   
135   this.abspielliste_liste = function() {
e44ed0 136     self.entitaet_liste('../api/store/Abspielliste/liste/', 
U 137       "data/tpl/abspielliste_liste.tpl", '../api/store/Abspielliste/', 
138       "self.abspielliste_form", function(responseText) {
139         var abspielliste = JSON.parse(responseText);
140         self.abspielliste_form(abspielliste);
141       });
8d7d35 142   };
U 143   
c7030d 144   /* -------------------- Entitaets-Formulare ------------------ */  
8d7d35 145   
U 146   this.abspielliste_form = function(al) {
c7030d 147     self.entitaet_form(al, al.name,
U 148       "data/tpl/form_abspielliste.tpl", '../api/store/Abspielliste/',
149       '#abspielliste-name', function() { 
150           self.abspielliste_auswahl_fuellen();
151           self.abspielliste_liste();
152     });
3d4bca 153   };
71def1 154   
3d4bca 155   this.abspieler_form = function(pl) {
c7030d 156     self.entitaet_form(pl, pl.key,
U 157       "data/tpl/form_abspieler.tpl", '../api/store/Abspieler/',
158       '#abspieler-name', function() { 
159           self.abspieler_auswahl_fuellen();
160           self.abspieler_liste();
161     });
71def1 162   };
U 163
cf6509 164   this.prefs_form = function(k) {
c7030d 165     self.entitaet_form(k, k.key,
U 166       "data/tpl/form_einstellung.tpl", '../api/store/Einstellung/',
167       '#einstellung-key', function() { 
168           self.prefs_liste();
169     });
a43e1a 170   };
cfa858 171
90f5d4 172   /* 
U 173    * Ablageort-Formular anzeigen
174    * 
175    * {"name":"Katalog 2","ort":"/home/ulrich/Videos","url":"/media/kat2"}: 
176    * 
177    * @param {type} ablageort  der Ablageort, der bearbeitet werden soll, leer fuer neuen Ort
178    * @returns {undefined} kein Rueckgabewert
179    */
180   this.ablageort_form = function(ort) {
c7030d 181     self.entitaet_form(ort, ort.name,
U 182       "data/tpl/form_ablageort.tpl", '../api/store/Ablageort/',
183       '#ablageort-name', function() { 
184         self.ablageort_liste();
185     });
b379f5 186   };
48f8f9 187   
748b6f 188   /* ------------------------------- UI-Dynamik ----------------------- */
48f8f9 189   
748b6f 190   self.reset_top_buttons = function() {
U 191     self.vorlage_laden_und_fuellen("data/tpl/top_btns.tpl", '', function (html) {
192       document.querySelector(".top-btns").innerHTML = html;
193     });
194   };
195   
196   this.abspieler_auswahl_fuellen = function() {
b56bb3 197     self.http_get('../api/store/Abspieler/liste/', function (responseText) {
748b6f 198       self.vorlage_laden_und_fuellen("data/tpl/abs_sel.tpl", JSON.parse(responseText), function (html) {
U 199         document.querySelector(".abs-sel").innerHTML = html;
200       });    
201     });
202   };
203
204   this.abspielliste_auswahl_fuellen = function() {
205     self.http_get('../api/store/Abspielliste/', function (responseText) {
206       self.vorlage_laden_und_fuellen("data/tpl/pl_sel.tpl", JSON.parse(responseText), function (html) {
207         document.querySelector(".pl-sel").innerHTML = html;
b56bb3 208         self.addEvtListener('#playlist', 'change', function() {
U 209           self.titel_liste();
210         });
748b6f 211       });    
U 212     });
213   };
214   
e44ed0 215   this.addSelectedTitel = function() {
U 216     var elem = document.querySelector(".selected");
b56bb3 217     //var titelName = elem.textContent;
U 218     var titelName = elem.attributes.dateiName.nodeValue;
e44ed0 219     var album = elem.attributes.album.nodeValue;
U 220     var interpret = elem.attributes.interpret.nodeValue;
221     var anzName = elem.attributes.titelAnzName.nodeValue;
222     var titel;
223     if(self.mediaPfad.endsWith('/')) {
224       titel = new Titel(titelName, self.mediaPfad, self.ortPfad, interpret, anzName, album);
225     } else {
226       titel = new Titel(titelName, self.mediaPfad + '/', self.ortPfad, interpret, anzName, album);
227     }
228     var plname = document.querySelector('#playlist').value;
229     self.http_put('../api/alist/' + plname, JSON.stringify(titel), function(responseText) {
230       self.meldung_mit_timeout(responseText, 1500);
231     });
232   };  
233   
748b6f 234   /* Unterer Einblendbereich */
U 235   
236   this.dialog_unten_zeigen = function() {
237     self.vorlage_laden_und_fuellen("data/tpl/ctrl.tpl", "", function (html) {
238       var dlg = document.querySelector(".dialog-unten");
239       dlg.style.height = '4.5em';
240       dlg.innerHTML = html;
241       self.abspieler_auswahl_fuellen();
242       self.abspielliste_auswahl_fuellen();
243       self.addEvtListener('#dazu-btn', 'click', self.addSelectedTitel);
b56bb3 244       self.addEvtListener('#play-btn', 'click', self.play);
748b6f 245       self.media_liste();
U 246     });
247   };
248   
249   /* Titel einer Abspielliste */
250   
251   this.titel_liste = function() {
252     self.reset_top_buttons();
253     var plname = document.querySelector('#playlist').value;
254     self.http_get('../api/alist/' + plname, function (responseText) {
255       self.vorlage_laden_und_fuellen("data/tpl/titel_liste.tpl", JSON.parse(responseText), function (html) {
256         document.querySelector(".zentraler-inhalt").innerHTML = html;
257         self.addEvtListener('.entity-eintrag', 'click', function (event) {
258           var t = event.target;
259           self.removeClassMulti('selected');
260           t.classList.add('selected');
261         });
262       });
263     });
264   };  
265   
b56bb3 266   /* ------------- Media-Steuerung ------------------------- */
U 267   
268   this.play = function() {
269     var abs = document.querySelector('#abspieler').value;
270     var lst = document.querySelector('#playlist').value;
271     console.log(
272       "play playlist.value: " + document.querySelector('#playlist').value + 
273       ", abspieler.value: " + document.querySelector('#abspieler').value);
274     self.http_get('../api/strg/' + abs + '/play/liste/' + lst, function(responseText) {
275       self.meldung_mit_timeout(responseText, 1500);
276     });
277   };
278   
748b6f 279   /* ------------- Helfer fuer Entitaets-Formulare ----------------------- */
14638b 280   
U 281   /*
282    * url: '../api/store/Ablageort/liste/'
283    * tpl: "data/tpl/ablageort_liste.tpl"
284    * storeUrl: '../api/store/Ablageort/'
285    * formFunc: "self.ablageort_form"
286    * cb: etwas wie
287    *   function(responseText){
288    *     var ablageort = JSON.parse(responseText);
289    *     self.ablageort_form(ablageort);
290    *   });
291    */
292   this.entitaet_liste = function(listUrl, tpl, storeUrl, formFunc, cb) {
293     self.reset_top_buttons();
294     self.http_get(listUrl, function (responseText) {
295       self.vorlage_laden_und_fuellen(tpl, JSON.parse(responseText), function (html) {
296         document.querySelector(".zentraler-inhalt").innerHTML = html;
297         self.addEvtListener('.entity-eintrag', 'click', function (event) {
298           var t = event.target;
299           self.http_get(storeUrl + t.textContent, cb);
300         });
301         //self.addEvtListener('#neu-btn', 'click', function (event) {
302         self.addEvtListener('#top-neu-btn', 'click', function(event) {
303           eval(formFunc + "(this)");
304         });        
305       });
306     });
307   };  
748b6f 308       
48f8f9 309   /*
c7030d 310    * dat: gefuelltes Datenobjekt bei Aenderung
U 311    * key: der alte schluesselbegriff bei Aenderung (z.B. al.name)
312    * tpl: "data/tpl/form_abspielliste.tpl"
313    * url: '../api/store/Abspielliste/'
314    * selector: '#abspielliste-name'
315    * cbOk: etwas wie
316    *    function() {
317    *       self.abspielliste_auswahl_fuellen();
318    *       self.abspielliste_liste();
319    *     });
320    * delSelector: '#abspielliste-name'
321    * cbDel: etwas wie
322    *    function() {
323    *       self.abspielliste_auswahl_fuellen();
324    *       self.abspielliste_liste();
325    *     });
326    */
327
328   this.entitaet_form = function(dat, key, tpl, url, selector, cb) {
329     self.vorlage_laden_und_fuellen(tpl, dat, function (html) {
330       document.querySelector(".zentraler-inhalt").innerHTML = html;
331       const form = document.querySelector('form');      
332       form.addEventListener('submit', function(event) {
333         self.handle_submit(event, key, url, selector, cb);
334       });
335       self.addEvtListener('#cancel-btn', 'click', cb);
336       self.addEvtListener('#loeschen-btn', 'click', function(event) {
337         event.preventDefault();
338         self.handle_del_btn(selector, url, cb);
339       });
340     });
341   };
342   
343   /*
48f8f9 344    * existingKey: wenn die Entitaet existiert und geandert werden soll
U 345    *                 leer, wenn neue Entitaet 
346    */
347   this.handle_submit = function(event, existingKey, putUrl, keySelector, cb) {
348     event.preventDefault();
349     const data = new FormData(event.target);
350     const value = Object.fromEntries(data.entries());
351     console.log({ value });
352     console.log(JSON.stringify(value));
353     var daten = JSON.stringify(value);
354     var formkey = document.querySelector(keySelector).value;
355     formkey = formkey.replace(' ', '').replace(/[\W]+/g, '');
356     if(typeof existingKey === "undefined" ||  existingKey.length < 1) {
357       // neu
358       self.http_put(putUrl + formkey, daten, function (responseText) {
359         if(typeof(cb) !== 'function') {
360           // ..
361         } else {
362           cb();
363         }
364       });
365     } else {
366       // aendern
367       self.http_put(putUrl + existingKey, daten, function (responseText) {
368         if(typeof(cb) !== 'function') {
369           // ..
370         } else {
371           cb();
372         }
373       });
374     }
375   };
376   
377   this.handle_del_btn = function(selectorKey, delUrl, cb) {
378     var pkey = document.querySelector(selectorKey).value;
379     var dlgdata = {"del-elem": pkey};
380     self.dialog_laden_und_zeigen('data/tpl/dlg-loeschen.tpl', dlgdata, function() {
381       self.addEvtListener('#nein-btn', 'click', self.dialog_schliessen);
382       self.addEvtListener('#ja-btn', 'click', function(event) {
383         console.log("loeschen geklickt.");
384         self.http_delete(delUrl + pkey, '', function (responseText) {
385           self.dialog_schliessen();
386           if(typeof(cb) !== 'function') {
387             // ..
388           } else {
389             cb();
390           }
391         });
392       });
393     });    
394   };  
748b6f 395   
U 396   /* ------------------ sonstige Helfer ----------------------- */
397       
7c22a2 398   this.addEvtListener = function(selector, eventName, func) {
U 399     document.querySelectorAll(selector).forEach(elem => { elem.addEventListener(eventName, func); });
400   };
401   
402   this.removeClassMulti = function(selector) {
403     document.querySelectorAll('.' + selector).forEach(elem => { elem.classList.remove(selector); });
404   };
405
f45e20 406   /* --------------------- asynchroner HTTP Client ----------------- */
faab2d 407   
f074f6 408   this.http_get = function (u, cb) {
b379f5 409     self.http_call('GET', u, null, cb);
U 410   };
f074f6 411
U 412   this.http_post = function (u, data, cb) {
b379f5 413     self.http_call('POST', u, data, cb);
U 414   };
415
90f5d4 416   this.http_put = function (u, data, cb) {
U 417     self.http_call('PUT', u, data, cb);
418   };
419   
5b7356 420   this.http_delete = function (u, data, cb) {
2597cd 421     console.log("delete " + u);
5b7356 422     self.http_call('DELETE', u, data, cb);
U 423   };
424   
f074f6 425   this.http_call = function (method, u, data, scallback) {
b379f5 426     var xhr = new XMLHttpRequest();
U 427     var url = u;
f074f6 428     xhr.onreadystatechange = function () {
b379f5 429       if (this.readyState === 4 && this.status === 200) {
U 430         scallback(this.responseText);
431       }
432     };
433     xhr.open(method, url);
f074f6 434     if (method === 'GET') {
b379f5 435       xhr.send();
2597cd 436     } else if (method === 'POST' || method === 'PUT' || method === 'DELETE') {
b379f5 437       xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
U 438       xhr.send(data);
439     }
440   };
8239d1 441   
f45e20 442   /* ------------------------ aus App-Vorlage -------------------  */
cfa858 443
f074f6 444   this.menue_umschalten = function () {
cfa858 445     var ham = document.querySelector(".hamburger");
U 446     ham.classList.toggle("is-active"); // hamburger-icon umschalten
447     self.appMenu.toggle(); // menue oeffnen/schliessen
448   };
449
f074f6 450   this.info_dialog_zeigen = function () {
cfa858 451     self.dialog_laden_und_zeigen('data/tpl/dlg-info.tpl', '');
U 452     self.menue_umschalten();
453   };
454
f074f6 455   this.seitenleiste_umschalten = function () {
cfa858 456     var ostDiv = document.querySelector('.ost');
f074f6 457     if (ostDiv.classList.contains('ost-open')) {
cfa858 458       ostDiv.classList.remove('ost-open');
f074f6 459       ostDiv.style.flexBasis = '0em';
cfa858 460     } else {
f074f6 461       ostDiv.classList.add('ost-open');
U 462       ostDiv.style.flexBasis = '6em';
cfa858 463     }
U 464     self.menue_umschalten();
465   };
466
f074f6 467   this.fusszeile_umschalten = function () {
cfa858 468     var suedDiv = document.querySelector('.sued');
f074f6 469     if (suedDiv.classList.contains('sued-open')) {
cfa858 470       suedDiv.classList.remove('sued-open');
f074f6 471       suedDiv.style.height = '0';
cfa858 472     } else {
U 473       suedDiv.classList.add('sued-open');
f074f6 474       suedDiv.style.height = '1.5em';
cfa858 475     }
U 476     self.menue_umschalten();
477   };
478
f074f6 479   this.menu_message = function (msg) {
cfa858 480     self.meldung_mit_timeout(msg, 1500);
U 481     var suedDiv = document.querySelector('.sued');
f074f6 482     if (suedDiv.classList.contains('sued-open')) {
cfa858 483     } else {
U 484       suedDiv.classList.add('sued-open');
f074f6 485       suedDiv.style.height = '1.5em';
cfa858 486     }
U 487     self.menue_umschalten();
488   };
489
f074f6 490   this.message_1 = function () {
cfa858 491     self.menu_message('Eine Mitteilung.');
U 492   };
493
f074f6 494   this.message_2 = function () {
cfa858 495     self.menu_message('Was wir schon immer sagen wollten.');
U 496   };
497
f074f6 498   this.message_3 = function (text) {
cfa858 499     self.menu_message(text);
U 500   };
501
f074f6 502   this.meldung_mit_timeout = function (meldung, timeout) {
cfa858 503     var s = document.querySelector('.sued');
a43e1a 504     s.classList.add('sued-open');
U 505     s.style.height = '1.5em';
cfa858 506     s.textContent = meldung;
f074f6 507     setTimeout(function () {
cfa858 508       s.textContent = 'Bereit.';
f074f6 509       setTimeout(function () {
cfa858 510         var suedDiv = document.querySelector('.sued');
f074f6 511         if (suedDiv.classList.contains('sued-open')) {
U 512           suedDiv.classList.remove('sued-open');
513           suedDiv.style.height = '0';
cfa858 514         }
U 515       }, 500);
516     }, timeout);
517   };
8239d1 518   
f45e20 519   /* --------------------- Dialog-Funktionen ------------------------ */
cfa858 520
U 521   /*
f074f6 522    Einen Dialog aus Vorlagen erzeugen
U 523    
524    vurl - URL zur Dialogvorlage
525    msgTpl - URL mit einer Vorlage eines Mitteilungstextes (optional)
526    */
5b7356 527   this.dialog_laden_und_zeigen = function (vurl, msgTpl, cb) {
U 528     var vorlage = self.cache[vurl];
529     if(vorlage === undefined) {
530       self.http_get(vurl, function(antwort) {
531         self.cache[vurl] = antwort;
532         self.dialog_zeigen(vurl, msgTpl, cb);
f074f6 533       });
cfa858 534     } else {
5b7356 535       self.dialog_zeigen(vurl, msgTpl, cb);
cfa858 536     }
U 537   };
538
5b7356 539   this.dialog_zeigen = function (vurl, inhalt, cb) {
U 540     var dlg = document.querySelector(".dialog");
2597cd 541     self.html_erzeugen(vurl, inhalt, function (html) {
U 542       dlg.style.height = '7em';
543       dlg.innerHTML = html;
544       document.querySelector('.close-btn').addEventListener('click', self.dialog_schliessen);
545       if(typeof(cb) !== 'function') {
546         // ..
547       } else {
548         cb();
549       }
550     });
5b7356 551   };
2597cd 552   
f45e20 553   this.dialog_schliessen = function () {
cfa858 554     document.querySelector('.close-btn').removeEventListener('click', self.dialog_schliessen);
U 555     var dlg = document.querySelector('.dialog');
556     dlg.style.height = '0';
557     dlg.innerHTML = '';
558   };
559
f45e20 560   /* ---------------------   Vorlagen   ---------------------- */
cfa858 561
U 562   /*
f074f6 563    Das HTML erzeugen, das entsteht, wenn eine Vorlage mit Inhalt
U 564    gefüllt wird
565    
566    Das Füllen erfolgt asynchron, d.h. der Programmlauf geht nach dem
567    Aufruf weiter ohne auf das Laden und Füllen der Vorlage zu warten.
568    Das fertige HTML wird der Callback-Funktion übergeben
569    sobald die Vorlage geladen und gefüllt ist, unabhängig davon, wo der
570    Programmlauf zu diesem Zeitpunkt mittlerweile ist.
571    
572    vurl - URL zur Vorlagendatei
573    inhalt - die JSON-Struktur, deren Inhalt in die
574    Vorlage gefüllt werden soll
575    cb - Callback-Funktion, die gerufen wird, wenn die Vorlage gefüllt ist.
576    Dieser Callback-Funktion wird das fertige HTML übergeben
577    */
578   this.html_erzeugen = function (vurl, inhalt, cb) {
cfa858 579     var vorlage = self.cache[vurl];
f074f6 580     if (vorlage === undefined) {
cfa858 581       self.vorlage_laden_und_fuellen(vurl, inhalt, cb);
U 582     } else {
583       self.vorlage_fuellen(vurl, inhalt, cb);
584     }
585   };
586
f074f6 587   this.vorlage_fuellen = function (vurl, inhalt, cb) {
cfa858 588     cb(Mustache.render(self.cache[vurl], inhalt));
U 589   };
590
591   /*
f074f6 592    Eine Vorlage vom Server in den lokalen Speicher laden
U 593    vurl - der URL unter dem die Vorlage zu finden ist
594    inhalt - die JSON-Struktur, deren Inhalt in die
595    Vorlage gefüllt werden soll
596    cb - callback: Diese Funktion wird gerufen, wenn die Vorlage mit dem
597    Inhalt gefüllt ist
598    */
599   this.vorlage_laden_und_fuellen = function (vurl, inhalt, cb) {
cfa858 600     var xmlhttp = new XMLHttpRequest();
f074f6 601     xmlhttp.onreadystatechange = function () {
cfa858 602       if (this.readyState == 4 && this.status == 200) {
U 603         self.cache[vurl] = this.responseText;
604         self.vorlage_fuellen(vurl, inhalt, cb);
605       }
606     };
607     xmlhttp.open("GET", vurl, true);
608     xmlhttp.send();
609   };
610
611
612 }
613
f45e20 614 /* ----------- Objekte ---------------- */
U 615
616 function Ablageort(n, o, u) {
617   this.name = n;
618   this.ort = o;
619   this.url = u;
620 }
621
622 function Einstellung(k, v) {
623   this.key = k;
624   this.value = v;
625 }
626
627 function Abspieler(n, u) {
628   this.name = n;
629   this.url = u;
8d7d35 630 }
U 631
632 function Abspielliste(n) {
633   this.name = n;
e60cff 634 }
U 635
245ac1 636 function Titel(n, p, u, i, t, a) {
e60cff 637   this.katalogUrl = u;
2bdd78 638   this.pfad = p;
e60cff 639   this.name = n;
245ac1 640   this.interpret = i;
U 641   this.titelAnzName = t;
642   this.album  = a;
d6b78c 643 }