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