]> git.wh0rd.org Git - tt-rss.git/blob - prefs.js
fix resize_feed_list if header or footer are disabled (closes #65)
[tt-rss.git] / prefs.js
1 var xmlhttp = false;
2
3 var active_feed_cat = false;
4 var active_label = false;
5 var active_tab = false;
6 var feed_to_expand = false;
7
8 var piggie_top = -400;
9 var piggie_fwd = true;
10
11 var xmlhttp = Ajax.getTransport();
12
13 var init_params = new Array();
14
15 function expand_feed_callback() {
16         if (xmlhttp.readyState == 4) {
17                 try {   
18                         var container = document.getElementById("BRDET-" + feed_to_expand);     
19                         container.innerHTML=xmlhttp.responseText;
20                         container.style.display = "block";
21 //                      p_notify("");
22                 } catch (e) {
23                         exception_error("expand_feed_callback", e);
24                 }
25         }
26 }
27
28 function feedlist_callback() {
29         if (xmlhttp.readyState == 4) {
30                 try {   
31                         var container = document.getElementById('prefContent'); 
32                         container.innerHTML=xmlhttp.responseText;
33                         selectTab("feedConfig", true);
34
35                         if (active_feed_cat) {
36                                 var row = document.getElementById("FCATR-" + active_feed_cat);
37                                 if (row) {
38                                         if (!row.className.match("Selected")) {
39                                                 row.className = row.className + "Selected";
40                                         }               
41                                 }
42                                 var checkbox = document.getElementById("FCCHK-" + active_feed_cat);
43                                 if (checkbox) {
44                                         checkbox.checked = true;
45                                 }
46                         }
47
48                         notify("");
49                 } catch (e) {
50                         exception_error("feedlist_callback", e);
51                 }
52         }
53 }
54
55 function filterlist_callback() {
56         var container = document.getElementById('prefContent');
57         if (xmlhttp.readyState == 4) {
58                 container.innerHTML=xmlhttp.responseText;
59                 notify("");
60         }
61 }
62
63 function labellist_callback() {
64         var container = document.getElementById('prefContent');
65         if (xmlhttp.readyState == 4) {
66                 container.innerHTML=xmlhttp.responseText;
67
68                 if (active_label) {
69                         var row = document.getElementById("LILRR-" + active_label);
70                         if (row) {
71                                 if (!row.className.match("Selected")) {
72                                         row.className = row.className + "Selected";
73                                 }               
74                         }
75                         var checkbox = document.getElementById("LICHK-" + active_label);
76                         
77                         if (checkbox) {
78                                 checkbox.checked = true;
79                         }
80                 }
81                 notify("");
82         }
83 }
84
85 function feed_browser_callback() {
86         var container = document.getElementById('prefContent');
87         if (xmlhttp.readyState == 4) {
88                 container.innerHTML=xmlhttp.responseText;
89                 notify("");
90         }
91 }
92
93 function userlist_callback() {
94         var container = document.getElementById('prefContent');
95         if (xmlhttp.readyState == 4) {
96                 container.innerHTML=xmlhttp.responseText;
97                 notify("");
98         }
99 }
100
101 function prefslist_callback() {
102         var container = document.getElementById('prefContent');
103         if (xmlhttp.readyState == 4) {
104
105                 container.innerHTML=xmlhttp.responseText;
106                 
107                 notify("");
108         }
109 }
110
111 function gethelp_callback() {
112         var container = document.getElementById('prefHelpBox');
113         if (xmlhttp.readyState == 4) {
114
115                 container.innerHTML = xmlhttp.responseText;
116                 container.style.display = "block";
117
118         }
119 }
120
121
122 function notify_callback() {
123         var container = document.getElementById('notify');
124         if (xmlhttp.readyState == 4) {
125                 container.innerHTML=xmlhttp.responseText;
126         }
127 }
128
129 function updateFeedList(sort_key) {
130
131         if (!xmlhttp_ready(xmlhttp)) {
132                 printLockingError();
133                 return
134         }
135
136 //      document.getElementById("prefContent").innerHTML = "Loading feeds, please wait...";
137
138 //      p_notify("Loading, please wait...");
139
140         var feed_search = document.getElementById("feed_search");
141         var search = "";
142         if (feed_search) { search = feed_search.value; }
143
144         xmlhttp.open("GET", "backend.php?op=pref-feeds" +
145                 "&sort=" + param_escape(sort_key) + 
146                 "&search=" + param_escape(search), true);
147         xmlhttp.onreadystatechange=feedlist_callback;
148         xmlhttp.send(null);
149
150 }
151
152 function updateUsersList() {
153
154         if (!xmlhttp_ready(xmlhttp)) {
155                 printLockingError();
156                 return
157         }
158
159 //      document.getElementById("prefContent").innerHTML = "Loading feeds, please wait...";
160
161 //      p_notify("Loading, please wait...");
162
163         xmlhttp.open("GET", "backend.php?op=pref-users", true);
164         xmlhttp.onreadystatechange=userlist_callback;
165         xmlhttp.send(null);
166
167 }
168
169 function addLabel() {
170
171         if (!xmlhttp_ready(xmlhttp)) {
172                 printLockingError();
173                 return
174         }
175
176         var sqlexp = document.getElementById("ladd_expr");
177
178         if (sqlexp.value.length == 0) {
179                 alert("Can't add label: missing SQL expression.");
180         } else {
181                 notify("Adding label...");
182
183                 xmlhttp.open("GET", "backend.php?op=pref-labels&subop=add&exp=" +
184                         param_escape(sqlexp.value), true);                      
185                         
186                 xmlhttp.onreadystatechange=labellist_callback;
187                 xmlhttp.send(null);
188
189                 sqlexp.value = "";
190         }
191
192 }
193
194 function addFilter() {
195
196         if (!xmlhttp_ready(xmlhttp)) {
197                 printLockingError();
198                 return
199         }
200
201         var regexp = document.getElementById("fadd_regexp");
202         var match = document.getElementById("fadd_match");
203         var feed = document.getElementById("fadd_feed");
204         var action = document.getElementById("fadd_action");
205
206         if (regexp.value.length == 0) {
207                 alert("Can't add filter: missing filter expression.");
208         } else {
209                 notify("Adding filter...");
210
211                 var v_match = match[match.selectedIndex].text;
212                 var feed_id = feed[feed.selectedIndex].id;
213                 var action_id = action[action.selectedIndex].id;
214
215                 xmlhttp.open("GET", "backend.php?op=pref-filters&subop=add&regexp=" +
216                         param_escape(regexp.value) + "&match=" + v_match +
217                         "&fid=" + param_escape(feed_id) + "&aid=" + param_escape(action_id), true);
218                         
219                 xmlhttp.onreadystatechange=filterlist_callback;
220                 xmlhttp.send(null);
221
222                 regexp.value = "";
223         }
224
225 }
226
227 function addFeed() {
228
229         if (!xmlhttp_ready(xmlhttp)) {
230                 printLockingError();
231                 return
232         }
233
234         var link = document.getElementById("fadd_link");
235
236         if (link.value.length == 0) {
237                 alert("Error: No feed URL given.");
238         } else if (!isValidURL(link.value)) {
239                 alert("Error: Invalid feed URL.");
240         } else {
241                 notify("Adding feed...");
242
243                 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=add&feed_url=" +
244                         param_escape(link.value), true);
245                 xmlhttp.onreadystatechange=feedlist_callback;
246                 xmlhttp.send(null);
247
248                 link.value = "";
249
250         }
251
252 }
253
254 function addFeedCat() {
255
256         if (!xmlhttp_ready(xmlhttp)) {
257                 printLockingError();
258                 return
259         }
260
261         var cat = document.getElementById("fadd_cat");
262
263         if (cat.value.length == 0) {
264                 alert("Can't add category: no name specified.");
265         } else {
266                 notify("Adding feed category...");
267
268                 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=addCat&cat=" +
269                         param_escape(cat.value), true);
270                 xmlhttp.onreadystatechange=feedlist_callback;
271                 xmlhttp.send(null);
272
273                 link.value = "";
274
275         }
276
277 }
278 function addUser() {
279
280         if (!xmlhttp_ready(xmlhttp)) {
281                 printLockingError();
282                 return
283         }
284
285         var sqlexp = document.getElementById("uadd_box");
286
287         if (sqlexp.value.length == 0) {
288                 alert("Can't add user: no login specified.");
289         } else {
290                 notify("Adding user...");
291
292                 xmlhttp.open("GET", "backend.php?op=pref-users&subop=add&login=" +
293                         param_escape(sqlexp.value), true);                      
294                         
295                 xmlhttp.onreadystatechange=userlist_callback;
296                 xmlhttp.send(null);
297
298                 sqlexp.value = "";
299         }
300
301 }
302
303 function editLabel(id) {
304
305         if (!xmlhttp_ready(xmlhttp)) {
306                 printLockingError();
307                 return
308         }
309
310         active_label = id;
311
312         xmlhttp.open("GET", "backend.php?op=pref-labels&subop=edit&id=" +
313                 param_escape(id), true);
314         xmlhttp.onreadystatechange=labellist_callback;
315         xmlhttp.send(null);
316
317 }
318
319 function editUser(id) {
320
321         if (!xmlhttp_ready(xmlhttp)) {
322                 printLockingError();
323                 return
324         }
325
326         selectTableRowsByIdPrefix('prefUserList', 'UMRR-', 'UMCHK-', false);
327         selectTableRowById('UMRR-'+id, 'UMCHK-'+id, true);
328
329         xmlhttp.open("GET", "backend.php?op=pref-users&subop=edit&id=" +
330                 param_escape(id), true);
331         xmlhttp.onreadystatechange=infobox_callback;
332         xmlhttp.send(null);
333
334 }
335
336 function editFilter(id) {
337
338         if (!xmlhttp_ready(xmlhttp)) {
339                 printLockingError();
340                 return
341         }
342
343         document.getElementById("create_filter_btn").disabled = true;
344
345         selectTableRowsByIdPrefix('prefFilterList', 'FILRR-', 'FICHK-', false);
346         selectTableRowById('FILRR-'+id, 'FICHK-'+id, true);
347
348         xmlhttp.open("GET", "backend.php?op=pref-filters&subop=edit&id=" + param_escape(id), true);
349         xmlhttp.onreadystatechange=infobox_callback;
350         xmlhttp.send(null);
351 }
352
353 function editFeed(feed) {
354
355 //      notify("Editing feed...");
356
357         if (!xmlhttp_ready(xmlhttp)) {
358                 printLockingError();
359                 return
360         }
361
362         // clean selection from all rows & select row being edited
363         selectTableRowsByIdPrefix('prefFeedList', 'FEEDR-', 'FRCHK-', false);
364         selectTableRowById('FEEDR-'+feed, 'FRCHK-'+feed, true);
365
366         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=editfeed&id=" +
367                 param_escape(feed), true);
368
369         xmlhttp.onreadystatechange=infobox_callback;
370         xmlhttp.send(null);
371
372 }
373
374 function editFeedCat(cat) {
375
376         if (!xmlhttp_ready(xmlhttp)) {
377                 printLockingError();
378                 return
379         }
380
381         active_feed_cat = cat;
382
383         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=editCat&id=" +
384                 param_escape(cat), true);
385         xmlhttp.onreadystatechange=feedlist_callback;
386         xmlhttp.send(null);
387
388 }
389
390 function getSelectedLabels() {
391         return getSelectedTableRowIds("prefLabelList", "LILRR");
392 }
393
394 function getSelectedUsers() {
395         return getSelectedTableRowIds("prefUserList", "UMRR");
396 }
397
398 function getSelectedFeeds() {
399         return getSelectedTableRowIds("prefFeedList", "FEEDR");
400 }
401
402 function getSelectedFilters() {
403         return getSelectedTableRowIds("prefFilterList", "FILRR");
404 }
405
406 function getSelectedFeedCats() {
407         return getSelectedTableRowIds("prefFeedCatList", "FCATR");
408 }
409
410 function getSelectedFeedsFromBrowser() {
411
412         var list = document.getElementById("browseFeedList");
413         if (!list) list = document.getElementById("browseBigFeedList");
414
415         var selected = new Array();
416         
417         for (i = 0; i < list.childNodes.length; i++) {
418                 var child = list.childNodes[i];
419                 if (child.id && child.id.match("FBROW-")) {
420                         var id = child.id.replace("FBROW-", "");
421                         
422                         var cb = document.getElementById("FBCHK-" + id);
423
424                         if (cb.checked) {
425                                 selected.push(id);
426                         }
427                 }
428         }
429
430         return selected;
431 }
432
433 function removeSelectedLabels() {
434
435         if (!xmlhttp_ready(xmlhttp)) {
436                 printLockingError();
437                 return
438         }
439
440         var sel_rows = getSelectedLabels();
441
442         if (sel_rows.length > 0) {
443
444                 var ok = confirm("Remove selected labels?");
445
446                 if (ok) {
447                         notify("Removing selected labels...");
448         
449                         xmlhttp.open("GET", "backend.php?op=pref-labels&subop=remove&ids="+
450                                 param_escape(sel_rows.toString()), true);
451                         xmlhttp.onreadystatechange=labellist_callback;
452                         xmlhttp.send(null);
453                 }
454         } else {
455                 alert("No labels are selected.");
456         }
457 }
458
459 function removeSelectedUsers() {
460
461         if (!xmlhttp_ready(xmlhttp)) {
462                 printLockingError();
463                 return
464         }
465
466         var sel_rows = getSelectedUsers();
467
468         if (sel_rows.length > 0) {
469
470                 var ok = confirm("Remove selected users?");
471
472                 if (ok) {
473                         notify("Removing selected users...");
474         
475                         xmlhttp.open("GET", "backend.php?op=pref-users&subop=remove&ids="+
476                                 param_escape(sel_rows.toString()), true);
477                         xmlhttp.onreadystatechange=userlist_callback;
478                         xmlhttp.send(null);
479                 }
480
481         } else {
482                 alert("No users are selected.");
483         }
484 }
485
486 function removeSelectedFilters() {
487
488         if (!xmlhttp_ready(xmlhttp)) {
489                 printLockingError();
490                 return
491         }
492
493         var sel_rows = getSelectedFilters();
494
495         if (sel_rows.length > 0) {
496
497                 var ok = confirm("Remove selected filters?");
498
499                 if (ok) {
500                         notify("Removing selected filters...");
501         
502                         xmlhttp.open("GET", "backend.php?op=pref-filters&subop=remove&ids="+
503                                 param_escape(sel_rows.toString()), true);
504                         xmlhttp.onreadystatechange=filterlist_callback;
505                         xmlhttp.send(null);
506                 }
507         } else {
508                 alert("No filters are selected.");
509         }
510 }
511
512
513 function removeSelectedFeeds() {
514
515         if (!xmlhttp_ready(xmlhttp)) {
516                 printLockingError();
517                 return
518         }
519
520         var sel_rows = getSelectedFeeds();
521
522         if (sel_rows.length > 0) {
523
524                 var ok = confirm("Unsubscribe from selected feeds?");
525
526                 if (ok) {
527
528                         notify("Unsubscribing from selected feeds...");
529         
530                         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=remove&ids="+
531                                 param_escape(sel_rows.toString()), true);
532                         xmlhttp.onreadystatechange=feedlist_callback;
533                         xmlhttp.send(null);
534                 }
535
536         } else {
537
538                 alert("No feeds are selected.");
539
540         }
541
542 }
543
544 function removeSelectedFeedCats() {
545
546         if (!xmlhttp_ready(xmlhttp)) {
547                 printLockingError();
548                 return
549         }
550
551         var sel_rows = getSelectedFeedCats();
552
553         if (sel_rows.length > 0) {
554
555                 var ok = confirm("Remove selected categories?");
556
557                 if (ok) {
558                         notify("Removing selected categories...");
559         
560                         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=removeCats&ids="+
561                                 param_escape(sel_rows.toString()), true);
562                         xmlhttp.onreadystatechange=feedlist_callback;
563                         xmlhttp.send(null);
564                 }
565
566         } else {
567
568                 alert("No categories are selected.");
569
570         }
571
572 }
573
574 function feedEditCancel() {
575
576         if (!xmlhttp_ready(xmlhttp)) {
577                 printLockingError();
578                 return
579         }
580
581         closeInfoBox();
582
583         selectPrefRows('feed', false); // cleanup feed selection
584
585 }
586
587 function feedCatEditCancel() {
588
589         if (!xmlhttp_ready(xmlhttp)) {
590                 printLockingError();
591                 return
592         }
593
594         active_feed_cat = false;
595
596 //      notify("Operation cancelled.");
597
598         xmlhttp.open("GET", "backend.php?op=pref-feeds", true);
599         xmlhttp.onreadystatechange=feedlist_callback;
600         xmlhttp.send(null);
601
602 }
603
604 function feedEditSave() {
605
606         try {
607         
608                 if (!xmlhttp_ready(xmlhttp)) {
609                         printLockingError();
610                         return
611                 }
612
613                 // FIXME: add parameter validation
614
615                 var query = Form.serialize("edit_feed_form");
616
617                 notify("Saving feed...");
618
619                 xmlhttp.open("POST", "backend.php", true);
620                 xmlhttp.onreadystatechange=feedlist_callback;
621                 xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
622                 xmlhttp.send(query);
623
624                 closeInfoBox();
625
626                 return false;
627
628         } catch (e) {
629                 exception_error("feedEditSave", e);
630         } 
631 }
632
633 function feedCatEditSave() {
634
635         if (!xmlhttp_ready(xmlhttp)) {
636                 printLockingError();
637                 return
638         }
639
640         notify("Saving category...");
641
642         var query = Form.serialize("feed_cat_edit_form");
643
644         xmlhttp.open("GET", "backend.php?" + query, true);
645         xmlhttp.onreadystatechange=feedlist_callback;
646         xmlhttp.send(null);
647
648         active_feed_cat = false;
649
650 }
651
652
653 function labelTest() {
654
655         var form = document.forms['label_edit_form'];
656
657         var sql_exp = form.sql_exp.value;
658         var description = form.description.value;
659
660         xmlhttp.open("GET", "backend.php?op=pref-labels&subop=test&expr=" +
661                 param_escape(sql_exp) + "&descr=" + param_escape(description), true);
662
663         xmlhttp.onreadystatechange=infobox_callback;
664         xmlhttp.send(null);
665
666 }
667
668 function displayHelpInfobox(topic_id) {
669
670         xmlhttp.open("GET", "backend.php?op=help&tid=" +
671                 param_escape(topic_id) + "&noheaders=1", true);
672
673         xmlhttp.onreadystatechange=infobox_callback;
674         xmlhttp.send(null);
675
676 }
677
678 function labelEditCancel() {
679
680         if (!xmlhttp_ready(xmlhttp)) {
681                 printLockingError();
682                 return
683         }
684
685         active_label = false;
686
687 //      notify("Operation cancelled.");
688
689         closeInfoBox();
690
691         xmlhttp.open("GET", "backend.php?op=pref-labels", true);
692         xmlhttp.onreadystatechange=labellist_callback;
693         xmlhttp.send(null);
694
695 }
696
697 function userEditCancel() {
698
699         if (!xmlhttp_ready(xmlhttp)) {
700                 printLockingError();
701                 return
702         }
703
704         selectPrefRows('user', false); // cleanup feed selection
705         closeInfoBox();
706 }
707
708 function filterEditCancel() {
709
710         if (!xmlhttp_ready(xmlhttp)) {
711                 printLockingError();
712                 return
713         }
714
715         document.getElementById("create_filter_btn").disabled = false;
716         
717         selectPrefRows('filter', false); // cleanup feed selection
718         closeInfoBox();
719 }
720
721 function labelEditSave() {
722
723         var label = active_label;
724
725         if (!xmlhttp_ready(xmlhttp)) {
726                 printLockingError();
727                 return
728         }
729
730         var sql_exp = document.forms["label_edit_form"].sql_exp.value;
731         var description = document.forms["label_edit_form"].description.value;
732
733         if (sql_exp.length == 0) {
734                 alert("SQL Expression cannot be blank.");
735                 return;
736         }
737
738         if (description.length == 0) {
739                 alert("Caption field cannot be blank.");
740                 return;
741         }
742
743         closeInfoBox();
744
745         notify("Saving label...");
746
747         active_label = false;
748
749         query = Form.serialize("label_edit_form");
750
751         xmlhttp.open("GET", "backend.php?" + query, true);              
752         xmlhttp.onreadystatechange=labellist_callback;
753         xmlhttp.send(null);
754
755 }
756
757 function userEditSave() {
758
759         if (!xmlhttp_ready(xmlhttp)) {
760                 printLockingError();
761                 return
762         }
763
764         var login = document.forms["user_edit_form"].login.value;
765
766         if (login.length == 0) {
767                 alert("Login field cannot be blank.");
768                 return;
769         }
770         
771         notify("Saving user...");
772
773         closeInfoBox();
774
775         var query = Form.serialize("user_edit_form");
776         
777         xmlhttp.open("GET", "backend.php?" + query, true);                      
778         xmlhttp.onreadystatechange=userlist_callback;
779         xmlhttp.send(null);
780 }
781
782
783 function filterEditSave() {
784
785         if (!xmlhttp_ready(xmlhttp)) {
786                 printLockingError();
787                 return
788         }
789
790         var reg_exp = document.forms["filter_edit_form"].reg_exp.value;
791
792         if (reg_exp.length == 0) {
793                 alert("Filter expression field cannot be blank.");
794                 return;
795         }
796
797         notify("Saving filter...");
798
799         var query = Form.serialize("filter_edit_form");
800
801         closeInfoBox();
802
803         document.getElementById("create_filter_btn").disabled = false;
804
805         xmlhttp.open("GET", "backend.php?" + query, true);
806         xmlhttp.onreadystatechange=filterlist_callback;
807         xmlhttp.send(null);
808
809 }
810
811 function editSelectedLabel() {
812         var rows = getSelectedLabels();
813
814         if (rows.length == 0) {
815                 alert("No labels are selected.");
816                 return;
817         }
818
819         if (rows.length > 1) {
820                 alert("Please select only one label.");
821                 return;
822         }
823
824         notify("");
825
826         editLabel(rows[0]);
827
828 }
829
830 function editSelectedUser() {
831         var rows = getSelectedUsers();
832
833         if (rows.length == 0) {
834                 alert("No users are selected.");
835                 return;
836         }
837
838         if (rows.length > 1) {
839                 alert("Please select only one user.");
840                 return;
841         }
842
843         notify("");
844
845         editUser(rows[0]);
846 }
847
848 function resetSelectedUserPass() {
849         var rows = getSelectedUsers();
850
851         if (rows.length == 0) {
852                 alert("No users are selected.");
853                 return;
854         }
855
856         if (rows.length > 1) {
857                 alert("Please select only one user.");
858                 return;
859         }
860
861         var ok = confirm("Reset password of selected user?");
862
863         if (ok) {
864                 notify("Resetting password for selected user...");
865         
866                 var id = rows[0];
867         
868                 xmlhttp.open("GET", "backend.php?op=pref-users&subop=resetPass&id=" +
869                         param_escape(id), true);
870                 xmlhttp.onreadystatechange=userlist_callback;
871                 xmlhttp.send(null);
872         }
873 }
874
875 function selectedUserDetails() {
876
877         if (!xmlhttp_ready(xmlhttp)) {
878                 printLockingError();
879                 return
880         }
881
882         var rows = getSelectedUsers();
883
884         if (rows.length == 0) {
885                 alert("No users are selected.");
886                 return;
887         }
888
889         if (rows.length > 1) {
890                 alert("Please select only one user.");
891                 return;
892         }
893
894         var id = rows[0];
895
896         notify("");
897
898         xmlhttp.open("GET", "backend.php?op=user-details&id=" + id, true);
899         xmlhttp.onreadystatechange=infobox_callback;
900         xmlhttp.send(null);
901
902 }
903
904 function selectedFeedDetails() {
905
906         if (!xmlhttp_ready(xmlhttp)) {
907                 printLockingError();
908                 return
909         }
910
911         var rows = getSelectedFeeds();
912
913         if (rows.length == 0) {
914                 alert("No feeds are selected.");
915                 return;
916         }
917
918         if (rows.length > 1) {
919                 notify("Please select only one feed.");
920                 return;
921         }
922
923 //      var id = rows[0];
924
925         notify("");
926
927         xmlhttp.open("GET", "backend.php?op=feed-details&id=" + 
928                 param_escape(rows.toString()), true);
929         xmlhttp.onreadystatechange=infobox_callback;
930         xmlhttp.send(null);
931
932 }
933
934 function editSelectedFilter() {
935         var rows = getSelectedFilters();
936
937         if (rows.length == 0) {
938                 alert("No filters are selected.");
939                 return;
940         }
941
942         if (rows.length > 1) {
943                 alert("Please select only one filter.");
944                 return;
945         }
946
947         notify("");
948
949         editFilter(rows[0]);
950
951 }
952
953
954 function editSelectedFeed() {
955         var rows = getSelectedFeeds();
956
957         if (rows.length == 0) {
958                 notify("No feeds are selected.");
959                 return;
960         }
961
962         if (rows.length > 1) {
963                 notify("Please select one feed.");
964                 return;
965         }
966
967         notify("");
968
969         editFeed(rows[0]);
970
971 }
972
973 function editSelectedFeedCat() {
974         var rows = getSelectedFeedCats();
975
976         if (rows.length == 0) {
977                 alert("No categories are selected.");
978                 return;
979         }
980
981         if (rows.length > 1) {
982                 alert("Please select only one category.");
983                 return;
984         }
985
986         notify("");
987
988         editFeedCat(rows[0]);
989
990 }
991
992 function piggie_callback() {
993         var piggie = document.getElementById("piggie");
994
995         piggie.style.top = piggie_top;
996         piggie.style.backgroundColor = "white";
997         piggie.style.borderWidth = "1px";
998
999         if (piggie_fwd && piggie_top < 0) {
1000                 setTimeout("piggie_callback()", 50);
1001                 piggie_top = piggie_top + 10;
1002         } else if (piggie_fwd && piggie_top >= 0) {
1003                 piggie_fwd = false;
1004                 setTimeout("piggie_callback()", 50);
1005         } else if (!piggie_fwd && piggie_top > -400) {
1006                 setTimeout("piggie_callback()", 50);
1007                 piggie_top = piggie_top - 10;
1008         } else if (!piggie_fwd && piggie_top <= -400) {
1009                 piggie.style.display = "none";
1010                 piggie_fwd = true;
1011         }
1012 }
1013
1014 var piggie_opacity = 0;
1015
1016 function piggie2_callback() {
1017         var piggie = document.getElementById("piggie");
1018         piggie.style.top = 0;
1019         piggie.style.opacity = piggie_opacity;
1020         piggie.style.backgroundColor = "transparent";
1021         piggie.style.borderWidth = "0px";
1022
1023         if (piggie_fwd && piggie_opacity < 1) {
1024                 setTimeout("piggie2_callback()", 50);
1025                 piggie_opacity = piggie_opacity + 0.03;
1026         } else if (piggie_fwd && piggie_opacity >= 1) {
1027                 piggie_fwd = false;
1028                 setTimeout("piggie2_callback()", 50);
1029         } else if (!piggie_fwd && piggie_opacity > 0) {
1030                 setTimeout("piggie2_callback()", 50);
1031                 piggie_opacity = piggie_opacity - 0.03;
1032         } else if (!piggie_fwd && piggie_opacity <= 0) {
1033                 piggie.style.display = "none";
1034                 piggie_fwd = true;
1035         }
1036 }
1037
1038 function localPiggieFunction(enable) {
1039         if (enable) {
1040                 var piggie = document.getElementById("piggie");
1041                 piggie.style.display = "block";
1042
1043                 if (navigator.userAgent.match("Gecko") && Math.random(1) > 0.5) {       
1044                         piggie2_callback();
1045                 } else {
1046                         piggie_callback();
1047                 }
1048         }
1049 }
1050
1051 function validateOpmlImport() {
1052         
1053         var opml_file = document.getElementById("opml_file");
1054
1055         if (opml_file.value.length == 0) {
1056                 alert("No OPML file to upload.");
1057                 return false;
1058         } else {
1059                 return true;
1060         }
1061 }
1062
1063 function updateFilterList() {
1064
1065         if (!xmlhttp_ready(xmlhttp)) {
1066                 printLockingError();
1067                 return
1068         }
1069
1070 //      document.getElementById("prefContent").innerHTML = "Loading filters, please wait...";
1071
1072 //      p_notify("Loading, please wait...");
1073
1074         xmlhttp.open("GET", "backend.php?op=pref-filters", true);
1075         xmlhttp.onreadystatechange=filterlist_callback;
1076         xmlhttp.send(null);
1077
1078 }
1079
1080 function updateLabelList() {
1081
1082         if (!xmlhttp_ready(xmlhttp)) {
1083                 printLockingError();
1084                 return
1085         }
1086
1087 //      p_notify("Loading, please wait...");
1088
1089 //      document.getElementById("prefContent").innerHTML = "Loading labels, please wait...";
1090
1091         xmlhttp.open("GET", "backend.php?op=pref-labels", true);
1092         xmlhttp.onreadystatechange=labellist_callback;
1093         xmlhttp.send(null);
1094 }
1095
1096 function updatePrefsList() {
1097
1098         if (!xmlhttp_ready(xmlhttp)) {
1099                 printLockingError();
1100                 return
1101         }
1102
1103 //      p_notify("Loading, please wait...");
1104
1105         xmlhttp.open("GET", "backend.php?op=pref-prefs", true);
1106         xmlhttp.onreadystatechange=prefslist_callback;
1107         xmlhttp.send(null);
1108
1109 }
1110
1111 function selectTab(id, noupdate) {
1112
1113 //      alert(id);
1114
1115         if (!xmlhttp_ready(xmlhttp)) {
1116                 printLockingError();
1117                 return
1118         }
1119
1120         if (!noupdate) {
1121
1122                 notify("Loading, please wait...", true);
1123
1124                 // close active infobox if needed
1125                 closeInfoBox();
1126
1127                 // clean up all current selections, just in case
1128                 active_feed_cat = false;
1129                 active_label = false;
1130
1131                 if (id == "feedConfig") {
1132                         updateFeedList();
1133                 } else if (id == "filterConfig") {
1134                         updateFilterList();
1135                 } else if (id == "labelConfig") {
1136                         updateLabelList();
1137                 } else if (id == "genConfig") {
1138                         updatePrefsList();
1139                 } else if (id == "userConfig") {
1140                         updateUsersList();
1141                 } else if (id == "feedBrowser") {
1142                         updateBigFeedBrowser();
1143                 }
1144         }
1145
1146         var tab = document.getElementById(active_tab + "Tab");
1147
1148         if (tab) {
1149                 if (tab.className.match("Selected")) {
1150                         tab.className = "prefsTab";
1151                 }
1152         }
1153
1154         tab = document.getElementById(id + "Tab");
1155
1156         if (tab) {
1157                 if (!tab.className.match("Selected")) {
1158                         tab.className = tab.className + "Selected";
1159                 }
1160         }
1161
1162         if (active_tab != id) {
1163                 storeInitParam("prefs_active_tab", id);
1164         }
1165
1166         active_tab = id;
1167 }
1168
1169 function backend_sanity_check_callback() {
1170
1171         if (xmlhttp.readyState == 4) {
1172
1173                 try {
1174                 
1175                         if (!xmlhttp.responseXML) {
1176                                 fatalError(3, "[D001, Received reply is not XML]: " + xmlhttp.responseText);
1177                                 return;
1178                         }
1179         
1180                         var reply = xmlhttp.responseXML.firstChild.firstChild;
1181         
1182                         if (!reply) {
1183                                 fatalError(3, "[D002, Invalid RPC reply]: " + xmlhttp.responseText);
1184                                 return;
1185                         }
1186         
1187                         var error_code = reply.getAttribute("error-code");
1188                 
1189                         if (error_code && error_code != 0) {
1190                                 return fatalError(error_code, reply.getAttribute("error-msg"));
1191                         }
1192         
1193                         debug("sanity check ok");
1194
1195                         var params = reply.nextSibling;
1196
1197                         if (params) {
1198                                 debug('reading init-params...');
1199                                 var param = params.firstChild;
1200
1201                                 while (param) {
1202                                         var k = param.getAttribute("key");
1203                                         var v = param.getAttribute("value");
1204                                         debug(k + " => " + v);
1205                                         init_params[k] = v;                                     
1206                                         param = param.nextSibling;
1207                                 }
1208                         }
1209
1210                         init_second_stage();
1211
1212                 } catch (e) {
1213                         exception_error("backend_sanity_check_callback", e);
1214                 }
1215         } 
1216 }
1217
1218 function init_second_stage() {
1219
1220         active_tab = getInitParam("prefs_active_tab");
1221         if (!active_tab) active_tab = "genConfig";
1222         selectTab(active_tab);
1223         
1224         notify("");
1225
1226 }
1227
1228 function init() {
1229
1230         try {
1231         
1232                 if (arguments.callee.done) return;
1233                 arguments.callee.done = true;           
1234
1235                 if (getURLParam('debug')) {
1236                         document.getElementById('debug_output').style.display = 'block';
1237                         debug('debug mode activated');
1238                 }
1239
1240                 // IE kludge
1241                 if (!xmlhttp) {
1242                         document.getElementById("prefContent").innerHTML = 
1243                                 "<b>Fatal error:</b> This program needs XmlHttpRequest " + 
1244                                 "to function properly. Your browser doesn't seem to support it.";
1245                         return;
1246                 }
1247
1248                 xmlhttp.open("GET", "backend.php?op=rpc&subop=sanityCheck", true);
1249                 xmlhttp.onreadystatechange=backend_sanity_check_callback;
1250                 xmlhttp.send(null);
1251
1252         } catch (e) {
1253                 exception_error("init", e);
1254         }
1255 }
1256
1257 function categorizeSelectedFeeds() {
1258
1259         if (!xmlhttp_ready(xmlhttp)) {
1260                 printLockingError();
1261                 return
1262         }
1263
1264         var sel_rows = getSelectedFeeds();
1265
1266         var cat_sel = document.getElementById("sfeed_set_fcat");
1267         var cat_id = cat_sel[cat_sel.selectedIndex].value;
1268
1269         if (sel_rows.length > 0) {
1270
1271                 notify("Changing category of selected feeds...");
1272
1273                 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=categorize&ids="+
1274                         param_escape(sel_rows.toString()) + "&cat_id=" + param_escape(cat_id), true);
1275                 xmlhttp.onreadystatechange=feedlist_callback;
1276                 xmlhttp.send(null);
1277
1278         } else {
1279
1280                 alert("No feeds are selected.");
1281
1282         }
1283
1284 }
1285
1286 function validatePrefsReset() {
1287         return confirm("Reset to defaults?");
1288 }
1289
1290 function browseFeeds(limit) {
1291
1292         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=browse", true);
1293         xmlhttp.onreadystatechange=infobox_callback;
1294         xmlhttp.send(null);
1295
1296 }
1297
1298 function feedBrowserSubscribe() {
1299         try {
1300
1301                 var selected = getSelectedFeedsFromBrowser();
1302
1303                 if (selected.length > 0) {
1304                         closeInfoBox();
1305                         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=massSubscribe&ids="+
1306                                 param_escape(selected.toString()), true);
1307                         xmlhttp.onreadystatechange=feedlist_callback;
1308                         xmlhttp.send(null);
1309                 } else {
1310                         alert("No feeds are selected.");
1311                 }
1312
1313         } catch (e) {
1314                 exception_error("feedBrowserSubscribe", e);
1315         }
1316 }
1317
1318 function updateBigFeedBrowser(limit) {
1319
1320         if (!xmlhttp_ready(xmlhttp)) {
1321                 printLockingError();
1322                 return
1323         }
1324
1325 //      p_notify("Loading, please wait...");
1326
1327         var query = "backend.php?op=pref-feed-browser";
1328
1329         var limit_sel = document.getElementById("feedBrowserLimit");
1330
1331         if (limit_sel) {
1332                 var limit = limit_sel[limit_sel.selectedIndex].value;
1333                 query = query + "&limit=" + param_escape(limit);
1334         }
1335
1336         xmlhttp.open("GET", query, true);
1337         xmlhttp.onreadystatechange=feed_browser_callback;
1338         xmlhttp.send(null);
1339 }
1340
1341 function browserToggleExpand(id) {
1342         try {
1343 /*              if (feed_to_expand && feed_to_expand != id) {
1344                         var d = document.getElementById("BRDET-" + feed_to_expand);
1345                         d.style.display = "none";
1346                 } */
1347
1348                 if (!xmlhttp_ready(xmlhttp)) {
1349                         printLockingError();
1350                         return
1351                 }
1352
1353                 var d = document.getElementById("BRDET-" + id);
1354
1355                 if (d.style.display == "block") {               
1356                         d.style.display = "none";
1357                         
1358                 } else {
1359         
1360                         feed_to_expand = id;
1361
1362                         d.style.display = "block";
1363                         d.innerHTML = "Loading, please wait...";
1364
1365                         xmlhttp.open("GET", "backend.php?op=pref-feed-browser&subop=details&id="
1366                                 + param_escape(id), true);
1367                         xmlhttp.onreadystatechange=expand_feed_callback;
1368                         xmlhttp.send(null);
1369                 }
1370
1371         } catch (e) {
1372                 exception_error("browserExpand", e);
1373         }
1374 }
1375
1376 function validateNewPassword(form) {
1377         if (form.OLD_PASSWORD.value == "") {
1378                 alert("Old password cannot be blank");
1379                 return false;
1380         }
1381         if (form.NEW_PASSWORD.value == "") {
1382                 alert("New password cannot be blank");
1383                 return false;
1384         }
1385         return true;
1386 }
1387
1388 function selectPrefRows(kind, select) {
1389
1390         if (kind) {
1391                 var opbarid = false;    
1392                 var nchk = false;
1393                 var nrow = false;
1394                 var lname = false;
1395
1396                 if (kind == "feed") {
1397                         opbarid = "feedOpToolbar";
1398                         nrow = "FEEDR-";
1399                         nchk = "FRCHK-";                        
1400                         lname = "prefFeedList";
1401                 } else if (kind == "fcat") {
1402                         opbarid = "catOpToolbar";
1403                         nrow = "FCATR-";
1404                         nchk = "FCHK-";
1405                         lname = "prefFeedCatList";
1406                 } else if (kind == "filter") {
1407                         opbarid = "filterOpToolbar";
1408                         nrow = "FILRR-";
1409                         nchk = "FICHK-";
1410                         lname = "prefFilterList";
1411                 } else if (kind == "label") {
1412                         opbarid = "labelOpToolbar";
1413                         nrow = "LILRR-";
1414                         nchk = "LCHK-";
1415                         lname = "prefLabelList";
1416                 } else if (kind == "user") {
1417                         opbarid = "userOpToolbar";
1418                         nrow = "UMRR-";
1419                         nchk = "UMCHK-";
1420                         lname = "prefUserList";
1421                 }
1422
1423                 if (opbarid) {
1424                         selectTableRowsByIdPrefix(lname, nrow, nchk, select);
1425                         disableContainerChildren(opbarid, !select);
1426                 }
1427
1428         } 
1429 }
1430
1431
1432 function toggleSelectPrefRow(sender, kind) {
1433
1434         toggleSelectRow(sender);
1435
1436         if (kind) {
1437                 var opbarid = false;    
1438                 var nsel = -1;
1439                 
1440                 if (kind == "feed") {
1441                         opbarid = "feedOpToolbar";
1442                         nsel = getSelectedFeeds();
1443                 } else if (kind == "fcat") {
1444                         opbarid = "catOpToolbar";
1445                         nsel = getSelectedFeedCats();
1446                 } else if (kind == "filter") {
1447                         opbarid = "filterOpToolbar";
1448                         nsel = getSelectedFilters();
1449                 } else if (kind == "label") {
1450                         opbarid = "labelOpToolbar";
1451                         nsel = getSelectedLabels();
1452                 } else if (kind == "user") {
1453                         opbarid = "userOpToolbar";
1454                         nsel = getSelectedUsers();
1455                 }
1456
1457                 if (opbarid && nsel != -1) {
1458                         disableContainerChildren(opbarid, nsel == false);
1459                 }
1460
1461         } 
1462 }
1463
1464 function toggleSelectFBListRow(sender) {
1465         toggleSelectListRow(sender);
1466         disableContainerChildren("fbrOpToolbar", getSelectedFeedsFromBrowser() == 0);
1467 }