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