]> git.wh0rd.org Git - tt-rss.git/blob - prefs.js
prefs: code cleanup
[tt-rss.git] / prefs.js
1 var xmlhttp = false;
2
3 var active_feed_cat = false;
4 var active_tab = false;
5
6 var xmlhttp = Ajax.getTransport();
7
8 var init_params = new Array();
9
10 var caller_subop = false;
11 var sanity_check_done = false;
12 var hotkey_prefix = false;
13
14 function infobox_callback() {
15         if (xmlhttp.readyState == 4) {
16                 infobox_callback2(xmlhttp);
17         }
18 }
19
20 function infobox_submit_callback() {
21         if (xmlhttp.readyState == 4) {
22                 infobox_submit_callback2(xmlhttp);
23         }
24 }
25
26
27 function replace_pubkey_callback() {
28         if (xmlhttp.readyState == 4) {
29                 try {   
30                         var link = document.getElementById("pubGenAddress");
31
32                         if (xmlhttp.responseXML) {
33
34                                 var new_link = xmlhttp.responseXML.getElementsByTagName("link")[0];
35
36                                 if (new_link) {
37                                         link.href = new_link.firstChild.nodeValue;
38                                         //link.innerHTML = new_link.firstChild.nodeValue;
39
40                                         new Effect.Highlight(link);
41
42                                         notify_info("Published feed URL changed.");
43                                 } else {
44                                         notify_error("Could not change feed URL.");
45                                 }
46
47                         } else {
48                                 notify_error("Could not change feed URL.");
49                         }
50                 } catch (e) {
51                         exception_error("replace_pubkey_callback", e);
52                 }
53         }
54 }
55
56 function feedlist_callback() {
57         if (xmlhttp.readyState == 4) {
58                 try {   
59                         var container = document.getElementById('prefContent'); 
60                         container.innerHTML=xmlhttp.responseText;
61                         selectTab("feedConfig", true);
62
63                         if (caller_subop) {
64                                 var tuple = caller_subop.split(":");
65                                 if (tuple[0] == 'editFeed') {
66                                         window.setTimeout('editFeed('+tuple[1]+')', 100);
67                                 }                               
68
69                                 caller_subop = false;
70                         }
71                         if (typeof correctPNG != 'undefined') {
72                                 correctPNG();
73                         }
74                         notify("");
75                         remove_splash();
76
77                 } catch (e) {
78                         exception_error("feedlist_callback", e);
79                 }
80         }
81 }
82
83 /* stub for subscription dialog */
84
85 function dlg_frefresh_callback(transport) {
86
87         try {
88                 var container = document.getElementById('prefContent'); 
89                 container.innerHTML=transport.responseText;
90                 selectTab("feedConfig", true);
91
92                 if (caller_subop) {
93                         var tuple = caller_subop.split(":");
94                         if (tuple[0] == 'editFeed') {
95                                 window.setTimeout('editFeed('+tuple[1]+')', 100);
96                         }                               
97
98                         caller_subop = false;
99                 }
100                 if (typeof correctPNG != 'undefined') {
101                         correctPNG();
102                 }
103                 notify("");
104         } catch (e) {
105                 exception_error("feedlist_callback", e);
106         }
107
108 }
109
110 function filterlist_callback() {
111         var container = document.getElementById('prefContent');
112         if (xmlhttp.readyState == 4) {
113                 container.innerHTML=xmlhttp.responseText;
114                 if (typeof correctPNG != 'undefined') {
115                         correctPNG();
116                 }
117                 notify("");
118                 remove_splash();
119         }
120 }
121
122 function labellist_callback() {
123
124         try {
125
126                 var container = document.getElementById('prefContent');
127                 if (xmlhttp.readyState == 4) {
128                         closeInfoBox();
129                         container.innerHTML=xmlhttp.responseText;
130         
131                         if (document.getElementById("prefLabelList")) {
132                                 var elems = document.getElementById("prefLabelList").getElementsByTagName("SPAN");
133
134                                 for (var i = 0; i < elems.length; i++) {
135                                         if (elems[i].id && elems[i].id.match("LILT-")) {
136
137                                                 var id = elems[i].id.replace("LILT-", "");
138                                                         new Ajax.InPlaceEditor(elems[i],
139                                                         'backend.php?op=pref-labels&subop=save&id=' + id,
140                                                         {cols: 20, rows: 1});
141                                         }
142                                 }
143                         }
144         
145                         if (typeof correctPNG != 'undefined') {
146                                 correctPNG();
147                         }
148                         notify("");
149                         remove_splash();
150                 }
151
152         } catch (e) {
153                 exception_error("labellist_callback", e);
154         }
155 }
156
157 function feed_browser_callback() {
158         var container = document.getElementById('prefContent');
159         if (xmlhttp.readyState == 4) {
160                 container.innerHTML=xmlhttp.responseText;
161                 notify("");
162                 remove_splash();
163         }
164 }
165
166 function userlist_callback() {
167         var container = document.getElementById('prefContent');
168         if (xmlhttp.readyState == 4) {
169                 container.innerHTML=xmlhttp.responseText;
170                 notify("");
171                 remove_splash();
172         }
173 }
174
175 function prefslist_callback() {
176         var container = document.getElementById('prefContent');
177         if (xmlhttp.readyState == 4) {
178                 container.innerHTML=xmlhttp.responseText;
179                 notify("");
180                 remove_splash();
181         }
182 }
183
184 function gethelp_callback() {
185         var container = document.getElementById('prefHelpBox');
186         if (xmlhttp.readyState == 4) {
187
188                 container.innerHTML = xmlhttp.responseText;
189                 container.style.display = "block";
190
191         }
192 }
193
194 function notify_callback() {
195         if (xmlhttp.readyState == 4) {
196                 notify_info(xmlhttp.responseText);
197         } 
198 }
199
200 function prefs_reset_callback() {
201         if (xmlhttp.readyState == 4) {
202                 notify_info(xmlhttp.responseText);
203                 selectTab();
204         } 
205 }
206
207
208 function changepass_callback() {
209         try {
210                 if (xmlhttp.readyState == 4) {
211         
212                         if (xmlhttp.responseText.indexOf("ERROR: ") == 0) {
213                                 notify_error(xmlhttp.responseText.replace("ERROR: ", ""));
214                         } else {
215                                 notify_info(xmlhttp.responseText);
216                                 var warn = document.getElementById("default_pass_warning");
217                                 if (warn) warn.style.display = "none";
218                         }
219         
220                         document.forms['change_pass_form'].reset();
221
222                 } 
223         } catch (e) {
224                 exception_error("changepass_callback", e);
225         }
226 }
227
228 function init_cat_inline_editor() {
229         try {
230
231                 if (document.getElementById("prefFeedCatList")) {
232                         var elems = document.getElementById("prefFeedCatList").getElementsByTagName("SPAN");
233
234                         for (var i = 0; i < elems.length; i++) {
235                                 if (elems[i].id && elems[i].id.match("FCATT-")) {
236                                         var cat_id = elems[i].id.replace("FCATT-", "");
237                                                 new Ajax.InPlaceEditor(elems[i],
238                                                 'backend.php?op=pref-feeds&subop=editCats&action=save&cid=' + cat_id);
239                                 }
240                         }
241                 }
242
243         } catch (e) {
244                 exception_error("init_cat_inline_editor", e);
245         }
246 }
247
248 function infobox_feed_cat_callback() {
249         if (xmlhttp.readyState == 4) {
250                 try {
251
252                         infobox_callback();
253                         init_cat_inline_editor();
254
255                 } catch (e) {
256                         exception_error("infobox_feed_cat_callback", e);
257                 }
258         }
259 }
260
261 function updateFeedList(sort_key) {
262
263         if (!xmlhttp_ready(xmlhttp)) {
264                 printLockingError();
265                 return
266         }
267
268         var feed_search = document.getElementById("feed_search");
269         var search = "";
270         if (feed_search) { search = feed_search.value; }
271
272         var slat = document.getElementById("show_last_article_times");
273
274         var slat_checked = false;
275         if (slat) {
276                 slat_checked = slat.checked;
277         }
278
279         xmlhttp.open("GET", "backend.php?op=pref-feeds" +
280                 "&sort=" + param_escape(sort_key) + 
281                 "&slat=" + param_escape(slat_checked) +
282                 "&search=" + param_escape(search), true);
283         xmlhttp.onreadystatechange=feedlist_callback;
284         xmlhttp.send(null);
285
286 }
287
288 function updateUsersList(sort_key) {
289
290         if (!xmlhttp_ready(xmlhttp)) {
291                 printLockingError();
292                 return
293         }
294
295         var user_search = document.getElementById("user_search");
296         var search = "";
297         if (user_search) { search = user_search.value; }
298
299         xmlhttp.open("GET", "backend.php?op=pref-users&sort="
300                 + param_escape(sort_key) +
301                 "&search=" + param_escape(search), true);
302         xmlhttp.onreadystatechange=userlist_callback;
303         xmlhttp.send(null);
304
305 }
306
307 function addLabel() {
308
309         try {
310
311         if (!xmlhttp_ready(xmlhttp)) {
312                 printLockingError();
313                 return
314         }
315
316         var caption = prompt(__("Please enter label caption:"), "");
317
318         if (caption == null) { 
319                 return false;
320         }
321
322         if (caption == "") {
323                 alert(__("Can't create label: missing caption."));
324                 return false;
325         }
326
327         // we can be called from some other tab
328         active_tab = "labelConfig";
329
330         var query = "caption=" + param_escape(caption);
331
332         xmlhttp.open("GET", "backend.php?op=pref-labels&subop=add&" + query, true);                     
333         xmlhttp.onreadystatechange=infobox_submit_callback;
334         xmlhttp.send(null);
335
336         } catch (e) {
337                 exception_error("addLabel", e);
338         }
339 }
340
341 function addFeed() {
342
343         if (!xmlhttp_ready(xmlhttp)) {
344                 printLockingError();
345                 return
346         }
347
348         var link = document.getElementById("fadd_link");
349
350         if (link.value.length == 0) {
351                 alert(__("Error: No feed URL given."));
352         } else if (!isValidURL(link.value)) {
353                 alert(__("Error: Invalid feed URL."));
354         } else {
355                 notify_progress("Adding feed...");
356
357                 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=add&from=tt-rss&feed_url=" +
358                         param_escape(link.value), true);
359                 xmlhttp.onreadystatechange=feedlist_callback;
360                 xmlhttp.send(null);
361
362                 link.value = "";
363
364         }
365
366 }
367
368 function addFeedCat() {
369
370         if (!xmlhttp_ready(xmlhttp)) {
371                 printLockingError();
372                 return
373         }
374
375         var cat = document.getElementById("fadd_cat");
376
377         if (cat.value.length == 0) {
378                 alert(__("Can't add category: no name specified."));
379         } else {
380                 notify_progress("Adding feed category...");
381
382                 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=editCats&action=add&cat=" +
383                         param_escape(cat.value), true);
384                 xmlhttp.onreadystatechange=infobox_feed_cat_callback;
385                 xmlhttp.send(null);
386
387                 link.value = "";
388
389         }
390
391 }
392 function addUser() {
393
394         if (!xmlhttp_ready(xmlhttp)) {
395                 printLockingError();
396                 return
397         }
398
399         var sqlexp = document.getElementById("uadd_box");
400
401         if (sqlexp.value.length == 0) {
402                 alert(__("Can't add user: no login specified."));
403         } else {
404                 notify_progress("Adding user...");
405
406                 xmlhttp.open("GET", "backend.php?op=pref-users&subop=add&login=" +
407                         param_escape(sqlexp.value), true);                      
408                         
409                 xmlhttp.onreadystatechange=userlist_callback;
410                 xmlhttp.send(null);
411
412                 sqlexp.value = "";
413         }
414
415 }
416
417 function editUser(id) {
418
419         if (!xmlhttp_ready(xmlhttp)) {
420                 printLockingError();
421                 return
422         }
423
424         disableHotkeys();
425
426         notify_progress("Loading, please wait...");
427
428         selectTableRowsByIdPrefix('prefUserList', 'UMRR-', 'UMCHK-', false);
429         selectTableRowById('UMRR-'+id, 'UMCHK-'+id, true);
430
431         disableContainerChildren("userOpToolbar", false);
432
433         xmlhttp.open("GET", "backend.php?op=pref-users&subop=edit&id=" +
434                 param_escape(id), true);
435         xmlhttp.onreadystatechange=infobox_callback;
436         xmlhttp.send(null);
437
438 }
439
440 function editFilter(id) {
441
442         if (!xmlhttp_ready(xmlhttp)) {
443                 printLockingError();
444                 return
445         }
446
447         disableHotkeys();
448
449         notify_progress("Loading, please wait...");
450
451 //      document.getElementById("create_filter_btn").disabled = true;
452
453         disableContainerChildren("filterOpToolbar", false);
454
455         selectTableRowsByIdPrefix('prefFilterList', 'FILRR-', 'FICHK-', false);
456         selectTableRowById('FILRR-'+id, 'FICHK-'+id, true);
457
458         xmlhttp.open("GET", "backend.php?op=pref-filters&subop=edit&id=" + param_escape(id), true);
459         xmlhttp.onreadystatechange=infobox_callback;
460         xmlhttp.send(null);
461 }
462
463 function editFeed(feed) {
464
465 //      notify("Editing feed...");
466
467         if (!xmlhttp_ready(xmlhttp)) {
468                 printLockingError();
469                 return
470         }
471
472         disableHotkeys();
473
474         notify_progress("Loading, please wait...");
475
476 /*      document.getElementById("subscribe_to_feed_btn").disabled = true;
477
478         try {
479                 document.getElementById("top25_feeds_btn").disabled = true;
480         } catch (e) {
481                 // this button is not always available, no-op if not found
482         } */
483
484         // clean selection from all rows & select row being edited
485         selectTableRowsByIdPrefix('prefFeedList', 'FEEDR-', 'FRCHK-', false);
486         selectTableRowById('FEEDR-'+feed, 'FRCHK-'+feed, true);
487
488         disableContainerChildren("feedOpToolbar", false);
489
490         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=editfeed&id=" +
491                 param_escape(feed), true);
492
493         xmlhttp.onreadystatechange=infobox_callback;
494         xmlhttp.send(null);
495
496 }
497
498 function editFeedCat(cat) {
499
500         if (!xmlhttp_ready(xmlhttp)) {
501                 printLockingError();
502                 return
503         }
504
505         disableHotkeys();
506
507         notify_progress("Loading, please wait...");
508
509         active_feed_cat = cat;
510
511         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=editCats&action=edit&id=" +
512                 param_escape(cat), true);
513         xmlhttp.onreadystatechange=infobox_callback;
514         xmlhttp.send(null);
515
516 }
517
518 function getSelectedLabels() {
519         return getSelectedTableRowIds("prefLabelList", "LILRR");
520 }
521
522 function getSelectedUsers() {
523         return getSelectedTableRowIds("prefUserList", "UMRR");
524 }
525
526 function getSelectedFeeds() {
527         return getSelectedTableRowIds("prefFeedList", "FEEDR");
528 }
529
530 function getSelectedFilters() {
531         return getSelectedTableRowIds("prefFilterList", "FILRR");
532 }
533
534 function getSelectedFeedCats() {
535         return getSelectedTableRowIds("prefFeedCatList", "FCATR");
536 }
537
538
539 function removeSelectedLabels() {
540
541         if (!xmlhttp_ready(xmlhttp)) {
542                 printLockingError();
543                 return
544         }
545
546         var sel_rows = getSelectedLabels();
547
548         if (sel_rows.length > 0) {
549
550                 var ok = confirm(__("Remove selected labels?"));
551
552                 if (ok) {
553                         notify_progress("Removing selected labels...");
554         
555                         xmlhttp.open("GET", "backend.php?op=pref-labels&subop=remove&ids="+
556                                 param_escape(sel_rows.toString()), true);
557                         xmlhttp.onreadystatechange=labellist_callback;
558                         xmlhttp.send(null);
559                 }
560         } else {
561                 alert(__("No labels are selected."));
562         }
563
564         return false;
565 }
566
567 function removeSelectedUsers() {
568
569         if (!xmlhttp_ready(xmlhttp)) {
570                 printLockingError();
571                 return
572         }
573
574         var sel_rows = getSelectedUsers();
575
576         if (sel_rows.length > 0) {
577
578                 var ok = confirm(__("Remove selected users?"));
579
580                 if (ok) {
581                         notify_progress("Removing selected users...");
582         
583                         xmlhttp.open("GET", "backend.php?op=pref-users&subop=remove&ids="+
584                                 param_escape(sel_rows.toString()), true);
585                         xmlhttp.onreadystatechange=userlist_callback;
586                         xmlhttp.send(null);
587                 }
588
589         } else {
590                 alert(__("No users are selected."));
591         }
592
593         return false;
594 }
595
596 function removeSelectedFilters() {
597
598         if (!xmlhttp_ready(xmlhttp)) {
599                 printLockingError();
600                 return
601         }
602
603         var sel_rows = getSelectedFilters();
604
605         if (sel_rows.length > 0) {
606
607                 var ok = confirm(__("Remove selected filters?"));
608
609                 if (ok) {
610                         notify_progress("Removing selected filters...");
611         
612                         xmlhttp.open("GET", "backend.php?op=pref-filters&subop=remove&ids="+
613                                 param_escape(sel_rows.toString()), true);
614                         xmlhttp.onreadystatechange=filterlist_callback;
615                         xmlhttp.send(null);
616                 }
617         } else {
618                 alert(__("No filters are selected."));
619         }
620
621         return false;
622 }
623
624
625 function removeSelectedFeeds() {
626
627         if (!xmlhttp_ready(xmlhttp)) {
628                 printLockingError();
629                 return
630         }
631
632         var sel_rows = getSelectedFeeds();
633
634         if (sel_rows.length > 0) {
635
636                 var ok = confirm(__("Unsubscribe from selected feeds?"));
637
638                 if (ok) {
639
640                         notify_progress("Unsubscribing from selected feeds...");
641         
642                         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=remove&ids="+
643                                 param_escape(sel_rows.toString()), true);
644                         xmlhttp.onreadystatechange=feedlist_callback;
645                         xmlhttp.send(null);
646                 }
647
648         } else {
649
650                 alert(__("No feeds are selected."));
651
652         }
653         
654         return false;
655 }
656
657 function clearSelectedFeeds() {
658
659         if (!xmlhttp_ready(xmlhttp)) {
660                 printLockingError();
661                 return
662         }
663
664         var sel_rows = getSelectedFeeds();
665
666         if (sel_rows.length > 1) {
667                 alert(__("Please select only one feed."));
668                 return;
669         }
670
671         if (sel_rows.length > 0) {
672
673                 var ok = confirm(__("Erase all non-starred articles in selected feed?"));
674
675                 if (ok) {
676                         notify_progress("Clearing selected feed...");
677                         clearFeedArticles(sel_rows[0]);
678                 }
679
680         } else {
681
682                 alert(__("No feeds are selected."));
683
684         }
685         
686         return false;
687 }
688
689 function purgeSelectedFeeds() {
690
691         if (!xmlhttp_ready(xmlhttp)) {
692                 printLockingError();
693                 return
694         }
695
696         var sel_rows = getSelectedFeeds();
697
698         if (sel_rows.length > 0) {
699
700                 var pr = prompt(__("How many days of articles to keep (0 - use default)?"), "0");
701
702                 if (pr != undefined) {
703                         notify_progress("Purging selected feed...");
704
705                         var query = "backend.php?op=rpc&subop=purge&ids="+
706                                 param_escape(sel_rows.toString()) + "&days=" + pr;
707
708                         debug(query);
709
710                         new Ajax.Request(query, {
711                                 onComplete: function(transport) {
712                                         notify('');
713                                 } });
714                 }
715
716         } else {
717
718                 alert(__("No feeds are selected."));
719
720         }
721         
722         return false;
723 }
724
725 function removeSelectedFeedCats() {
726
727         if (!xmlhttp_ready(xmlhttp)) {
728                 printLockingError();
729                 return
730         }
731
732         var sel_rows = getSelectedFeedCats();
733
734         if (sel_rows.length > 0) {
735
736                 var ok = confirm(__("Remove selected categories?"));
737
738                 if (ok) {
739                         notify_progress("Removing selected categories...");
740         
741                         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=editCats&action=remove&ids="+
742                                 param_escape(sel_rows.toString()), true);
743                         xmlhttp.onreadystatechange=infobox_feed_cat_callback;
744                         xmlhttp.send(null);
745                 }
746
747         } else {
748
749                 alert(__("No categories are selected."));
750
751         }
752
753         return false;
754 }
755
756 function feedEditCancel() {
757
758         if (!xmlhttp_ready(xmlhttp)) {
759                 printLockingError();
760                 return
761         }
762
763         try {
764                 document.getElementById("subscribe_to_feed_btn").disabled = false;
765                 document.getElementById("top25_feeds_btn").disabled = false;
766         } catch (e) {
767                 // this button is not always available, no-op if not found
768         }
769
770         closeInfoBox();
771
772         selectPrefRows('feed', false); // cleanup feed selection
773
774         return false;
775 }
776
777 function feedCatEditCancel() {
778
779         if (!xmlhttp_ready(xmlhttp)) {
780                 printLockingError();
781                 return
782         }
783
784         active_feed_cat = false;
785
786         try {
787                 document.getElementById("subscribe_to_feed_btn").disabled = false;
788                 document.getElementById("top25_feeds_btn").disabled = false;
789         } catch (e) {
790                 // this button is not always available, no-op if not found
791         }
792
793         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=editCats", true);
794         xmlhttp.onreadystatechange=infobox_callback;
795         xmlhttp.send(null);
796
797         return false;
798 }
799
800 function feedEditSave() {
801
802         try {
803         
804                 if (!xmlhttp_ready(xmlhttp)) {
805                         printLockingError();
806                         return
807                 }
808
809                 // FIXME: add parameter validation
810
811                 var query = Form.serialize("edit_feed_form");
812
813                 notify_progress("Saving feed...");
814
815                 xmlhttp.open("POST", "backend.php", true);
816                 xmlhttp.onreadystatechange=feedlist_callback;
817                 xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
818                 xmlhttp.send(query);
819
820                 closeInfoBox();
821
822                 return false;
823
824         } catch (e) {
825                 exception_error("feedEditSave", e);
826         } 
827 }
828
829 function userEditCancel() {
830
831         if (!xmlhttp_ready(xmlhttp)) {
832                 printLockingError();
833                 return
834         }
835
836         selectPrefRows('user', false); // cleanup feed selection
837         closeInfoBox();
838
839         return false;
840 }
841
842 function filterEditCancel() {
843
844         if (!xmlhttp_ready(xmlhttp)) {
845                 printLockingError();
846                 return
847         }
848
849         try {
850                 document.getElementById("create_filter_btn").disabled = false;
851                 selectPrefRows('filter', false); // cleanup feed selection
852         } catch (e) { }
853
854         closeInfoBox();
855
856         return false;
857 }
858
859 function userEditSave() {
860
861         if (!xmlhttp_ready(xmlhttp)) {
862                 printLockingError();
863                 return
864         }
865
866         var login = document.forms["user_edit_form"].login.value;
867
868         if (login.length == 0) {
869                 alert(__("Login field cannot be blank."));
870                 return;
871         }
872         
873         notify_progress("Saving user...");
874
875         closeInfoBox();
876
877         var query = Form.serialize("user_edit_form");
878         
879         xmlhttp.open("GET", "backend.php?" + query, true);                      
880         xmlhttp.onreadystatechange=userlist_callback;
881         xmlhttp.send(null);
882
883         return false;
884 }
885
886
887 function filterEditSave() {
888
889         if (!xmlhttp_ready(xmlhttp)) {
890                 printLockingError();
891                 return
892         }
893
894 /*      if (!is_opera()) {
895                 var reg_exp = document.forms["filter_edit_form"].reg_exp.value;
896         
897                 if (reg_exp.length == 0) {
898                         alert("Filter expression field cannot be blank.");
899                         return;
900                 }
901         } */
902
903         notify_progress("Saving filter...");
904
905         var query = Form.serialize("filter_edit_form");
906
907         closeInfoBox();
908
909         document.getElementById("create_filter_btn").disabled = false;
910
911         xmlhttp.open("GET", "backend.php?" + query, true);
912         xmlhttp.onreadystatechange=filterlist_callback;
913         xmlhttp.send(null);
914
915         return false;
916 }
917
918
919 function editSelectedUser() {
920         var rows = getSelectedUsers();
921
922         if (rows.length == 0) {
923                 alert(__("No users are selected."));
924                 return;
925         }
926
927         if (rows.length > 1) {
928                 alert(__("Please select only one user."));
929                 return;
930         }
931
932         notify("");
933
934         editUser(rows[0]);
935 }
936
937 function resetSelectedUserPass() {
938         var rows = getSelectedUsers();
939
940         if (rows.length == 0) {
941                 alert(__("No users are selected."));
942                 return;
943         }
944
945         if (rows.length > 1) {
946                 alert(__("Please select only one user."));
947                 return;
948         }
949
950         var ok = confirm(__("Reset password of selected user?"));
951
952         if (ok) {
953                 notify_progress("Resetting password for selected user...");
954         
955                 var id = rows[0];
956         
957                 xmlhttp.open("GET", "backend.php?op=pref-users&subop=resetPass&id=" +
958                         param_escape(id), true);
959                 xmlhttp.onreadystatechange=userlist_callback;
960                 xmlhttp.send(null);
961         }
962 }
963
964 function selectedUserDetails() {
965
966         if (!xmlhttp_ready(xmlhttp)) {
967                 printLockingError();
968                 return
969         }
970
971         var rows = getSelectedUsers();
972
973         if (rows.length == 0) {
974                 alert(__("No users are selected."));
975                 return;
976         }
977
978         if (rows.length > 1) {
979                 alert(__("Please select only one user."));
980                 return;
981         }
982
983         notify_progress("Loading, please wait...");
984
985         var id = rows[0];
986
987         xmlhttp.open("GET", "backend.php?op=pref-users&subop=user-details&id=" + id, true);
988         xmlhttp.onreadystatechange=infobox_callback;
989         xmlhttp.send(null);
990
991 }
992
993 function selectedFeedDetails() {
994
995         if (!xmlhttp_ready(xmlhttp)) {
996                 printLockingError();
997                 return
998         }
999
1000         var rows = getSelectedFeeds();
1001
1002         if (rows.length == 0) {
1003                 alert(__("No feeds are selected."));
1004                 return;
1005         }
1006
1007         if (rows.length > 1) {
1008                 alert(__("Please select only one feed."));
1009                 return;
1010         }
1011
1012 //      var id = rows[0];
1013
1014         notify("");
1015
1016         xmlhttp.open("GET", "backend.php?op=feed-details&id=" + 
1017                 param_escape(rows.toString()), true);
1018         xmlhttp.onreadystatechange=infobox_callback;
1019         xmlhttp.send(null);
1020
1021 }
1022
1023 function editSelectedFilter() {
1024         var rows = getSelectedFilters();
1025
1026         if (rows.length == 0) {
1027                 alert(__("No filters are selected."));
1028                 return;
1029         }
1030
1031         if (rows.length > 1) {
1032                 alert(__("Please select only one filter."));
1033                 return;
1034         }
1035
1036         notify("");
1037
1038         editFilter(rows[0]);
1039
1040 }
1041
1042
1043 function editSelectedFeed() {
1044         var rows = getSelectedFeeds();
1045
1046         if (rows.length == 0) {
1047                 alert(__("No feeds are selected."));
1048                 return;
1049         }
1050
1051         if (rows.length > 1) {
1052                 alert(__("Please select one feed."));
1053                 return;
1054         }
1055
1056         notify("");
1057
1058         editFeed(rows[0]);
1059
1060 }
1061
1062 function editSelectedFeeds() {
1063
1064         if (!xmlhttp_ready(xmlhttp)) {
1065                 printLockingError();
1066                 return
1067         }
1068
1069         var rows = getSelectedFeeds();
1070
1071         if (rows.length == 0) {
1072                 alert(__("No feeds are selected."));
1073                 return;
1074         }
1075
1076         notify("");
1077
1078         disableHotkeys();
1079
1080         notify_progress("Loading, please wait...");
1081
1082         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=editfeeds&ids=" +
1083                 param_escape(rows.toString()), true);
1084
1085         xmlhttp.onreadystatechange=infobox_callback;
1086         xmlhttp.send(null);
1087
1088 }
1089
1090 function editSelectedFeedCat() {
1091         var rows = getSelectedFeedCats();
1092
1093         if (rows.length == 0) {
1094                 alert(__("No categories are selected."));
1095                 return;
1096         }
1097
1098         if (rows.length > 1) {
1099                 alert(__("Please select only one category."));
1100                 return;
1101         }
1102
1103         notify("");
1104
1105         editFeedCat(rows[0]);
1106
1107 }
1108
1109 function piggie(enable) {
1110         if (enable) {
1111                 debug("I LOVEDED IT!");
1112                 var piggie = document.getElementById("piggie");
1113
1114                 Element.show(piggie);
1115                 Position.Center(piggie);
1116                 Effect.Puff(piggie);
1117
1118         }
1119 }
1120
1121 function validateOpmlImport() {
1122         
1123         var opml_file = document.getElementById("opml_file");
1124
1125         if (opml_file.value.length == 0) {
1126                 alert(__("No OPML file to upload."));
1127                 return false;
1128         } else {
1129                 return true;
1130         }
1131 }
1132
1133 function updateFilterList(sort_key) {
1134
1135         if (!xmlhttp_ready(xmlhttp)) {
1136                 printLockingError();
1137                 return
1138         }
1139
1140         var filter_search = document.getElementById("filter_search");
1141         var search = "";
1142         if (filter_search) { search = filter_search.value; }
1143
1144         xmlhttp.open("GET", "backend.php?op=pref-filters&sort=" + 
1145                 param_escape(sort_key) + 
1146                 "&search=" + param_escape(search), true);
1147         xmlhttp.onreadystatechange=filterlist_callback;
1148         xmlhttp.send(null);
1149
1150 }
1151
1152 function updateLabelList(sort_key) {
1153
1154         if (!xmlhttp_ready(xmlhttp)) {
1155                 printLockingError();
1156                 return
1157         }
1158
1159         var label_search = document.getElementById("label_search");
1160         var search = "";
1161         if (label_search) { search = label_search.value; }
1162
1163         xmlhttp.open("GET", "backend.php?op=pref-labels&sort=" + 
1164                 param_escape(sort_key) +
1165                 "&search=" + param_escape(search), true);
1166         xmlhttp.onreadystatechange=labellist_callback;
1167         xmlhttp.send(null);
1168 }
1169
1170 function updatePrefsList() {
1171
1172         if (!xmlhttp_ready(xmlhttp)) {
1173                 printLockingError();
1174                 return
1175         }
1176
1177         xmlhttp.open("GET", "backend.php?op=pref-prefs", true);
1178         xmlhttp.onreadystatechange=prefslist_callback;
1179         xmlhttp.send(null);
1180
1181 }
1182
1183 function selectTab(id, noupdate, subop) {
1184
1185 //      alert(id);
1186
1187         if (!id) id = active_tab;
1188
1189         try {
1190
1191                 if (!xmlhttp_ready(xmlhttp)) {
1192                         printLockingError();
1193                         return
1194                 }
1195
1196                 try {
1197                         var c = document.getElementById('prefContent'); 
1198                         c.scrollTop = 0;
1199                 } catch (e) { };
1200
1201                 if (!noupdate) {
1202
1203                         debug("selectTab: " + id + "(NU: " + noupdate + ")");
1204         
1205                         notify_progress("Loading, please wait...");
1206         
1207                         // close active infobox if needed
1208                         closeInfoBox();
1209         
1210                         // clean up all current selections, just in case
1211                         active_feed_cat = false;
1212
1213 //                      Effect.Fade("prefContent", {duration: 1, to: 0.01, 
1214 //                              queue: { position:'end', scope: 'FEED_TAB', limit: 1 } } );
1215
1216                         if (id == "feedConfig") {
1217                                 updateFeedList();
1218                         } else if (id == "filterConfig") {
1219                                 updateFilterList();
1220                         } else if (id == "labelConfig") {
1221                                 updateLabelList();
1222                         } else if (id == "genConfig") {
1223                                 updatePrefsList();
1224                         } else if (id == "userConfig") {
1225                                 updateUsersList();
1226                         }
1227                 }
1228
1229                 /* clean selection from all tabs */
1230         
1231                 var tabs_holder = document.getElementById("prefTabs");
1232                 var tab = tabs_holder.firstChild;
1233
1234                 while (tab) {
1235                         if (tab.className && tab.className.match("prefsTabSelected")) {
1236                                 tab.className = "prefsTab";
1237                         }
1238                         tab = tab.nextSibling;
1239                 }
1240
1241                 /* mark new tab as selected */
1242
1243                 tab = document.getElementById(id + "Tab");
1244         
1245                 if (tab) {
1246                         if (!tab.className.match("Selected")) {
1247                                 tab.className = tab.className + "Selected";
1248                         }
1249                 }
1250         
1251                 active_tab = id;
1252
1253         } catch (e) {
1254                 exception_error("selectTab", e);
1255         }
1256 }
1257
1258 function backend_sanity_check_callback() {
1259
1260         if (xmlhttp.readyState == 4) {
1261
1262                 try {
1263
1264                         if (sanity_check_done) {
1265                                 fatalError(11, "Sanity check request received twice. This can indicate "+
1266                               "presence of Firebug or some other disrupting extension. "+
1267                                         "Please disable it and try again.");
1268                                 return;
1269                         }
1270
1271                         if (!xmlhttp.responseXML) {
1272                                 fatalError(3, "Sanity Check: Received reply is not XML", 
1273                                         xmlhttp.responseText);
1274                                 return;
1275                         }
1276         
1277                         var reply = xmlhttp.responseXML.firstChild.firstChild;
1278         
1279                         if (!reply) {
1280                                 fatalError(3, "Sanity Check: Invalid RPC reply", xmlhttp.responseText);
1281                                 return;
1282                         }
1283         
1284                         var error_code = reply.getAttribute("error-code");
1285                 
1286                         if (error_code && error_code != 0) {
1287                                 return fatalError(error_code, reply.getAttribute("error-msg"));
1288                         }
1289         
1290                         debug("sanity check ok");
1291
1292                         var params = reply.nextSibling;
1293
1294                         if (params) {
1295                                 debug('reading init-params...');
1296                                 var param = params.firstChild;
1297
1298                                 while (param) {
1299                                         var k = param.getAttribute("key");
1300                                         var v = param.getAttribute("value");
1301                                         debug(k + " => " + v);
1302                                         init_params[k] = v;                                     
1303                                         param = param.nextSibling;
1304                                 }
1305                         }
1306
1307                         sanity_check_done = true;
1308
1309                         init_second_stage();
1310
1311                 } catch (e) {
1312                         exception_error("backend_sanity_check_callback", e);
1313                 }
1314         } 
1315 }
1316
1317 function init_second_stage() {
1318
1319         try {
1320                 active_tab = getInitParam("prefs_active_tab");
1321                 if (!document.getElementById(active_tab+"Tab")) active_tab = "genConfig";
1322                 if (!active_tab || active_tab == '0') active_tab = "genConfig";
1323
1324                 document.onkeydown = pref_hotkey_handler;
1325
1326                 var tab = getURLParam('tab');
1327                 
1328                 caller_subop = getURLParam('subop');
1329
1330                 if (getURLParam("subopparam")) {
1331                         caller_subop = caller_subop + ":" + getURLParam("subopparam");
1332                 }
1333
1334                 if (tab) {
1335                         active_tab = tab;
1336                 }
1337
1338                 if (navigator.userAgent.match("Opera")) {       
1339                         setTimeout("selectTab()", 500);
1340                 } else {
1341                         selectTab(active_tab);
1342                 }
1343                 notify("");
1344
1345                 loading_set_progress(60);
1346
1347         } catch (e) {
1348                 exception_error("init_second_stage", e);
1349         }
1350 }
1351
1352 function init() {
1353
1354         try {
1355         
1356                 if (arguments.callee.done) return;
1357                 arguments.callee.done = true;           
1358
1359                 if (getURLParam('debug')) {
1360                         Element.show("debug_output");
1361                         debug('debug mode activated');
1362                 }
1363
1364                 // IE kludge
1365                 if (!xmlhttp) {
1366                         document.getElementById("prefContent").innerHTML = 
1367                                 "<b>Fatal error:</b> This program needs XmlHttpRequest " + 
1368                                 "to function properly. Your browser doesn't seem to support it.";
1369                         return;
1370                 }
1371
1372                 loading_set_progress(30);
1373
1374                 xmlhttp.open("GET", "backend.php?op=rpc&subop=sanityCheck", true);
1375                 xmlhttp.onreadystatechange=backend_sanity_check_callback;
1376                 xmlhttp.send(null);
1377
1378         } catch (e) {
1379                 exception_error("init", e);
1380         }
1381 }
1382
1383 function categorizeSelectedFeeds() {
1384
1385         if (!xmlhttp_ready(xmlhttp)) {
1386                 printLockingError();
1387                 return
1388         }
1389
1390         var sel_rows = getSelectedFeeds();
1391
1392         var cat_sel = document.getElementById("sfeed_set_fcat");
1393         var cat_id = cat_sel[cat_sel.selectedIndex].value;
1394
1395         if (sel_rows.length > 0) {
1396
1397                 notify_progress("Changing category of selected feeds...");
1398
1399                 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=categorize&ids="+
1400                         param_escape(sel_rows.toString()) + "&cat_id=" + param_escape(cat_id), true);
1401                 xmlhttp.onreadystatechange=feedlist_callback;
1402                 xmlhttp.send(null);
1403
1404         } else {
1405
1406                 alert(__("No feeds are selected."));
1407
1408         }
1409
1410 }
1411
1412 function validatePrefsReset() {
1413         try {
1414                 var ok = confirm(__("Reset to defaults?"));
1415
1416                 if (ok) {
1417
1418                         var query = Form.serialize("pref_prefs_form");
1419                         query = query + "&subop=reset-config";
1420                         debug(query);
1421
1422                         xmlhttp.open("POST", "backend.php", true);
1423                         xmlhttp.onreadystatechange=prefs_reset_callback;
1424                         xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
1425                         xmlhttp.send(query);
1426                 }
1427
1428         } catch (e) {
1429                 exception_error("validatePrefsSave", e);
1430         }
1431
1432         return false;
1433
1434 }
1435
1436 function browseFeeds(limit) {
1437
1438         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=browse", true);
1439         xmlhttp.onreadystatechange=infobox_callback;
1440         xmlhttp.send(null);
1441
1442 }
1443
1444 function feedBrowserSubscribe() {
1445         try {
1446
1447                 var selected = getSelectedFeedsFromBrowser();
1448
1449                 if (selected.length > 0) {
1450                         closeInfoBox();
1451                         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=massSubscribe&ids="+
1452                                 param_escape(selected.toString()), true);
1453                         xmlhttp.onreadystatechange=feedlist_callback;
1454                         xmlhttp.send(null);
1455                 } else {
1456                         alert(__("No feeds are selected."));
1457                 }
1458
1459         } catch (e) {
1460                 exception_error("feedBrowserSubscribe", e);
1461         }
1462 }
1463
1464 function updateBigFeedBrowserBtn() {
1465         notify_progress("Loading, please wait...");
1466         return updateBigFeedBrowser();
1467 }
1468
1469 function selectPrefRows(kind, select) {
1470
1471         if (kind) {
1472                 var opbarid = false;    
1473                 var nchk = false;
1474                 var nrow = false;
1475                 var lname = false;
1476
1477                 if (kind == "feed") {
1478                         opbarid = "feedOpToolbar";
1479                         nrow = "FEEDR-";
1480                         nchk = "FRCHK-";                        
1481                         lname = "prefFeedList";
1482                 } else if (kind == "fcat") {
1483                         opbarid = "catOpToolbar";
1484                         nrow = "FCATR-";
1485                         nchk = "FCCHK-";
1486                         lname = "prefFeedCatList";
1487                 } else if (kind == "filter") {
1488                         opbarid = "filterOpToolbar";
1489                         nrow = "FILRR-";
1490                         nchk = "FICHK-";
1491                         lname = "prefFilterList";
1492                 } else if (kind == "label") {
1493                         opbarid = "labelOpToolbar";
1494                         nrow = "LILRR-";
1495                         nchk = "LICHK-";
1496                         lname = "prefLabelList";
1497                 } else if (kind == "user") {
1498                         opbarid = "userOpToolbar";
1499                         nrow = "UMRR-";
1500                         nchk = "UMCHK-";
1501                         lname = "prefUserList";
1502                 }
1503
1504                 if (opbarid) {
1505                         selectTableRowsByIdPrefix(lname, nrow, nchk, select);
1506                         disableContainerChildren(opbarid, !select);
1507                 }
1508
1509         } 
1510 }
1511
1512
1513 function toggleSelectPrefRow(sender, kind) {
1514
1515         toggleSelectRow(sender);
1516
1517         if (kind) {
1518                 var opbarid = false;    
1519                 var nsel = -1;
1520                 
1521                 if (kind == "feed") {
1522                         opbarid = "feedOpToolbar";
1523                         nsel = getSelectedFeeds();
1524                 } else if (kind == "fcat") {
1525                         opbarid = "catOpToolbar";
1526                         nsel = getSelectedFeedCats();
1527                 } else if (kind == "filter") {
1528                         opbarid = "filterOpToolbar";
1529                         nsel = getSelectedFilters();
1530                 } else if (kind == "label") {
1531                         opbarid = "labelOpToolbar";
1532                         nsel = getSelectedLabels();
1533                 } else if (kind == "user") {
1534                         opbarid = "userOpToolbar";
1535                         nsel = getSelectedUsers();
1536                 }
1537
1538                 if (opbarid && nsel != -1) {
1539                         disableContainerChildren(opbarid, nsel == false);
1540                 }
1541
1542         } 
1543 }
1544
1545 function toggleSelectFBListRow(sender) {
1546         toggleSelectListRow(sender);
1547         disableContainerChildren("fbrOpToolbar", getSelectedFeedsFromBrowser() == 0);
1548 }
1549
1550 var seq = "";
1551
1552 function pref_hotkey_handler(e) {
1553         try {
1554
1555                 var keycode;
1556                 var shift_key = false;
1557
1558                 try {
1559                         shift_key = e.shiftKey;
1560                 } catch (e) {
1561
1562                 }
1563
1564                 if (window.event) {
1565                         keycode = window.event.keyCode;
1566                 } else if (e) {
1567                         keycode = e.which;
1568                 }
1569
1570                 var keychar = String.fromCharCode(keycode);
1571
1572                 if (keycode == 27) { // escape
1573                         if (Element.visible("hotkey_help_overlay")) {
1574                                 Element.hide("hotkey_help_overlay");
1575                         }
1576                         hotkey_prefix = false;
1577                         closeInfoBox();
1578                 } 
1579
1580                 if (!hotkeys_enabled) {
1581                         debug("hotkeys disabled");
1582                         return;
1583                 }
1584
1585                 if (keycode == 16) return; // ignore lone shift
1586
1587                 if ((keycode == 67 || keycode == 71) && !hotkey_prefix) {
1588                         hotkey_prefix = keycode;
1589                         debug("KP: PREFIX=" + keycode + " CHAR=" + keychar);
1590                         return;
1591                 }
1592
1593                 if (Element.visible("hotkey_help_overlay")) {
1594                         Element.hide("hotkey_help_overlay");
1595                 }
1596
1597                 if (keycode == 13 || keycode == 27) {
1598                         seq = "";
1599                 } else {
1600                         seq = seq + "" + keycode;
1601                 }
1602
1603                 /* Global hotkeys */
1604
1605                 if (!hotkey_prefix) {
1606
1607                         if (keycode == 68 && shift_key) { // d
1608                                 if (!Element.visible("debug_output")) {
1609                                         Element.show("debug_output");
1610                                         debug('debug mode activated');
1611                                 } else {
1612                                         Element.hide("debug_output");
1613                                 }
1614                                 return;
1615                         }
1616         
1617                         if ((keycode == 191 || keychar == '?') && shift_key) { // ?
1618                                 if (!Element.visible("hotkey_help_overlay")) {
1619                                         //Element.show("hotkey_help_overlay");
1620                                         Effect.Appear("hotkey_help_overlay", {duration : 0.3});
1621                                 } else {
1622                                         Element.hide("hotkey_help_overlay");
1623                                 }
1624                                 return false;
1625                         }
1626
1627                         if (keycode == 191 || keychar == '/') { // /
1628                                 var search_boxes = new Array("label_search", 
1629                                         "feed_search", "filter_search", "user_search", "feed_browser_search");
1630
1631                                 for (var i = 0; i < search_boxes.length; i++) {
1632                                         var elem = document.getElementById(search_boxes[i]);
1633                                         if (elem) {
1634                                                 focus_element(search_boxes[i]);
1635                                                 return false;
1636                                         }
1637                                 }
1638                         }
1639                 }
1640
1641                 /* Prefix c */
1642
1643                 if (hotkey_prefix == 67) { // c
1644                         hotkey_prefix = false;
1645
1646                         if (keycode == 70) { // f
1647                                 displayDlg("quickAddFilter");
1648                                 return false;
1649                         }
1650
1651                         if (keycode == 83) { // s
1652                                 displayDlg("quickAddFeed");
1653                                 return false;
1654                         }
1655
1656 /*                      if (keycode == 76) { // l
1657                                 displayDlg("quickAddLabel");
1658                                 return false;
1659                         } */
1660
1661                         if (keycode == 85) { // u
1662                                 // no-op
1663                         }
1664
1665                         if (keycode == 67) { // c
1666                                 editFeedCats();
1667                                 return false;
1668                         }
1669
1670                         if (keycode == 84 && shift_key) { // T
1671                                 browseFeeds();
1672                                 return false;
1673                         }
1674
1675                 }
1676
1677                 /* Prefix g */
1678
1679                 if (hotkey_prefix == 71) { // g
1680
1681                         hotkey_prefix = false;
1682
1683                         if (keycode == 49 && document.getElementById("genConfigTab")) { // 1
1684                                 selectTab("genConfig");
1685                                 return false;
1686                         }
1687
1688                         if (keycode == 50 && document.getElementById("feedConfigTab")) { // 2
1689                                 selectTab("feedConfig");
1690                                 return false;
1691                         }
1692
1693                         if (keycode == 51 && document.getElementById("filterConfigTab")) { // 4
1694                                 selectTab("filterConfig");
1695                                 return false;
1696                         }
1697
1698                         if (keycode == 52 && document.getElementById("labelConfigTab")) { // 5
1699                                 selectTab("labelConfig");
1700                                 return false;
1701                         }
1702
1703                         if (keycode == 53 && document.getElementById("userConfigTab")) { // 6
1704                                 selectTab("userConfig");
1705                                 return false;
1706                         }
1707
1708                         if (keycode == 88) { // x
1709                                 return gotoMain();
1710                         }
1711
1712                 }
1713
1714                 if (document.getElementById("piggie")) {
1715         
1716                         if (seq.match("807371717369")) {
1717                                 seq = "";
1718                                 piggie(true);
1719                         } else {
1720                                 piggie(false);
1721                         }
1722                 }
1723
1724                 if (hotkey_prefix) {
1725                         debug("KP: PREFIX=" + hotkey_prefix + " CODE=" + keycode + " CHAR=" + keychar);
1726                 } else {
1727                         debug("KP: CODE=" + keycode + " CHAR=" + keychar);
1728                 }
1729
1730         } catch (e) {
1731                 exception_error("pref_hotkey_handler", e);
1732         }
1733 }
1734
1735 function editFeedCats() {
1736         if (!xmlhttp_ready(xmlhttp)) {
1737                 printLockingError();
1738                 return
1739         }
1740
1741         document.getElementById("subscribe_to_feed_btn").disabled = true;
1742
1743         try {
1744                 document.getElementById("top25_feeds_btn").disabled = true;
1745         } catch (e) {
1746                 // this button is not always available, no-op if not found
1747         }
1748
1749         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=editCats", true);
1750         xmlhttp.onreadystatechange=infobox_feed_cat_callback;
1751         xmlhttp.send(null);
1752 }
1753
1754 function showFeedsWithErrors() {
1755         displayDlg('feedUpdateErrors');
1756 }
1757
1758 function changeUserPassword() {
1759
1760         try {
1761
1762                 if (!xmlhttp_ready(xmlhttp)) {
1763                         printLockingError();
1764                         return false;
1765                 }
1766         
1767                 var f = document.forms["change_pass_form"];
1768
1769                 if (f) {
1770                         if (f.OLD_PASSWORD.value == "") {
1771                                 new Effect.Highlight(f.OLD_PASSWORD);
1772                                 notify_error("Old password cannot be blank.");
1773                                 return false;
1774                         }
1775
1776                         if (f.NEW_PASSWORD.value == "") {
1777                                 new Effect.Highlight(f.NEW_PASSWORD);
1778                                 notify_error("New password cannot be blank.");
1779                                 return false;
1780                         }
1781
1782                         if (f.CONFIRM_PASSWORD.value == "") {
1783                                 new Effect.Highlight(f.CONFIRM_PASSWORD);
1784                                 notify_error("Entered passwords do not match.");
1785                                 return false;
1786                         }
1787
1788                         if (f.CONFIRM_PASSWORD.value != f.NEW_PASSWORD.value) {
1789                                 new Effect.Highlight(f.CONFIRM_PASSWORD);
1790                                 new Effect.Highlight(f.NEW_PASSWORD);
1791                                 notify_error("Entered passwords do not match.");
1792                                 return false;
1793                         }
1794
1795                 }
1796
1797                 var query = Form.serialize("change_pass_form");
1798         
1799                 notify_progress("Trying to change password...");
1800         
1801                 xmlhttp.open("POST", "backend.php", true);
1802                 xmlhttp.onreadystatechange=changepass_callback;
1803                 xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
1804                 xmlhttp.send(query);
1805
1806         } catch (e) {
1807                 exception_error("changeUserPassword", e);
1808         }
1809         
1810         return false;
1811 }
1812
1813 function changeUserEmail() {
1814
1815         try {
1816
1817                 if (!xmlhttp_ready(xmlhttp)) {
1818                         printLockingError();
1819                         return false;
1820                 }
1821         
1822                 var query = Form.serialize("change_email_form");
1823         
1824                 notify_progress("Trying to change e-mail...");
1825         
1826                 xmlhttp.open("POST", "backend.php", true);
1827                 xmlhttp.onreadystatechange=notify_callback;
1828                 xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
1829                 xmlhttp.send(query);
1830
1831         } catch (e) {
1832                 exception_error("changeUserPassword", e);
1833         }
1834         
1835         return false;
1836
1837 }
1838
1839 function feedlistToggleSLAT() {
1840         notify_progress("Loading, please wait...");
1841         updateFeedList()
1842 }
1843
1844 function pubRegenKey() {
1845
1846         if (!xmlhttp_ready(xmlhttp)) {
1847                 printLockingError();
1848                 return false;
1849         }
1850
1851         var ok = confirm(__("Replace current publishing address with a new one?"));
1852
1853         if (ok) {
1854
1855                 notify_progress("Trying to change address...");
1856
1857                 xmlhttp.open("GET", "backend.php?op=rpc&subop=regenPubKey");
1858                 xmlhttp.onreadystatechange=replace_pubkey_callback;
1859                 xmlhttp.send(null);
1860         }
1861
1862         return false;
1863 }
1864
1865 function pubToClipboard() {
1866
1867         try {
1868
1869                 if (!xmlhttp_ready(xmlhttp)) {
1870                         printLockingError();
1871                         return false;
1872                 }
1873         
1874                 var link = document.getElementById("pubGenAddress");
1875                 alert(link.href);
1876
1877         } catch (e) {
1878                 exception_error("pubToClipboard", e);
1879         }
1880
1881         return false; 
1882 }
1883
1884 function validatePrefsSave() {
1885         try {
1886
1887                 var ok = confirm(__("Save current configuration?"));
1888
1889                 if (ok) {
1890
1891                         var query = Form.serialize("pref_prefs_form");
1892                         query = query + "&subop=save-config";
1893                         debug(query);
1894
1895                         xmlhttp.open("POST", "backend.php", true);
1896                         xmlhttp.onreadystatechange=notify_callback;
1897                         xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
1898                         xmlhttp.send(query);
1899                 }
1900
1901         } catch (e) {
1902                 exception_error("validatePrefsSave", e);
1903         }
1904
1905         return false;
1906 }
1907
1908 function feedActionChange() {
1909         try {
1910                 var chooser = document.getElementById("feedActionChooser");
1911                 var opid = chooser[chooser.selectedIndex].value;
1912
1913                 chooser.selectedIndex = 0;
1914                 feedActionGo(opid);
1915         } catch (e) {
1916                 exception_error("feedActionChange", e);
1917         }
1918 }
1919
1920 function feedActionGo(op) {     
1921         try {
1922                 if (op == "facEdit") {
1923
1924                         var rows = getSelectedFeeds();
1925
1926                         if (rows.length > 1) {
1927                                 editSelectedFeeds();
1928                         } else {
1929                                 editSelectedFeed();
1930                         }
1931                 }
1932
1933                 if (op == "facClear") {
1934                         clearSelectedFeeds();
1935                 }
1936
1937                 if (op == "facPurge") {
1938                         purgeSelectedFeeds();
1939                 }
1940
1941                 if (op == "facEditCats") {
1942                         editFeedCats();
1943                 }
1944
1945                 if (op == "facRescore") {
1946                         rescoreSelectedFeeds();
1947                 }
1948
1949                 if (op == "facUnsubscribe") {
1950                         removeSelectedFeeds();
1951                 }
1952
1953         } catch (e) {
1954                 exception_error("feedActionGo", e);
1955
1956         }
1957 }
1958
1959 function clearFeedArticles(feed_id) {
1960
1961         notify_progress("Clearing feed...");
1962
1963         var query = "backend.php?op=pref-feeds&quiet=1&subop=clear&id=" + feed_id;
1964
1965         new Ajax.Request(query, {
1966                 onComplete: function(transport) {
1967                                 notify('');
1968                         } });
1969
1970         return false;
1971 }
1972
1973 function rescoreSelectedFeeds() {
1974
1975         if (!xmlhttp_ready(xmlhttp)) {
1976                 printLockingError();
1977                 return
1978         }
1979
1980         var sel_rows = getSelectedFeeds();
1981
1982         if (sel_rows.length > 0) {
1983
1984                 //var ok = confirm(__("Rescore last 100 articles in selected feeds?"));
1985                 var ok = confirm(__("Rescore articles in selected feeds?"));
1986
1987                 if (ok) {
1988                         notify_progress("Rescoring selected feeds...", true);
1989         
1990                         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=rescore&quiet=1&ids="+
1991                                 param_escape(sel_rows.toString()), true);
1992                         xmlhttp.onreadystatechange=notify_callback;
1993                         xmlhttp.send(null);
1994                 }
1995         } else {
1996                 alert(__("No feeds are selected."));
1997         }
1998
1999         return false;
2000 }
2001
2002 function rescore_all_feeds() {
2003                 var ok = confirm(__("Rescore all articles? This operation may take a lot of time."));
2004
2005                 if (ok) {
2006                         notify_progress("Rescoring feeds...", true);
2007
2008                         xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=rescoreAll&quiet=1", true);
2009                         xmlhttp.onreadystatechange=notify_callback;
2010                         xmlhttp.send(null);
2011                 }
2012 }
2013
2014 function removeFilter(id, title) {
2015
2016         if (!xmlhttp_ready(xmlhttp)) {
2017                 printLockingError();
2018                 return
2019         }
2020
2021         var msg = __("Remove filter %s?").replace("%s", title);
2022
2023         var ok = confirm(msg);
2024
2025         if (ok) {
2026                 closeInfoBox();
2027
2028                 notify_progress("Removing filter...");
2029         
2030                 xmlhttp.open("GET", "backend.php?op=pref-filters&subop=remove&ids="+
2031                         param_escape(id), true);
2032                 xmlhttp.onreadystatechange=filterlist_callback;
2033                 xmlhttp.send(null);
2034         }
2035
2036         return false;
2037 }
2038
2039 function unsubscribeFeed(id, title) {
2040
2041         if (!xmlhttp_ready(xmlhttp)) {
2042                 printLockingError();
2043                 return
2044         }
2045
2046         var msg = __("Unsubscribe from %s?").replace("%s", title);
2047
2048         var ok = confirm(msg);
2049
2050         if (ok) {
2051                 closeInfoBox();
2052
2053                 notify_progress("Removing feed...");
2054         
2055                 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=remove&ids="+
2056                         param_escape(id), true);
2057                 xmlhttp.onreadystatechange=filterlist_callback;
2058                 xmlhttp.send(null);
2059         }
2060
2061         return false;
2062
2063         return false;
2064
2065 }
2066
2067 function feedsEditSave() {
2068         try {
2069
2070                 if (!xmlhttp_ready(xmlhttp)) {
2071                         printLockingError();
2072                         return
2073                 }
2074
2075                 var ok = confirm(__("Save changes to selected feeds?"));
2076
2077                 if (ok) {
2078
2079                         var f = document.forms["batch_edit_feed_form"];
2080
2081                         var query = Form.serialize("batch_edit_feed_form");
2082
2083                         /* Form.serialize ignores unchecked checkboxes */
2084
2085                         if (!query.match("&hidden=") && 
2086                                         f.hidden.disabled == false) {
2087                                 query = query + "&hidden=false";
2088                         }
2089
2090                         if (!query.match("&rtl_content=") && 
2091                                         f.rtl_content.disabled == false) {
2092                                 query = query + "&rtl_content=false";
2093                         }
2094
2095                         if (!query.match("&private=") && 
2096                                         f.private.disabled == false) {
2097                                 query = query + "&private=false";
2098                         }
2099
2100                         if (!query.match("&cache_images=") && 
2101                                         f.cache_images.disabled == false) {
2102                                 query = query + "&cache_images=false";
2103                         }
2104
2105                         if (!query.match("&include_in_digest=") && 
2106                                         f.include_in_digest.disabled == false) {
2107                                 query = query + "&include_in_digest=false";
2108                         }
2109         
2110                         closeInfoBox();
2111         
2112                         notify_progress("Saving feeds...");
2113         
2114                         xmlhttp.open("POST", "backend.php", true);
2115                         xmlhttp.onreadystatechange=feedlist_callback;
2116                         xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
2117                         xmlhttp.send(query);
2118                 }
2119
2120                 return false;
2121         } catch (e) {
2122                 exception_error("feedsEditSave", e);
2123         }
2124 }
2125
2126 function batchFeedsToggleField(cb, elem, label) {
2127         try {
2128                 var f = document.forms["batch_edit_feed_form"];
2129                 var l = document.getElementById(label);
2130
2131                 if (cb.checked) {
2132                         f[elem].disabled = false;
2133
2134                         if (l) {
2135                                 l.className = "";
2136                         };
2137
2138 //                      new Effect.Highlight(f[elem], {duration: 1, startcolor: "#fff7d5",
2139 //                              queue: { position:'end', scope: 'BPEFQ', limit: 1 } } );
2140
2141                 } else {
2142                         f[elem].disabled = true;
2143
2144                         if (l) {
2145                                 l.className = "insensitive";
2146                         };
2147
2148                 }
2149         } catch (e) {
2150                 exception_error("batchFeedsToggleField", e);
2151         }
2152 }
2153
2154