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