3 var active_feed_cat = false;
4 var active_label = false;
5 var active_tab = false;
6 var feed_to_expand = false;
8 var xmlhttp = Ajax.getTransport();
10 var init_params = new Array();
12 var caller_subop = false;
13 var sanity_check_done = false;
14 var hotkey_prefix = false;
16 function infobox_callback() {
17 if (xmlhttp.readyState == 4) {
18 infobox_callback2(xmlhttp);
22 function infobox_submit_callback() {
23 if (xmlhttp.readyState == 4) {
24 infobox_submit_callback2(xmlhttp);
29 function replace_pubkey_callback() {
30 if (xmlhttp.readyState == 4) {
32 var link = document.getElementById("pubGenAddress");
34 if (xmlhttp.responseXML) {
36 var new_link = xmlhttp.responseXML.getElementsByTagName("link")[0];
39 link.href = new_link.firstChild.nodeValue;
40 //link.innerHTML = new_link.firstChild.nodeValue;
42 new Effect.Highlight(link);
44 notify_info("Published feed URL changed.");
46 notify_error("Could not change feed URL.");
50 notify_error("Could not change feed URL.");
53 exception_error("replace_pubkey_callback", e);
58 function expand_feed_callback() {
59 if (xmlhttp.readyState == 4) {
61 var container = document.getElementById("BRDET-" + feed_to_expand);
62 container.innerHTML=xmlhttp.responseText;
63 // container.style.display = "block";
64 Effect.Appear(container, {duration : 0.5});
66 exception_error("expand_feed_callback", e);
71 function feedlist_callback() {
72 if (xmlhttp.readyState == 4) {
74 var container = document.getElementById('prefContent');
75 container.innerHTML=xmlhttp.responseText;
76 selectTab("feedConfig", true);
79 var tuple = caller_subop.split(":");
80 if (tuple[0] == 'editFeed') {
81 window.setTimeout('editFeed('+tuple[1]+')', 100);
86 if (typeof correctPNG != 'undefined') {
91 exception_error("feedlist_callback", e);
96 /* stub for subscription dialog */
98 function dlg_frefresh_callback(transport) {
101 var container = document.getElementById('prefContent');
102 container.innerHTML=transport.responseText;
103 selectTab("feedConfig", true);
106 var tuple = caller_subop.split(":");
107 if (tuple[0] == 'editFeed') {
108 window.setTimeout('editFeed('+tuple[1]+')', 100);
111 caller_subop = false;
113 if (typeof correctPNG != 'undefined') {
118 exception_error("feedlist_callback", e);
123 function filterlist_callback() {
124 var container = document.getElementById('prefContent');
125 if (xmlhttp.readyState == 4) {
126 container.innerHTML=xmlhttp.responseText;
127 if (typeof correctPNG != 'undefined') {
134 function labellist_callback() {
135 var container = document.getElementById('prefContent');
136 if (xmlhttp.readyState == 4) {
138 container.innerHTML=xmlhttp.responseText;
140 var row = document.getElementById("LILRR-" + active_label);
142 if (!row.className.match("Selected")) {
143 row.className = row.className + "Selected";
146 var checkbox = document.getElementById("LICHK-" + active_label);
149 checkbox.checked = true;
152 if (typeof correctPNG != 'undefined') {
159 function feed_browser_callback() {
160 var container = document.getElementById('prefContent');
161 if (xmlhttp.readyState == 4) {
162 container.innerHTML=xmlhttp.responseText;
167 function userlist_callback() {
168 var container = document.getElementById('prefContent');
169 if (xmlhttp.readyState == 4) {
170 container.innerHTML=xmlhttp.responseText;
175 function prefslist_callback() {
176 var container = document.getElementById('prefContent');
177 if (xmlhttp.readyState == 4) {
179 container.innerHTML=xmlhttp.responseText;
185 function gethelp_callback() {
186 var container = document.getElementById('prefHelpBox');
187 if (xmlhttp.readyState == 4) {
189 container.innerHTML = xmlhttp.responseText;
190 container.style.display = "block";
195 function notify_callback() {
196 if (xmlhttp.readyState == 4) {
197 notify_info(xmlhttp.responseText);
201 function prefs_reset_callback() {
202 if (xmlhttp.readyState == 4) {
203 notify_info(xmlhttp.responseText);
209 function changepass_callback() {
211 if (xmlhttp.readyState == 4) {
213 if (xmlhttp.responseText.indexOf("ERROR: ") == 0) {
214 notify_error(xmlhttp.responseText.replace("ERROR: ", ""));
216 notify_info(xmlhttp.responseText);
217 var warn = document.getElementById("default_pass_warning");
218 if (warn) warn.style.display = "none";
221 document.forms['change_pass_form'].reset();
225 exception_error("changepass_callback", e);
229 function infobox_feed_cat_callback() {
230 if (xmlhttp.readyState == 4) {
235 if (document.getElementById("prefFeedCatList")) {
236 var elems = document.getElementById("prefFeedCatList").getElementsByTagName("SPAN");
238 for (var i = 0; i < elems.length; i++) {
239 if (elems[i].id && elems[i].id.match("FCATT-")) {
240 var cat_id = elems[i].id.replace("FCATT-", "");
242 new Ajax.InPlaceEditor(elems[i],
243 'backend.php?op=pref-feeds&subop=editCats&action=save&cid=' + cat_id);
249 exception_error("infobox_feed_cat_callback", e);
254 function updateFeedList(sort_key) {
256 if (!xmlhttp_ready(xmlhttp)) {
261 var feed_search = document.getElementById("feed_search");
263 if (feed_search) { search = feed_search.value; }
265 var slat = document.getElementById("show_last_article_times");
267 var slat_checked = false;
269 slat_checked = slat.checked;
272 xmlhttp.open("GET", "backend.php?op=pref-feeds" +
273 "&sort=" + param_escape(sort_key) +
274 "&slat=" + param_escape(slat_checked) +
275 "&search=" + param_escape(search), true);
276 xmlhttp.onreadystatechange=feedlist_callback;
281 function updateUsersList(sort_key) {
283 if (!xmlhttp_ready(xmlhttp)) {
288 var user_search = document.getElementById("user_search");
290 if (user_search) { search = user_search.value; }
292 xmlhttp.open("GET", "backend.php?op=pref-users&sort="
293 + param_escape(sort_key) +
294 "&search=" + param_escape(search), true);
295 xmlhttp.onreadystatechange=userlist_callback;
300 function addLabel() {
302 if (!xmlhttp_ready(xmlhttp)) {
307 var form = document.forms['label_edit_form'];
309 var sql_exp = form.sql_exp.value;
310 var description = form.description.value;
313 alert(__("Can't create label: missing SQL expression."));
317 if (description == "") {
318 alert(__("Can't create label: missing caption."));
322 var query = Form.serialize("label_edit_form");
324 // we can be called from some other tab
325 active_tab = "labelConfig";
327 xmlhttp.open("GET", "backend.php?op=pref-labels&subop=add&" + query, true);
328 xmlhttp.onreadystatechange=infobox_submit_callback;
334 if (!xmlhttp_ready(xmlhttp)) {
339 var link = document.getElementById("fadd_link");
341 if (link.value.length == 0) {
342 alert(__("Error: No feed URL given."));
343 } else if (!isValidURL(link.value)) {
344 alert(__("Error: Invalid feed URL."));
346 notify_progress("Adding feed...");
348 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=add&from=tt-rss&feed_url=" +
349 param_escape(link.value), true);
350 xmlhttp.onreadystatechange=feedlist_callback;
359 function addFeedCat() {
361 if (!xmlhttp_ready(xmlhttp)) {
366 var cat = document.getElementById("fadd_cat");
368 if (cat.value.length == 0) {
369 alert(__("Can't add category: no name specified."));
371 notify_progress("Adding feed category...");
373 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=editCats&action=add&cat=" +
374 param_escape(cat.value), true);
375 xmlhttp.onreadystatechange=infobox_callback;
385 if (!xmlhttp_ready(xmlhttp)) {
390 var sqlexp = document.getElementById("uadd_box");
392 if (sqlexp.value.length == 0) {
393 alert(__("Can't add user: no login specified."));
395 notify_progress("Adding user...");
397 xmlhttp.open("GET", "backend.php?op=pref-users&subop=add&login=" +
398 param_escape(sqlexp.value), true);
400 xmlhttp.onreadystatechange=userlist_callback;
408 function editLabel(id) {
410 if (!xmlhttp_ready(xmlhttp)) {
417 notify_progress("Loading, please wait...");
419 document.getElementById("label_create_btn").disabled = true;
423 selectTableRowsByIdPrefix('prefLabelList', 'LILRR-', 'LICHK-', false);
424 selectTableRowById('LILRR-'+id, 'LICHK-'+id, true);
426 xmlhttp.open("GET", "backend.php?op=pref-labels&subop=edit&id=" +
427 param_escape(id), true);
428 xmlhttp.onreadystatechange=infobox_callback;
433 function editUser(id) {
435 if (!xmlhttp_ready(xmlhttp)) {
442 notify_progress("Loading, please wait...");
444 selectTableRowsByIdPrefix('prefUserList', 'UMRR-', 'UMCHK-', false);
445 selectTableRowById('UMRR-'+id, 'UMCHK-'+id, true);
447 xmlhttp.open("GET", "backend.php?op=pref-users&subop=edit&id=" +
448 param_escape(id), true);
449 xmlhttp.onreadystatechange=infobox_callback;
454 function editFilter(id) {
456 if (!xmlhttp_ready(xmlhttp)) {
463 notify_progress("Loading, please wait...");
465 document.getElementById("create_filter_btn").disabled = true;
467 selectTableRowsByIdPrefix('prefFilterList', 'FILRR-', 'FICHK-', false);
468 selectTableRowById('FILRR-'+id, 'FICHK-'+id, true);
470 xmlhttp.open("GET", "backend.php?op=pref-filters&subop=edit&id=" + param_escape(id), true);
471 xmlhttp.onreadystatechange=infobox_callback;
475 function editFeed(feed) {
477 // notify("Editing feed...");
479 if (!xmlhttp_ready(xmlhttp)) {
486 notify_progress("Loading, please wait...");
488 document.getElementById("subscribe_to_feed_btn").disabled = true;
491 document.getElementById("top25_feeds_btn").disabled = true;
493 // this button is not always available, no-op if not found
496 // clean selection from all rows & select row being edited
497 selectTableRowsByIdPrefix('prefFeedList', 'FEEDR-', 'FRCHK-', false);
498 selectTableRowById('FEEDR-'+feed, 'FRCHK-'+feed, true);
500 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=editfeed&id=" +
501 param_escape(feed), true);
503 xmlhttp.onreadystatechange=infobox_callback;
508 function editFeedCat(cat) {
510 if (!xmlhttp_ready(xmlhttp)) {
517 notify_progress("Loading, please wait...");
519 active_feed_cat = cat;
521 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=editCats&action=edit&id=" +
522 param_escape(cat), true);
523 xmlhttp.onreadystatechange=infobox_callback;
528 function getSelectedLabels() {
529 return getSelectedTableRowIds("prefLabelList", "LILRR");
532 function getSelectedUsers() {
533 return getSelectedTableRowIds("prefUserList", "UMRR");
536 function getSelectedFeeds() {
537 return getSelectedTableRowIds("prefFeedList", "FEEDR");
540 function getSelectedFilters() {
541 return getSelectedTableRowIds("prefFilterList", "FILRR");
544 function getSelectedFeedCats() {
545 return getSelectedTableRowIds("prefFeedCatList", "FCATR");
548 function getSelectedFeedsFromBrowser() {
550 var list = document.getElementById("browseFeedList");
551 if (!list) list = document.getElementById("browseBigFeedList");
553 var selected = new Array();
555 for (i = 0; i < list.childNodes.length; i++) {
556 var child = list.childNodes[i];
557 if (child.id && child.id.match("FBROW-")) {
558 var id = child.id.replace("FBROW-", "");
560 var cb = document.getElementById("FBCHK-" + id);
571 function removeSelectedLabels() {
573 if (!xmlhttp_ready(xmlhttp)) {
578 var sel_rows = getSelectedLabels();
580 if (sel_rows.length > 0) {
582 var ok = confirm(__("Remove selected labels?"));
585 notify_progress("Removing selected labels...");
587 xmlhttp.open("GET", "backend.php?op=pref-labels&subop=remove&ids="+
588 param_escape(sel_rows.toString()), true);
589 xmlhttp.onreadystatechange=labellist_callback;
593 alert(__("No labels are selected."));
599 function removeSelectedUsers() {
601 if (!xmlhttp_ready(xmlhttp)) {
606 var sel_rows = getSelectedUsers();
608 if (sel_rows.length > 0) {
610 var ok = confirm(__("Remove selected users?"));
613 notify_progress("Removing selected users...");
615 xmlhttp.open("GET", "backend.php?op=pref-users&subop=remove&ids="+
616 param_escape(sel_rows.toString()), true);
617 xmlhttp.onreadystatechange=userlist_callback;
622 alert(__("No users are selected."));
628 function removeSelectedFilters() {
630 if (!xmlhttp_ready(xmlhttp)) {
635 var sel_rows = getSelectedFilters();
637 if (sel_rows.length > 0) {
639 var ok = confirm(__("Remove selected filters?"));
642 notify_progress("Removing selected filters...");
644 xmlhttp.open("GET", "backend.php?op=pref-filters&subop=remove&ids="+
645 param_escape(sel_rows.toString()), true);
646 xmlhttp.onreadystatechange=filterlist_callback;
650 alert(__("No filters are selected."));
657 function removeSelectedFeeds() {
659 if (!xmlhttp_ready(xmlhttp)) {
664 var sel_rows = getSelectedFeeds();
666 if (sel_rows.length > 0) {
668 var ok = confirm(__("Unsubscribe from selected feeds?"));
672 notify_progress("Unsubscribing from selected feeds...");
674 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=remove&ids="+
675 param_escape(sel_rows.toString()), true);
676 xmlhttp.onreadystatechange=feedlist_callback;
682 alert(__("No feeds are selected."));
689 function clearSelectedFeeds() {
691 if (!xmlhttp_ready(xmlhttp)) {
696 var sel_rows = getSelectedFeeds();
698 if (sel_rows.length > 1) {
699 alert(__("Please select only one feed."));
703 if (sel_rows.length > 0) {
705 var ok = confirm(__("Erase all non-starred articles in selected feed?"));
708 notify_progress("Clearing selected feed...");
709 clearFeedArticles(sel_rows[0]);
714 alert(__("No feeds are selected."));
721 function purgeSelectedFeeds() {
723 if (!xmlhttp_ready(xmlhttp)) {
728 var sel_rows = getSelectedFeeds();
730 if (sel_rows.length > 0) {
732 var pr = prompt(__("How many days of articles to keep (0 - use default)?"), "0");
734 if (pr != undefined) {
735 notify_progress("Purging selected feed...");
737 var query = "backend.php?op=rpc&subop=purge&ids="+
738 param_escape(sel_rows.toString()) + "&days=" + pr;
742 new Ajax.Request(query, {
743 onComplete: function(transport) {
750 alert(__("No feeds are selected."));
757 function removeSelectedFeedCats() {
759 if (!xmlhttp_ready(xmlhttp)) {
764 var sel_rows = getSelectedFeedCats();
766 if (sel_rows.length > 0) {
768 var ok = confirm(__("Remove selected categories?"));
771 notify_progress("Removing selected categories...");
773 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=editCats&action=remove&ids="+
774 param_escape(sel_rows.toString()), true);
775 xmlhttp.onreadystatechange=infobox_callback;
781 alert(__("No categories are selected."));
788 function feedEditCancel() {
790 if (!xmlhttp_ready(xmlhttp)) {
796 document.getElementById("subscribe_to_feed_btn").disabled = false;
797 document.getElementById("top25_feeds_btn").disabled = false;
799 // this button is not always available, no-op if not found
804 selectPrefRows('feed', false); // cleanup feed selection
809 function feedCatEditCancel() {
811 if (!xmlhttp_ready(xmlhttp)) {
816 active_feed_cat = false;
818 // notify("Operation cancelled.");
820 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=editCats", true);
821 xmlhttp.onreadystatechange=infobox_callback;
827 function feedEditSave() {
831 if (!xmlhttp_ready(xmlhttp)) {
836 // FIXME: add parameter validation
838 var query = Form.serialize("edit_feed_form");
840 notify_progress("Saving feed...");
842 xmlhttp.open("POST", "backend.php", true);
843 xmlhttp.onreadystatechange=feedlist_callback;
844 xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
852 exception_error("feedEditSave", e);
856 function feedCatEditSave() {
858 if (!xmlhttp_ready(xmlhttp)) {
863 notify_progress("Saving category...");
865 var query = Form.serialize("feed_cat_edit_form");
867 xmlhttp.open("GET", "backend.php?" + query, true);
868 xmlhttp.onreadystatechange=infobox_callback;
871 active_feed_cat = false;
876 function labelEditCancel() {
878 if (!xmlhttp_ready(xmlhttp)) {
884 document.getElementById("label_create_btn").disabled = false;
885 selectPrefRows('label', false); // cleanup feed selection
888 active_label = false;
895 function userEditCancel() {
897 if (!xmlhttp_ready(xmlhttp)) {
902 selectPrefRows('user', false); // cleanup feed selection
908 function filterEditCancel() {
910 if (!xmlhttp_ready(xmlhttp)) {
916 document.getElementById("create_filter_btn").disabled = false;
917 selectPrefRows('filter', false); // cleanup feed selection
925 function labelEditSave() {
927 var label = active_label;
929 if (!xmlhttp_ready(xmlhttp)) {
934 /* if (!is_opera()) {
936 var sql_exp = document.forms["label_edit_form"].sql_exp.value;
937 var description = document.forms["label_edit_form"].description.value;
939 if (sql_exp.length == 0) {
940 alert("SQL Expression cannot be blank.");
944 if (description.length == 0) {
945 alert("Caption field cannot be blank.");
952 notify_progress("Saving label...");
954 active_label = false;
956 query = Form.serialize("label_edit_form");
958 xmlhttp.open("GET", "backend.php?" + query, true);
959 xmlhttp.onreadystatechange=labellist_callback;
965 function userEditSave() {
967 if (!xmlhttp_ready(xmlhttp)) {
972 var login = document.forms["user_edit_form"].login.value;
974 if (login.length == 0) {
975 alert(__("Login field cannot be blank."));
979 notify_progress("Saving user...");
983 var query = Form.serialize("user_edit_form");
985 xmlhttp.open("GET", "backend.php?" + query, true);
986 xmlhttp.onreadystatechange=userlist_callback;
993 function filterEditSave() {
995 if (!xmlhttp_ready(xmlhttp)) {
1000 /* if (!is_opera()) {
1001 var reg_exp = document.forms["filter_edit_form"].reg_exp.value;
1003 if (reg_exp.length == 0) {
1004 alert("Filter expression field cannot be blank.");
1009 notify_progress("Saving filter...");
1011 var query = Form.serialize("filter_edit_form");
1015 document.getElementById("create_filter_btn").disabled = false;
1017 xmlhttp.open("GET", "backend.php?" + query, true);
1018 xmlhttp.onreadystatechange=filterlist_callback;
1024 function editSelectedLabel() {
1025 var rows = getSelectedLabels();
1027 if (rows.length == 0) {
1028 alert(__("No labels are selected."));
1032 if (rows.length > 1) {
1033 alert(__("Please select only one label."));
1043 function editSelectedUser() {
1044 var rows = getSelectedUsers();
1046 if (rows.length == 0) {
1047 alert(__("No users are selected."));
1051 if (rows.length > 1) {
1052 alert(__("Please select only one user."));
1061 function resetSelectedUserPass() {
1062 var rows = getSelectedUsers();
1064 if (rows.length == 0) {
1065 alert(__("No users are selected."));
1069 if (rows.length > 1) {
1070 alert(__("Please select only one user."));
1074 var ok = confirm(__("Reset password of selected user?"));
1077 notify_progress("Resetting password for selected user...");
1081 xmlhttp.open("GET", "backend.php?op=pref-users&subop=resetPass&id=" +
1082 param_escape(id), true);
1083 xmlhttp.onreadystatechange=userlist_callback;
1088 function selectedUserDetails() {
1090 if (!xmlhttp_ready(xmlhttp)) {
1091 printLockingError();
1095 var rows = getSelectedUsers();
1097 if (rows.length == 0) {
1098 alert(__("No users are selected."));
1102 if (rows.length > 1) {
1103 alert(__("Please select only one user."));
1107 notify_progress("Loading, please wait...");
1111 xmlhttp.open("GET", "backend.php?op=user-details&id=" + id, true);
1112 xmlhttp.onreadystatechange=infobox_callback;
1117 function selectedFeedDetails() {
1119 if (!xmlhttp_ready(xmlhttp)) {
1120 printLockingError();
1124 var rows = getSelectedFeeds();
1126 if (rows.length == 0) {
1127 alert(__("No feeds are selected."));
1131 if (rows.length > 1) {
1132 alert(__("Please select only one feed."));
1136 // var id = rows[0];
1140 xmlhttp.open("GET", "backend.php?op=feed-details&id=" +
1141 param_escape(rows.toString()), true);
1142 xmlhttp.onreadystatechange=infobox_callback;
1147 function editSelectedFilter() {
1148 var rows = getSelectedFilters();
1150 if (rows.length == 0) {
1151 alert(__("No filters are selected."));
1155 if (rows.length > 1) {
1156 alert(__("Please select only one filter."));
1162 editFilter(rows[0]);
1167 function editSelectedFeed() {
1168 var rows = getSelectedFeeds();
1170 if (rows.length == 0) {
1171 alert(__("No feeds are selected."));
1175 if (rows.length > 1) {
1176 alert(__("Please select one feed."));
1186 function editSelectedFeedCat() {
1187 var rows = getSelectedFeedCats();
1189 if (rows.length == 0) {
1190 alert(__("No categories are selected."));
1194 if (rows.length > 1) {
1195 alert(__("Please select only one category."));
1201 editFeedCat(rows[0]);
1205 function localPiggieFunction(enable) {
1207 debug("I LOVEDED IT!");
1208 var piggie = document.getElementById("piggie");
1210 Element.show(piggie);
1211 Position.Center(piggie);
1212 Effect.Puff(piggie);
1217 function validateOpmlImport() {
1219 var opml_file = document.getElementById("opml_file");
1221 if (opml_file.value.length == 0) {
1222 alert(__("No OPML file to upload."));
1229 function updateFilterList(sort_key) {
1231 if (!xmlhttp_ready(xmlhttp)) {
1232 printLockingError();
1236 var filter_search = document.getElementById("filter_search");
1238 if (filter_search) { search = filter_search.value; }
1240 xmlhttp.open("GET", "backend.php?op=pref-filters&sort=" +
1241 param_escape(sort_key) +
1242 "&search=" + param_escape(search), true);
1243 xmlhttp.onreadystatechange=filterlist_callback;
1248 function updateLabelList(sort_key) {
1250 if (!xmlhttp_ready(xmlhttp)) {
1251 printLockingError();
1255 var label_search = document.getElementById("label_search");
1257 if (label_search) { search = label_search.value; }
1259 xmlhttp.open("GET", "backend.php?op=pref-labels&sort=" +
1260 param_escape(sort_key) +
1261 "&search=" + param_escape(search), true);
1262 xmlhttp.onreadystatechange=labellist_callback;
1266 function updatePrefsList() {
1268 if (!xmlhttp_ready(xmlhttp)) {
1269 printLockingError();
1273 xmlhttp.open("GET", "backend.php?op=pref-prefs", true);
1274 xmlhttp.onreadystatechange=prefslist_callback;
1279 function selectTab(id, noupdate, subop) {
1283 if (!id) id = active_tab;
1287 if (!xmlhttp_ready(xmlhttp)) {
1288 printLockingError();
1293 var c = document.getElementById('prefContent');
1299 debug("selectTab: " + id + "(NU: " + noupdate + ")");
1301 notify_progress("Loading, please wait...");
1303 // close active infobox if needed
1306 // clean up all current selections, just in case
1307 active_feed_cat = false;
1308 active_label = false;
1310 // Effect.Fade("prefContent", {duration: 1, to: 0.01,
1311 // queue: { position:'end', scope: 'FEED_TAB', limit: 1 } } );
1313 if (id == "feedConfig") {
1315 } else if (id == "filterConfig") {
1317 } else if (id == "labelConfig") {
1319 } else if (id == "genConfig") {
1321 } else if (id == "userConfig") {
1323 } else if (id == "feedBrowser") {
1324 updateBigFeedBrowser();
1328 /* clean selection from all tabs */
1330 var tabs_holder = document.getElementById("prefTabs");
1331 var tab = tabs_holder.firstChild;
1334 if (tab.className && tab.className.match("prefsTabSelected")) {
1335 tab.className = "prefsTab";
1337 tab = tab.nextSibling;
1340 /* mark new tab as selected */
1342 tab = document.getElementById(id + "Tab");
1345 if (!tab.className.match("Selected")) {
1346 tab.className = tab.className + "Selected";
1353 exception_error("selectTab", e);
1357 function backend_sanity_check_callback() {
1359 if (xmlhttp.readyState == 4) {
1363 if (sanity_check_done) {
1364 fatalError(11, "Sanity check request received twice. This can indicate "+
1365 "presence of Firebug or some other disrupting extension. "+
1366 "Please disable it and try again.");
1370 if (!xmlhttp.responseXML) {
1371 fatalError(3, "[D001, Received reply is not XML]: " + xmlhttp.responseText);
1375 var reply = xmlhttp.responseXML.firstChild.firstChild;
1378 fatalError(3, "[D002, Invalid RPC reply]: " + xmlhttp.responseText);
1382 var error_code = reply.getAttribute("error-code");
1384 if (error_code && error_code != 0) {
1385 return fatalError(error_code, reply.getAttribute("error-msg"));
1388 debug("sanity check ok");
1390 var params = reply.nextSibling;
1393 debug('reading init-params...');
1394 var param = params.firstChild;
1397 var k = param.getAttribute("key");
1398 var v = param.getAttribute("value");
1399 debug(k + " => " + v);
1401 param = param.nextSibling;
1405 sanity_check_done = true;
1407 init_second_stage();
1410 exception_error("backend_sanity_check_callback", e);
1415 function init_second_stage() {
1418 active_tab = getInitParam("prefs_active_tab");
1419 if (!active_tab || active_tab == '0') active_tab = "genConfig";
1421 document.onkeydown = pref_hotkey_handler;
1423 var tab = getURLParam('tab');
1425 caller_subop = getURLParam('subop');
1431 if (navigator.userAgent.match("Opera")) {
1432 setTimeout("selectTab()", 500);
1434 selectTab(active_tab);
1438 exception_error("init_second_stage", e);
1446 if (arguments.callee.done) return;
1447 arguments.callee.done = true;
1449 if (getURLParam('debug')) {
1450 document.getElementById('debug_output').style.display = 'block';
1451 debug('debug mode activated');
1456 document.getElementById("prefContent").innerHTML =
1457 "<b>Fatal error:</b> This program needs XmlHttpRequest " +
1458 "to function properly. Your browser doesn't seem to support it.";
1462 xmlhttp.open("GET", "backend.php?op=rpc&subop=sanityCheck", true);
1463 xmlhttp.onreadystatechange=backend_sanity_check_callback;
1467 exception_error("init", e);
1471 function categorizeSelectedFeeds() {
1473 if (!xmlhttp_ready(xmlhttp)) {
1474 printLockingError();
1478 var sel_rows = getSelectedFeeds();
1480 var cat_sel = document.getElementById("sfeed_set_fcat");
1481 var cat_id = cat_sel[cat_sel.selectedIndex].value;
1483 if (sel_rows.length > 0) {
1485 notify_progress("Changing category of selected feeds...");
1487 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=categorize&ids="+
1488 param_escape(sel_rows.toString()) + "&cat_id=" + param_escape(cat_id), true);
1489 xmlhttp.onreadystatechange=feedlist_callback;
1494 alert(__("No feeds are selected."));
1500 function validatePrefsReset() {
1502 var ok = confirm(__("Reset to defaults?"));
1506 var query = Form.serialize("pref_prefs_form");
1507 query = query + "&subop=reset-config";
1510 xmlhttp.open("POST", "backend.php", true);
1511 xmlhttp.onreadystatechange=prefs_reset_callback;
1512 xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
1513 xmlhttp.send(query);
1517 exception_error("validatePrefsSave", e);
1524 function browseFeeds(limit) {
1526 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=browse", true);
1527 xmlhttp.onreadystatechange=infobox_callback;
1532 function feedBrowserSubscribe() {
1535 var selected = getSelectedFeedsFromBrowser();
1537 if (selected.length > 0) {
1539 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=massSubscribe&ids="+
1540 param_escape(selected.toString()), true);
1541 xmlhttp.onreadystatechange=feedlist_callback;
1544 alert(__("No feeds are selected."));
1548 exception_error("feedBrowserSubscribe", e);
1552 function updateBigFeedBrowser(limit) {
1554 if (!xmlhttp_ready(xmlhttp)) {
1555 printLockingError();
1559 var query = "backend.php?op=pref-feed-browser";
1561 var limit_sel = document.getElementById("feedBrowserLimit");
1564 var limit = limit_sel[limit_sel.selectedIndex].value;
1565 query = query + "&limit=" + param_escape(limit);
1568 xmlhttp.open("GET", query, true);
1569 xmlhttp.onreadystatechange=feed_browser_callback;
1573 function browserToggleExpand(id) {
1575 /* if (feed_to_expand && feed_to_expand != id) {
1576 var d = document.getElementById("BRDET-" + feed_to_expand);
1577 d.style.display = "none";
1580 if (!xmlhttp_ready(xmlhttp)) {
1581 printLockingError();
1585 /* if (feed_to_expand && id != feed_to_expand) {
1586 Effect.Fade('BRDET-' + feed_to_expand, {duration : 0.5});
1589 var d = document.getElementById("BRDET-" + id);
1591 if (Element.visible(d)) {
1592 Effect.Fade(d, {duration : 0.5});
1594 feed_to_expand = id;
1596 xmlhttp.open("GET", "backend.php?op=pref-feed-browser&subop=details&id="
1597 + param_escape(id), true);
1598 xmlhttp.onreadystatechange=expand_feed_callback;
1603 exception_error("browserToggleExpand", e);
1607 function selectPrefRows(kind, select) {
1610 var opbarid = false;
1615 if (kind == "feed") {
1616 opbarid = "feedOpToolbar";
1619 lname = "prefFeedList";
1620 } else if (kind == "fcat") {
1621 opbarid = "catOpToolbar";
1624 lname = "prefFeedCatList";
1625 } else if (kind == "filter") {
1626 opbarid = "filterOpToolbar";
1629 lname = "prefFilterList";
1630 } else if (kind == "label") {
1631 opbarid = "labelOpToolbar";
1634 lname = "prefLabelList";
1635 } else if (kind == "user") {
1636 opbarid = "userOpToolbar";
1639 lname = "prefUserList";
1643 selectTableRowsByIdPrefix(lname, nrow, nchk, select);
1644 disableContainerChildren(opbarid, !select);
1651 function toggleSelectPrefRow(sender, kind) {
1653 toggleSelectRow(sender);
1656 var opbarid = false;
1659 if (kind == "feed") {
1660 opbarid = "feedOpToolbar";
1661 nsel = getSelectedFeeds();
1662 } else if (kind == "fcat") {
1663 opbarid = "catOpToolbar";
1664 nsel = getSelectedFeedCats();
1665 } else if (kind == "filter") {
1666 opbarid = "filterOpToolbar";
1667 nsel = getSelectedFilters();
1668 } else if (kind == "label") {
1669 opbarid = "labelOpToolbar";
1670 nsel = getSelectedLabels();
1671 } else if (kind == "user") {
1672 opbarid = "userOpToolbar";
1673 nsel = getSelectedUsers();
1676 if (opbarid && nsel != -1) {
1677 disableContainerChildren(opbarid, nsel == false);
1683 function toggleSelectFBListRow(sender) {
1684 toggleSelectListRow(sender);
1685 disableContainerChildren("fbrOpToolbar", getSelectedFeedsFromBrowser() == 0);
1690 function pref_hotkey_handler(e) {
1694 var shift_key = false;
1697 shift_key = e.shiftKey;
1703 keycode = window.event.keyCode;
1708 if (keycode == 27) { // escape
1709 if (Element.visible("hotkey_help_overlay")) {
1710 Element.hide("hotkey_help_overlay");
1712 hotkey_prefix = false;
1716 if (!hotkeys_enabled) {
1717 debug("hotkeys disabled");
1721 if (keycode == 16) return; // ignore lone shift
1723 if ((keycode == 67 || keycode == 71) && !hotkey_prefix) {
1724 hotkey_prefix = keycode;
1725 debug("KP: PREFIX=" + keycode);
1729 if (Element.visible("hotkey_help_overlay")) {
1730 Element.hide("hotkey_help_overlay");
1733 if (keycode == 13 || keycode == 27) {
1736 seq = seq + "" + keycode;
1739 /* Global hotkeys */
1741 if (!hotkey_prefix) {
1743 if (keycode == 68 && shift_key) { // d
1744 if (!debug_mode_enabled) {
1745 document.getElementById('debug_output').style.display = 'block';
1746 debug('debug mode activated');
1748 document.getElementById('debug_output').style.display = 'none';
1751 debug_mode_enabled = !debug_mode_enabled;
1755 if (keycode == 191 && shift_key) { // ?
1756 if (!Element.visible("hotkey_help_overlay")) {
1757 //Element.show("hotkey_help_overlay");
1758 Effect.Appear("hotkey_help_overlay", {duration : 0.3});
1760 Element.hide("hotkey_help_overlay");
1765 if (keycode == 191) { // /
1766 var search_boxes = new Array("label_search",
1767 "feed_search", "filter_search", "user_search");
1769 for (var i = 0; i < search_boxes.length; i++) {
1770 var elem = document.getElementById(search_boxes[i]);
1772 return focus_element(search_boxes[i]);
1781 if (hotkey_prefix == 67) { // c
1782 hotkey_prefix = false;
1784 if (keycode == 70) { // f
1785 return displayDlg("quickAddFilter");
1788 if (keycode == 83) { // s
1789 return displayDlg("quickAddFeed");
1792 if (keycode == 76) { // l
1793 return displayDlg("quickAddLabel");
1796 if (keycode == 85) { // u
1800 if (keycode == 67) { // c
1801 return editFeedCats();
1804 if (keycode == 84 && shift_key) { // T
1805 return browseFeeds();
1808 if (keycode == 69) { // e
1809 return editCurrentEntryDispatcher();
1816 if (hotkey_prefix == 71) { // g
1818 hotkey_prefix = false;
1820 if (keycode == 49 && document.getElementById("genConfigTab")) { // 1
1821 selectTab("genConfig");
1824 if (keycode == 50 && document.getElementById("feedConfigTab")) { // 2
1825 return selectTab("feedConfig");
1828 if (keycode == 51 && document.getElementById("feedBrowserTab")) { // 3
1829 return selectTab("feedBrowser");
1832 if (keycode == 52 && document.getElementById("filterConfigTab")) { // 4
1833 return selectTab("filterConfig");
1836 if (keycode == 53 && document.getElementById("labelConfigTab")) { // 5
1837 return selectTab("labelConfig");
1840 if (keycode == 54 && document.getElementById("userConfigTab")) { // 6
1841 return selectTab("userConfig");
1844 if (keycode == 88) { // x
1850 if (document.getElementById("piggie")) {
1852 if (seq.match("807371717369")) {
1854 localPiggieFunction(true);
1856 localPiggieFunction(false);
1860 if (hotkey_prefix) {
1861 debug("KP: PREFIX=" + hotkey_prefix + " CODE=" + keycode);
1863 debug("KP: CODE=" + keycode);
1867 exception_error("pref_hotkey_handler", e);
1871 function editFeedCats() {
1872 if (!xmlhttp_ready(xmlhttp)) {
1873 printLockingError();
1877 document.getElementById("subscribe_to_feed_btn").disabled = true;
1880 document.getElementById("top25_feeds_btn").disabled = true;
1882 // this button is not always available, no-op if not found
1885 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=editCats", true);
1886 xmlhttp.onreadystatechange=infobox_feed_cat_callback;
1890 function showFeedsWithErrors() {
1891 displayDlg('feedUpdateErrors');
1894 function changeUserPassword() {
1898 if (!xmlhttp_ready(xmlhttp)) {
1899 printLockingError();
1903 var f = document.forms["change_pass_form"];
1906 if (f.OLD_PASSWORD.value == "") {
1907 new Effect.Highlight(f.OLD_PASSWORD);
1908 notify_error("Old password cannot be blank.");
1912 if (f.NEW_PASSWORD.value == "") {
1913 new Effect.Highlight(f.NEW_PASSWORD);
1914 notify_error("New password cannot be blank.");
1918 if (f.CONFIRM_PASSWORD.value == "") {
1919 new Effect.Highlight(f.CONFIRM_PASSWORD);
1920 notify_error("Entered passwords do not match.");
1924 if (f.CONFIRM_PASSWORD.value != f.NEW_PASSWORD.value) {
1925 new Effect.Highlight(f.CONFIRM_PASSWORD);
1926 new Effect.Highlight(f.NEW_PASSWORD);
1927 notify_error("Entered passwords do not match.");
1933 var query = Form.serialize("change_pass_form");
1935 notify_progress("Trying to change password...");
1937 xmlhttp.open("POST", "backend.php", true);
1938 xmlhttp.onreadystatechange=changepass_callback;
1939 xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
1940 xmlhttp.send(query);
1943 exception_error("changeUserPassword", e);
1949 function changeUserEmail() {
1953 if (!xmlhttp_ready(xmlhttp)) {
1954 printLockingError();
1958 var query = Form.serialize("change_email_form");
1960 notify_progress("Trying to change e-mail...");
1962 xmlhttp.open("POST", "backend.php", true);
1963 xmlhttp.onreadystatechange=notify_callback;
1964 xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
1965 xmlhttp.send(query);
1968 exception_error("changeUserPassword", e);
1975 function feedlistToggleSLAT() {
1976 notify_progress("Loading, please wait...");
1980 function pubRegenKey() {
1982 if (!xmlhttp_ready(xmlhttp)) {
1983 printLockingError();
1987 var ok = confirm(__("Replace current publishing address with a new one?"));
1991 notify_progress("Trying to change address...");
1993 xmlhttp.open("GET", "backend.php?op=rpc&subop=regenPubKey");
1994 xmlhttp.onreadystatechange=replace_pubkey_callback;
2001 function pubToClipboard() {
2005 if (!xmlhttp_ready(xmlhttp)) {
2006 printLockingError();
2010 var link = document.getElementById("pubGenAddress");
2014 exception_error("pubToClipboard", e);
2020 function validatePrefsSave() {
2023 var ok = confirm(__("Save current configuration?"));
2027 var query = Form.serialize("pref_prefs_form");
2028 query = query + "&subop=save-config";
2031 xmlhttp.open("POST", "backend.php", true);
2032 xmlhttp.onreadystatechange=notify_callback;
2033 xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
2034 xmlhttp.send(query);
2038 exception_error("validatePrefsSave", e);
2044 function feedActionChange() {
2046 var chooser = document.getElementById("feedActionChooser");
2047 var opid = chooser[chooser.selectedIndex].value;
2049 chooser.selectedIndex = 0;
2052 exception_error("feedActionChange", e);
2056 function feedActionGo(op) {
2058 if (op == "facEdit") {
2062 if (op == "facClear") {
2063 clearSelectedFeeds();
2066 if (op == "facPurge") {
2067 purgeSelectedFeeds();
2070 if (op == "facEditCats") {
2074 if (op == "facRescore") {
2075 rescoreSelectedFeeds();
2078 if (op == "facUnsubscribe") {
2079 removeSelectedFeeds();
2083 exception_error("feedActionGo", e);
2088 function clearFeedArticles(feed_id) {
2090 notify_progress("Clearing feed...");
2092 var query = "backend.php?op=pref-feeds&quiet=1&subop=clear&id=" + feed_id;
2094 new Ajax.Request(query, {
2095 onComplete: function(transport) {
2102 function rescoreSelectedFeeds() {
2104 if (!xmlhttp_ready(xmlhttp)) {
2105 printLockingError();
2109 var sel_rows = getSelectedFeeds();
2111 if (sel_rows.length > 0) {
2113 //var ok = confirm(__("Rescore last 100 articles in selected feeds?"));
2114 var ok = confirm(__("Rescore articles in selected feeds?"));
2117 notify_progress("Rescoring selected feeds...");
2119 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=rescore&quiet=1&ids="+
2120 param_escape(sel_rows.toString()), true);
2121 xmlhttp.onreadystatechange=notify_callback;
2125 alert(__("No feeds are selected."));
2131 function rescore_all_feeds() {
2132 var ok = confirm(__("Rescore all articles? This operation may take a lot of time."));
2135 notify_progress("Rescoring feeds...");
2137 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=rescoreAll&quiet=1", true);
2138 xmlhttp.onreadystatechange=notify_callback;
2143 function editCurrentEntryDispatcher() {