1 var active_feed_cat = false;
2 var active_tab = false;
4 var init_params = new Array();
6 var caller_subop = false;
7 var sanity_check_done = false;
8 var hotkey_prefix = false;
9 var hotkey_prefix_pressed = false;
11 var color_picker_active = false;
12 var selection_disabled = false;
13 var mouse_is_down = false;
15 function feedlist_callback2(transport) {
19 var container = $('prefContent');
20 container.innerHTML=transport.responseText;
21 selectTab("feedConfig", true);
24 var tuple = caller_subop.split(":");
25 if (tuple[0] == 'editFeed') {
26 window.setTimeout('editFeed('+tuple[1]+')', 100);
31 if (typeof correctPNG != 'undefined') {
38 exception_error("feedlist_callback2", e);
42 /* stub for subscription dialog */
44 function dlg_frefresh_callback(transport) {
45 return feedlist_callback2(transport);
48 function filterlist_callback2(transport) {
49 var container = $('prefContent');
50 container.innerHTML=transport.responseText;
51 if (typeof correctPNG != 'undefined') {
58 function init_label_inline_editor() {
60 if ($("prefLabelList")) {
61 var elems = $("prefLabelList").getElementsByTagName("SPAN");
63 for (var i = 0; i < elems.length; i++) {
64 if (elems[i].id && elems[i].id.match("LILT-")) {
66 var id = elems[i].id.replace("LILT-", "");
68 new Ajax.InPlaceEditor(elems[i],
69 'backend.php?op=pref-labels&subop=save&id=' + id,
77 exception_error("init_label_inline_editor", e);
81 function labellist_callback2(transport) {
85 var container = $('prefContent');
87 container.innerHTML=transport.responseText;
89 init_label_inline_editor();
91 if (typeof correctPNG != 'undefined') {
98 exception_error("labellist_callback2", e);
102 function userlist_callback2(transport) {
104 var container = $('prefContent');
105 if (transport.readyState == 4) {
106 container.innerHTML=transport.responseText;
111 exception_error("userlist_callback2", e);
115 function prefslist_callback2(transport) {
117 var container = $('prefContent');
118 container.innerHTML=transport.responseText;
122 exception_error("prefslist_callback2", e);
126 function notify_callback2(transport) {
127 notify_info(transport.responseText);
130 function prefs_reset_callback2(transport) {
132 notify_info(transport.responseText);
135 exception_error("prefs_reset_callback2", e);
140 function changepass_callback2(transport) {
143 if (transport.responseText.indexOf("ERROR: ") == 0) {
144 notify_error(transport.responseText.replace("ERROR: ", ""));
146 notify_info(transport.responseText);
147 var warn = $("default_pass_warning");
148 if (warn) warn.style.display = "none";
151 document.forms['change_pass_form'].reset();
154 exception_error("changepass_callback2", e);
158 function init_cat_inline_editor() {
161 if ($("prefFeedCatList")) {
162 var elems = $("prefFeedCatList").getElementsByTagName("SPAN");
164 for (var i = 0; i < elems.length; i++) {
165 if (elems[i].id && elems[i].id.match("FCATT-")) {
166 var cat_id = elems[i].id.replace("FCATT-", "");
167 new Ajax.InPlaceEditor(elems[i],
168 'backend.php?op=pref-feeds&subop=editCats&action=save&cid=' + cat_id);
174 exception_error("init_cat_inline_editor", e);
178 function infobox_feed_cat_callback2(transport) {
180 infobox_callback2(transport);
181 init_cat_inline_editor();
183 exception_error("infobox_feed_cat_callback2", e);
187 function updateFeedList(sort_key) {
191 var feed_search = $("feed_search");
193 if (feed_search) { search = feed_search.value; }
195 var slat = $("show_last_article_times");
197 var slat_checked = false;
199 slat_checked = slat.checked;
202 var query = "?op=pref-feeds" +
203 "&sort=" + param_escape(sort_key) +
204 "&slat=" + param_escape(slat_checked) +
205 "&search=" + param_escape(search);
207 new Ajax.Request("backend.php", {
209 onComplete: function(transport) {
210 feedlist_callback2(transport);
213 exception_error("updateFeedList", e);
217 function updateUsersList(sort_key) {
221 var user_search = $("user_search");
223 if (user_search) { search = user_search.value; }
225 var query = "?op=pref-users&sort="
226 + param_escape(sort_key) +
227 "&search=" + param_escape(search);
229 new Ajax.Request("backend.php", {
231 onComplete: function(transport) {
232 userlist_callback2(transport);
236 exception_error("updateUsersList", e);
240 function addLabel() {
244 var caption = prompt(__("Please enter label caption:"), "");
246 if (caption == null) {
251 alert(__("Can't create label: missing caption."));
255 // we can be called from some other tab
256 active_tab = "labelConfig";
258 query = "?op=pref-labels&subop=add&caption=" +
259 param_escape(caption);
261 new Ajax.Request("backend.php", {
263 onComplete: function(transport) {
264 infobox_submit_callback2(transport);
268 exception_error("addLabel", e);
276 var link = $("fadd_link");
278 if (link.value.length == 0) {
279 alert(__("Error: No feed URL given."));
280 } else if (!isValidURL(link.value)) {
281 alert(__("Error: Invalid feed URL."));
283 notify_progress("Adding feed...");
285 var query = "?op=pref-feeds&subop=add&from=tt-rss&feed_url=" +
286 param_escape(link.value);
288 new Ajax.Request("backend.php", {
290 onComplete: function(transport) {
291 feedlist_callback2(transport);
299 exception_error("addFeed", e);
304 function addFeedCat() {
306 var cat = $("fadd_cat");
308 if (cat.value.length == 0) {
309 alert(__("Can't add category: no name specified."));
311 notify_progress("Adding feed category...");
313 var query = "?op=pref-feeds&subop=editCats&action=add&cat=" +
314 param_escape(cat.value);
316 new Ajax.Request("backend.php", {
318 onComplete: function(transport) {
319 infobox_feed_cat_callback2(transport);
331 var login = prompt(__("Please enter login:"), "");
338 alert(__("Can't create user: no login specified."));
342 notify_progress("Adding user...");
344 var query = "?op=pref-users&subop=add&login=" +
347 new Ajax.Request("backend.php", {
349 onComplete: function(transport) {
350 userlist_callback2(transport);
354 exception_error("addUser", e);
358 function editUser(id) {
364 notify_progress("Loading, please wait...");
366 selectTableRowsByIdPrefix('prefUserList', 'UMRR-', 'UMCHK-', false);
367 selectTableRowById('UMRR-'+id, 'UMCHK-'+id, true);
369 disableContainerChildren("userOpToolbar", false);
371 var query = "?op=pref-users&subop=edit&id=" +
374 new Ajax.Request("backend.php", {
376 onComplete: function(transport) {
377 infobox_callback2(transport);
381 exception_error("editUser", e);
386 function editFilter(id) {
392 notify_progress("Loading, please wait...");
394 disableContainerChildren("filterOpToolbar", false);
396 selectTableRowsByIdPrefix('prefFilterList', 'FILRR-', 'FICHK-', false);
397 selectTableRowById('FILRR-'+id, 'FICHK-'+id, true);
399 var query = "?op=pref-filters&subop=edit&id=" +
402 new Ajax.Request("backend.php", {
404 onComplete: function(transport) {
405 infobox_callback2(transport);
408 exception_error("editFilter", e);
412 function editFeed(feed) {
418 notify_progress("Loading, please wait...");
420 // clean selection from all rows & select row being edited
421 selectTableRowsByIdPrefix('prefFeedList', 'FEEDR-', 'FRCHK-', false);
422 selectTableRowById('FEEDR-'+feed, 'FRCHK-'+feed, true);
424 disableContainerChildren("feedOpToolbar", false);
426 var query = "?op=pref-feeds&subop=editfeed&id=" +
429 new Ajax.Request("backend.php", {
431 onComplete: function(transport) {
432 infobox_callback2(transport);
436 exception_error("editFeed", e);
440 function getSelectedLabels() {
441 return getSelectedTableRowIds("prefLabelList", "LILRR");
444 function getSelectedUsers() {
445 return getSelectedTableRowIds("prefUserList", "UMRR");
448 function getSelectedFeeds() {
449 return getSelectedTableRowIds("prefFeedList", "FEEDR");
452 function getSelectedFilters() {
453 return getSelectedTableRowIds("prefFilterList", "FILRR");
456 function getSelectedFeedCats() {
457 return getSelectedTableRowIds("prefFeedCatList", "FCATR");
461 function removeSelectedLabels() {
463 var sel_rows = getSelectedLabels();
465 if (sel_rows.length > 0) {
467 var ok = confirm(__("Remove selected labels?"));
470 notify_progress("Removing selected labels...");
472 var query = "?op=pref-labels&subop=remove&ids="+
473 param_escape(sel_rows.toString());
475 new Ajax.Request("backend.php", {
477 onComplete: function(transport) {
478 labellist_callback2(transport);
483 alert(__("No labels are selected."));
489 function removeSelectedUsers() {
493 var sel_rows = getSelectedUsers();
495 if (sel_rows.length > 0) {
497 var ok = confirm(__("Remove selected users?"));
500 notify_progress("Removing selected users...");
502 var query = "?op=pref-users&subop=remove&ids="+
503 param_escape(sel_rows.toString());
505 new Ajax.Request("backend.php", {
507 onComplete: function(transport) {
508 userlist_callback2(transport);
514 alert(__("No users are selected."));
518 exception_error("removeSelectedUsers", e);
524 function removeSelectedFilters() {
528 var sel_rows = getSelectedFilters();
530 if (sel_rows.length > 0) {
532 var ok = confirm(__("Remove selected filters?"));
535 notify_progress("Removing selected filters...");
537 var query = "?op=pref-filters&subop=remove&ids="+
538 param_escape(sel_rows.toString());
540 new Ajax.Request("backend.php", {
542 onComplete: function(transport) {
543 filterlist_callback2(transport);
548 alert(__("No filters are selected."));
552 exception_error("removeSelectedFilters", e);
559 function removeSelectedFeeds() {
563 var sel_rows = getSelectedFeeds();
565 if (sel_rows.length > 0) {
567 var ok = confirm(__("Unsubscribe from selected feeds?"));
571 notify_progress("Unsubscribing from selected feeds...");
573 var query = "?op=pref-feeds&subop=remove&ids="+
574 param_escape(sel_rows.toString());
576 new Ajax.Request("backend.php", {
578 onComplete: function(transport) {
579 feedlist_callback2(transport);
584 alert(__("No feeds are selected."));
588 exception_error("removeSelectedFeeds", e);
594 function clearSelectedFeeds() {
596 var sel_rows = getSelectedFeeds();
598 if (sel_rows.length > 1) {
599 alert(__("Please select only one feed."));
603 if (sel_rows.length > 0) {
605 var ok = confirm(__("Erase all non-starred articles in selected feed?"));
608 notify_progress("Clearing selected feed...");
609 clearFeedArticles(sel_rows[0]);
614 alert(__("No feeds are selected."));
621 function purgeSelectedFeeds() {
623 var sel_rows = getSelectedFeeds();
625 if (sel_rows.length > 0) {
627 var pr = prompt(__("How many days of articles to keep (0 - use default)?"), "0");
629 if (pr != undefined) {
630 notify_progress("Purging selected feed...");
632 var query = "?op=rpc&subop=purge&ids="+
633 param_escape(sel_rows.toString()) + "&days=" + pr;
637 new Ajax.Request("prefs.php", {
639 onComplete: function(transport) {
646 alert(__("No feeds are selected."));
653 function removeSelectedFeedCats() {
655 var sel_rows = getSelectedFeedCats();
657 if (sel_rows.length > 0) {
659 var ok = confirm(__("Remove selected categories?"));
662 notify_progress("Removing selected categories...");
664 var query = "?op=pref-feeds&subop=editCats&action=remove&ids="+
665 param_escape(sel_rows.toString());
667 new Ajax.Request("backend.php", {
669 onComplete: function(transport) {
670 infobox_feed_cat_callback2(transport);
677 alert(__("No categories are selected."));
684 function feedEditCancel() {
688 selectPrefRows('feed', false); // cleanup feed selection
693 function feedEditSave() {
697 // FIXME: add parameter validation
699 var query = Form.serialize("edit_feed_form");
701 notify_progress("Saving feed...");
703 new Ajax.Request("backend.php", {
705 onComplete: function(transport) {
706 feedlist_callback2(transport);
714 exception_error("feedEditSave", e);
718 function userEditCancel() {
720 selectPrefRows('user', false); // cleanup feed selection
726 function filterEditCancel() {
729 selectPrefRows('filter', false); // cleanup feed selection
737 function userEditSave() {
741 var login = document.forms["user_edit_form"].login.value;
743 if (login.length == 0) {
744 alert(__("Login field cannot be blank."));
748 notify_progress("Saving user...");
752 var query = Form.serialize("user_edit_form");
754 new Ajax.Request("backend.php", {
756 onComplete: function(transport) {
757 userlist_callback2(transport);
761 exception_error("userEditSave", e);
769 function filterEditSave() {
773 notify_progress("Saving filter...");
775 var query = "?" + Form.serialize("filter_edit_form");
779 new Ajax.Request("backend.php", {
781 onComplete: function(transport) {
782 filterlist_callback2(transport);
786 exception_error("filterEditSave", e);
793 function editSelectedUser() {
794 var rows = getSelectedUsers();
796 if (rows.length == 0) {
797 alert(__("No users are selected."));
801 if (rows.length > 1) {
802 alert(__("Please select only one user."));
811 function resetSelectedUserPass() {
815 var rows = getSelectedUsers();
817 if (rows.length == 0) {
818 alert(__("No users are selected."));
822 if (rows.length > 1) {
823 alert(__("Please select only one user."));
827 var ok = confirm(__("Reset password of selected user?"));
830 notify_progress("Resetting password for selected user...");
834 var query = "?op=pref-users&subop=resetPass&id=" +
837 new Ajax.Request("backend.php", {
839 onComplete: function(transport) {
840 userlist_callback2(transport);
846 exception_error("resetSelectedUserPass", e);
850 function selectedUserDetails() {
854 var rows = getSelectedUsers();
856 if (rows.length == 0) {
857 alert(__("No users are selected."));
861 if (rows.length > 1) {
862 alert(__("Please select only one user."));
866 notify_progress("Loading, please wait...");
870 var query = "?op=pref-users&subop=user-details&id=" + id;
872 new Ajax.Request("backend.php", {
874 onComplete: function(transport) {
875 infobox_callback2(transport);
878 exception_error("selectedUserDetails", e);
883 function editSelectedFilter() {
884 var rows = getSelectedFilters();
886 if (rows.length == 0) {
887 alert(__("No filters are selected."));
891 if (rows.length > 1) {
892 alert(__("Please select only one filter."));
903 function editSelectedFeed() {
904 var rows = getSelectedFeeds();
906 if (rows.length == 0) {
907 alert(__("No feeds are selected."));
911 if (rows.length > 1) {
912 return editSelectedFeeds();
921 function editSelectedFeeds() {
924 var rows = getSelectedFeeds();
926 if (rows.length == 0) {
927 alert(__("No feeds are selected."));
935 notify_progress("Loading, please wait...");
937 var query = "?op=pref-feeds&subop=editfeeds&ids=" +
938 param_escape(rows.toString());
940 new Ajax.Request("backend.php", {
942 onComplete: function(transport) {
943 infobox_callback2(transport);
947 exception_error("editSelectedFeeds", e);
951 function piggie(enable) {
953 debug("I LOVEDED IT!");
954 var piggie = $("piggie");
956 Element.show(piggie);
957 Position.Center(piggie);
963 function validateOpmlImport() {
965 var opml_file = $("opml_file");
967 if (opml_file.value.length == 0) {
968 alert(__("No OPML file to upload."));
975 function updateFilterList(sort_key) {
978 var filter_search = $("filter_search");
980 if (filter_search) { search = filter_search.value; }
982 var query = "?op=pref-filters&sort=" +
983 param_escape(sort_key) +
984 "&search=" + param_escape(search);
986 new Ajax.Request("backend.php", {
988 onComplete: function(transport) {
989 filterlist_callback2(transport);
993 exception_error("updateFilterList", e);
998 function updateLabelList(sort_key) {
1002 var label_search = $("label_search");
1004 if (label_search) { search = label_search.value; }
1006 var query = "?op=pref-labels&sort=" +
1007 param_escape(sort_key) +
1008 "&search=" + param_escape(search);
1010 new Ajax.Request("backend.php", {
1012 onComplete: function(transport) {
1013 labellist_callback2(transport);
1017 exception_error("updateLabelList", e);
1021 function updatePrefsList() {
1023 var query = "?op=pref-prefs";
1025 new Ajax.Request("backend.php", {
1027 onComplete: function(transport) {
1028 prefslist_callback2(transport);
1033 function selectTab(id, noupdate, subop) {
1037 if (!id) id = active_tab;
1042 if (id != active_tab) {
1043 var c = $('prefContent');
1050 debug("selectTab: " + id + "(NU: " + noupdate + ")");
1052 notify_progress("Loading, please wait...");
1054 // close active infobox if needed
1057 // clean up all current selections, just in case
1058 active_feed_cat = false;
1060 // Effect.Fade("prefContent", {duration: 1, to: 0.01,
1061 // queue: { position:'end', scope: 'FEED_TAB', limit: 1 } } );
1063 if (id == "feedConfig") {
1065 } else if (id == "filterConfig") {
1067 } else if (id == "labelConfig") {
1069 } else if (id == "genConfig") {
1071 } else if (id == "userConfig") {
1076 /* clean selection from all tabs */
1078 var tabs_holder = $("prefTabs");
1079 var tab = tabs_holder.firstChild;
1082 if (tab.className && tab.className.match("prefsTabSelected")) {
1083 tab.className = "prefsTab";
1085 tab = tab.nextSibling;
1088 /* mark new tab as selected */
1090 tab = $(id + "Tab");
1093 if (!tab.className.match("Selected")) {
1094 tab.className = tab.className + "Selected";
1101 exception_error("selectTab", e);
1105 function backend_sanity_check_callback2(transport) {
1109 if (sanity_check_done) {
1110 fatalError(11, "Sanity check request received twice. This can indicate "+
1111 "presence of Firebug or some other disrupting extension. "+
1112 "Please disable it and try again.");
1116 if (!transport.responseXML) {
1117 fatalError(3, "Sanity Check: Received reply is not XML",
1118 transport.responseText);
1122 var reply = transport.responseXML.firstChild.firstChild;
1125 fatalError(3, "Sanity Check: Invalid RPC reply", transport.responseText);
1129 var error_code = reply.getAttribute("error-code");
1131 if (error_code && error_code != 0) {
1132 return fatalError(error_code, reply.getAttribute("error-msg"));
1135 debug("sanity check ok");
1137 var params = reply.nextSibling;
1140 debug('reading init-params...');
1141 var param = params.firstChild;
1144 var k = param.getAttribute("key");
1145 var v = param.getAttribute("value");
1146 debug(k + " => " + v);
1148 param = param.nextSibling;
1152 sanity_check_done = true;
1154 init_second_stage();
1157 exception_error("backend_sanity_check_callback", e);
1161 function init_second_stage() {
1164 active_tab = getInitParam("prefs_active_tab");
1165 if (!$(active_tab+"Tab")) active_tab = "genConfig";
1166 if (!active_tab || active_tab == '0') active_tab = "genConfig";
1168 document.onkeydown = pref_hotkey_handler;
1169 document.onmousedown = mouse_down_handler;
1170 document.onmouseup = mouse_up_handler;
1172 var tab = getURLParam('tab');
1174 caller_subop = getURLParam('subop');
1176 if (getURLParam("subopparam")) {
1177 caller_subop = caller_subop + ":" + getURLParam("subopparam");
1184 if (navigator.userAgent.match("Opera")) {
1185 setTimeout("selectTab()", 500);
1187 selectTab(active_tab);
1191 loading_set_progress(60);
1193 setTimeout("hotkey_prefix_timeout()", 5*1000);
1196 exception_error("init_second_stage", e);
1204 if (getURLParam('debug')) {
1205 Element.show("debug_output");
1206 debug('debug mode activated');
1209 loading_set_progress(30);
1211 var query = "?op=rpc&subop=sanityCheck";
1213 new Ajax.Request("backend.php", {
1215 onComplete: function(transport) {
1216 backend_sanity_check_callback2(transport);
1220 exception_error("init", e);
1224 function categorizeSelectedFeeds() {
1226 var sel_rows = getSelectedFeeds();
1228 var cat_sel = $("sfeed_set_fcat");
1229 var cat_id = cat_sel[cat_sel.selectedIndex].value;
1231 if (sel_rows.length > 0) {
1233 notify_progress("Changing category of selected feeds...");
1235 var query = "?op=pref-feeds&subop=categorize&ids="+
1236 param_escape(sel_rows.toString()) + "&cat_id=" + param_escape(cat_id);
1238 new Ajax.Request("backend.php", {
1240 onComplete: function(transport) {
1241 feedlist_callback2(transport);
1246 alert(__("No feeds are selected."));
1252 function validatePrefsReset() {
1254 var ok = confirm(__("Reset to defaults?"));
1258 var query = Form.serialize("pref_prefs_form");
1259 query = query + "&subop=reset-config";
1262 new Ajax.Request("backend.php", {
1264 onComplete: function(transport) {
1265 prefs_reset_callback2(transport);
1271 exception_error("validatePrefsSave", e);
1278 function feedBrowserSubscribe() {
1281 var selected = getSelectedFeedsFromBrowser();
1283 var mode = document.forms['feed_browser'].mode;
1285 mode = mode[mode.selectedIndex].value;
1287 if (selected.length > 0) {
1290 var query = "?op=pref-feeds&subop=massSubscribe&ids="+
1291 param_escape(selected.toString()) + "&mode=" + param_escape(mode);
1293 new Ajax.Request("backend.php", {
1295 onComplete: function(transport) {
1296 feedlist_callback2(transport);
1300 alert(__("No feeds are selected."));
1304 exception_error("feedBrowserSubscribe", e);
1308 function updateBigFeedBrowserBtn() {
1309 notify_progress("Loading, please wait...");
1310 return updateBigFeedBrowser();
1313 function selectPrefRows(kind, select) {
1316 var opbarid = false;
1321 if (kind == "feed") {
1322 opbarid = "feedOpToolbar";
1325 lname = "prefFeedList";
1326 } else if (kind == "fcat") {
1327 opbarid = "catOpToolbar";
1330 lname = "prefFeedCatList";
1331 } else if (kind == "filter") {
1332 opbarid = "filterOpToolbar";
1335 lname = "prefFilterList";
1336 } else if (kind == "label") {
1337 opbarid = "labelOpToolbar";
1340 lname = "prefLabelList";
1341 } else if (kind == "user") {
1342 opbarid = "userOpToolbar";
1345 lname = "prefUserList";
1349 selectTableRowsByIdPrefix(lname, nrow, nchk, select);
1350 disableContainerChildren(opbarid, !select);
1357 function toggleSelectPrefRow(sender, kind) {
1359 toggleSelectRow(sender);
1362 var opbarid = false;
1365 if (kind == "feed") {
1366 opbarid = "feedOpToolbar";
1367 nsel = getSelectedFeeds();
1368 } else if (kind == "fcat") {
1369 opbarid = "catOpToolbar";
1370 nsel = getSelectedFeedCats();
1371 } else if (kind == "filter") {
1372 opbarid = "filterOpToolbar";
1373 nsel = getSelectedFilters();
1374 } else if (kind == "label") {
1375 opbarid = "labelOpToolbar";
1376 nsel = getSelectedLabels();
1377 } else if (kind == "user") {
1378 opbarid = "userOpToolbar";
1379 nsel = getSelectedUsers();
1382 if (opbarid && nsel != -1) {
1383 disableContainerChildren(opbarid, nsel == false);
1389 function toggleSelectFBListRow(sender) {
1390 toggleSelectListRow(sender);
1391 disableContainerChildren("fbrOpToolbar", getSelectedFeedsFromBrowser() == 0);
1396 function pref_hotkey_handler(e) {
1400 var shift_key = false;
1402 var cmdline = $('cmdline');
1405 shift_key = e.shiftKey;
1411 keycode = window.event.keyCode;
1416 var keychar = String.fromCharCode(keycode);
1418 if (keycode == 27) { // escape
1419 if (Element.visible("hotkey_help_overlay")) {
1420 Element.hide("hotkey_help_overlay");
1422 colorPickerHideAll();
1423 hotkey_prefix = false;
1427 if (!hotkeys_enabled) {
1428 debug("hotkeys disabled");
1432 if (keycode == 16) return; // ignore lone shift
1434 if ((keycode == 67 || keycode == 71) && !hotkey_prefix) {
1435 hotkey_prefix = keycode;
1437 var date = new Date();
1438 var ts = Math.round(date.getTime() / 1000);
1440 hotkey_prefix_pressed = ts;
1442 cmdline.innerHTML = keychar;
1443 Element.show(cmdline);
1445 debug("KP: PREFIX=" + keycode + " CHAR=" + keychar);
1449 if (Element.visible("hotkey_help_overlay")) {
1450 Element.hide("hotkey_help_overlay");
1453 if (keycode == 13 || keycode == 27) {
1456 seq = seq + "" + keycode;
1459 /* Global hotkeys */
1461 Element.hide(cmdline);
1463 if (!hotkey_prefix) {
1465 if (keycode == 68 && shift_key) { // d
1466 if (!Element.visible("debug_output")) {
1467 Element.show("debug_output");
1468 debug('debug mode activated');
1470 Element.hide("debug_output");
1475 if ((keycode == 191 || keychar == '?') && shift_key) { // ?
1476 if (!Element.visible("hotkey_help_overlay")) {
1477 //Element.show("hotkey_help_overlay");
1478 Effect.Appear("hotkey_help_overlay", {duration : 0.3});
1480 Element.hide("hotkey_help_overlay");
1485 if (keycode == 191 || keychar == '/') { // /
1486 var search_boxes = new Array("label_search",
1487 "feed_search", "filter_search", "user_search", "feed_browser_search");
1489 for (var i = 0; i < search_boxes.length; i++) {
1490 var elem = $(search_boxes[i]);
1492 focus_element(search_boxes[i]);
1501 if (hotkey_prefix == 67) { // c
1502 hotkey_prefix = false;
1504 if (keycode == 70) { // f
1505 displayDlg("quickAddFilter");
1509 if (keycode == 83) { // s
1510 displayDlg("quickAddFeed");
1514 /* if (keycode == 76) { // l
1515 displayDlg("quickAddLabel");
1519 if (keycode == 85) { // u
1523 if (keycode == 67) { // c
1528 if (keycode == 84 && shift_key) { // T
1537 if (hotkey_prefix == 71) { // g
1539 hotkey_prefix = false;
1541 if (keycode == 49 && $("genConfigTab")) { // 1
1542 selectTab("genConfig");
1546 if (keycode == 50 && $("feedConfigTab")) { // 2
1547 selectTab("feedConfig");
1551 if (keycode == 51 && $("filterConfigTab")) { // 4
1552 selectTab("filterConfig");
1556 if (keycode == 52 && $("labelConfigTab")) { // 5
1557 selectTab("labelConfig");
1561 if (keycode == 53 && $("userConfigTab")) { // 6
1562 selectTab("userConfig");
1566 if (keycode == 88) { // x
1574 if (seq.match("807371717369")) {
1582 if (hotkey_prefix) {
1583 debug("KP: PREFIX=" + hotkey_prefix + " CODE=" + keycode + " CHAR=" + keychar);
1585 debug("KP: CODE=" + keycode + " CHAR=" + keychar);
1589 exception_error("pref_hotkey_handler", e);
1593 function editFeedCats() {
1595 var query = "?op=pref-feeds&subop=editCats";
1597 new Ajax.Request("backend.php", {
1599 onComplete: function(transport) {
1600 infobox_feed_cat_callback2(transport);
1603 exception_error("editFeedCats", e);
1607 function showFeedsWithErrors() {
1608 displayDlg('feedUpdateErrors');
1611 function changeUserPassword() {
1615 var f = document.forms["change_pass_form"];
1618 if (f.OLD_PASSWORD.value == "") {
1619 new Effect.Highlight(f.OLD_PASSWORD);
1620 notify_error("Old password cannot be blank.");
1624 if (f.NEW_PASSWORD.value == "") {
1625 new Effect.Highlight(f.NEW_PASSWORD);
1626 notify_error("New password cannot be blank.");
1630 if (f.CONFIRM_PASSWORD.value == "") {
1631 new Effect.Highlight(f.CONFIRM_PASSWORD);
1632 notify_error("Entered passwords do not match.");
1636 if (f.CONFIRM_PASSWORD.value != f.NEW_PASSWORD.value) {
1637 new Effect.Highlight(f.CONFIRM_PASSWORD);
1638 new Effect.Highlight(f.NEW_PASSWORD);
1639 notify_error("Entered passwords do not match.");
1645 var query = Form.serialize("change_pass_form");
1647 notify_progress("Trying to change password...");
1649 new Ajax.Request("backend.php", {
1651 onComplete: function(transport) {
1652 changepass_callback2(transport);
1657 exception_error("changeUserPassword", e);
1663 function changeUserEmail() {
1667 var query = Form.serialize("change_email_form");
1669 notify_progress("Trying to change e-mail...");
1671 new Ajax.Request("backend.php", {
1673 onComplete: function(transport) {
1674 notify_callback2(transport);
1678 exception_error("changeUserPassword", e);
1685 function feedlistToggleSLAT() {
1686 notify_progress("Loading, please wait...");
1690 function pubRegenKey() {
1693 var ok = confirm(__("Replace current publishing address with a new one?"));
1697 notify_progress("Trying to change address...", true);
1699 var query = "?op=rpc&subop=regenPubKey";
1701 new Ajax.Request("backend.php", {
1703 onComplete: function(transport) {
1704 var new_link = transport.responseXML.getElementsByTagName("link")[0];
1706 var e = $('pub_feed_url');
1709 e.href = new_link.firstChild.nodeValue;
1710 e.innerHTML = new_link.firstChild.nodeValue;
1712 new Effect.Highlight(e);
1717 notify_error("Could not change feed URL.");
1722 exception_error("pubRegenKey", e);
1727 function validatePrefsSave() {
1730 var ok = confirm(__("Save current configuration?"));
1734 var query = Form.serialize("pref_prefs_form");
1735 query = query + "&subop=save-config";
1738 new Ajax.Request("backend.php", {
1740 onComplete: function(transport) {
1741 notify_callback2(transport);
1747 exception_error("validatePrefsSave", e);
1753 function feedActionChange() {
1755 var chooser = $("feedActionChooser");
1756 var opid = chooser[chooser.selectedIndex].value;
1758 chooser.selectedIndex = 0;
1761 exception_error("feedActionChange", e);
1765 function feedActionGo(op) {
1767 if (op == "facEdit") {
1769 var rows = getSelectedFeeds();
1771 if (rows.length > 1) {
1772 editSelectedFeeds();
1778 if (op == "facClear") {
1779 clearSelectedFeeds();
1782 if (op == "facPurge") {
1783 purgeSelectedFeeds();
1786 if (op == "facEditCats") {
1790 if (op == "facRescore") {
1791 rescoreSelectedFeeds();
1794 if (op == "facUnsubscribe") {
1795 removeSelectedFeeds();
1799 exception_error("feedActionGo", e);
1804 function clearFeedArticles(feed_id) {
1806 notify_progress("Clearing feed...");
1808 var query = "?op=pref-feeds&quiet=1&subop=clear&id=" + feed_id;
1810 new Ajax.Request("backend.php", {
1812 onComplete: function(transport) {
1819 function rescoreSelectedFeeds() {
1821 var sel_rows = getSelectedFeeds();
1823 if (sel_rows.length > 0) {
1825 //var ok = confirm(__("Rescore last 100 articles in selected feeds?"));
1826 var ok = confirm(__("Rescore articles in selected feeds?"));
1829 notify_progress("Rescoring selected feeds...", true);
1831 var query = "?op=pref-feeds&subop=rescore&quiet=1&ids="+
1832 param_escape(sel_rows.toString());
1834 new Ajax.Request("backend.php", {
1836 onComplete: function(transport) {
1837 notify_callback2(transport);
1842 alert(__("No feeds are selected."));
1848 function rescore_all_feeds() {
1849 var ok = confirm(__("Rescore all articles? This operation may take a lot of time."));
1852 notify_progress("Rescoring feeds...", true);
1854 var query = "?op=pref-feeds&subop=rescoreAll&quiet=1";
1856 new Ajax.Request("backend.php", {
1858 onComplete: function(transport) {
1859 notify_callback2(transport);
1864 function removeFilter(id, title) {
1868 var msg = __("Remove filter %s?").replace("%s", title);
1870 var ok = confirm(msg);
1875 notify_progress("Removing filter...");
1877 var query = "?op=pref-filters&subop=remove&ids="+
1880 new Ajax.Request("backend.php", {
1882 onComplete: function(transport) {
1883 filterlist_callback2(transport);
1889 exception_error("removeFilter", e);
1895 function unsubscribeFeed(id, title) {
1899 var msg = __("Unsubscribe from %s?").replace("%s", title);
1901 var ok = confirm(msg);
1906 notify_progress("Removing feed...");
1908 var query = "?op=pref-feeds&subop=remove&ids="+
1911 new Ajax.Request("backend.php", {
1913 onComplete: function(transport) {
1914 feedlist_callback2(transport);
1919 exception_error("unsubscribeFeed", e);
1926 function feedsEditSave() {
1929 var ok = confirm(__("Save changes to selected feeds?"));
1933 var f = document.forms["batch_edit_feed_form"];
1935 var query = Form.serialize("batch_edit_feed_form");
1937 /* Form.serialize ignores unchecked checkboxes */
1939 if (!query.match("&hidden=") &&
1940 f.hidden.disabled == false) {
1941 query = query + "&hidden=false";
1944 if (!query.match("&rtl_content=") &&
1945 f.rtl_content.disabled == false) {
1946 query = query + "&rtl_content=false";
1949 if (!query.match("&private=") &&
1950 f.private.disabled == false) {
1951 query = query + "&private=false";
1954 if (!query.match("&cache_images=") &&
1955 f.cache_images.disabled == false) {
1956 query = query + "&cache_images=false";
1959 if (!query.match("&include_in_digest=") &&
1960 f.include_in_digest.disabled == false) {
1961 query = query + "&include_in_digest=false";
1966 notify_progress("Saving feeds...");
1968 new Ajax.Request("backend.php", {
1970 onComplete: function(transport) {
1971 feedlist_callback2(transport);
1978 exception_error("feedsEditSave", e);
1982 function batchFeedsToggleField(cb, elem, label) {
1984 var f = document.forms["batch_edit_feed_form"];
1988 f[elem].disabled = false;
1994 // new Effect.Highlight(f[elem], {duration: 1, startcolor: "#fff7d5",
1995 // queue: { position:'end', scope: 'BPEFQ', limit: 1 } } );
1998 f[elem].disabled = true;
2001 l.className = "insensitive";
2006 exception_error("batchFeedsToggleField", e);
2010 function labelColorReset() {
2012 var labels = getSelectedLabels();
2014 var ok = confirm(__("Reset label colors to default?"));
2018 var query = "?op=pref-labels&subop=color-reset&ids="+
2019 param_escape(labels.toString());
2021 new Ajax.Request("backend.php", {
2023 onComplete: function(transport) {
2024 labellist_callback2(transport);
2029 exception_error("labelColorReset", e);
2033 function labelColorAsk(id, kind) {
2039 p = prompt(__("Please enter new label foreground color:"));
2041 p = prompt(__("Please enter new label background color:"));
2046 var query = "?op=pref-labels&subop=color-set&kind=" + kind +
2047 "&ids="+ param_escape(id) + "&color=" + param_escape(p);
2049 selectPrefRows('label', false);
2051 var e = $("LICID-" + id);
2057 e.style.backgroundColor = p;
2061 new Ajax.Request("backend.php", { parameters: query });
2065 exception_error("labelColorReset", e);
2070 function colorPicker(id, fg, bg) {
2072 var picker = $("colorPicker-" + id);
2074 if (picker) Element.show(picker);
2077 exception_error("colorPicker", e);
2081 function colorPickerHideAll() {
2083 if ($("prefLabelList")) {
2085 var elems = $("prefLabelList").getElementsByTagName("DIV");
2087 for (var i = 0; i < elems.length; i++) {
2088 if (elems[i].id && elems[i].id.match("colorPicker-")) {
2089 Element.hide(elems[i]);
2095 exception_error("colorPickerHideAll", e);
2099 function colorPickerDo(id, fg, bg) {
2102 var query = "?op=pref-labels&subop=color-set&kind=both"+
2103 "&ids=" + param_escape(id) + "&fg=" + param_escape(fg) +
2104 "&bg=" + param_escape(bg);
2106 var e = $("LICID-" + id);
2110 e.style.backgroundColor = bg;
2113 new Ajax.Request("backend.php", { parameters: query });
2116 exception_error("colorPickerDo", e);
2120 function colorPickerActive(b) {
2121 color_picker_active = b;
2124 function mouse_down_handler(e) {
2127 /* do not prevent right click */
2128 if (e && e.button && e.button == 2) return;
2130 if (selection_disabled) {
2131 document.onselectstart = function() { return false; };
2136 exception_error("mouse_down_handler", e);
2140 function mouse_up_handler(e) {
2142 mouse_is_down = false;
2144 if (!selection_disabled) {
2145 document.onselectstart = null;
2148 if (!color_picker_active) {
2149 colorPickerHideAll();
2153 exception_error("mouse_up_handler", e);