prefs.js 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514
  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() {
  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) {
  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. var 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. var 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 editSelectedUser() {
  308. var rows = getSelectedUsers();
  309. if (rows.length == 0) {
  310. alert(__("No users are selected."));
  311. return;
  312. }
  313. if (rows.length > 1) {
  314. alert(__("Please select only one user."));
  315. return;
  316. }
  317. notify("");
  318. editUser(rows[0]);
  319. }
  320. function resetSelectedUserPass() {
  321. var rows = getSelectedUsers();
  322. if (rows.length == 0) {
  323. alert(__("No users are selected."));
  324. return;
  325. }
  326. if (rows.length > 1) {
  327. alert(__("Please select only one user."));
  328. return;
  329. }
  330. var ok = confirm(__("Reset password of selected user?"));
  331. if (ok) {
  332. notify_progress("Resetting password for selected user...");
  333. var id = rows[0];
  334. var query = "?op=pref-users&method=resetPass&id=" +
  335. param_escape(id);
  336. new Ajax.Request("backend.php", {
  337. parameters: query,
  338. onComplete: function (transport) {
  339. notify_info(transport.responseText, true);
  340. }
  341. });
  342. }
  343. }
  344. function selectedUserDetails() {
  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. var id = rows[0];
  355. var query = "backend.php?op=pref-users&method=userdetails&id=" + id;
  356. if (dijit.byId("userDetailsDlg"))
  357. dijit.byId("userDetailsDlg").destroyRecursive();
  358. var dialog = new dijit.Dialog({
  359. id: "userDetailsDlg",
  360. title: __("User details"),
  361. style: "width: 600px",
  362. execute: function () {
  363. dialog.hide();
  364. },
  365. href: query
  366. });
  367. dialog.show();
  368. }
  369. function editSelectedFilter() {
  370. var rows = getSelectedFilters();
  371. if (rows.length == 0) {
  372. alert(__("No filters are selected."));
  373. return;
  374. }
  375. if (rows.length > 1) {
  376. alert(__("Please select only one filter."));
  377. return;
  378. }
  379. notify("");
  380. editFilter(rows[0]);
  381. }
  382. function joinSelectedFilters() {
  383. var rows = getSelectedFilters();
  384. if (rows.length == 0) {
  385. alert(__("No filters are selected."));
  386. return;
  387. }
  388. var ok = confirm(__("Combine selected filters?"));
  389. if (ok) {
  390. notify_progress("Joining filters...");
  391. var query = "?op=pref-filters&method=join&ids="+
  392. param_escape(rows.toString());
  393. console.log(query);
  394. new Ajax.Request("backend.php", {
  395. parameters: query,
  396. onComplete: function(transport) {
  397. updateFilterList();
  398. } });
  399. }
  400. }
  401. function editSelectedFeed() {
  402. var rows = getSelectedFeeds();
  403. if (rows.length == 0) {
  404. alert(__("No feeds are selected."));
  405. return;
  406. }
  407. if (rows.length > 1) {
  408. return editSelectedFeeds();
  409. }
  410. notify("");
  411. editFeed(rows[0], {});
  412. }
  413. function editSelectedFeeds() {
  414. var rows = getSelectedFeeds();
  415. if (rows.length == 0) {
  416. alert(__("No feeds are selected."));
  417. return;
  418. }
  419. notify_progress("Loading, please wait...");
  420. var query = "backend.php?op=pref-feeds&method=editfeeds&ids=" +
  421. param_escape(rows.toString());
  422. console.log(query);
  423. if (dijit.byId("feedEditDlg"))
  424. dijit.byId("feedEditDlg").destroyRecursive();
  425. new Ajax.Request("backend.php", {
  426. parameters: query,
  427. onComplete: function (transport) {
  428. notify("");
  429. var dialog = new dijit.Dialog({
  430. id: "feedEditDlg",
  431. title: __("Edit Multiple Feeds"),
  432. style: "width: 600px",
  433. getChildByName: function (name) {
  434. var rv = null;
  435. this.getChildren().each(
  436. function (child) {
  437. if (child.name == name) {
  438. rv = child;
  439. return;
  440. }
  441. });
  442. return rv;
  443. },
  444. toggleField: function (checkbox, elem, label) {
  445. this.getChildByName(elem).attr('disabled', !checkbox.checked);
  446. if ($(label))
  447. if (checkbox.checked)
  448. $(label).removeClassName('insensitive');
  449. else
  450. $(label).addClassName('insensitive');
  451. },
  452. execute: function () {
  453. if (this.validate() && confirm(__("Save changes to selected feeds?"))) {
  454. var query = dojo.objectToQuery(this.attr('value'));
  455. /* Form.serialize ignores unchecked checkboxes */
  456. if (!query.match("&private=") &&
  457. this.getChildByName('private').attr('disabled') == false) {
  458. query = query + "&private=false";
  459. }
  460. try {
  461. if (!query.match("&cache_images=") &&
  462. this.getChildByName('cache_images').attr('disabled') == false) {
  463. query = query + "&cache_images=false";
  464. }
  465. } catch (e) {
  466. }
  467. try {
  468. if (!query.match("&hide_images=") &&
  469. this.getChildByName('hide_images').attr('disabled') == false) {
  470. query = query + "&hide_images=false";
  471. }
  472. } catch (e) {
  473. }
  474. if (!query.match("&include_in_digest=") &&
  475. this.getChildByName('include_in_digest').attr('disabled') == false) {
  476. query = query + "&include_in_digest=false";
  477. }
  478. if (!query.match("&always_display_enclosures=") &&
  479. this.getChildByName('always_display_enclosures').attr('disabled') == false) {
  480. query = query + "&always_display_enclosures=false";
  481. }
  482. if (!query.match("&mark_unread_on_update=") &&
  483. this.getChildByName('mark_unread_on_update').attr('disabled') == false) {
  484. query = query + "&mark_unread_on_update=false";
  485. }
  486. console.log(query);
  487. notify_progress("Saving data...", true);
  488. new Ajax.Request("backend.php", {
  489. parameters: query,
  490. onComplete: function (transport) {
  491. dialog.hide();
  492. updateFeedList();
  493. }
  494. });
  495. }
  496. },
  497. content: transport.responseText
  498. });
  499. dialog.show();
  500. }
  501. });
  502. }
  503. function opmlImportComplete(iframe) {
  504. if (!iframe.contentDocument.body.innerHTML) return false;
  505. Element.show(iframe);
  506. notify('');
  507. if (dijit.byId('opmlImportDlg'))
  508. dijit.byId('opmlImportDlg').destroyRecursive();
  509. var content = iframe.contentDocument.body.innerHTML;
  510. var dialog = new dijit.Dialog({
  511. id: "opmlImportDlg",
  512. title: __("OPML Import"),
  513. style: "width: 600px",
  514. onCancel: function () {
  515. window.location.reload();
  516. },
  517. execute: function () {
  518. window.location.reload();
  519. },
  520. content: content
  521. });
  522. dialog.show();
  523. }
  524. function opmlImport() {
  525. var opml_file = $("opml_file");
  526. if (opml_file.value.length == 0) {
  527. alert(__("Please choose an OPML file first."));
  528. return false;
  529. } else {
  530. notify_progress("Importing, please wait...", true);
  531. Element.show("upload_iframe");
  532. return true;
  533. }
  534. }
  535. function updateFilterList() {
  536. var user_search = $("filter_search");
  537. var search = "";
  538. if (user_search) { search = user_search.value; }
  539. new Ajax.Request("backend.php", {
  540. parameters: "?op=pref-filters&search=" + param_escape(search),
  541. onComplete: function(transport) {
  542. dijit.byId('filterConfigTab').attr('content', transport.responseText);
  543. notify("");
  544. } });
  545. }
  546. function updateLabelList() {
  547. new Ajax.Request("backend.php", {
  548. parameters: "?op=pref-labels",
  549. onComplete: function(transport) {
  550. dijit.byId('labelConfigTab').attr('content', transport.responseText);
  551. notify("");
  552. } });
  553. }
  554. function updatePrefsList() {
  555. new Ajax.Request("backend.php", {
  556. parameters: "?op=pref-prefs",
  557. onComplete: function(transport) {
  558. dijit.byId('genConfigTab').attr('content', transport.responseText);
  559. notify("");
  560. } });
  561. }
  562. function updateSystemList() {
  563. new Ajax.Request("backend.php", {
  564. parameters: "?op=pref-system",
  565. onComplete: function(transport) {
  566. dijit.byId('systemConfigTab').attr('content', transport.responseText);
  567. notify("");
  568. } });
  569. }
  570. function selectTab(id, noupdate) {
  571. if (!noupdate) {
  572. notify_progress("Loading, please wait...");
  573. if (id == "feedConfig") {
  574. updateFeedList();
  575. } else if (id == "filterConfig") {
  576. updateFilterList();
  577. } else if (id == "labelConfig") {
  578. updateLabelList();
  579. } else if (id == "genConfig") {
  580. updatePrefsList();
  581. } else if (id == "userConfig") {
  582. updateUsersList();
  583. } else if (id == "systemConfig") {
  584. updateSystemList();
  585. }
  586. var tab = dijit.byId(id + "Tab");
  587. dijit.byId("pref-tabs").selectChild(tab);
  588. }
  589. }
  590. function init_second_stage() {
  591. document.onkeydown = pref_hotkey_handler;
  592. loading_set_progress(50);
  593. notify("");
  594. var tab = getURLParam('tab');
  595. if (tab) {
  596. tab = dijit.byId(tab + "Tab");
  597. if (tab) dijit.byId("pref-tabs").selectChild(tab);
  598. }
  599. var method = getURLParam('method');
  600. if (method == 'editFeed') {
  601. var param = getURLParam('methodparam');
  602. window.setTimeout(function() { editFeed(param) }, 100);
  603. }
  604. setTimeout(hotkey_prefix_timeout, 5*1000);
  605. }
  606. function init() {
  607. window.onerror = function (message, filename, lineno, colno, error) {
  608. report_error(message, filename, lineno, colno, error);
  609. };
  610. require(["dojo/_base/kernel",
  611. "dojo/ready",
  612. "dojo/parser",
  613. "dojo/_base/loader",
  614. "dojo/_base/html",
  615. "dijit/ColorPalette",
  616. "dijit/Dialog",
  617. "dijit/form/Button",
  618. "dijit/form/CheckBox",
  619. "dijit/form/DropDownButton",
  620. "dijit/form/FilteringSelect",
  621. "dijit/form/MultiSelect",
  622. "dijit/form/Form",
  623. "dijit/form/RadioButton",
  624. "dijit/form/ComboButton",
  625. "dijit/form/Select",
  626. "dijit/form/SimpleTextarea",
  627. "dijit/form/TextBox",
  628. "dijit/form/ValidationTextBox",
  629. "dijit/InlineEditBox",
  630. "dijit/layout/AccordionContainer",
  631. "dijit/layout/AccordionPane",
  632. "dijit/layout/BorderContainer",
  633. "dijit/layout/ContentPane",
  634. "dijit/layout/TabContainer",
  635. "dijit/Menu",
  636. "dijit/ProgressBar",
  637. "dijit/Toolbar",
  638. "dijit/Tree",
  639. "dijit/tree/dndSource",
  640. "dojo/data/ItemFileWriteStore",
  641. "fox/PrefFeedTree",
  642. "fox/PrefFilterTree",
  643. "fox/PrefLabelTree"], function (dojo, ready, parser) {
  644. ready(function () {
  645. try {
  646. parser.parse();
  647. loading_set_progress(50);
  648. var clientTzOffset = new Date().getTimezoneOffset() * 60;
  649. new Ajax.Request("backend.php", {
  650. parameters: {
  651. op: "rpc", method: "sanityCheck",
  652. clientTzOffset: clientTzOffset
  653. },
  654. onComplete: function (transport) {
  655. backend_sanity_check_callback(transport);
  656. }
  657. });
  658. } catch (e) {
  659. exception_error(e);
  660. }
  661. });
  662. });
  663. }
  664. function validatePrefsReset() {
  665. var ok = confirm(__("Reset to defaults?"));
  666. if (ok) {
  667. var query = "?op=pref-prefs&method=resetconfig";
  668. console.log(query);
  669. new Ajax.Request("backend.php", {
  670. parameters: query,
  671. onComplete: function(transport) {
  672. updatePrefsList();
  673. notify_info(transport.responseText);
  674. } });
  675. }
  676. return false;
  677. }
  678. function pref_hotkey_handler(e) {
  679. if (e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA") return;
  680. var keycode = false;
  681. var shift_key = false;
  682. var cmdline = $('cmdline');
  683. try {
  684. shift_key = e.shiftKey;
  685. } catch (e) {
  686. }
  687. if (window.event) {
  688. keycode = window.event.keyCode;
  689. } else if (e) {
  690. keycode = e.which;
  691. }
  692. var keychar = String.fromCharCode(keycode);
  693. if (keycode == 27) { // escape
  694. hotkey_prefix = false;
  695. }
  696. if (keycode == 16) return; // ignore lone shift
  697. if (keycode == 17) return; // ignore lone ctrl
  698. if (!shift_key) keychar = keychar.toLowerCase();
  699. var hotkeys = getInitParam("hotkeys");
  700. if (!hotkey_prefix && hotkeys[0].indexOf(keychar) != -1) {
  701. var date = new Date();
  702. var ts = Math.round(date.getTime() / 1000);
  703. hotkey_prefix = keychar;
  704. hotkey_prefix_pressed = ts;
  705. cmdline.innerHTML = keychar;
  706. Element.show(cmdline);
  707. return true;
  708. }
  709. Element.hide(cmdline);
  710. var hotkey = keychar.search(/[a-zA-Z0-9]/) != -1 ? keychar : "(" + keycode + ")";
  711. hotkey = hotkey_prefix ? hotkey_prefix + " " + hotkey : hotkey;
  712. hotkey_prefix = false;
  713. var hotkey_action = false;
  714. var hotkeys = getInitParam("hotkeys");
  715. for (var sequence in hotkeys[1]) {
  716. if (sequence == hotkey) {
  717. hotkey_action = hotkeys[1][sequence];
  718. break;
  719. }
  720. }
  721. switch (hotkey_action) {
  722. case "feed_subscribe":
  723. quickAddFeed();
  724. return false;
  725. case "create_label":
  726. addLabel();
  727. return false;
  728. case "create_filter":
  729. quickAddFilter();
  730. return false;
  731. case "help_dialog":
  732. //helpDialog("prefs");
  733. return false;
  734. default:
  735. console.log("unhandled action: " + hotkey_action + "; hotkey: " + hotkey);
  736. }
  737. }
  738. function removeCategory(id, item) {
  739. var ok = confirm(__("Remove category %s? Any nested feeds would be placed into Uncategorized.").replace("%s", item.name));
  740. if (ok) {
  741. var query = "?op=pref-feeds&method=removeCat&ids=" +
  742. param_escape(id);
  743. notify_progress("Removing category...");
  744. new Ajax.Request("backend.php", {
  745. parameters: query,
  746. onComplete: function (transport) {
  747. notify('');
  748. updateFeedList();
  749. }
  750. });
  751. }
  752. }
  753. function removeSelectedCategories() {
  754. var sel_rows = getSelectedCategories();
  755. if (sel_rows.length > 0) {
  756. var ok = confirm(__("Remove selected categories?"));
  757. if (ok) {
  758. notify_progress("Removing selected categories...");
  759. var query = "?op=pref-feeds&method=removeCat&ids="+
  760. param_escape(sel_rows.toString());
  761. new Ajax.Request("backend.php", {
  762. parameters: query,
  763. onComplete: function(transport) {
  764. updateFeedList();
  765. } });
  766. }
  767. } else {
  768. alert(__("No categories are selected."));
  769. }
  770. return false;
  771. }
  772. function createCategory() {
  773. var title = prompt(__("Category title:"));
  774. if (title) {
  775. notify_progress("Creating category...");
  776. var query = "?op=pref-feeds&method=addCat&cat=" +
  777. param_escape(title);
  778. new Ajax.Request("backend.php", {
  779. parameters: query,
  780. onComplete: function (transport) {
  781. notify('');
  782. updateFeedList();
  783. }
  784. });
  785. }
  786. }
  787. function showInactiveFeeds() {
  788. var query = "backend.php?op=pref-feeds&method=inactiveFeeds";
  789. if (dijit.byId("inactiveFeedsDlg"))
  790. dijit.byId("inactiveFeedsDlg").destroyRecursive();
  791. var dialog = new dijit.Dialog({
  792. id: "inactiveFeedsDlg",
  793. title: __("Feeds without recent updates"),
  794. style: "width: 600px",
  795. getSelectedFeeds: function () {
  796. return getSelectedTableRowIds("prefInactiveFeedList");
  797. },
  798. removeSelected: function () {
  799. var sel_rows = this.getSelectedFeeds();
  800. console.log(sel_rows);
  801. if (sel_rows.length > 0) {
  802. var ok = confirm(__("Remove selected feeds?"));
  803. if (ok) {
  804. notify_progress("Removing selected feeds...", true);
  805. var query = "?op=pref-feeds&method=remove&ids=" +
  806. param_escape(sel_rows.toString());
  807. new Ajax.Request("backend.php", {
  808. parameters: query,
  809. onComplete: function (transport) {
  810. notify('');
  811. dialog.hide();
  812. updateFeedList();
  813. }
  814. });
  815. }
  816. } else {
  817. alert(__("No feeds are selected."));
  818. }
  819. },
  820. execute: function () {
  821. if (this.validate()) {
  822. }
  823. },
  824. href: query
  825. });
  826. dialog.show();
  827. }
  828. function opmlRegenKey() {
  829. var ok = confirm(__("Replace current OPML publishing address with a new one?"));
  830. if (ok) {
  831. notify_progress("Trying to change address...", true);
  832. var query = "?op=pref-feeds&method=regenOPMLKey";
  833. new Ajax.Request("backend.php", {
  834. parameters: query,
  835. onComplete: function (transport) {
  836. var reply = JSON.parse(transport.responseText);
  837. var new_link = reply.link;
  838. var e = $('pub_opml_url');
  839. if (new_link) {
  840. e.href = new_link;
  841. e.innerHTML = new_link;
  842. new Effect.Highlight(e);
  843. notify('');
  844. } else {
  845. notify_error("Could not change feed URL.");
  846. }
  847. }
  848. });
  849. }
  850. return false;
  851. }
  852. function labelColorReset() {
  853. var labels = getSelectedLabels();
  854. if (labels.length > 0) {
  855. var ok = confirm(__("Reset selected labels to default colors?"));
  856. if (ok) {
  857. var query = "?op=pref-labels&method=colorreset&ids=" +
  858. param_escape(labels.toString());
  859. new Ajax.Request("backend.php", {
  860. parameters: query,
  861. onComplete: function (transport) {
  862. updateLabelList();
  863. }
  864. });
  865. }
  866. } else {
  867. alert(__("No labels are selected."));
  868. }
  869. }
  870. function inPreferences() {
  871. return true;
  872. }
  873. function editProfiles() {
  874. if (dijit.byId("profileEditDlg"))
  875. dijit.byId("profileEditDlg").destroyRecursive();
  876. var query = "backend.php?op=pref-prefs&method=editPrefProfiles";
  877. var dialog = new dijit.Dialog({
  878. id: "profileEditDlg",
  879. title: __("Settings Profiles"),
  880. style: "width: 600px",
  881. getSelectedProfiles: function () {
  882. return getSelectedTableRowIds("prefFeedProfileList");
  883. },
  884. removeSelected: function () {
  885. var sel_rows = this.getSelectedProfiles();
  886. if (sel_rows.length > 0) {
  887. var ok = confirm(__("Remove selected profiles? Active and default profiles will not be removed."));
  888. if (ok) {
  889. notify_progress("Removing selected profiles...", true);
  890. var query = "?op=rpc&method=remprofiles&ids=" +
  891. param_escape(sel_rows.toString());
  892. new Ajax.Request("backend.php", {
  893. parameters: query,
  894. onComplete: function (transport) {
  895. notify('');
  896. editProfiles();
  897. }
  898. });
  899. }
  900. } else {
  901. alert(__("No profiles are selected."));
  902. }
  903. },
  904. activateProfile: function () {
  905. var sel_rows = this.getSelectedProfiles();
  906. if (sel_rows.length == 1) {
  907. var ok = confirm(__("Activate selected profile?"));
  908. if (ok) {
  909. notify_progress("Loading, please wait...");
  910. var query = "?op=rpc&method=setprofile&id=" +
  911. param_escape(sel_rows.toString());
  912. new Ajax.Request("backend.php", {
  913. parameters: query,
  914. onComplete: function (transport) {
  915. window.location.reload();
  916. }
  917. });
  918. }
  919. } else {
  920. alert(__("Please choose a profile to activate."));
  921. }
  922. },
  923. addProfile: function () {
  924. if (this.validate()) {
  925. notify_progress("Creating profile...", true);
  926. var query = "?op=rpc&method=addprofile&title=" +
  927. param_escape(dialog.attr('value').newprofile);
  928. new Ajax.Request("backend.php", {
  929. parameters: query,
  930. onComplete: function (transport) {
  931. notify('');
  932. editProfiles();
  933. }
  934. });
  935. }
  936. },
  937. execute: function () {
  938. if (this.validate()) {
  939. }
  940. },
  941. href: query
  942. });
  943. dialog.show();
  944. }
  945. function activatePrefProfile() {
  946. var sel_rows = getSelectedFeedCats();
  947. if (sel_rows.length == 1) {
  948. var ok = confirm(__("Activate selected profile?"));
  949. if (ok) {
  950. notify_progress("Loading, please wait...");
  951. var query = "?op=rpc&method=setprofile&id="+
  952. param_escape(sel_rows.toString());
  953. new Ajax.Request("backend.php", {
  954. parameters: query,
  955. onComplete: function(transport) {
  956. window.location.reload();
  957. } });
  958. }
  959. } else {
  960. alert(__("Please choose a profile to activate."));
  961. }
  962. return false;
  963. }
  964. function clearFeedAccessKeys() {
  965. var ok = confirm(__("This will invalidate all previously generated feed URLs. Continue?"));
  966. if (ok) {
  967. notify_progress("Clearing URLs...");
  968. var query = "?op=pref-feeds&method=clearKeys";
  969. new Ajax.Request("backend.php", {
  970. parameters: query,
  971. onComplete: function(transport) {
  972. notify_info("Generated URLs cleared.");
  973. } });
  974. }
  975. return false;
  976. }
  977. function resetFilterOrder() {
  978. notify_progress("Loading, please wait...");
  979. new Ajax.Request("backend.php", {
  980. parameters: "?op=pref-filters&method=filtersortreset",
  981. onComplete: function (transport) {
  982. updateFilterList();
  983. }
  984. });
  985. }
  986. function resetFeedOrder() {
  987. notify_progress("Loading, please wait...");
  988. new Ajax.Request("backend.php", {
  989. parameters: "?op=pref-feeds&method=feedsortreset",
  990. onComplete: function (transport) {
  991. updateFeedList();
  992. }
  993. });
  994. }
  995. function resetCatOrder() {
  996. notify_progress("Loading, please wait...");
  997. new Ajax.Request("backend.php", {
  998. parameters: "?op=pref-feeds&method=catsortreset",
  999. onComplete: function (transport) {
  1000. updateFeedList();
  1001. }
  1002. });
  1003. }
  1004. function editCat(id, item) {
  1005. var new_name = prompt(__('Rename category to:'), item.name);
  1006. if (new_name && new_name != item.name) {
  1007. notify_progress("Loading, please wait...");
  1008. new Ajax.Request("backend.php", {
  1009. parameters: {
  1010. op: 'pref-feeds',
  1011. method: 'renamecat',
  1012. id: id,
  1013. title: new_name,
  1014. },
  1015. onComplete: function (transport) {
  1016. updateFeedList();
  1017. }
  1018. });
  1019. }
  1020. }
  1021. function editLabel(id) {
  1022. var query = "backend.php?op=pref-labels&method=edit&id=" +
  1023. param_escape(id);
  1024. if (dijit.byId("labelEditDlg"))
  1025. dijit.byId("labelEditDlg").destroyRecursive();
  1026. var dialog = new dijit.Dialog({
  1027. id: "labelEditDlg",
  1028. title: __("Label Editor"),
  1029. style: "width: 600px",
  1030. setLabelColor: function (id, fg, bg) {
  1031. var kind = '';
  1032. var color = '';
  1033. if (fg && bg) {
  1034. kind = 'both';
  1035. } else if (fg) {
  1036. kind = 'fg';
  1037. color = fg;
  1038. } else if (bg) {
  1039. kind = 'bg';
  1040. color = bg;
  1041. }
  1042. var query = "?op=pref-labels&method=colorset&kind=" + kind +
  1043. "&ids=" + param_escape(id) + "&fg=" + param_escape(fg) +
  1044. "&bg=" + param_escape(bg) + "&color=" + param_escape(color);
  1045. // console.log(query);
  1046. var e = $("LICID-" + id);
  1047. if (e) {
  1048. if (fg) e.style.color = fg;
  1049. if (bg) e.style.backgroundColor = bg;
  1050. }
  1051. new Ajax.Request("backend.php", {parameters: query});
  1052. updateFilterList();
  1053. },
  1054. execute: function () {
  1055. if (this.validate()) {
  1056. var caption = this.attr('value').caption;
  1057. var fg_color = this.attr('value').fg_color;
  1058. var bg_color = this.attr('value').bg_color;
  1059. var query = dojo.objectToQuery(this.attr('value'));
  1060. dijit.byId('labelTree').setNameById(id, caption);
  1061. this.setLabelColor(id, fg_color, bg_color);
  1062. this.hide();
  1063. new Ajax.Request("backend.php", {
  1064. parameters: query,
  1065. onComplete: function (transport) {
  1066. updateFilterList();
  1067. }
  1068. });
  1069. }
  1070. },
  1071. href: query
  1072. });
  1073. dialog.show();
  1074. }
  1075. function customizeCSS() {
  1076. var query = "backend.php?op=pref-prefs&method=customizeCSS";
  1077. if (dijit.byId("cssEditDlg"))
  1078. dijit.byId("cssEditDlg").destroyRecursive();
  1079. var dialog = new dijit.Dialog({
  1080. id: "cssEditDlg",
  1081. title: __("Customize stylesheet"),
  1082. style: "width: 600px",
  1083. execute: function () {
  1084. notify_progress('Saving data...', true);
  1085. new Ajax.Request("backend.php", {
  1086. parameters: dojo.objectToQuery(this.attr('value')),
  1087. onComplete: function (transport) {
  1088. notify('');
  1089. window.location.reload();
  1090. }
  1091. });
  1092. },
  1093. href: query
  1094. });
  1095. dialog.show();
  1096. }
  1097. function insertSSLserial(value) {
  1098. dijit.byId("SSL_CERT_SERIAL").attr('value', value);
  1099. }
  1100. function gotoExportOpml(filename, settings) {
  1101. var tmp = settings ? 1 : 0;
  1102. document.location.href = "backend.php?op=opml&method=export&filename=" + filename + "&settings=" + tmp;
  1103. }
  1104. function batchSubscribe() {
  1105. var query = "backend.php?op=pref-feeds&method=batchSubscribe";
  1106. // overlapping widgets
  1107. if (dijit.byId("batchSubDlg")) dijit.byId("batchSubDlg").destroyRecursive();
  1108. if (dijit.byId("feedAddDlg")) dijit.byId("feedAddDlg").destroyRecursive();
  1109. var dialog = new dijit.Dialog({
  1110. id: "batchSubDlg",
  1111. title: __("Batch subscribe"),
  1112. style: "width: 600px",
  1113. execute: function () {
  1114. if (this.validate()) {
  1115. console.log(dojo.objectToQuery(this.attr('value')));
  1116. notify_progress(__("Subscribing to feeds..."), true);
  1117. new Ajax.Request("backend.php", {
  1118. parameters: dojo.objectToQuery(this.attr('value')),
  1119. onComplete: function (transport) {
  1120. notify("");
  1121. updateFeedList();
  1122. dialog.hide();
  1123. }
  1124. });
  1125. }
  1126. },
  1127. href: query
  1128. });
  1129. dialog.show();
  1130. }
  1131. function clearPluginData(name) {
  1132. if (confirm(__("Clear stored data for this plugin?"))) {
  1133. notify_progress("Loading, please wait...");
  1134. new Ajax.Request("backend.php", {
  1135. parameters: "?op=pref-prefs&method=clearplugindata&name=" + param_escape(name),
  1136. onComplete: function(transport) {
  1137. notify('');
  1138. updatePrefsList();
  1139. } });
  1140. }
  1141. }
  1142. function clearSqlLog() {
  1143. if (confirm(__("Clear all messages in the error log?"))) {
  1144. notify_progress("Loading, please wait...");
  1145. var query = "?op=pref-system&method=clearLog";
  1146. new Ajax.Request("backend.php", {
  1147. parameters: query,
  1148. onComplete: function(transport) {
  1149. updateSystemList();
  1150. } });
  1151. }
  1152. }
  1153. function updateSelectedPrompt() {
  1154. // no-op shim for toggleSelectedRow()
  1155. }