prefs.js 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674
  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. window.location.reload();
  553. },
  554. execute: function () {
  555. window.location.reload();
  556. },
  557. content: content
  558. });
  559. dialog.show();
  560. }
  561. function opmlImport() {
  562. var opml_file = $("opml_file");
  563. if (opml_file.value.length == 0) {
  564. alert(__("Please choose an OPML file first."));
  565. return false;
  566. } else {
  567. notify_progress("Importing, please wait...", true);
  568. Element.show("upload_iframe");
  569. return true;
  570. }
  571. }
  572. function updateFilterList() {
  573. var user_search = $("filter_search");
  574. var search = "";
  575. if (user_search) { search = user_search.value; }
  576. new Ajax.Request("backend.php", {
  577. parameters: "?op=pref-filters&search=" + param_escape(search),
  578. onComplete: function(transport) {
  579. dijit.byId('filterConfigTab').attr('content', transport.responseText);
  580. notify("");
  581. } });
  582. }
  583. function updateLabelList() {
  584. new Ajax.Request("backend.php", {
  585. parameters: "?op=pref-labels",
  586. onComplete: function(transport) {
  587. dijit.byId('labelConfigTab').attr('content', transport.responseText);
  588. notify("");
  589. } });
  590. }
  591. function updatePrefsList() {
  592. new Ajax.Request("backend.php", {
  593. parameters: "?op=pref-prefs",
  594. onComplete: function(transport) {
  595. dijit.byId('genConfigTab').attr('content', transport.responseText);
  596. notify("");
  597. } });
  598. }
  599. function updateSystemList() {
  600. new Ajax.Request("backend.php", {
  601. parameters: "?op=pref-system",
  602. onComplete: function(transport) {
  603. dijit.byId('systemConfigTab').attr('content', transport.responseText);
  604. notify("");
  605. } });
  606. }
  607. function selectTab(id, noupdate, method) {
  608. if (!noupdate) {
  609. notify_progress("Loading, please wait...");
  610. if (id == "feedConfig") {
  611. updateFeedList();
  612. } else if (id == "filterConfig") {
  613. updateFilterList();
  614. } else if (id == "labelConfig") {
  615. updateLabelList();
  616. } else if (id == "genConfig") {
  617. updatePrefsList();
  618. } else if (id == "userConfig") {
  619. updateUsersList();
  620. } else if (id == "systemConfig") {
  621. updateSystemList();
  622. }
  623. var tab = dijit.byId(id + "Tab");
  624. dijit.byId("pref-tabs").selectChild(tab);
  625. }
  626. }
  627. function init_second_stage() {
  628. document.onkeydown = pref_hotkey_handler;
  629. loading_set_progress(50);
  630. notify("");
  631. var tab = getURLParam('tab');
  632. if (tab) {
  633. tab = dijit.byId(tab + "Tab");
  634. if (tab) dijit.byId("pref-tabs").selectChild(tab);
  635. }
  636. var method = getURLParam('method');
  637. if (method == 'editFeed') {
  638. var param = getURLParam('methodparam');
  639. window.setTimeout(function() { editFeed(param) }, 100);
  640. }
  641. setTimeout(hotkey_prefix_timeout, 5*1000);
  642. }
  643. function init() {
  644. window.onerror = function (message, filename, lineno, colno, error) {
  645. report_error(message, filename, lineno, colno, error);
  646. };
  647. require(["dojo/_base/kernel",
  648. "dojo/ready",
  649. "dojo/parser",
  650. "dojo/_base/loader",
  651. "dojo/_base/html",
  652. "dijit/ColorPalette",
  653. "dijit/Dialog",
  654. "dijit/form/Button",
  655. "dijit/form/CheckBox",
  656. "dijit/form/DropDownButton",
  657. "dijit/form/FilteringSelect",
  658. "dijit/form/MultiSelect",
  659. "dijit/form/Form",
  660. "dijit/form/RadioButton",
  661. "dijit/form/ComboButton",
  662. "dijit/form/Select",
  663. "dijit/form/SimpleTextarea",
  664. "dijit/form/TextBox",
  665. "dijit/form/ValidationTextBox",
  666. "dijit/InlineEditBox",
  667. "dijit/layout/AccordionContainer",
  668. "dijit/layout/AccordionPane",
  669. "dijit/layout/BorderContainer",
  670. "dijit/layout/ContentPane",
  671. "dijit/layout/TabContainer",
  672. "dijit/Menu",
  673. "dijit/ProgressBar",
  674. "dijit/Toolbar",
  675. "dijit/Tree",
  676. "dijit/tree/dndSource",
  677. "dojo/data/ItemFileWriteStore",
  678. "fox/PrefFeedTree",
  679. "fox/PrefFilterTree",
  680. "fox/PrefLabelTree"], function (dojo, ready, parser) {
  681. ready(function () {
  682. try {
  683. parser.parse();
  684. loading_set_progress(50);
  685. var clientTzOffset = new Date().getTimezoneOffset() * 60;
  686. new Ajax.Request("backend.php", {
  687. parameters: {
  688. op: "rpc", method: "sanityCheck",
  689. clientTzOffset: clientTzOffset
  690. },
  691. onComplete: function (transport) {
  692. backend_sanity_check_callback(transport);
  693. }
  694. });
  695. } catch (e) {
  696. exception_error(e);
  697. }
  698. });
  699. });
  700. }
  701. function validatePrefsReset() {
  702. var ok = confirm(__("Reset to defaults?"));
  703. if (ok) {
  704. query = "?op=pref-prefs&method=resetconfig";
  705. console.log(query);
  706. new Ajax.Request("backend.php", {
  707. parameters: query,
  708. onComplete: function(transport) {
  709. updatePrefsList();
  710. notify_info(transport.responseText);
  711. } });
  712. }
  713. return false;
  714. }
  715. function pref_hotkey_handler(e) {
  716. if (e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA") return;
  717. var keycode = false;
  718. var shift_key = false;
  719. var cmdline = $('cmdline');
  720. try {
  721. shift_key = e.shiftKey;
  722. } catch (e) {
  723. }
  724. if (window.event) {
  725. keycode = window.event.keyCode;
  726. } else if (e) {
  727. keycode = e.which;
  728. }
  729. var keychar = String.fromCharCode(keycode);
  730. if (keycode == 27) { // escape
  731. hotkey_prefix = false;
  732. }
  733. if (keycode == 16) return; // ignore lone shift
  734. if (keycode == 17) return; // ignore lone ctrl
  735. if (!shift_key) keychar = keychar.toLowerCase();
  736. var hotkeys = getInitParam("hotkeys");
  737. if (!hotkey_prefix && hotkeys[0].indexOf(keychar) != -1) {
  738. var date = new Date();
  739. var ts = Math.round(date.getTime() / 1000);
  740. hotkey_prefix = keychar;
  741. hotkey_prefix_pressed = ts;
  742. cmdline.innerHTML = keychar;
  743. Element.show(cmdline);
  744. return true;
  745. }
  746. Element.hide(cmdline);
  747. var hotkey = keychar.search(/[a-zA-Z0-9]/) != -1 ? keychar : "(" + keycode + ")";
  748. hotkey = hotkey_prefix ? hotkey_prefix + " " + hotkey : hotkey;
  749. hotkey_prefix = false;
  750. var hotkey_action = false;
  751. var hotkeys = getInitParam("hotkeys");
  752. for (sequence in hotkeys[1]) {
  753. if (sequence == hotkey) {
  754. hotkey_action = hotkeys[1][sequence];
  755. break;
  756. }
  757. }
  758. switch (hotkey_action) {
  759. case "feed_subscribe":
  760. quickAddFeed();
  761. return false;
  762. case "create_label":
  763. addLabel();
  764. return false;
  765. case "create_filter":
  766. quickAddFilter();
  767. return false;
  768. case "help_dialog":
  769. //helpDialog("prefs");
  770. return false;
  771. default:
  772. console.log("unhandled action: " + hotkey_action + "; hotkey: " + hotkey);
  773. }
  774. }
  775. function removeCategory(id, item) {
  776. var ok = confirm(__("Remove category %s? Any nested feeds would be placed into Uncategorized.").replace("%s", item.name));
  777. if (ok) {
  778. var query = "?op=pref-feeds&method=removeCat&ids=" +
  779. param_escape(id);
  780. notify_progress("Removing category...");
  781. new Ajax.Request("backend.php", {
  782. parameters: query,
  783. onComplete: function (transport) {
  784. notify('');
  785. updateFeedList();
  786. }
  787. });
  788. }
  789. }
  790. function removeSelectedCategories() {
  791. var sel_rows = getSelectedCategories();
  792. if (sel_rows.length > 0) {
  793. var ok = confirm(__("Remove selected categories?"));
  794. if (ok) {
  795. notify_progress("Removing selected categories...");
  796. var query = "?op=pref-feeds&method=removeCat&ids="+
  797. param_escape(sel_rows.toString());
  798. new Ajax.Request("backend.php", {
  799. parameters: query,
  800. onComplete: function(transport) {
  801. updateFeedList();
  802. } });
  803. }
  804. } else {
  805. alert(__("No categories are selected."));
  806. }
  807. return false;
  808. }
  809. function createCategory() {
  810. var title = prompt(__("Category title:"));
  811. if (title) {
  812. notify_progress("Creating category...");
  813. var query = "?op=pref-feeds&method=addCat&cat=" +
  814. param_escape(title);
  815. new Ajax.Request("backend.php", {
  816. parameters: query,
  817. onComplete: function (transport) {
  818. notify('');
  819. updateFeedList();
  820. }
  821. });
  822. }
  823. }
  824. function showInactiveFeeds() {
  825. var query = "backend.php?op=pref-feeds&method=inactiveFeeds";
  826. if (dijit.byId("inactiveFeedsDlg"))
  827. dijit.byId("inactiveFeedsDlg").destroyRecursive();
  828. dialog = new dijit.Dialog({
  829. id: "inactiveFeedsDlg",
  830. title: __("Feeds without recent updates"),
  831. style: "width: 600px",
  832. getSelectedFeeds: function () {
  833. return getSelectedTableRowIds("prefInactiveFeedList");
  834. },
  835. removeSelected: function () {
  836. var sel_rows = this.getSelectedFeeds();
  837. console.log(sel_rows);
  838. if (sel_rows.length > 0) {
  839. var ok = confirm(__("Remove selected feeds?"));
  840. if (ok) {
  841. notify_progress("Removing selected feeds...", true);
  842. var query = "?op=pref-feeds&method=remove&ids=" +
  843. param_escape(sel_rows.toString());
  844. new Ajax.Request("backend.php", {
  845. parameters: query,
  846. onComplete: function (transport) {
  847. notify('');
  848. dialog.hide();
  849. updateFeedList();
  850. }
  851. });
  852. }
  853. } else {
  854. alert(__("No feeds are selected."));
  855. }
  856. },
  857. execute: function () {
  858. if (this.validate()) {
  859. }
  860. },
  861. href: query
  862. });
  863. dialog.show();
  864. }
  865. function opmlRegenKey() {
  866. var ok = confirm(__("Replace current OPML publishing address with a new one?"));
  867. if (ok) {
  868. notify_progress("Trying to change address...", true);
  869. var query = "?op=pref-feeds&method=regenOPMLKey";
  870. new Ajax.Request("backend.php", {
  871. parameters: query,
  872. onComplete: function (transport) {
  873. var reply = JSON.parse(transport.responseText);
  874. var new_link = reply.link;
  875. var e = $('pub_opml_url');
  876. if (new_link) {
  877. e.href = new_link;
  878. e.innerHTML = new_link;
  879. new Effect.Highlight(e);
  880. notify('');
  881. } else {
  882. notify_error("Could not change feed URL.");
  883. }
  884. }
  885. });
  886. }
  887. return false;
  888. }
  889. function feedActionChange() {
  890. var chooser = $("feedActionChooser");
  891. var opid = chooser[chooser.selectedIndex].value;
  892. chooser.selectedIndex = 0;
  893. feedActionGo(opid);
  894. }
  895. function feedActionGo(op) {
  896. if (op == "facEdit") {
  897. var rows = getSelectedFeeds();
  898. if (rows.length > 1) {
  899. editSelectedFeeds();
  900. } else {
  901. editSelectedFeed();
  902. }
  903. }
  904. if (op == "facClear") {
  905. clearSelectedFeeds();
  906. }
  907. if (op == "facPurge") {
  908. purgeSelectedFeeds();
  909. }
  910. if (op == "facEditCats") {
  911. editFeedCats();
  912. }
  913. if (op == "facRescore") {
  914. rescoreSelectedFeeds();
  915. }
  916. if (op == "facUnsubscribe") {
  917. removeSelectedFeeds();
  918. }
  919. }
  920. function clearFeedArticles(feed_id) {
  921. notify_progress("Clearing feed...");
  922. var query = "?op=pref-feeds&quiet=1&method=clear&id=" + feed_id;
  923. new Ajax.Request("backend.php", {
  924. parameters: query,
  925. onComplete: function(transport) {
  926. notify('');
  927. } });
  928. return false;
  929. }
  930. function rescoreSelectedFeeds() {
  931. var sel_rows = getSelectedFeeds();
  932. if (sel_rows.length > 0) {
  933. //var ok = confirm(__("Rescore last 100 articles in selected feeds?"));
  934. var ok = confirm(__("Rescore articles in selected feeds?"));
  935. if (ok) {
  936. notify_progress("Rescoring selected feeds...", true);
  937. var query = "?op=pref-feeds&method=rescore&quiet=1&ids="+
  938. param_escape(sel_rows.toString());
  939. new Ajax.Request("backend.php", {
  940. parameters: query,
  941. onComplete: function(transport) {
  942. notify_callback2(transport);
  943. } });
  944. }
  945. } else {
  946. alert(__("No feeds are selected."));
  947. }
  948. return false;
  949. }
  950. function rescore_all_feeds() {
  951. var ok = confirm(__("Rescore all articles? This operation may take a lot of time."));
  952. if (ok) {
  953. notify_progress("Rescoring feeds...", true);
  954. var query = "?op=pref-feeds&method=rescoreAll&quiet=1";
  955. new Ajax.Request("backend.php", {
  956. parameters: query,
  957. onComplete: function(transport) {
  958. notify_callback2(transport);
  959. } });
  960. }
  961. }
  962. function labelColorReset() {
  963. var labels = getSelectedLabels();
  964. if (labels.length > 0) {
  965. var ok = confirm(__("Reset selected labels to default colors?"));
  966. if (ok) {
  967. var query = "?op=pref-labels&method=colorreset&ids=" +
  968. param_escape(labels.toString());
  969. new Ajax.Request("backend.php", {
  970. parameters: query,
  971. onComplete: function (transport) {
  972. updateLabelList();
  973. }
  974. });
  975. }
  976. } else {
  977. alert(__("No labels are selected."));
  978. }
  979. }
  980. function inPreferences() {
  981. return true;
  982. }
  983. function editProfiles() {
  984. if (dijit.byId("profileEditDlg"))
  985. dijit.byId("profileEditDlg").destroyRecursive();
  986. var query = "backend.php?op=pref-prefs&method=editPrefProfiles";
  987. dialog = new dijit.Dialog({
  988. id: "profileEditDlg",
  989. title: __("Settings Profiles"),
  990. style: "width: 600px",
  991. getSelectedProfiles: function () {
  992. return getSelectedTableRowIds("prefFeedProfileList");
  993. },
  994. removeSelected: function () {
  995. var sel_rows = this.getSelectedProfiles();
  996. if (sel_rows.length > 0) {
  997. var ok = confirm(__("Remove selected profiles? Active and default profiles will not be removed."));
  998. if (ok) {
  999. notify_progress("Removing selected profiles...", true);
  1000. var query = "?op=rpc&method=remprofiles&ids=" +
  1001. param_escape(sel_rows.toString());
  1002. new Ajax.Request("backend.php", {
  1003. parameters: query,
  1004. onComplete: function (transport) {
  1005. notify('');
  1006. editProfiles();
  1007. }
  1008. });
  1009. }
  1010. } else {
  1011. alert(__("No profiles are selected."));
  1012. }
  1013. },
  1014. activateProfile: function () {
  1015. var sel_rows = this.getSelectedProfiles();
  1016. if (sel_rows.length == 1) {
  1017. var ok = confirm(__("Activate selected profile?"));
  1018. if (ok) {
  1019. notify_progress("Loading, please wait...");
  1020. var query = "?op=rpc&method=setprofile&id=" +
  1021. param_escape(sel_rows.toString());
  1022. new Ajax.Request("backend.php", {
  1023. parameters: query,
  1024. onComplete: function (transport) {
  1025. window.location.reload();
  1026. }
  1027. });
  1028. }
  1029. } else {
  1030. alert(__("Please choose a profile to activate."));
  1031. }
  1032. },
  1033. addProfile: function () {
  1034. if (this.validate()) {
  1035. notify_progress("Creating profile...", true);
  1036. var query = "?op=rpc&method=addprofile&title=" +
  1037. param_escape(dialog.attr('value').newprofile);
  1038. new Ajax.Request("backend.php", {
  1039. parameters: query,
  1040. onComplete: function (transport) {
  1041. notify('');
  1042. editProfiles();
  1043. }
  1044. });
  1045. }
  1046. },
  1047. execute: function () {
  1048. if (this.validate()) {
  1049. }
  1050. },
  1051. href: query
  1052. });
  1053. dialog.show();
  1054. }
  1055. function activatePrefProfile() {
  1056. var sel_rows = getSelectedFeedCats();
  1057. if (sel_rows.length == 1) {
  1058. var ok = confirm(__("Activate selected profile?"));
  1059. if (ok) {
  1060. notify_progress("Loading, please wait...");
  1061. var query = "?op=rpc&method=setprofile&id="+
  1062. param_escape(sel_rows.toString());
  1063. new Ajax.Request("backend.php", {
  1064. parameters: query,
  1065. onComplete: function(transport) {
  1066. window.location.reload();
  1067. } });
  1068. }
  1069. } else {
  1070. alert(__("Please choose a profile to activate."));
  1071. }
  1072. return false;
  1073. }
  1074. function clearFeedAccessKeys() {
  1075. var ok = confirm(__("This will invalidate all previously generated feed URLs. Continue?"));
  1076. if (ok) {
  1077. notify_progress("Clearing URLs...");
  1078. var query = "?op=pref-feeds&method=clearKeys";
  1079. new Ajax.Request("backend.php", {
  1080. parameters: query,
  1081. onComplete: function(transport) {
  1082. notify_info("Generated URLs cleared.");
  1083. } });
  1084. }
  1085. return false;
  1086. }
  1087. function resetFilterOrder() {
  1088. notify_progress("Loading, please wait...");
  1089. new Ajax.Request("backend.php", {
  1090. parameters: "?op=pref-filters&method=filtersortreset",
  1091. onComplete: function (transport) {
  1092. updateFilterList();
  1093. }
  1094. });
  1095. }
  1096. function resetFeedOrder() {
  1097. notify_progress("Loading, please wait...");
  1098. new Ajax.Request("backend.php", {
  1099. parameters: "?op=pref-feeds&method=feedsortreset",
  1100. onComplete: function (transport) {
  1101. updateFeedList();
  1102. }
  1103. });
  1104. }
  1105. function resetCatOrder() {
  1106. notify_progress("Loading, please wait...");
  1107. new Ajax.Request("backend.php", {
  1108. parameters: "?op=pref-feeds&method=catsortreset",
  1109. onComplete: function (transport) {
  1110. updateFeedList();
  1111. }
  1112. });
  1113. }
  1114. function editCat(id, item, event) {
  1115. var new_name = prompt(__('Rename category to:'), item.name);
  1116. if (new_name && new_name != item.name) {
  1117. notify_progress("Loading, please wait...");
  1118. new Ajax.Request("backend.php", {
  1119. parameters: {
  1120. op: 'pref-feeds',
  1121. method: 'renamecat',
  1122. id: id,
  1123. title: new_name,
  1124. },
  1125. onComplete: function (transport) {
  1126. updateFeedList();
  1127. }
  1128. });
  1129. }
  1130. }
  1131. function editLabel(id, event) {
  1132. var query = "backend.php?op=pref-labels&method=edit&id=" +
  1133. param_escape(id);
  1134. if (dijit.byId("labelEditDlg"))
  1135. dijit.byId("labelEditDlg").destroyRecursive();
  1136. dialog = new dijit.Dialog({
  1137. id: "labelEditDlg",
  1138. title: __("Label Editor"),
  1139. style: "width: 600px",
  1140. setLabelColor: function (id, fg, bg) {
  1141. var kind = '';
  1142. var color = '';
  1143. if (fg && bg) {
  1144. kind = 'both';
  1145. } else if (fg) {
  1146. kind = 'fg';
  1147. color = fg;
  1148. } else if (bg) {
  1149. kind = 'bg';
  1150. color = bg;
  1151. }
  1152. var query = "?op=pref-labels&method=colorset&kind=" + kind +
  1153. "&ids=" + param_escape(id) + "&fg=" + param_escape(fg) +
  1154. "&bg=" + param_escape(bg) + "&color=" + param_escape(color);
  1155. // console.log(query);
  1156. var e = $("LICID-" + id);
  1157. if (e) {
  1158. if (fg) e.style.color = fg;
  1159. if (bg) e.style.backgroundColor = bg;
  1160. }
  1161. new Ajax.Request("backend.php", {parameters: query});
  1162. updateFilterList();
  1163. },
  1164. execute: function () {
  1165. if (this.validate()) {
  1166. var caption = this.attr('value').caption;
  1167. var fg_color = this.attr('value').fg_color;
  1168. var bg_color = this.attr('value').bg_color;
  1169. var query = dojo.objectToQuery(this.attr('value'));
  1170. dijit.byId('labelTree').setNameById(id, caption);
  1171. this.setLabelColor(id, fg_color, bg_color);
  1172. this.hide();
  1173. new Ajax.Request("backend.php", {
  1174. parameters: query,
  1175. onComplete: function (transport) {
  1176. updateFilterList();
  1177. }
  1178. });
  1179. }
  1180. },
  1181. href: query
  1182. });
  1183. dialog.show();
  1184. }
  1185. function customizeCSS() {
  1186. var query = "backend.php?op=pref-prefs&method=customizeCSS";
  1187. if (dijit.byId("cssEditDlg"))
  1188. dijit.byId("cssEditDlg").destroyRecursive();
  1189. dialog = new dijit.Dialog({
  1190. id: "cssEditDlg",
  1191. title: __("Customize stylesheet"),
  1192. style: "width: 600px",
  1193. execute: function () {
  1194. notify_progress('Saving data...', true);
  1195. new Ajax.Request("backend.php", {
  1196. parameters: dojo.objectToQuery(this.attr('value')),
  1197. onComplete: function (transport) {
  1198. notify('');
  1199. window.location.reload();
  1200. }
  1201. });
  1202. },
  1203. href: query
  1204. });
  1205. dialog.show();
  1206. }
  1207. function insertSSLserial(value) {
  1208. dijit.byId("SSL_CERT_SERIAL").attr('value', value);
  1209. }
  1210. function gotoExportOpml(filename, settings) {
  1211. tmp = settings ? 1 : 0;
  1212. document.location.href = "backend.php?op=opml&method=export&filename=" + filename + "&settings=" + tmp;
  1213. }
  1214. function batchSubscribe() {
  1215. var query = "backend.php?op=pref-feeds&method=batchSubscribe";
  1216. // overlapping widgets
  1217. if (dijit.byId("batchSubDlg")) dijit.byId("batchSubDlg").destroyRecursive();
  1218. if (dijit.byId("feedAddDlg")) dijit.byId("feedAddDlg").destroyRecursive();
  1219. var dialog = new dijit.Dialog({
  1220. id: "batchSubDlg",
  1221. title: __("Batch subscribe"),
  1222. style: "width: 600px",
  1223. execute: function () {
  1224. if (this.validate()) {
  1225. console.log(dojo.objectToQuery(this.attr('value')));
  1226. notify_progress(__("Subscribing to feeds..."), true);
  1227. new Ajax.Request("backend.php", {
  1228. parameters: dojo.objectToQuery(this.attr('value')),
  1229. onComplete: function (transport) {
  1230. notify("");
  1231. updateFeedList();
  1232. dialog.hide();
  1233. }
  1234. });
  1235. }
  1236. },
  1237. href: query
  1238. });
  1239. dialog.show();
  1240. }
  1241. function clearPluginData(name) {
  1242. if (confirm(__("Clear stored data for this plugin?"))) {
  1243. notify_progress("Loading, please wait...");
  1244. new Ajax.Request("backend.php", {
  1245. parameters: "?op=pref-prefs&method=clearplugindata&name=" + param_escape(name),
  1246. onComplete: function(transport) {
  1247. notify('');
  1248. updatePrefsList();
  1249. } });
  1250. }
  1251. }
  1252. function clearSqlLog() {
  1253. if (confirm(__("Clear all messages in the error log?"))) {
  1254. notify_progress("Loading, please wait...");
  1255. var query = "?op=pref-system&method=clearLog";
  1256. new Ajax.Request("backend.php", {
  1257. parameters: query,
  1258. onComplete: function(transport) {
  1259. updateSystemList();
  1260. } });
  1261. }
  1262. }
  1263. function updateSelectedPrompt() {
  1264. // no-op shim for toggleSelectedRow()
  1265. }