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