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