3 var active_feed_cat = false;
4 var active_tab = false;
6 var xmlhttp = Ajax.getTransport();
8 var init_params = new Array();
10 var caller_subop = false;
11 var sanity_check_done = false;
12 var hotkey_prefix = false;
14 function infobox_callback() {
15 if (xmlhttp.readyState == 4) {
16 infobox_callback2(xmlhttp);
20 function infobox_submit_callback() {
21 if (xmlhttp.readyState == 4) {
22 infobox_submit_callback2(xmlhttp);
27 function replace_pubkey_callback() {
28 if (xmlhttp.readyState == 4) {
30 var link = document.getElementById("pubGenAddress");
32 if (xmlhttp.responseXML) {
34 var new_link = xmlhttp.responseXML.getElementsByTagName("link")[0];
37 link.href = new_link.firstChild.nodeValue;
38 //link.innerHTML = new_link.firstChild.nodeValue;
40 new Effect.Highlight(link);
42 notify_info("Published feed URL changed.");
44 notify_error("Could not change feed URL.");
48 notify_error("Could not change feed URL.");
51 exception_error("replace_pubkey_callback", e);
56 function feedlist_callback() {
57 if (xmlhttp.readyState == 4) {
58 return feedlist_callback2(xmlhttp);
62 function feedlist_callback2(transport) {
64 var container = document.getElementById('prefContent');
65 container.innerHTML=transport.responseText;
66 selectTab("feedConfig", true);
69 var tuple = caller_subop.split(":");
70 if (tuple[0] == 'editFeed') {
71 window.setTimeout('editFeed('+tuple[1]+')', 100);
76 if (typeof correctPNG != 'undefined') {
83 exception_error("feedlist_callback2", e);
87 /* stub for subscription dialog */
89 function dlg_frefresh_callback(transport) {
90 return feedlist_callback2(transport);
93 function filterlist_callback() {
94 var container = document.getElementById('prefContent');
95 if (xmlhttp.readyState == 4) {
96 container.innerHTML=xmlhttp.responseText;
97 if (typeof correctPNG != 'undefined') {
105 function labellist_callback2(transport) {
109 var container = document.getElementById('prefContent');
111 container.innerHTML=transport.responseText;
113 if (document.getElementById("prefLabelList")) {
114 var elems = document.getElementById("prefLabelList").getElementsByTagName("SPAN");
116 for (var i = 0; i < elems.length; i++) {
117 if (elems[i].id && elems[i].id.match("LILT-")) {
119 var id = elems[i].id.replace("LILT-", "");
120 new Ajax.InPlaceEditor(elems[i],
121 'backend.php?op=pref-labels&subop=save&id=' + id,
122 {cols: 20, rows: 1});
127 if (typeof correctPNG != 'undefined') {
134 exception_error("labellist_callback2", e);
138 function feed_browser_callback() {
139 var container = document.getElementById('prefContent');
140 if (xmlhttp.readyState == 4) {
141 container.innerHTML=xmlhttp.responseText;
147 function userlist_callback() {
148 var container = document.getElementById('prefContent');
149 if (xmlhttp.readyState == 4) {
150 container.innerHTML=xmlhttp.responseText;
156 function prefslist_callback() {
157 var container = document.getElementById('prefContent');
158 if (xmlhttp.readyState == 4) {
159 container.innerHTML=xmlhttp.responseText;
165 function gethelp_callback() {
166 var container = document.getElementById('prefHelpBox');
167 if (xmlhttp.readyState == 4) {
169 container.innerHTML = xmlhttp.responseText;
170 container.style.display = "block";
175 function notify_callback() {
176 if (xmlhttp.readyState == 4) {
177 notify_info(xmlhttp.responseText);
181 function prefs_reset_callback() {
182 if (xmlhttp.readyState == 4) {
183 notify_info(xmlhttp.responseText);
189 function changepass_callback() {
191 if (xmlhttp.readyState == 4) {
193 if (xmlhttp.responseText.indexOf("ERROR: ") == 0) {
194 notify_error(xmlhttp.responseText.replace("ERROR: ", ""));
196 notify_info(xmlhttp.responseText);
197 var warn = document.getElementById("default_pass_warning");
198 if (warn) warn.style.display = "none";
201 document.forms['change_pass_form'].reset();
205 exception_error("changepass_callback", e);
209 function init_cat_inline_editor() {
212 if (document.getElementById("prefFeedCatList")) {
213 var elems = document.getElementById("prefFeedCatList").getElementsByTagName("SPAN");
215 for (var i = 0; i < elems.length; i++) {
216 if (elems[i].id && elems[i].id.match("FCATT-")) {
217 var cat_id = elems[i].id.replace("FCATT-", "");
218 new Ajax.InPlaceEditor(elems[i],
219 'backend.php?op=pref-feeds&subop=editCats&action=save&cid=' + cat_id);
225 exception_error("init_cat_inline_editor", e);
229 function infobox_feed_cat_callback2(transport) {
231 infobox_callback2(transport);
232 init_cat_inline_editor();
234 exception_error("infobox_feed_cat_callback2", e);
238 function updateFeedList(sort_key) {
240 if (!xmlhttp_ready(xmlhttp)) {
245 var feed_search = document.getElementById("feed_search");
247 if (feed_search) { search = feed_search.value; }
249 var slat = document.getElementById("show_last_article_times");
251 var slat_checked = false;
253 slat_checked = slat.checked;
256 xmlhttp.open("GET", "backend.php?op=pref-feeds" +
257 "&sort=" + param_escape(sort_key) +
258 "&slat=" + param_escape(slat_checked) +
259 "&search=" + param_escape(search), true);
260 xmlhttp.onreadystatechange=feedlist_callback;
265 function updateUsersList(sort_key) {
267 if (!xmlhttp_ready(xmlhttp)) {
272 var user_search = document.getElementById("user_search");
274 if (user_search) { search = user_search.value; }
276 xmlhttp.open("GET", "backend.php?op=pref-users&sort="
277 + param_escape(sort_key) +
278 "&search=" + param_escape(search), true);
279 xmlhttp.onreadystatechange=userlist_callback;
284 function addLabel() {
288 var caption = prompt(__("Please enter label caption:"), "");
290 if (caption == null) {
295 alert(__("Can't create label: missing caption."));
299 // we can be called from some other tab
300 active_tab = "labelConfig";
302 query = "backend.php?op=pref-labels&subop=add&caption=" +
303 param_escape(caption);
305 new Ajax.Request(query, {
306 onComplete: function(transport) {
307 infobox_submit_callback2(transport);
311 exception_error("addLabel", e);
319 var link = document.getElementById("fadd_link");
321 if (link.value.length == 0) {
322 alert(__("Error: No feed URL given."));
323 } else if (!isValidURL(link.value)) {
324 alert(__("Error: Invalid feed URL."));
326 notify_progress("Adding feed...");
328 var query = "backend.php?op=pref-feeds&subop=add&from=tt-rss&feed_url=" +
329 param_escape(link.value);
331 new Ajax.Request(query, {
332 onComplete: function(transport) {
333 feedlist_callback2(transport);
341 exception_error("addFeed", e);
346 function addFeedCat() {
348 if (!xmlhttp_ready(xmlhttp)) {
353 var cat = document.getElementById("fadd_cat");
355 if (cat.value.length == 0) {
356 alert(__("Can't add category: no name specified."));
358 notify_progress("Adding feed category...");
360 var query = "backend.php?op=pref-feeds&subop=editCats&action=add&cat=" +
361 param_escape(cat.value);
363 new Ajax.Request(query, {
364 onComplete: function(transport) {
365 infobox_feed_cat_callback2(transport);
375 if (!xmlhttp_ready(xmlhttp)) {
380 var sqlexp = document.getElementById("uadd_box");
382 if (sqlexp.value.length == 0) {
383 alert(__("Can't add user: no login specified."));
385 notify_progress("Adding user...");
387 xmlhttp.open("GET", "backend.php?op=pref-users&subop=add&login=" +
388 param_escape(sqlexp.value), true);
390 xmlhttp.onreadystatechange=userlist_callback;
398 function editUser(id) {
404 notify_progress("Loading, please wait...");
406 selectTableRowsByIdPrefix('prefUserList', 'UMRR-', 'UMCHK-', false);
407 selectTableRowById('UMRR-'+id, 'UMCHK-'+id, true);
409 disableContainerChildren("userOpToolbar", false);
411 var query = "backend.php?op=pref-users&subop=edit&id=" +
414 new Ajax.Request(query, {
415 onComplete: function(transport) {
416 infobox_callback2(transport);
420 exception_error("editUser", e);
425 function editFilter(id) {
431 notify_progress("Loading, please wait...");
433 disableContainerChildren("filterOpToolbar", false);
435 selectTableRowsByIdPrefix('prefFilterList', 'FILRR-', 'FICHK-', false);
436 selectTableRowById('FILRR-'+id, 'FICHK-'+id, true);
438 var query = "backend.php?op=pref-filters&subop=edit&id=" +
441 new Ajax.Request(query, {
442 onComplete: function(transport) {
443 infobox_callback2(transport);
446 exception_error("editFilter", e);
450 function editFeed(feed) {
456 notify_progress("Loading, please wait...");
458 // clean selection from all rows & select row being edited
459 selectTableRowsByIdPrefix('prefFeedList', 'FEEDR-', 'FRCHK-', false);
460 selectTableRowById('FEEDR-'+feed, 'FRCHK-'+feed, true);
462 disableContainerChildren("feedOpToolbar", false);
464 var query = "backend.php?op=pref-feeds&subop=editfeed&id=" +
467 new Ajax.Request(query, {
468 onComplete: function(transport) {
469 infobox_callback2(transport);
473 exception_error("editFeed", e);
477 function getSelectedLabels() {
478 return getSelectedTableRowIds("prefLabelList", "LILRR");
481 function getSelectedUsers() {
482 return getSelectedTableRowIds("prefUserList", "UMRR");
485 function getSelectedFeeds() {
486 return getSelectedTableRowIds("prefFeedList", "FEEDR");
489 function getSelectedFilters() {
490 return getSelectedTableRowIds("prefFilterList", "FILRR");
493 function getSelectedFeedCats() {
494 return getSelectedTableRowIds("prefFeedCatList", "FCATR");
498 function removeSelectedLabels() {
500 var sel_rows = getSelectedLabels();
502 if (sel_rows.length > 0) {
504 var ok = confirm(__("Remove selected labels?"));
507 notify_progress("Removing selected labels...");
509 var query = "backend.php?op=pref-labels&subop=remove&ids="+
510 param_escape(sel_rows.toString());
512 new Ajax.Request(query, {
513 onComplete: function(transport) {
514 labellist_callback2(transport);
519 alert(__("No labels are selected."));
525 function removeSelectedUsers() {
527 if (!xmlhttp_ready(xmlhttp)) {
532 var sel_rows = getSelectedUsers();
534 if (sel_rows.length > 0) {
536 var ok = confirm(__("Remove selected users?"));
539 notify_progress("Removing selected users...");
541 xmlhttp.open("GET", "backend.php?op=pref-users&subop=remove&ids="+
542 param_escape(sel_rows.toString()), true);
543 xmlhttp.onreadystatechange=userlist_callback;
548 alert(__("No users are selected."));
554 function removeSelectedFilters() {
556 if (!xmlhttp_ready(xmlhttp)) {
561 var sel_rows = getSelectedFilters();
563 if (sel_rows.length > 0) {
565 var ok = confirm(__("Remove selected filters?"));
568 notify_progress("Removing selected filters...");
570 xmlhttp.open("GET", "backend.php?op=pref-filters&subop=remove&ids="+
571 param_escape(sel_rows.toString()), true);
572 xmlhttp.onreadystatechange=filterlist_callback;
576 alert(__("No filters are selected."));
583 function removeSelectedFeeds() {
587 var sel_rows = getSelectedFeeds();
589 if (sel_rows.length > 0) {
591 var ok = confirm(__("Unsubscribe from selected feeds?"));
595 notify_progress("Unsubscribing from selected feeds...");
597 var query = "backend.php?op=pref-feeds&subop=remove&ids="+
598 param_escape(sel_rows.toString());
600 new Ajax.Request(query, {
601 onComplete: function(transport) {
602 feedlist_callback2(transport);
607 alert(__("No feeds are selected."));
611 exception_error("removeSelectedFeeds", e);
617 function clearSelectedFeeds() {
619 if (!xmlhttp_ready(xmlhttp)) {
624 var sel_rows = getSelectedFeeds();
626 if (sel_rows.length > 1) {
627 alert(__("Please select only one feed."));
631 if (sel_rows.length > 0) {
633 var ok = confirm(__("Erase all non-starred articles in selected feed?"));
636 notify_progress("Clearing selected feed...");
637 clearFeedArticles(sel_rows[0]);
642 alert(__("No feeds are selected."));
649 function purgeSelectedFeeds() {
651 if (!xmlhttp_ready(xmlhttp)) {
656 var sel_rows = getSelectedFeeds();
658 if (sel_rows.length > 0) {
660 var pr = prompt(__("How many days of articles to keep (0 - use default)?"), "0");
662 if (pr != undefined) {
663 notify_progress("Purging selected feed...");
665 var query = "backend.php?op=rpc&subop=purge&ids="+
666 param_escape(sel_rows.toString()) + "&days=" + pr;
670 new Ajax.Request(query, {
671 onComplete: function(transport) {
678 alert(__("No feeds are selected."));
685 function removeSelectedFeedCats() {
687 if (!xmlhttp_ready(xmlhttp)) {
692 var sel_rows = getSelectedFeedCats();
694 if (sel_rows.length > 0) {
696 var ok = confirm(__("Remove selected categories?"));
699 notify_progress("Removing selected categories...");
701 var query = "backend.php?op=pref-feeds&subop=editCats&action=remove&ids="+
702 param_escape(sel_rows.toString());
704 new Ajax.Request(query, {
705 onComplete: function(transport) {
706 infobox_feed_cat_callback2(transport);
713 alert(__("No categories are selected."));
720 function feedEditCancel() {
722 if (!xmlhttp_ready(xmlhttp)) {
728 document.getElementById("subscribe_to_feed_btn").disabled = false;
729 document.getElementById("top25_feeds_btn").disabled = false;
731 // this button is not always available, no-op if not found
736 selectPrefRows('feed', false); // cleanup feed selection
741 function feedEditSave() {
745 if (!xmlhttp_ready(xmlhttp)) {
750 // FIXME: add parameter validation
752 var query = Form.serialize("edit_feed_form");
754 notify_progress("Saving feed...");
756 xmlhttp.open("POST", "backend.php", true);
757 xmlhttp.onreadystatechange=feedlist_callback;
758 xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
766 exception_error("feedEditSave", e);
770 function userEditCancel() {
772 if (!xmlhttp_ready(xmlhttp)) {
777 selectPrefRows('user', false); // cleanup feed selection
783 function filterEditCancel() {
785 if (!xmlhttp_ready(xmlhttp)) {
791 document.getElementById("create_filter_btn").disabled = false;
792 selectPrefRows('filter', false); // cleanup feed selection
800 function userEditSave() {
802 if (!xmlhttp_ready(xmlhttp)) {
807 var login = document.forms["user_edit_form"].login.value;
809 if (login.length == 0) {
810 alert(__("Login field cannot be blank."));
814 notify_progress("Saving user...");
818 var query = Form.serialize("user_edit_form");
820 xmlhttp.open("GET", "backend.php?" + query, true);
821 xmlhttp.onreadystatechange=userlist_callback;
828 function filterEditSave() {
830 if (!xmlhttp_ready(xmlhttp)) {
835 /* if (!is_opera()) {
836 var reg_exp = document.forms["filter_edit_form"].reg_exp.value;
838 if (reg_exp.length == 0) {
839 alert("Filter expression field cannot be blank.");
844 notify_progress("Saving filter...");
846 var query = Form.serialize("filter_edit_form");
850 document.getElementById("create_filter_btn").disabled = false;
852 xmlhttp.open("GET", "backend.php?" + query, true);
853 xmlhttp.onreadystatechange=filterlist_callback;
860 function editSelectedUser() {
861 var rows = getSelectedUsers();
863 if (rows.length == 0) {
864 alert(__("No users are selected."));
868 if (rows.length > 1) {
869 alert(__("Please select only one user."));
878 function resetSelectedUserPass() {
879 var rows = getSelectedUsers();
881 if (rows.length == 0) {
882 alert(__("No users are selected."));
886 if (rows.length > 1) {
887 alert(__("Please select only one user."));
891 var ok = confirm(__("Reset password of selected user?"));
894 notify_progress("Resetting password for selected user...");
898 xmlhttp.open("GET", "backend.php?op=pref-users&subop=resetPass&id=" +
899 param_escape(id), true);
900 xmlhttp.onreadystatechange=userlist_callback;
905 function selectedUserDetails() {
909 var rows = getSelectedUsers();
911 if (rows.length == 0) {
912 alert(__("No users are selected."));
916 if (rows.length > 1) {
917 alert(__("Please select only one user."));
921 notify_progress("Loading, please wait...");
925 var query = "backend.php?op=pref-users&subop=user-details&id=" + id;
927 new Ajax.Request(query, {
928 onComplete: function(transport) {
929 infobox_callback2(transport);
932 exception_error("selectedUserDetails", e);
937 function editSelectedFilter() {
938 var rows = getSelectedFilters();
940 if (rows.length == 0) {
941 alert(__("No filters are selected."));
945 if (rows.length > 1) {
946 alert(__("Please select only one filter."));
957 function editSelectedFeed() {
958 var rows = getSelectedFeeds();
960 if (rows.length == 0) {
961 alert(__("No feeds are selected."));
965 if (rows.length > 1) {
966 alert(__("Please select one feed."));
976 function editSelectedFeeds() {
979 var rows = getSelectedFeeds();
981 if (rows.length == 0) {
982 alert(__("No feeds are selected."));
990 notify_progress("Loading, please wait...");
992 var query = "backend.php?op=pref-feeds&subop=editfeeds&ids=" +
993 param_escape(rows.toString());
995 new Ajax.Request(query, {
996 onComplete: function(transport) {
997 infobox_callback2(transport);
1001 exception_error("editSelectedFeeds", e);
1005 function piggie(enable) {
1007 debug("I LOVEDED IT!");
1008 var piggie = document.getElementById("piggie");
1010 Element.show(piggie);
1011 Position.Center(piggie);
1012 Effect.Puff(piggie);
1017 function validateOpmlImport() {
1019 var opml_file = document.getElementById("opml_file");
1021 if (opml_file.value.length == 0) {
1022 alert(__("No OPML file to upload."));
1029 function updateFilterList(sort_key) {
1031 if (!xmlhttp_ready(xmlhttp)) {
1032 printLockingError();
1036 var filter_search = document.getElementById("filter_search");
1038 if (filter_search) { search = filter_search.value; }
1040 xmlhttp.open("GET", "backend.php?op=pref-filters&sort=" +
1041 param_escape(sort_key) +
1042 "&search=" + param_escape(search), true);
1043 xmlhttp.onreadystatechange=filterlist_callback;
1048 function updateLabelList(sort_key) {
1052 var label_search = document.getElementById("label_search");
1054 if (label_search) { search = label_search.value; }
1056 var query = "backend.php?op=pref-labels&sort=" +
1057 param_escape(sort_key) +
1058 "&search=" + param_escape(search);
1060 new Ajax.Request(query, {
1061 onComplete: function(transport) {
1062 labellist_callback2(transport);
1066 exception_error("updateLabelList", e);
1070 function updatePrefsList() {
1072 if (!xmlhttp_ready(xmlhttp)) {
1073 printLockingError();
1077 xmlhttp.open("GET", "backend.php?op=pref-prefs", true);
1078 xmlhttp.onreadystatechange=prefslist_callback;
1083 function selectTab(id, noupdate, subop) {
1087 if (!id) id = active_tab;
1091 if (!xmlhttp_ready(xmlhttp)) {
1092 printLockingError();
1097 var c = document.getElementById('prefContent');
1103 debug("selectTab: " + id + "(NU: " + noupdate + ")");
1105 notify_progress("Loading, please wait...");
1107 // close active infobox if needed
1110 // clean up all current selections, just in case
1111 active_feed_cat = false;
1113 // Effect.Fade("prefContent", {duration: 1, to: 0.01,
1114 // queue: { position:'end', scope: 'FEED_TAB', limit: 1 } } );
1116 if (id == "feedConfig") {
1118 } else if (id == "filterConfig") {
1120 } else if (id == "labelConfig") {
1122 } else if (id == "genConfig") {
1124 } else if (id == "userConfig") {
1129 /* clean selection from all tabs */
1131 var tabs_holder = document.getElementById("prefTabs");
1132 var tab = tabs_holder.firstChild;
1135 if (tab.className && tab.className.match("prefsTabSelected")) {
1136 tab.className = "prefsTab";
1138 tab = tab.nextSibling;
1141 /* mark new tab as selected */
1143 tab = document.getElementById(id + "Tab");
1146 if (!tab.className.match("Selected")) {
1147 tab.className = tab.className + "Selected";
1154 exception_error("selectTab", e);
1158 function backend_sanity_check_callback() {
1160 if (xmlhttp.readyState == 4) {
1164 if (sanity_check_done) {
1165 fatalError(11, "Sanity check request received twice. This can indicate "+
1166 "presence of Firebug or some other disrupting extension. "+
1167 "Please disable it and try again.");
1171 if (!xmlhttp.responseXML) {
1172 fatalError(3, "Sanity Check: Received reply is not XML",
1173 xmlhttp.responseText);
1177 var reply = xmlhttp.responseXML.firstChild.firstChild;
1180 fatalError(3, "Sanity Check: Invalid RPC reply", xmlhttp.responseText);
1184 var error_code = reply.getAttribute("error-code");
1186 if (error_code && error_code != 0) {
1187 return fatalError(error_code, reply.getAttribute("error-msg"));
1190 debug("sanity check ok");
1192 var params = reply.nextSibling;
1195 debug('reading init-params...');
1196 var param = params.firstChild;
1199 var k = param.getAttribute("key");
1200 var v = param.getAttribute("value");
1201 debug(k + " => " + v);
1203 param = param.nextSibling;
1207 sanity_check_done = true;
1209 init_second_stage();
1212 exception_error("backend_sanity_check_callback", e);
1217 function init_second_stage() {
1220 active_tab = getInitParam("prefs_active_tab");
1221 if (!document.getElementById(active_tab+"Tab")) active_tab = "genConfig";
1222 if (!active_tab || active_tab == '0') active_tab = "genConfig";
1224 document.onkeydown = pref_hotkey_handler;
1226 var tab = getURLParam('tab');
1228 caller_subop = getURLParam('subop');
1230 if (getURLParam("subopparam")) {
1231 caller_subop = caller_subop + ":" + getURLParam("subopparam");
1238 if (navigator.userAgent.match("Opera")) {
1239 setTimeout("selectTab()", 500);
1241 selectTab(active_tab);
1245 loading_set_progress(60);
1248 exception_error("init_second_stage", e);
1256 if (arguments.callee.done) return;
1257 arguments.callee.done = true;
1259 if (getURLParam('debug')) {
1260 Element.show("debug_output");
1261 debug('debug mode activated');
1266 document.getElementById("prefContent").innerHTML =
1267 "<b>Fatal error:</b> This program needs XmlHttpRequest " +
1268 "to function properly. Your browser doesn't seem to support it.";
1272 loading_set_progress(30);
1274 xmlhttp.open("GET", "backend.php?op=rpc&subop=sanityCheck", true);
1275 xmlhttp.onreadystatechange=backend_sanity_check_callback;
1279 exception_error("init", e);
1283 function categorizeSelectedFeeds() {
1285 if (!xmlhttp_ready(xmlhttp)) {
1286 printLockingError();
1290 var sel_rows = getSelectedFeeds();
1292 var cat_sel = document.getElementById("sfeed_set_fcat");
1293 var cat_id = cat_sel[cat_sel.selectedIndex].value;
1295 if (sel_rows.length > 0) {
1297 notify_progress("Changing category of selected feeds...");
1299 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=categorize&ids="+
1300 param_escape(sel_rows.toString()) + "&cat_id=" + param_escape(cat_id), true);
1301 xmlhttp.onreadystatechange=feedlist_callback;
1306 alert(__("No feeds are selected."));
1312 function validatePrefsReset() {
1314 var ok = confirm(__("Reset to defaults?"));
1318 var query = Form.serialize("pref_prefs_form");
1319 query = query + "&subop=reset-config";
1322 xmlhttp.open("POST", "backend.php", true);
1323 xmlhttp.onreadystatechange=prefs_reset_callback;
1324 xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
1325 xmlhttp.send(query);
1329 exception_error("validatePrefsSave", e);
1336 function feedBrowserSubscribe() {
1339 var selected = getSelectedFeedsFromBrowser();
1341 if (selected.length > 0) {
1343 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=massSubscribe&ids="+
1344 param_escape(selected.toString()), true);
1345 xmlhttp.onreadystatechange=feedlist_callback;
1348 alert(__("No feeds are selected."));
1352 exception_error("feedBrowserSubscribe", e);
1356 function updateBigFeedBrowserBtn() {
1357 notify_progress("Loading, please wait...");
1358 return updateBigFeedBrowser();
1361 function selectPrefRows(kind, select) {
1364 var opbarid = false;
1369 if (kind == "feed") {
1370 opbarid = "feedOpToolbar";
1373 lname = "prefFeedList";
1374 } else if (kind == "fcat") {
1375 opbarid = "catOpToolbar";
1378 lname = "prefFeedCatList";
1379 } else if (kind == "filter") {
1380 opbarid = "filterOpToolbar";
1383 lname = "prefFilterList";
1384 } else if (kind == "label") {
1385 opbarid = "labelOpToolbar";
1388 lname = "prefLabelList";
1389 } else if (kind == "user") {
1390 opbarid = "userOpToolbar";
1393 lname = "prefUserList";
1397 selectTableRowsByIdPrefix(lname, nrow, nchk, select);
1398 disableContainerChildren(opbarid, !select);
1405 function toggleSelectPrefRow(sender, kind) {
1407 toggleSelectRow(sender);
1410 var opbarid = false;
1413 if (kind == "feed") {
1414 opbarid = "feedOpToolbar";
1415 nsel = getSelectedFeeds();
1416 } else if (kind == "fcat") {
1417 opbarid = "catOpToolbar";
1418 nsel = getSelectedFeedCats();
1419 } else if (kind == "filter") {
1420 opbarid = "filterOpToolbar";
1421 nsel = getSelectedFilters();
1422 } else if (kind == "label") {
1423 opbarid = "labelOpToolbar";
1424 nsel = getSelectedLabels();
1425 } else if (kind == "user") {
1426 opbarid = "userOpToolbar";
1427 nsel = getSelectedUsers();
1430 if (opbarid && nsel != -1) {
1431 disableContainerChildren(opbarid, nsel == false);
1437 function toggleSelectFBListRow(sender) {
1438 toggleSelectListRow(sender);
1439 disableContainerChildren("fbrOpToolbar", getSelectedFeedsFromBrowser() == 0);
1444 function pref_hotkey_handler(e) {
1448 var shift_key = false;
1451 shift_key = e.shiftKey;
1457 keycode = window.event.keyCode;
1462 var keychar = String.fromCharCode(keycode);
1464 if (keycode == 27) { // escape
1465 if (Element.visible("hotkey_help_overlay")) {
1466 Element.hide("hotkey_help_overlay");
1468 hotkey_prefix = false;
1472 if (!hotkeys_enabled) {
1473 debug("hotkeys disabled");
1477 if (keycode == 16) return; // ignore lone shift
1479 if ((keycode == 67 || keycode == 71) && !hotkey_prefix) {
1480 hotkey_prefix = keycode;
1481 debug("KP: PREFIX=" + keycode + " CHAR=" + keychar);
1485 if (Element.visible("hotkey_help_overlay")) {
1486 Element.hide("hotkey_help_overlay");
1489 if (keycode == 13 || keycode == 27) {
1492 seq = seq + "" + keycode;
1495 /* Global hotkeys */
1497 if (!hotkey_prefix) {
1499 if (keycode == 68 && shift_key) { // d
1500 if (!Element.visible("debug_output")) {
1501 Element.show("debug_output");
1502 debug('debug mode activated');
1504 Element.hide("debug_output");
1509 if ((keycode == 191 || keychar == '?') && shift_key) { // ?
1510 if (!Element.visible("hotkey_help_overlay")) {
1511 //Element.show("hotkey_help_overlay");
1512 Effect.Appear("hotkey_help_overlay", {duration : 0.3});
1514 Element.hide("hotkey_help_overlay");
1519 if (keycode == 191 || keychar == '/') { // /
1520 var search_boxes = new Array("label_search",
1521 "feed_search", "filter_search", "user_search", "feed_browser_search");
1523 for (var i = 0; i < search_boxes.length; i++) {
1524 var elem = document.getElementById(search_boxes[i]);
1526 focus_element(search_boxes[i]);
1535 if (hotkey_prefix == 67) { // c
1536 hotkey_prefix = false;
1538 if (keycode == 70) { // f
1539 displayDlg("quickAddFilter");
1543 if (keycode == 83) { // s
1544 displayDlg("quickAddFeed");
1548 /* if (keycode == 76) { // l
1549 displayDlg("quickAddLabel");
1553 if (keycode == 85) { // u
1557 if (keycode == 67) { // c
1562 if (keycode == 84 && shift_key) { // T
1571 if (hotkey_prefix == 71) { // g
1573 hotkey_prefix = false;
1575 if (keycode == 49 && document.getElementById("genConfigTab")) { // 1
1576 selectTab("genConfig");
1580 if (keycode == 50 && document.getElementById("feedConfigTab")) { // 2
1581 selectTab("feedConfig");
1585 if (keycode == 51 && document.getElementById("filterConfigTab")) { // 4
1586 selectTab("filterConfig");
1590 if (keycode == 52 && document.getElementById("labelConfigTab")) { // 5
1591 selectTab("labelConfig");
1595 if (keycode == 53 && document.getElementById("userConfigTab")) { // 6
1596 selectTab("userConfig");
1600 if (keycode == 88) { // x
1606 if (document.getElementById("piggie")) {
1608 if (seq.match("807371717369")) {
1616 if (hotkey_prefix) {
1617 debug("KP: PREFIX=" + hotkey_prefix + " CODE=" + keycode + " CHAR=" + keychar);
1619 debug("KP: CODE=" + keycode + " CHAR=" + keychar);
1623 exception_error("pref_hotkey_handler", e);
1627 function editFeedCats() {
1629 document.getElementById("subscribe_to_feed_btn").disabled = true;
1632 document.getElementById("top25_feeds_btn").disabled = true;
1634 // this button is not always available, no-op if not found
1637 var query = "backend.php?op=pref-feeds&subop=editCats";
1639 new Ajax.Request(query, {
1640 onComplete: function(transport) {
1641 infobox_feed_cat_callback2(transport);
1644 exception_error("editFeedCats", e);
1648 function showFeedsWithErrors() {
1649 displayDlg('feedUpdateErrors');
1652 function changeUserPassword() {
1656 if (!xmlhttp_ready(xmlhttp)) {
1657 printLockingError();
1661 var f = document.forms["change_pass_form"];
1664 if (f.OLD_PASSWORD.value == "") {
1665 new Effect.Highlight(f.OLD_PASSWORD);
1666 notify_error("Old password cannot be blank.");
1670 if (f.NEW_PASSWORD.value == "") {
1671 new Effect.Highlight(f.NEW_PASSWORD);
1672 notify_error("New password cannot be blank.");
1676 if (f.CONFIRM_PASSWORD.value == "") {
1677 new Effect.Highlight(f.CONFIRM_PASSWORD);
1678 notify_error("Entered passwords do not match.");
1682 if (f.CONFIRM_PASSWORD.value != f.NEW_PASSWORD.value) {
1683 new Effect.Highlight(f.CONFIRM_PASSWORD);
1684 new Effect.Highlight(f.NEW_PASSWORD);
1685 notify_error("Entered passwords do not match.");
1691 var query = Form.serialize("change_pass_form");
1693 notify_progress("Trying to change password...");
1695 xmlhttp.open("POST", "backend.php", true);
1696 xmlhttp.onreadystatechange=changepass_callback;
1697 xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
1698 xmlhttp.send(query);
1701 exception_error("changeUserPassword", e);
1707 function changeUserEmail() {
1711 if (!xmlhttp_ready(xmlhttp)) {
1712 printLockingError();
1716 var query = Form.serialize("change_email_form");
1718 notify_progress("Trying to change e-mail...");
1720 xmlhttp.open("POST", "backend.php", true);
1721 xmlhttp.onreadystatechange=notify_callback;
1722 xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
1723 xmlhttp.send(query);
1726 exception_error("changeUserPassword", e);
1733 function feedlistToggleSLAT() {
1734 notify_progress("Loading, please wait...");
1738 function pubRegenKey() {
1740 if (!xmlhttp_ready(xmlhttp)) {
1741 printLockingError();
1745 var ok = confirm(__("Replace current publishing address with a new one?"));
1749 notify_progress("Trying to change address...");
1751 xmlhttp.open("GET", "backend.php?op=rpc&subop=regenPubKey");
1752 xmlhttp.onreadystatechange=replace_pubkey_callback;
1759 function pubToClipboard() {
1763 if (!xmlhttp_ready(xmlhttp)) {
1764 printLockingError();
1768 var link = document.getElementById("pubGenAddress");
1772 exception_error("pubToClipboard", e);
1778 function validatePrefsSave() {
1781 var ok = confirm(__("Save current configuration?"));
1785 var query = Form.serialize("pref_prefs_form");
1786 query = query + "&subop=save-config";
1789 xmlhttp.open("POST", "backend.php", true);
1790 xmlhttp.onreadystatechange=notify_callback;
1791 xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
1792 xmlhttp.send(query);
1796 exception_error("validatePrefsSave", e);
1802 function feedActionChange() {
1804 var chooser = document.getElementById("feedActionChooser");
1805 var opid = chooser[chooser.selectedIndex].value;
1807 chooser.selectedIndex = 0;
1810 exception_error("feedActionChange", e);
1814 function feedActionGo(op) {
1816 if (op == "facEdit") {
1818 var rows = getSelectedFeeds();
1820 if (rows.length > 1) {
1821 editSelectedFeeds();
1827 if (op == "facClear") {
1828 clearSelectedFeeds();
1831 if (op == "facPurge") {
1832 purgeSelectedFeeds();
1835 if (op == "facEditCats") {
1839 if (op == "facRescore") {
1840 rescoreSelectedFeeds();
1843 if (op == "facUnsubscribe") {
1844 removeSelectedFeeds();
1848 exception_error("feedActionGo", e);
1853 function clearFeedArticles(feed_id) {
1855 notify_progress("Clearing feed...");
1857 var query = "backend.php?op=pref-feeds&quiet=1&subop=clear&id=" + feed_id;
1859 new Ajax.Request(query, {
1860 onComplete: function(transport) {
1867 function rescoreSelectedFeeds() {
1869 if (!xmlhttp_ready(xmlhttp)) {
1870 printLockingError();
1874 var sel_rows = getSelectedFeeds();
1876 if (sel_rows.length > 0) {
1878 //var ok = confirm(__("Rescore last 100 articles in selected feeds?"));
1879 var ok = confirm(__("Rescore articles in selected feeds?"));
1882 notify_progress("Rescoring selected feeds...", true);
1884 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=rescore&quiet=1&ids="+
1885 param_escape(sel_rows.toString()), true);
1886 xmlhttp.onreadystatechange=notify_callback;
1890 alert(__("No feeds are selected."));
1896 function rescore_all_feeds() {
1897 var ok = confirm(__("Rescore all articles? This operation may take a lot of time."));
1900 notify_progress("Rescoring feeds...", true);
1902 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=rescoreAll&quiet=1", true);
1903 xmlhttp.onreadystatechange=notify_callback;
1908 function removeFilter(id, title) {
1910 if (!xmlhttp_ready(xmlhttp)) {
1911 printLockingError();
1915 var msg = __("Remove filter %s?").replace("%s", title);
1917 var ok = confirm(msg);
1922 notify_progress("Removing filter...");
1924 xmlhttp.open("GET", "backend.php?op=pref-filters&subop=remove&ids="+
1925 param_escape(id), true);
1926 xmlhttp.onreadystatechange=filterlist_callback;
1933 function unsubscribeFeed(id, title) {
1935 if (!xmlhttp_ready(xmlhttp)) {
1936 printLockingError();
1940 var msg = __("Unsubscribe from %s?").replace("%s", title);
1942 var ok = confirm(msg);
1947 notify_progress("Removing feed...");
1949 xmlhttp.open("GET", "backend.php?op=pref-feeds&subop=remove&ids="+
1950 param_escape(id), true);
1951 xmlhttp.onreadystatechange=filterlist_callback;
1961 function feedsEditSave() {
1964 if (!xmlhttp_ready(xmlhttp)) {
1965 printLockingError();
1969 var ok = confirm(__("Save changes to selected feeds?"));
1973 var f = document.forms["batch_edit_feed_form"];
1975 var query = Form.serialize("batch_edit_feed_form");
1977 /* Form.serialize ignores unchecked checkboxes */
1979 if (!query.match("&hidden=") &&
1980 f.hidden.disabled == false) {
1981 query = query + "&hidden=false";
1984 if (!query.match("&rtl_content=") &&
1985 f.rtl_content.disabled == false) {
1986 query = query + "&rtl_content=false";
1989 if (!query.match("&private=") &&
1990 f.private.disabled == false) {
1991 query = query + "&private=false";
1994 if (!query.match("&cache_images=") &&
1995 f.cache_images.disabled == false) {
1996 query = query + "&cache_images=false";
1999 if (!query.match("&include_in_digest=") &&
2000 f.include_in_digest.disabled == false) {
2001 query = query + "&include_in_digest=false";
2006 notify_progress("Saving feeds...");
2008 xmlhttp.open("POST", "backend.php", true);
2009 xmlhttp.onreadystatechange=feedlist_callback;
2010 xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
2011 xmlhttp.send(query);
2016 exception_error("feedsEditSave", e);
2020 function batchFeedsToggleField(cb, elem, label) {
2022 var f = document.forms["batch_edit_feed_form"];
2023 var l = document.getElementById(label);
2026 f[elem].disabled = false;
2032 // new Effect.Highlight(f[elem], {duration: 1, startcolor: "#fff7d5",
2033 // queue: { position:'end', scope: 'BPEFQ', limit: 1 } } );
2036 f[elem].disabled = true;
2039 l.className = "insensitive";
2044 exception_error("batchFeedsToggleField", e);