prefs.js 34 KB

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