prefs.js 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678
  1. var init_params = new Array();
  2. var hotkey_prefix = false;
  3. var hotkey_prefix_pressed = false;
  4. var seq = "";
  5. function notify_callback2(transport, sticky) {
  6. notify_info(transport.responseText, sticky);
  7. }
  8. function updateFeedList(sort_key) {
  9. var user_search = $("feed_search");
  10. var search = "";
  11. if (user_search) { search = user_search.value; }
  12. new Ajax.Request("backend.php", {
  13. parameters: "?op=pref-feeds&search=" + param_escape(search),
  14. onComplete: function(transport) {
  15. dijit.byId('feedConfigTab').attr('content', transport.responseText);
  16. selectTab("feedConfig", true);
  17. notify("");
  18. } });
  19. }
  20. function checkInactiveFeeds() {
  21. new Ajax.Request("backend.php", {
  22. parameters: "?op=pref-feeds&method=getinactivefeeds",
  23. onComplete: function (transport) {
  24. if (parseInt(transport.responseText) > 0) {
  25. Element.show(dijit.byId("pref_feeds_inactive_btn").domNode);
  26. }
  27. }
  28. });
  29. }
  30. function updateUsersList(sort_key) {
  31. var user_search = $("user_search");
  32. var search = "";
  33. if (user_search) {
  34. search = user_search.value;
  35. }
  36. var query = "?op=pref-users&sort="
  37. + param_escape(sort_key) +
  38. "&search=" + param_escape(search);
  39. new Ajax.Request("backend.php", {
  40. parameters: query,
  41. onComplete: function (transport) {
  42. dijit.byId('userConfigTab').attr('content', transport.responseText);
  43. selectTab("userConfig", true)
  44. notify("");
  45. }
  46. });
  47. }
  48. function addUser() {
  49. var login = prompt(__("Please enter login:"), "");
  50. if (login == null) {
  51. return false;
  52. }
  53. if (login == "") {
  54. alert(__("Can't create user: no login specified."));
  55. return false;
  56. }
  57. notify_progress("Adding user...");
  58. var query = "?op=pref-users&method=add&login=" +
  59. param_escape(login);
  60. new Ajax.Request("backend.php", {
  61. parameters: query,
  62. onComplete: function (transport) {
  63. notify_callback2(transport);
  64. updateUsersList();
  65. }
  66. });
  67. }
  68. function editUser(id, event) {
  69. var query = "backend.php?op=pref-users&method=edit&id=" +
  70. param_escape(id);
  71. if (dijit.byId("userEditDlg"))
  72. dijit.byId("userEditDlg").destroyRecursive();
  73. dialog = new dijit.Dialog({
  74. id: "userEditDlg",
  75. title: __("User Editor"),
  76. style: "width: 600px",
  77. execute: function () {
  78. if (this.validate()) {
  79. notify_progress("Saving data...", true);
  80. var query = dojo.formToQuery("user_edit_form");
  81. new Ajax.Request("backend.php", {
  82. parameters: query,
  83. onComplete: function (transport) {
  84. dialog.hide();
  85. updateUsersList();
  86. }
  87. });
  88. }
  89. },
  90. href: query
  91. });
  92. dialog.show();
  93. }
  94. function editFilter(id) {
  95. var query = "backend.php?op=pref-filters&method=edit&id=" + param_escape(id);
  96. if (dijit.byId("feedEditDlg"))
  97. dijit.byId("feedEditDlg").destroyRecursive();
  98. if (dijit.byId("filterEditDlg"))
  99. dijit.byId("filterEditDlg").destroyRecursive();
  100. dialog = new dijit.Dialog({
  101. id: "filterEditDlg",
  102. title: __("Edit Filter"),
  103. style: "width: 600px",
  104. test: function () {
  105. var query = "backend.php?" + dojo.formToQuery("filter_edit_form") + "&savemode=test";
  106. editFilterTest(query);
  107. },
  108. selectRules: function (select) {
  109. $$("#filterDlg_Matches input[type=checkbox]").each(function (e) {
  110. e.checked = select;
  111. if (select)
  112. e.parentNode.addClassName("Selected");
  113. else
  114. e.parentNode.removeClassName("Selected");
  115. });
  116. },
  117. selectActions: function (select) {
  118. $$("#filterDlg_Actions input[type=checkbox]").each(function (e) {
  119. e.checked = select;
  120. if (select)
  121. e.parentNode.addClassName("Selected");
  122. else
  123. e.parentNode.removeClassName("Selected");
  124. });
  125. },
  126. editRule: function (e) {
  127. var li = e.parentNode;
  128. var rule = li.getElementsByTagName("INPUT")[1].value;
  129. addFilterRule(li, rule);
  130. },
  131. editAction: function (e) {
  132. var li = e.parentNode;
  133. var action = li.getElementsByTagName("INPUT")[1].value;
  134. addFilterAction(li, action);
  135. },
  136. removeFilter: function () {
  137. var msg = __("Remove filter?");
  138. if (confirm(msg)) {
  139. this.hide();
  140. notify_progress("Removing filter...");
  141. var id = this.attr('value').id;
  142. var query = "?op=pref-filters&method=remove&ids=" +
  143. param_escape(id);
  144. new Ajax.Request("backend.php", {
  145. parameters: query,
  146. onComplete: function (transport) {
  147. updateFilterList();
  148. }
  149. });
  150. }
  151. },
  152. addAction: function () {
  153. addFilterAction();
  154. },
  155. addRule: function () {
  156. addFilterRule();
  157. },
  158. deleteAction: function () {
  159. $$("#filterDlg_Actions li[class*=Selected]").each(function (e) {
  160. e.parentNode.removeChild(e)
  161. });
  162. },
  163. deleteRule: function () {
  164. $$("#filterDlg_Matches li[class*=Selected]").each(function (e) {
  165. e.parentNode.removeChild(e)
  166. });
  167. },
  168. execute: function () {
  169. if (this.validate()) {
  170. notify_progress("Saving data...", true);
  171. var query = dojo.formToQuery("filter_edit_form");
  172. console.log(query);
  173. new Ajax.Request("backend.php", {
  174. parameters: query,
  175. onComplete: function (transport) {
  176. dialog.hide();
  177. updateFilterList();
  178. }
  179. });
  180. }
  181. },
  182. href: query
  183. });
  184. dialog.show();
  185. }
  186. function getSelectedLabels() {
  187. var tree = dijit.byId("labelTree");
  188. var items = tree.model.getCheckedItems();
  189. var rv = [];
  190. items.each(function(item) {
  191. rv.push(tree.model.store.getValue(item, 'bare_id'));
  192. });
  193. return rv;
  194. }
  195. function getSelectedUsers() {
  196. return getSelectedTableRowIds("prefUserList");
  197. }
  198. function getSelectedFeeds() {
  199. var tree = dijit.byId("feedTree");
  200. var items = tree.model.getCheckedItems();
  201. var rv = [];
  202. items.each(function(item) {
  203. if (item.id[0].match("FEED:"))
  204. rv.push(tree.model.store.getValue(item, 'bare_id'));
  205. });
  206. return rv;
  207. }
  208. function getSelectedCategories() {
  209. var tree = dijit.byId("feedTree");
  210. var items = tree.model.getCheckedItems();
  211. var rv = [];
  212. items.each(function(item) {
  213. if (item.id[0].match("CAT:"))
  214. rv.push(tree.model.store.getValue(item, 'bare_id'));
  215. });
  216. return rv;
  217. }
  218. function getSelectedFilters() {
  219. var tree = dijit.byId("filterTree");
  220. var items = tree.model.getCheckedItems();
  221. var rv = [];
  222. items.each(function(item) {
  223. rv.push(tree.model.store.getValue(item, 'bare_id'));
  224. });
  225. return rv;
  226. }
  227. function removeSelectedLabels() {
  228. var sel_rows = getSelectedLabels();
  229. if (sel_rows.length > 0) {
  230. var ok = confirm(__("Remove selected labels?"));
  231. if (ok) {
  232. notify_progress("Removing selected labels...");
  233. var query = "?op=pref-labels&method=remove&ids="+
  234. param_escape(sel_rows.toString());
  235. new Ajax.Request("backend.php", {
  236. parameters: query,
  237. onComplete: function(transport) {
  238. updateLabelList();
  239. } });
  240. }
  241. } else {
  242. alert(__("No labels are selected."));
  243. }
  244. return false;
  245. }
  246. function removeSelectedUsers() {
  247. var sel_rows = getSelectedUsers();
  248. if (sel_rows.length > 0) {
  249. var ok = confirm(__("Remove selected users? Neither default admin nor your account will be removed."));
  250. if (ok) {
  251. notify_progress("Removing selected users...");
  252. var query = "?op=pref-users&method=remove&ids=" +
  253. param_escape(sel_rows.toString());
  254. new Ajax.Request("backend.php", {
  255. parameters: query,
  256. onComplete: function (transport) {
  257. updateUsersList();
  258. }
  259. });
  260. }
  261. } else {
  262. alert(__("No users are selected."));
  263. }
  264. return false;
  265. }
  266. function removeSelectedFilters() {
  267. var sel_rows = getSelectedFilters();
  268. if (sel_rows.length > 0) {
  269. var ok = confirm(__("Remove selected filters?"));
  270. if (ok) {
  271. notify_progress("Removing selected filters...");
  272. var query = "?op=pref-filters&method=remove&ids=" +
  273. param_escape(sel_rows.toString());
  274. new Ajax.Request("backend.php", {
  275. parameters: query,
  276. onComplete: function (transport) {
  277. updateFilterList();
  278. }
  279. });
  280. }
  281. } else {
  282. alert(__("No filters are selected."));
  283. }
  284. return false;
  285. }
  286. function removeSelectedFeeds() {
  287. var sel_rows = getSelectedFeeds();
  288. if (sel_rows.length > 0) {
  289. var ok = confirm(__("Unsubscribe from selected feeds?"));
  290. if (ok) {
  291. notify_progress("Unsubscribing from selected feeds...", true);
  292. var query = "?op=pref-feeds&method=remove&ids=" +
  293. param_escape(sel_rows.toString());
  294. console.log(query);
  295. new Ajax.Request("backend.php", {
  296. parameters: query,
  297. onComplete: function (transport) {
  298. updateFeedList();
  299. }
  300. });
  301. }
  302. } else {
  303. alert(__("No feeds are selected."));
  304. }
  305. return false;
  306. }
  307. function clearSelectedFeeds() {
  308. var sel_rows = getSelectedFeeds();
  309. if (sel_rows.length > 1) {
  310. alert(__("Please select only one feed."));
  311. return;
  312. }
  313. if (sel_rows.length > 0) {
  314. var ok = confirm(__("Erase all non-starred articles in selected feed?"));
  315. if (ok) {
  316. notify_progress("Clearing selected feed...");
  317. clearFeedArticles(sel_rows[0]);
  318. }
  319. } else {
  320. alert(__("No feeds are selected."));
  321. }
  322. return false;
  323. }
  324. function purgeSelectedFeeds() {
  325. var sel_rows = getSelectedFeeds();
  326. if (sel_rows.length > 0) {
  327. var pr = prompt(__("How many days of articles to keep (0 - use default)?"), "0");
  328. if (pr != undefined) {
  329. notify_progress("Purging selected feed...");
  330. var query = "?op=rpc&method=purge&ids="+
  331. param_escape(sel_rows.toString()) + "&days=" + pr;
  332. console.log(query);
  333. new Ajax.Request("prefs.php", {
  334. parameters: query,
  335. onComplete: function(transport) {
  336. notify('');
  337. } });
  338. }
  339. } else {
  340. alert(__("No feeds are selected."));
  341. }
  342. return false;
  343. }
  344. function editSelectedUser() {
  345. var rows = getSelectedUsers();
  346. if (rows.length == 0) {
  347. alert(__("No users are selected."));
  348. return;
  349. }
  350. if (rows.length > 1) {
  351. alert(__("Please select only one user."));
  352. return;
  353. }
  354. notify("");
  355. editUser(rows[0]);
  356. }
  357. function resetSelectedUserPass() {
  358. var rows = getSelectedUsers();
  359. if (rows.length == 0) {
  360. alert(__("No users are selected."));
  361. return;
  362. }
  363. if (rows.length > 1) {
  364. alert(__("Please select only one user."));
  365. return;
  366. }
  367. var ok = confirm(__("Reset password of selected user?"));
  368. if (ok) {
  369. notify_progress("Resetting password for selected user...");
  370. var id = rows[0];
  371. var query = "?op=pref-users&method=resetPass&id=" +
  372. param_escape(id);
  373. new Ajax.Request("backend.php", {
  374. parameters: query,
  375. onComplete: function (transport) {
  376. notify_info(transport.responseText, true);
  377. }
  378. });
  379. }
  380. }
  381. function selectedUserDetails() {
  382. var rows = getSelectedUsers();
  383. if (rows.length == 0) {
  384. alert(__("No users are selected."));
  385. return;
  386. }
  387. if (rows.length > 1) {
  388. alert(__("Please select only one user."));
  389. return;
  390. }
  391. var id = rows[0];
  392. var query = "backend.php?op=pref-users&method=userdetails&id=" + id;
  393. if (dijit.byId("userDetailsDlg"))
  394. dijit.byId("userDetailsDlg").destroyRecursive();
  395. dialog = new dijit.Dialog({
  396. id: "userDetailsDlg",
  397. title: __("User details"),
  398. style: "width: 600px",
  399. execute: function () {
  400. dialog.hide();
  401. },
  402. href: query
  403. });
  404. dialog.show();
  405. }
  406. function editSelectedFilter() {
  407. var rows = getSelectedFilters();
  408. if (rows.length == 0) {
  409. alert(__("No filters are selected."));
  410. return;
  411. }
  412. if (rows.length > 1) {
  413. alert(__("Please select only one filter."));
  414. return;
  415. }
  416. notify("");
  417. editFilter(rows[0]);
  418. }
  419. function joinSelectedFilters() {
  420. var rows = getSelectedFilters();
  421. if (rows.length == 0) {
  422. alert(__("No filters are selected."));
  423. return;
  424. }
  425. var ok = confirm(__("Combine selected filters?"));
  426. if (ok) {
  427. notify_progress("Joining filters...");
  428. var query = "?op=pref-filters&method=join&ids="+
  429. param_escape(rows.toString());
  430. console.log(query);
  431. new Ajax.Request("backend.php", {
  432. parameters: query,
  433. onComplete: function(transport) {
  434. updateFilterList();
  435. } });
  436. }
  437. }
  438. function editSelectedFeed() {
  439. var rows = getSelectedFeeds();
  440. if (rows.length == 0) {
  441. alert(__("No feeds are selected."));
  442. return;
  443. }
  444. if (rows.length > 1) {
  445. return editSelectedFeeds();
  446. }
  447. notify("");
  448. editFeed(rows[0], {});
  449. }
  450. function editSelectedFeeds() {
  451. var rows = getSelectedFeeds();
  452. if (rows.length == 0) {
  453. alert(__("No feeds are selected."));
  454. return;
  455. }
  456. notify_progress("Loading, please wait...");
  457. var query = "backend.php?op=pref-feeds&method=editfeeds&ids=" +
  458. param_escape(rows.toString());
  459. console.log(query);
  460. if (dijit.byId("feedEditDlg"))
  461. dijit.byId("feedEditDlg").destroyRecursive();
  462. new Ajax.Request("backend.php", {
  463. parameters: query,
  464. onComplete: function (transport) {
  465. notify("");
  466. var dialog = new dijit.Dialog({
  467. id: "feedEditDlg",
  468. title: __("Edit Multiple Feeds"),
  469. style: "width: 600px",
  470. getChildByName: function (name) {
  471. var rv = null;
  472. this.getChildren().each(
  473. function (child) {
  474. if (child.name == name) {
  475. rv = child;
  476. return;
  477. }
  478. });
  479. return rv;
  480. },
  481. toggleField: function (checkbox, elem, label) {
  482. this.getChildByName(elem).attr('disabled', !checkbox.checked);
  483. if ($(label))
  484. if (checkbox.checked)
  485. $(label).removeClassName('insensitive');
  486. else
  487. $(label).addClassName('insensitive');
  488. },
  489. execute: function () {
  490. if (this.validate() && confirm(__("Save changes to selected feeds?"))) {
  491. var query = dojo.objectToQuery(this.attr('value'));
  492. /* Form.serialize ignores unchecked checkboxes */
  493. if (!query.match("&private=") &&
  494. this.getChildByName('private').attr('disabled') == false) {
  495. query = query + "&private=false";
  496. }
  497. try {
  498. if (!query.match("&cache_images=") &&
  499. this.getChildByName('cache_images').attr('disabled') == false) {
  500. query = query + "&cache_images=false";
  501. }
  502. } catch (e) {
  503. }
  504. try {
  505. if (!query.match("&hide_images=") &&
  506. this.getChildByName('hide_images').attr('disabled') == false) {
  507. query = query + "&hide_images=false";
  508. }
  509. } catch (e) {
  510. }
  511. if (!query.match("&include_in_digest=") &&
  512. this.getChildByName('include_in_digest').attr('disabled') == false) {
  513. query = query + "&include_in_digest=false";
  514. }
  515. if (!query.match("&always_display_enclosures=") &&
  516. this.getChildByName('always_display_enclosures').attr('disabled') == false) {
  517. query = query + "&always_display_enclosures=false";
  518. }
  519. if (!query.match("&mark_unread_on_update=") &&
  520. this.getChildByName('mark_unread_on_update').attr('disabled') == false) {
  521. query = query + "&mark_unread_on_update=false";
  522. }
  523. console.log(query);
  524. notify_progress("Saving data...", true);
  525. new Ajax.Request("backend.php", {
  526. parameters: query,
  527. onComplete: function (transport) {
  528. dialog.hide();
  529. updateFeedList();
  530. }
  531. });
  532. }
  533. },
  534. content: transport.responseText
  535. });
  536. dialog.show();
  537. }
  538. });
  539. }
  540. function opmlImportComplete(iframe) {
  541. if (!iframe.contentDocument.body.innerHTML) return false;
  542. Element.show(iframe);
  543. notify('');
  544. if (dijit.byId('opmlImportDlg'))
  545. dijit.byId('opmlImportDlg').destroyRecursive();
  546. var content = iframe.contentDocument.body.innerHTML;
  547. dialog = new dijit.Dialog({
  548. id: "opmlImportDlg",
  549. title: __("OPML Import"),
  550. style: "width: 600px",
  551. onCancel: function () {
  552. updateFeedList();
  553. updateFilterList();
  554. updateLabelList();
  555. },
  556. execute: function () {
  557. updateFeedList();
  558. updateFilterList();
  559. updateLabelList();
  560. this.hide();
  561. },
  562. content: content
  563. });
  564. dialog.show();
  565. }
  566. function opmlImport() {
  567. var opml_file = $("opml_file");
  568. if (opml_file.value.length == 0) {
  569. alert(__("Please choose an OPML file first."));
  570. return false;
  571. } else {
  572. notify_progress("Importing, please wait...", true);
  573. Element.show("upload_iframe");
  574. return true;
  575. }
  576. }
  577. function updateFilterList() {
  578. var user_search = $("filter_search");
  579. var search = "";
  580. if (user_search) { search = user_search.value; }
  581. new Ajax.Request("backend.php", {
  582. parameters: "?op=pref-filters&search=" + param_escape(search),
  583. onComplete: function(transport) {
  584. dijit.byId('filterConfigTab').attr('content', transport.responseText);
  585. notify("");
  586. } });
  587. }
  588. function updateLabelList() {
  589. new Ajax.Request("backend.php", {
  590. parameters: "?op=pref-labels",
  591. onComplete: function(transport) {
  592. dijit.byId('labelConfigTab').attr('content', transport.responseText);
  593. notify("");
  594. } });
  595. }
  596. function updatePrefsList() {
  597. new Ajax.Request("backend.php", {
  598. parameters: "?op=pref-prefs",
  599. onComplete: function(transport) {
  600. dijit.byId('genConfigTab').attr('content', transport.responseText);
  601. notify("");
  602. } });
  603. }
  604. function updateSystemList() {
  605. new Ajax.Request("backend.php", {
  606. parameters: "?op=pref-system",
  607. onComplete: function(transport) {
  608. dijit.byId('systemConfigTab').attr('content', transport.responseText);
  609. notify("");
  610. } });
  611. }
  612. function selectTab(id, noupdate, method) {
  613. if (!noupdate) {
  614. notify_progress("Loading, please wait...");
  615. if (id == "feedConfig") {
  616. updateFeedList();
  617. } else if (id == "filterConfig") {
  618. updateFilterList();
  619. } else if (id == "labelConfig") {
  620. updateLabelList();
  621. } else if (id == "genConfig") {
  622. updatePrefsList();
  623. } else if (id == "userConfig") {
  624. updateUsersList();
  625. } else if (id == "systemConfig") {
  626. updateSystemList();
  627. }
  628. var tab = dijit.byId(id + "Tab");
  629. dijit.byId("pref-tabs").selectChild(tab);
  630. }
  631. }
  632. function init_second_stage() {
  633. document.onkeydown = pref_hotkey_handler;
  634. loading_set_progress(50);
  635. notify("");
  636. var tab = getURLParam('tab');
  637. if (tab) {
  638. tab = dijit.byId(tab + "Tab");
  639. if (tab) dijit.byId("pref-tabs").selectChild(tab);
  640. }
  641. var method = getURLParam('method');
  642. if (method == 'editFeed') {
  643. var param = getURLParam('methodparam');
  644. window.setTimeout(function() { editFeed(param) }, 100);
  645. }
  646. setTimeout(hotkey_prefix_timeout, 5*1000);
  647. }
  648. function init() {
  649. window.onerror = function (message, filename, lineno, colno, error) {
  650. report_error(message, filename, lineno, colno, error);
  651. };
  652. require(["dojo/_base/kernel",
  653. "dojo/ready",
  654. "dojo/parser",
  655. "dojo/_base/loader",
  656. "dojo/_base/html",
  657. "dijit/ColorPalette",
  658. "dijit/Dialog",
  659. "dijit/form/Button",
  660. "dijit/form/CheckBox",
  661. "dijit/form/DropDownButton",
  662. "dijit/form/FilteringSelect",
  663. "dijit/form/Form",
  664. "dijit/form/RadioButton",
  665. "dijit/form/ComboButton",
  666. "dijit/form/Select",
  667. "dijit/form/SimpleTextarea",
  668. "dijit/form/TextBox",
  669. "dijit/form/ValidationTextBox",
  670. "dijit/InlineEditBox",
  671. "dijit/layout/AccordionContainer",
  672. "dijit/layout/AccordionPane",
  673. "dijit/layout/BorderContainer",
  674. "dijit/layout/ContentPane",
  675. "dijit/layout/TabContainer",
  676. "dijit/Menu",
  677. "dijit/ProgressBar",
  678. "dijit/Toolbar",
  679. "dijit/Tree",
  680. "dijit/tree/dndSource",
  681. "dojo/data/ItemFileWriteStore",
  682. "fox/PrefFeedTree",
  683. "fox/PrefFilterTree",
  684. "fox/PrefLabelTree"], function (dojo, ready, parser) {
  685. ready(function () {
  686. try {
  687. parser.parse();
  688. loading_set_progress(50);
  689. var clientTzOffset = new Date().getTimezoneOffset() * 60;
  690. new Ajax.Request("backend.php", {
  691. parameters: {
  692. op: "rpc", method: "sanityCheck",
  693. clientTzOffset: clientTzOffset
  694. },
  695. onComplete: function (transport) {
  696. backend_sanity_check_callback(transport);
  697. }
  698. });
  699. } catch (e) {
  700. exception_error(e);
  701. }
  702. });
  703. });
  704. }
  705. function validatePrefsReset() {
  706. var ok = confirm(__("Reset to defaults?"));
  707. if (ok) {
  708. query = "?op=pref-prefs&method=resetconfig";
  709. console.log(query);
  710. new Ajax.Request("backend.php", {
  711. parameters: query,
  712. onComplete: function(transport) {
  713. updatePrefsList();
  714. notify_info(transport.responseText);
  715. } });
  716. }
  717. return false;
  718. }
  719. function pref_hotkey_handler(e) {
  720. if (e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA") return;
  721. var keycode = false;
  722. var shift_key = false;
  723. var cmdline = $('cmdline');
  724. try {
  725. shift_key = e.shiftKey;
  726. } catch (e) {
  727. }
  728. if (window.event) {
  729. keycode = window.event.keyCode;
  730. } else if (e) {
  731. keycode = e.which;
  732. }
  733. var keychar = String.fromCharCode(keycode);
  734. if (keycode == 27) { // escape
  735. hotkey_prefix = false;
  736. }
  737. if (keycode == 16) return; // ignore lone shift
  738. if (keycode == 17) return; // ignore lone ctrl
  739. if (!shift_key) keychar = keychar.toLowerCase();
  740. var hotkeys = getInitParam("hotkeys");
  741. if (!hotkey_prefix && hotkeys[0].indexOf(keychar) != -1) {
  742. var date = new Date();
  743. var ts = Math.round(date.getTime() / 1000);
  744. hotkey_prefix = keychar;
  745. hotkey_prefix_pressed = ts;
  746. cmdline.innerHTML = keychar;
  747. Element.show(cmdline);
  748. return true;
  749. }
  750. Element.hide(cmdline);
  751. var hotkey = keychar.search(/[a-zA-Z0-9]/) != -1 ? keychar : "(" + keycode + ")";
  752. hotkey = hotkey_prefix ? hotkey_prefix + " " + hotkey : hotkey;
  753. hotkey_prefix = false;
  754. var hotkey_action = false;
  755. var hotkeys = getInitParam("hotkeys");
  756. for (sequence in hotkeys[1]) {
  757. if (sequence == hotkey) {
  758. hotkey_action = hotkeys[1][sequence];
  759. break;
  760. }
  761. }
  762. switch (hotkey_action) {
  763. case "feed_subscribe":
  764. quickAddFeed();
  765. return false;
  766. case "create_label":
  767. addLabel();
  768. return false;
  769. case "create_filter":
  770. quickAddFilter();
  771. return false;
  772. case "help_dialog":
  773. //helpDialog("prefs");
  774. return false;
  775. default:
  776. console.log("unhandled action: " + hotkey_action + "; hotkey: " + hotkey);
  777. }
  778. }
  779. function removeCategory(id, item) {
  780. var ok = confirm(__("Remove category %s? Any nested feeds would be placed into Uncategorized.").replace("%s", item.name));
  781. if (ok) {
  782. var query = "?op=pref-feeds&method=removeCat&ids=" +
  783. param_escape(id);
  784. notify_progress("Removing category...");
  785. new Ajax.Request("backend.php", {
  786. parameters: query,
  787. onComplete: function (transport) {
  788. notify('');
  789. updateFeedList();
  790. }
  791. });
  792. }
  793. }
  794. function removeSelectedCategories() {
  795. var sel_rows = getSelectedCategories();
  796. if (sel_rows.length > 0) {
  797. var ok = confirm(__("Remove selected categories?"));
  798. if (ok) {
  799. notify_progress("Removing selected categories...");
  800. var query = "?op=pref-feeds&method=removeCat&ids="+
  801. param_escape(sel_rows.toString());
  802. new Ajax.Request("backend.php", {
  803. parameters: query,
  804. onComplete: function(transport) {
  805. updateFeedList();
  806. } });
  807. }
  808. } else {
  809. alert(__("No categories are selected."));
  810. }
  811. return false;
  812. }
  813. function createCategory() {
  814. var title = prompt(__("Category title:"));
  815. if (title) {
  816. notify_progress("Creating category...");
  817. var query = "?op=pref-feeds&method=addCat&cat=" +
  818. param_escape(title);
  819. new Ajax.Request("backend.php", {
  820. parameters: query,
  821. onComplete: function (transport) {
  822. notify('');
  823. updateFeedList();
  824. }
  825. });
  826. }
  827. }
  828. function showInactiveFeeds() {
  829. var query = "backend.php?op=pref-feeds&method=inactiveFeeds";
  830. if (dijit.byId("inactiveFeedsDlg"))
  831. dijit.byId("inactiveFeedsDlg").destroyRecursive();
  832. dialog = new dijit.Dialog({
  833. id: "inactiveFeedsDlg",
  834. title: __("Feeds without recent updates"),
  835. style: "width: 600px",
  836. getSelectedFeeds: function () {
  837. return getSelectedTableRowIds("prefInactiveFeedList");
  838. },
  839. removeSelected: function () {
  840. var sel_rows = this.getSelectedFeeds();
  841. console.log(sel_rows);
  842. if (sel_rows.length > 0) {
  843. var ok = confirm(__("Remove selected feeds?"));
  844. if (ok) {
  845. notify_progress("Removing selected feeds...", true);
  846. var query = "?op=pref-feeds&method=remove&ids=" +
  847. param_escape(sel_rows.toString());
  848. new Ajax.Request("backend.php", {
  849. parameters: query,
  850. onComplete: function (transport) {
  851. notify('');
  852. dialog.hide();
  853. updateFeedList();
  854. }
  855. });
  856. }
  857. } else {
  858. alert(__("No feeds are selected."));
  859. }
  860. },
  861. execute: function () {
  862. if (this.validate()) {
  863. }
  864. },
  865. href: query
  866. });
  867. dialog.show();
  868. }
  869. function opmlRegenKey() {
  870. var ok = confirm(__("Replace current OPML publishing address with a new one?"));
  871. if (ok) {
  872. notify_progress("Trying to change address...", true);
  873. var query = "?op=pref-feeds&method=regenOPMLKey";
  874. new Ajax.Request("backend.php", {
  875. parameters: query,
  876. onComplete: function (transport) {
  877. var reply = JSON.parse(transport.responseText);
  878. var new_link = reply.link;
  879. var e = $('pub_opml_url');
  880. if (new_link) {
  881. e.href = new_link;
  882. e.innerHTML = new_link;
  883. new Effect.Highlight(e);
  884. notify('');
  885. } else {
  886. notify_error("Could not change feed URL.");
  887. }
  888. }
  889. });
  890. }
  891. return false;
  892. }
  893. function feedActionChange() {
  894. var chooser = $("feedActionChooser");
  895. var opid = chooser[chooser.selectedIndex].value;
  896. chooser.selectedIndex = 0;
  897. feedActionGo(opid);
  898. }
  899. function feedActionGo(op) {
  900. if (op == "facEdit") {
  901. var rows = getSelectedFeeds();
  902. if (rows.length > 1) {
  903. editSelectedFeeds();
  904. } else {
  905. editSelectedFeed();
  906. }
  907. }
  908. if (op == "facClear") {
  909. clearSelectedFeeds();
  910. }
  911. if (op == "facPurge") {
  912. purgeSelectedFeeds();
  913. }
  914. if (op == "facEditCats") {
  915. editFeedCats();
  916. }
  917. if (op == "facRescore") {
  918. rescoreSelectedFeeds();
  919. }
  920. if (op == "facUnsubscribe") {
  921. removeSelectedFeeds();
  922. }
  923. }
  924. function clearFeedArticles(feed_id) {
  925. notify_progress("Clearing feed...");
  926. var query = "?op=pref-feeds&quiet=1&method=clear&id=" + feed_id;
  927. new Ajax.Request("backend.php", {
  928. parameters: query,
  929. onComplete: function(transport) {
  930. notify('');
  931. } });
  932. return false;
  933. }
  934. function rescoreSelectedFeeds() {
  935. var sel_rows = getSelectedFeeds();
  936. if (sel_rows.length > 0) {
  937. //var ok = confirm(__("Rescore last 100 articles in selected feeds?"));
  938. var ok = confirm(__("Rescore articles in selected feeds?"));
  939. if (ok) {
  940. notify_progress("Rescoring selected feeds...", true);
  941. var query = "?op=pref-feeds&method=rescore&quiet=1&ids="+
  942. param_escape(sel_rows.toString());
  943. new Ajax.Request("backend.php", {
  944. parameters: query,
  945. onComplete: function(transport) {
  946. notify_callback2(transport);
  947. } });
  948. }
  949. } else {
  950. alert(__("No feeds are selected."));
  951. }
  952. return false;
  953. }
  954. function rescore_all_feeds() {
  955. var ok = confirm(__("Rescore all articles? This operation may take a lot of time."));
  956. if (ok) {
  957. notify_progress("Rescoring feeds...", true);
  958. var query = "?op=pref-feeds&method=rescoreAll&quiet=1";
  959. new Ajax.Request("backend.php", {
  960. parameters: query,
  961. onComplete: function(transport) {
  962. notify_callback2(transport);
  963. } });
  964. }
  965. }
  966. function labelColorReset() {
  967. var labels = getSelectedLabels();
  968. if (labels.length > 0) {
  969. var ok = confirm(__("Reset selected labels to default colors?"));
  970. if (ok) {
  971. var query = "?op=pref-labels&method=colorreset&ids=" +
  972. param_escape(labels.toString());
  973. new Ajax.Request("backend.php", {
  974. parameters: query,
  975. onComplete: function (transport) {
  976. updateLabelList();
  977. }
  978. });
  979. }
  980. } else {
  981. alert(__("No labels are selected."));
  982. }
  983. }
  984. function inPreferences() {
  985. return true;
  986. }
  987. function editProfiles() {
  988. if (dijit.byId("profileEditDlg"))
  989. dijit.byId("profileEditDlg").destroyRecursive();
  990. var query = "backend.php?op=pref-prefs&method=editPrefProfiles";
  991. dialog = new dijit.Dialog({
  992. id: "profileEditDlg",
  993. title: __("Settings Profiles"),
  994. style: "width: 600px",
  995. getSelectedProfiles: function () {
  996. return getSelectedTableRowIds("prefFeedProfileList");
  997. },
  998. removeSelected: function () {
  999. var sel_rows = this.getSelectedProfiles();
  1000. if (sel_rows.length > 0) {
  1001. var ok = confirm(__("Remove selected profiles? Active and default profiles will not be removed."));
  1002. if (ok) {
  1003. notify_progress("Removing selected profiles...", true);
  1004. var query = "?op=rpc&method=remprofiles&ids=" +
  1005. param_escape(sel_rows.toString());
  1006. new Ajax.Request("backend.php", {
  1007. parameters: query,
  1008. onComplete: function (transport) {
  1009. notify('');
  1010. editProfiles();
  1011. }
  1012. });
  1013. }
  1014. } else {
  1015. alert(__("No profiles are selected."));
  1016. }
  1017. },
  1018. activateProfile: function () {
  1019. var sel_rows = this.getSelectedProfiles();
  1020. if (sel_rows.length == 1) {
  1021. var ok = confirm(__("Activate selected profile?"));
  1022. if (ok) {
  1023. notify_progress("Loading, please wait...");
  1024. var query = "?op=rpc&method=setprofile&id=" +
  1025. param_escape(sel_rows.toString());
  1026. new Ajax.Request("backend.php", {
  1027. parameters: query,
  1028. onComplete: function (transport) {
  1029. window.location.reload();
  1030. }
  1031. });
  1032. }
  1033. } else {
  1034. alert(__("Please choose a profile to activate."));
  1035. }
  1036. },
  1037. addProfile: function () {
  1038. if (this.validate()) {
  1039. notify_progress("Creating profile...", true);
  1040. var query = "?op=rpc&method=addprofile&title=" +
  1041. param_escape(dialog.attr('value').newprofile);
  1042. new Ajax.Request("backend.php", {
  1043. parameters: query,
  1044. onComplete: function (transport) {
  1045. notify('');
  1046. editProfiles();
  1047. }
  1048. });
  1049. }
  1050. },
  1051. execute: function () {
  1052. if (this.validate()) {
  1053. }
  1054. },
  1055. href: query
  1056. });
  1057. dialog.show();
  1058. }
  1059. function activatePrefProfile() {
  1060. var sel_rows = getSelectedFeedCats();
  1061. if (sel_rows.length == 1) {
  1062. var ok = confirm(__("Activate selected profile?"));
  1063. if (ok) {
  1064. notify_progress("Loading, please wait...");
  1065. var query = "?op=rpc&method=setprofile&id="+
  1066. param_escape(sel_rows.toString());
  1067. new Ajax.Request("backend.php", {
  1068. parameters: query,
  1069. onComplete: function(transport) {
  1070. window.location.reload();
  1071. } });
  1072. }
  1073. } else {
  1074. alert(__("Please choose a profile to activate."));
  1075. }
  1076. return false;
  1077. }
  1078. function clearFeedAccessKeys() {
  1079. var ok = confirm(__("This will invalidate all previously generated feed URLs. Continue?"));
  1080. if (ok) {
  1081. notify_progress("Clearing URLs...");
  1082. var query = "?op=pref-feeds&method=clearKeys";
  1083. new Ajax.Request("backend.php", {
  1084. parameters: query,
  1085. onComplete: function(transport) {
  1086. notify_info("Generated URLs cleared.");
  1087. } });
  1088. }
  1089. return false;
  1090. }
  1091. function resetFilterOrder() {
  1092. notify_progress("Loading, please wait...");
  1093. new Ajax.Request("backend.php", {
  1094. parameters: "?op=pref-filters&method=filtersortreset",
  1095. onComplete: function (transport) {
  1096. updateFilterList();
  1097. }
  1098. });
  1099. }
  1100. function resetFeedOrder() {
  1101. notify_progress("Loading, please wait...");
  1102. new Ajax.Request("backend.php", {
  1103. parameters: "?op=pref-feeds&method=feedsortreset",
  1104. onComplete: function (transport) {
  1105. updateFeedList();
  1106. }
  1107. });
  1108. }
  1109. function resetCatOrder() {
  1110. notify_progress("Loading, please wait...");
  1111. new Ajax.Request("backend.php", {
  1112. parameters: "?op=pref-feeds&method=catsortreset",
  1113. onComplete: function (transport) {
  1114. updateFeedList();
  1115. }
  1116. });
  1117. }
  1118. function editCat(id, item, event) {
  1119. var new_name = prompt(__('Rename category to:'), item.name);
  1120. if (new_name && new_name != item.name) {
  1121. notify_progress("Loading, please wait...");
  1122. new Ajax.Request("backend.php", {
  1123. parameters: {
  1124. op: 'pref-feeds',
  1125. method: 'renamecat',
  1126. id: id,
  1127. title: new_name,
  1128. },
  1129. onComplete: function (transport) {
  1130. updateFeedList();
  1131. }
  1132. });
  1133. }
  1134. }
  1135. function editLabel(id, event) {
  1136. var query = "backend.php?op=pref-labels&method=edit&id=" +
  1137. param_escape(id);
  1138. if (dijit.byId("labelEditDlg"))
  1139. dijit.byId("labelEditDlg").destroyRecursive();
  1140. dialog = new dijit.Dialog({
  1141. id: "labelEditDlg",
  1142. title: __("Label Editor"),
  1143. style: "width: 600px",
  1144. setLabelColor: function (id, fg, bg) {
  1145. var kind = '';
  1146. var color = '';
  1147. if (fg && bg) {
  1148. kind = 'both';
  1149. } else if (fg) {
  1150. kind = 'fg';
  1151. color = fg;
  1152. } else if (bg) {
  1153. kind = 'bg';
  1154. color = bg;
  1155. }
  1156. var query = "?op=pref-labels&method=colorset&kind=" + kind +
  1157. "&ids=" + param_escape(id) + "&fg=" + param_escape(fg) +
  1158. "&bg=" + param_escape(bg) + "&color=" + param_escape(color);
  1159. // console.log(query);
  1160. var e = $("LICID-" + id);
  1161. if (e) {
  1162. if (fg) e.style.color = fg;
  1163. if (bg) e.style.backgroundColor = bg;
  1164. }
  1165. new Ajax.Request("backend.php", {parameters: query});
  1166. updateFilterList();
  1167. },
  1168. execute: function () {
  1169. if (this.validate()) {
  1170. var caption = this.attr('value').caption;
  1171. var fg_color = this.attr('value').fg_color;
  1172. var bg_color = this.attr('value').bg_color;
  1173. var query = dojo.objectToQuery(this.attr('value'));
  1174. dijit.byId('labelTree').setNameById(id, caption);
  1175. this.setLabelColor(id, fg_color, bg_color);
  1176. this.hide();
  1177. new Ajax.Request("backend.php", {
  1178. parameters: query,
  1179. onComplete: function (transport) {
  1180. updateFilterList();
  1181. }
  1182. });
  1183. }
  1184. },
  1185. href: query
  1186. });
  1187. dialog.show();
  1188. }
  1189. function customizeCSS() {
  1190. var query = "backend.php?op=pref-prefs&method=customizeCSS";
  1191. if (dijit.byId("cssEditDlg"))
  1192. dijit.byId("cssEditDlg").destroyRecursive();
  1193. dialog = new dijit.Dialog({
  1194. id: "cssEditDlg",
  1195. title: __("Customize stylesheet"),
  1196. style: "width: 600px",
  1197. execute: function () {
  1198. notify_progress('Saving data...', true);
  1199. new Ajax.Request("backend.php", {
  1200. parameters: dojo.objectToQuery(this.attr('value')),
  1201. onComplete: function (transport) {
  1202. notify('');
  1203. window.location.reload();
  1204. }
  1205. });
  1206. },
  1207. href: query
  1208. });
  1209. dialog.show();
  1210. }
  1211. function insertSSLserial(value) {
  1212. dijit.byId("SSL_CERT_SERIAL").attr('value', value);
  1213. }
  1214. function gotoExportOpml(filename, settings) {
  1215. tmp = settings ? 1 : 0;
  1216. document.location.href = "backend.php?op=opml&method=export&filename=" + filename + "&settings=" + tmp;
  1217. }
  1218. function batchSubscribe() {
  1219. var query = "backend.php?op=pref-feeds&method=batchSubscribe";
  1220. // overlapping widgets
  1221. if (dijit.byId("batchSubDlg")) dijit.byId("batchSubDlg").destroyRecursive();
  1222. if (dijit.byId("feedAddDlg")) dijit.byId("feedAddDlg").destroyRecursive();
  1223. var dialog = new dijit.Dialog({
  1224. id: "batchSubDlg",
  1225. title: __("Batch subscribe"),
  1226. style: "width: 600px",
  1227. execute: function () {
  1228. if (this.validate()) {
  1229. console.log(dojo.objectToQuery(this.attr('value')));
  1230. notify_progress(__("Subscribing to feeds..."), true);
  1231. new Ajax.Request("backend.php", {
  1232. parameters: dojo.objectToQuery(this.attr('value')),
  1233. onComplete: function (transport) {
  1234. notify("");
  1235. updateFeedList();
  1236. dialog.hide();
  1237. }
  1238. });
  1239. }
  1240. },
  1241. href: query
  1242. });
  1243. dialog.show();
  1244. }
  1245. function clearPluginData(name) {
  1246. if (confirm(__("Clear stored data for this plugin?"))) {
  1247. notify_progress("Loading, please wait...");
  1248. new Ajax.Request("backend.php", {
  1249. parameters: "?op=pref-prefs&method=clearplugindata&name=" + param_escape(name),
  1250. onComplete: function(transport) {
  1251. notify('');
  1252. updatePrefsList();
  1253. } });
  1254. }
  1255. }
  1256. function clearSqlLog() {
  1257. if (confirm(__("Clear all messages in the error log?"))) {
  1258. notify_progress("Loading, please wait...");
  1259. var query = "?op=pref-system&method=clearLog";
  1260. new Ajax.Request("backend.php", {
  1261. parameters: query,
  1262. onComplete: function(transport) {
  1263. updateSystemList();
  1264. } });
  1265. }
  1266. }
  1267. function updateSelectedPrompt() {
  1268. // no-op shim for toggleSelectedRow()
  1269. }