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