]> git.wh0rd.org - tt-rss.git/blame - js/tt-rss.js
create_published_article: validate url
[tt-rss.git] / js / tt-rss.js
CommitLineData
76798ff3 1var total_unread = 0;
806a3d14 2var global_unread = -1;
2bf6e0a8 3var firsttime_update = true;
3ea91b2d 4var _active_feed_id = undefined;
3d72bbdb 5var _active_feed_is_cat = false;
93f66472 6var hotkey_prefix = false;
164469f9 7var hotkey_prefix_pressed = false;
f8fb4498
AD
8var _force_scheduled_update = false;
9var last_scheduled_update = false;
a5550322 10
6237ea05
AD
11var _rpc_seq = 0;
12
13function next_seq() {
14 _rpc_seq += 1;
15 return _rpc_seq;
16}
17
18function get_seq() {
19 return _rpc_seq;
20}
21
3d72bbdb
AD
22function activeFeedIsCat() {
23 return _active_feed_is_cat;
24}
25
26function getActiveFeedId() {
3d72bbdb 27 try {
50eefedb 28 //console.log("gAFID: " + _active_feed_id);
3d72bbdb
AD
29 return _active_feed_id;
30 } catch (e) {
31 exception_error("getActiveFeedId", e);
32 }
33}
34
35function setActiveFeedId(id, is_cat) {
3d72bbdb 36 try {
3d72bbdb
AD
37 _active_feed_id = id;
38
39 if (is_cat != undefined) {
40 _active_feed_is_cat = is_cat;
41 }
42
fcf70c51
AD
43 selectFeed(id, is_cat);
44
854a2ace
AD
45 dijit.byId("include_children").attr("disabled", !(is_cat && id > 0));
46
09101297 47
3d72bbdb
AD
48 } catch (e) {
49 exception_error("setActiveFeedId", e);
50 }
51}
52
53
50eefedb
AD
54function updateFeedList() {
55 try {
102cfe73 56
009646d2 57// $("feeds-holder").innerHTML = "<div id=\"feedlistLoading\">" +
9c99281f
AD
58// __("Loading, please wait...") + "</div>";
59
60 Element.show("feedlistLoading");
61
102cfe73
AD
62 if (dijit.byId("feedTree")) {
63 dijit.byId("feedTree").destroyRecursive();
50eefedb 64 }
102cfe73
AD
65
66 var store = new dojo.data.ItemFileWriteStore({
2ecd2df5 67 url: "backend.php?op=pref_feeds&method=getfeedtree&mode=2"});
102cfe73 68
e032e2e7 69 var treeModel = new fox.FeedStoreModel({
102cfe73
AD
70 store: store,
71 query: {
854a2ace 72 "type": getInitParam('enable_feed_cats') == 1 ? "category" : "feed"
102cfe73
AD
73 },
74 rootId: "root",
75 rootLabel: "Feeds",
76 childrenAttrs: ["items"]
77 });
78
05f224a3 79 var tree = new fox.FeedTree({
247bb1bf 80 persist: false,
102cfe73 81 model: treeModel,
102cfe73
AD
82 onOpen: function (item, node) {
83 var id = String(item.id);
84 var cat_id = id.substr(id.indexOf(":")+1);
85
009646d2 86 new Ajax.Request("backend.php",
f30ef1fa 87 { parameters: "backend.php?op=feeds&method=collapse&cid=" +
1a709d21 88 param_escape(cat_id) + "&mode=0" } );
102cfe73
AD
89 },
90 onClose: function (item, node) {
91 var id = String(item.id);
92 var cat_id = id.substr(id.indexOf(":")+1);
93
009646d2 94 new Ajax.Request("backend.php",
f30ef1fa 95 { parameters: "backend.php?op=feeds&method=collapse&cid=" +
1a709d21 96 param_escape(cat_id) + "&mode=1" } );
102cfe73
AD
97
98 },
99 onClick: function (item, node) {
100 var id = String(item.id);
101 var is_cat = id.match("^CAT:");
102 var feed = id.substr(id.indexOf(":")+1);
103 viewfeed(feed, '', is_cat);
104 return false;
105 },
106 openOnClick: false,
107 showRoot: false,
108 id: "feedTree",
109 }, "feedTree");
110
2ecd2df5
AD
111 _force_scheduled_update = true;
112
997429c2 113/* var menu = new dijit.Menu({id: 'feedMenu'});
009646d2 114
997429c2
AD
115 menu.addChild(new dijit.MenuItem({
116 label: "Simple menu item"
117 }));
118
119// menu.bindDomNode(tree.domNode); */
009646d2
AD
120
121 var tmph = dojo.connect(dijit.byId('feedMenu'), '_openMyself', function (event) {
997429c2
AD
122 console.log(dijit.getEnclosingWidget(event.target));
123 dojo.disconnect(tmph);
124 });
125
102cfe73
AD
126 $("feeds-holder").appendChild(tree.domNode);
127
9c99281f
AD
128 var tmph = dojo.connect(tree, 'onLoad', function() {
129 dojo.disconnect(tmph);
130 Element.hide("feedlistLoading");
1a709d21
AD
131
132 tree.collapseHiddenCats();
133
1beea800 134 feedlist_init();
997429c2
AD
135
136// var node = dijit.byId("feedTree")._itemNodesMap['FEED:-2'][0].domNode
137// menu.bindDomNode(node);
138
fcc36744 139 loading_set_progress(25);
9c99281f
AD
140 });
141
102cfe73 142 tree.startup();
e1123aee 143
50eefedb
AD
144 } catch (e) {
145 exception_error("updateFeedList", e);
146 }
1a66d16e 147}
175847de 148
476cac42 149function catchupAllFeeds() {
076682aa 150
f8232151 151 var str = __("Mark all articles as read?");
476cac42 152
f8232151 153 if (getInitParam("confirm_feed_catchup") != 1 || confirm(str)) {
476cac42 154
f30ef1fa 155 var query_str = "backend.php?op=feeds&method=catchupAll";
1a66d16e 156
f8232151 157 notify_progress("Marking all feeds as read...");
476cac42 158
f8fb4498 159 //console.log("catchupAllFeeds Q=" + query_str);
fc69e641 160
b4e75b2a
AD
161 new Ajax.Request("backend.php", {
162 parameters: query_str,
009646d2
AD
163 onComplete: function(transport) {
164 feedlist_callback2(transport);
f8232151
AD
165 } });
166
167 global_unread = 0;
168 updateTitle("");
169 }
476cac42 170}
1cd17194 171
f30ef1fa 172function viewCurrentFeed(method) {
973c4a64 173 console.log("viewCurrentFeed");
1a66d16e 174
ec6e2fd3 175 if (getActiveFeedId() != undefined) {
f30ef1fa 176 viewfeed(getActiveFeedId(), method, activeFeedIsCat());
f0601b87 177 }
164f4738 178 return false; // block unneeded form submits
f0601b87
AD
179}
180
40d13c28 181function timeout() {
a598370d
AD
182 if (getInitParam("bw_limit") == "1") return;
183
f8fb4498
AD
184 try {
185 var date = new Date();
186 var ts = Math.round(date.getTime() / 1000);
187
188 if (ts - last_scheduled_update > 10 || _force_scheduled_update) {
f5de0d8d 189
ac49453b
AD
190 //console.log("timeout()");
191
f8fb4498 192 window.clearTimeout(counter_timeout_id);
009646d2 193
f30ef1fa 194 var query_str = "?op=rpc&method=getAllCounters&seq=" + next_seq();
009646d2 195
f8fb4498 196 var omode;
009646d2 197
f8fb4498
AD
198 if (firsttime_update && !navigator.userAgent.match("Opera")) {
199 firsttime_update = false;
200 omode = "T";
201 } else {
9c99281f 202 omode = "flc";
f8fb4498 203 }
009646d2 204
f8fb4498 205 query_str = query_str + "&omode=" + omode;
ac49453b
AD
206
207 if (!_force_scheduled_update)
208 query_str = query_str + "&last_article_id=" + getInitParam("last_article_id");
009646d2 209
f8fb4498 210 //console.log("[timeout]" + query_str);
009646d2 211
f8fb4498
AD
212 new Ajax.Request("backend.php", {
213 parameters: query_str,
009646d2 214 onComplete: function(transport) {
563b9c78 215 handle_rpc_json(transport, !_force_scheduled_update);
47fb32b0 216 _force_scheduled_update = false;
f8fb4498
AD
217 } });
218
219 last_scheduled_update = ts;
220 }
221
222 } catch (e) {
223 exception_error("timeout", e);
224 }
225
226 setTimeout("timeout()", 3000);
ac53063a
AD
227}
228
f0601b87 229function search() {
3f363052 230 var query = "backend.php?op=dlg&method=search&param=" +
973fe3c6
AD
231 param_escape(getActiveFeedId() + ":" + activeFeedIsCat());
232
233 if (dijit.byId("searchDlg"))
234 dijit.byId("searchDlg").destroyRecursive();
235
236 dialog = new dijit.Dialog({
237 id: "searchDlg",
238 title: __("Search"),
239 style: "width: 600px",
240 execute: function() {
241 if (this.validate()) {
242 _search_query = dojo.objectToQuery(this.attr('value'));
243 this.hide();
244 viewCurrentFeed();
245 }
246 },
247 href: query});
248
249 dialog.show();
76798ff3 250}
1cd17194 251
f8fb4498 252function updateTitle() {
fc69e641 253 var tmp = "Tiny Tiny RSS";
21703604 254
fc69e641
AD
255 if (global_unread > 0) {
256 tmp = tmp + " (" + global_unread + ")";
257 }
258
fdf47b9d
AD
259 if (window.fluid) {
260 if (global_unread > 0) {
261 window.fluid.dockBadge = global_unread;
262 } else {
263 window.fluid.dockBadge = "";
264 }
265 }
266
fc69e641
AD
267 document.title = tmp;
268}
269
22a93ad8 270function genericSanityCheck() {
57937c42 271 setCookie("ttrss_test", "TEST");
009646d2 272
57937c42 273 if (getCookie("ttrss_test") != "TEST") {
68535211 274 return fatalError(2);
295f9b42
AD
275 }
276
22a93ad8
AD
277 return true;
278}
279
280function init() {
7719618b 281 try {
04150375 282 //dojo.registerModulePath("fox", "../../js/");
05f224a3
AD
283
284 dojo.require("fox.FeedTree");
285
8d3cb8c0
AD
286 if (typeof themeBeforeLayout == 'function') {
287 themeBeforeLayout();
288 }
289
1354d172
AD
290 dojo.require("dijit.ColorPalette");
291 dojo.require("dijit.Dialog");
292 dojo.require("dijit.form.Button");
293 dojo.require("dijit.form.CheckBox");
294 dojo.require("dijit.form.DropDownButton");
295 dojo.require("dijit.form.FilteringSelect");
296 dojo.require("dijit.form.Form");
297 dojo.require("dijit.form.RadioButton");
298 dojo.require("dijit.form.Select");
299 dojo.require("dijit.form.SimpleTextarea");
300 dojo.require("dijit.form.TextBox");
301 dojo.require("dijit.form.ValidationTextBox");
302 dojo.require("dijit.InlineEditBox");
303 dojo.require("dijit.layout.AccordionContainer");
304 dojo.require("dijit.layout.BorderContainer");
305 dojo.require("dijit.layout.ContentPane");
306 dojo.require("dijit.layout.TabContainer");
307 dojo.require("dijit.Menu");
308 dojo.require("dijit.ProgressBar");
309 dojo.require("dijit.ProgressBar");
310 dojo.require("dijit.Toolbar");
311 dojo.require("dijit.Tree");
312 dojo.require("dijit.tree.dndSource");
313 dojo.require("dojo.data.ItemFileWriteStore");
314
d80b3f3d
AD
315 dojo.parser.parse();
316
009646d2 317 if (!genericSanityCheck())
68535211 318 return false;
ac43eba1 319
fcc36744 320 loading_set_progress(20);
fca95d5f 321
c3edc667
AD
322 var hasAudio = !!((myAudioTag = document.createElement('audio')).canPlayType);
323
b4e75b2a 324 new Ajax.Request("backend.php", {
f30ef1fa 325 parameters: {op: "rpc", method: "sanityCheck", hasAudio: hasAudio},
9ca945a6
AD
326 onComplete: function(transport) {
327 backend_sanity_check_callback(transport);
328 } });
47179952 329
7719618b
AD
330 } catch (e) {
331 exception_error("init", e);
a8d28f48 332 }
7719618b 333}
86741347 334
7719618b 335function init_second_stage() {
295f9b42 336
7719618b 337 try {
118f4180
AD
338 dojo.addOnLoad(function() {
339 updateFeedList();
340 closeArticlePanel();
341
342 if (typeof themeAfterLayout == 'function') {
343 themeAfterLayout();
344 }
345
346 });
2f587484 347
57937c42 348 delCookie("ttrss_test");
770bbb02 349
40496720 350 var toolbar = document.forms["main_toolbar_form"];
f31673f7 351
009646d2 352 dijit.getEnclosingWidget(toolbar.view_mode).attr('value',
37f1a234
AD
353 getInitParam("default_view_mode"));
354
009646d2 355 dijit.getEnclosingWidget(toolbar.order_by).attr('value',
37f1a234 356 getInitParam("default_view_order_by"));
c6784aea 357
854a2ace
AD
358
359 if (getInitParam("enable_feed_cats") == 0)
360 Element.hide(dijit.byId("include_children").domNode);
361
3ea91b2d
AD
362 dijit.byId("include_children").attr("checked",
363 getInitParam("default_include_children"));
854a2ace 364
61a20560 365 feeds_sort_by_unread = getInitParam("feeds_sort_by_unread") == 1;
5f136c9a 366
fcc36744 367 loading_set_progress(30);
730dbf19 368
37c03d3a
AD
369 // can't use cache_clear() here because viewfeed might not have initialized yet
370 if ('sessionStorage' in window && window['sessionStorage'] !== null)
371 sessionStorage.clear();
ff0010c1 372
4a28ab44 373 console.log("second stage ok");
fcf70c51 374
7719618b
AD
375 } catch (e) {
376 exception_error("init_second_stage", e);
2f587484 377 }
1cd17194 378}
ac43eba1 379
c09ec856 380function quickMenuGo(opid) {
bb3423cf 381 try {
bb3423cf
AD
382 if (opid == "qmcPrefs") {
383 gotoPreferences();
384 }
009646d2 385
9c99281f
AD
386 if (opid == "qmcTagCloud") {
387 displayDlg("printTagCloud");
388 }
389
147f5632
CM
390 if (opid == "qmcTagSelect") {
391 displayDlg("printTagSelect");
392 }
393
bb3423cf 394 if (opid == "qmcSearch") {
973fe3c6 395 search();
6de5d056
AD
396 return;
397 }
009646d2 398
bb3423cf 399 if (opid == "qmcAddFeed") {
3393238d 400 quickAddFeed();
bb3423cf 401 return;
69668465 402 }
7086277c 403
1bf679a3
AD
404 if (opid == "qmcDigest") {
405 window.location.href = "digest.php";
406 return;
407 }
408
7086277c 409 if (opid == "qmcEditFeed") {
33f31dfd
AD
410 if (activeFeedIsCat())
411 alert(__("You can't edit this kind of feed."));
412 else
413 editFeed(getActiveFeedId());
414 return;
7086277c 415 }
009646d2 416
bb3423cf
AD
417 if (opid == "qmcRemoveFeed") {
418 var actid = getActiveFeedId();
442d77f1
AD
419
420 if (activeFeedIsCat()) {
89cb787e 421 alert(__("You can't unsubscribe from the category."));
442d77f1 422 return;
009646d2 423 }
442d77f1
AD
424
425 if (!actid) {
89cb787e 426 alert(__("Please select some feed first."));
bb3423cf
AD
427 return;
428 }
64a2875d
AD
429
430 var fn = getFeedName(actid);
89cb787e
AD
431
432 var pr = __("Unsubscribe from %s?").replace("%s", fn);
433
434 if (confirm(pr)) {
e978f78d 435 unsubscribeFeed(actid);
bb3423cf 436 }
009646d2 437
bb3423cf
AD
438 return;
439 }
d1f0c584 440
bb3423cf
AD
441 if (opid == "qmcCatchupAll") {
442 catchupAllFeeds();
443 return;
444 }
009646d2 445
bb3423cf
AD
446 if (opid == "qmcShowOnlyUnread") {
447 toggleDispRead();
448 return;
449 }
009646d2 450
bb3423cf 451 if (opid == "qmcAddFilter") {
db4e4539
AD
452 quickAddFilter();
453 return;
bb3423cf 454 }
0979b696 455
1380f8ee
AD
456 if (opid == "qmcAddLabel") {
457 addLabel();
db4e4539 458 return;
1380f8ee
AD
459 }
460
9a85081a
AD
461 if (opid == "qmcRescoreFeed") {
462 rescoreCurrentFeed();
db4e4539 463 return;
9a85081a
AD
464 }
465
238eff01 466 if (opid == "qmcHKhelp") {
66be620a
AD
467 new Ajax.Request("backend.php", {
468 parameters: "?op=backend&method=help&topic=main",
469 onComplete: function(transport) {
470 $("hotkey_help_overlay").innerHTML = transport.responseText;
471 Effect.Appear("hotkey_help_overlay", {duration : 0.3});
472 } });
238eff01
AD
473 }
474
bb3423cf
AD
475 } catch (e) {
476 exception_error("quickMenuGo", e);
a24f525c 477 }
e2f8f7b4
AD
478}
479
3745788e 480function toggleDispRead() {
7f123cda 481 try {
3745788e 482
dbfc9522 483 var hide = !(getInitParam("hide_read_feeds") == "1");
3745788e 484
dbfc9522 485 hideOrShowFeeds(hide);
e8bd0da9 486
f30ef1fa 487 var query = "?op=rpc&method=setpref&key=HIDE_READ_FEEDS&value=" +
dbfc9522 488 param_escape(hide);
e8bd0da9 489
05f224a3
AD
490 setInitParam("hide_read_feeds", hide);
491
dbfc9522
AD
492 new Ajax.Request("backend.php", {
493 parameters: query,
009646d2 494 onComplete: function(transport) {
dbfc9522 495 } });
009646d2 496
7f123cda
AD
497 } catch (e) {
498 exception_error("toggleDispRead", e);
3745788e 499 }
3745788e 500}
295f9b42 501
563b9c78 502function parse_runtime_info(data) {
71ad883b 503
f8fb4498 504 //console.log("parsing runtime info...");
1cb7492d 505
c4f7ba80
AD
506 for (k in data) {
507 var v = data[k];
3ac2b520 508
563b9c78 509// console.log("RI: " + k + " => " + v);
1cb7492d 510
d9fa39f1 511 if (k == "new_version_available") {
acac8448 512 var icon = $("newVersionIcon");
d9fa39f1
AD
513 if (icon) {
514 if (v == "1") {
515 icon.style.display = "inline";
516 } else {
517 icon.style.display = "none";
518 }
519 }
5ae8f858 520 return;
d9fa39f1
AD
521 }
522
ef16ae37 523 if (k == "daemon_is_running" && v != 1) {
8e00ae9b 524 notify_error("<span onclick=\"javascript:explainError(1)\">Update daemon is not running.</span>", true);
5ae8f858 525 return;
8e00ae9b
AD
526 }
527
528 if (k == "daemon_stamp_ok" && v != 1) {
529 notify_error("<span onclick=\"javascript:explainError(3)\">Update daemon is not updating feeds.</span>", true);
5ae8f858 530 return;
8e00ae9b
AD
531 }
532
8cd576a1
AD
533 if (k == "max_feed_id" || k == "num_feeds") {
534 if (init_params[k] != v) {
535 console.log("feed count changed, need to reload feedlist.");
536 updateFeedList();
537 }
538 }
539
009646d2 540 init_params[k] = v;
5ae8f858 541 notify('');
71ad883b
AD
542 }
543}
fce24838 544
8389b150
AD
545function collapse_feedlist() {
546 try {
0ce61157
AD
547
548 if (!Element.visible('feeds-holder')) {
549 Element.show('feeds-holder');
ab7b5042 550 Element.show('feeds-holder_splitter');
0ce61157
AD
551 $("collapse_feeds_btn").innerHTML = "&lt;&lt;";
552 } else {
553 Element.hide('feeds-holder');
ab7b5042 554 Element.hide('feeds-holder_splitter');
0ce61157
AD
555 $("collapse_feeds_btn").innerHTML = "&gt;&gt;";
556 }
557
558 dijit.byId("main").resize();
6e4f4ce1 559
f30ef1fa 560 query = "?op=rpc&method=setpref&key=_COLLAPSED_FEEDLIST&value=true";
fcf70c51 561 new Ajax.Request("backend.php", { parameters: query });
6e4f4ce1 562
8389b150 563 } catch (e) {
f88c7814 564 exception_error("collapse_feedlist", e);
8389b150 565 }
3c2d7945 566}
8389b150 567
3c2d7945 568function viewModeChanged() {
4f79e9aa 569 cache_clear();
e331188f 570 return viewCurrentFeed('');
3c2d7945 571}
8389b150 572
3c2d7945 573function viewLimitChanged() {
e331188f 574 return viewCurrentFeed('');
8389b150 575}
546499a9 576
9bf3f101 577/* function adjustArticleScore(id, score) {
546499a9
AD
578 try {
579
580 var pr = prompt(__("Assign score to article:"), score);
581
582 if (pr != undefined) {
f30ef1fa 583 var query = "?op=rpc&method=setScore&id=" + id + "&score=" + pr;
546499a9 584
b4e75b2a
AD
585 new Ajax.Request("backend.php", {
586 parameters: query,
546499a9
AD
587 onComplete: function(transport) {
588 viewCurrentFeed();
589 } });
590
591 }
592 } catch (e) {
438f2ce9 593 exception_error("adjustArticleScore", e);
546499a9 594 }
9bf3f101 595} */
9a85081a
AD
596
597function rescoreCurrentFeed() {
598
599 var actid = getActiveFeedId();
600
9c99281f 601 if (activeFeedIsCat() || actid < 0) {
9a85081a
AD
602 alert(__("You can't rescore this kind of feed."));
603 return;
009646d2 604 }
9a85081a
AD
605
606 if (!actid) {
607 alert(__("Please select some feed first."));
608 return;
609 }
610
611 var fn = getFeedName(actid);
69811a7d 612 var pr = __("Rescore articles in %s?").replace("%s", fn);
9a85081a
AD
613
614 if (confirm(pr)) {
615 notify_progress("Rescoring articles...");
616
f30ef1fa 617 var query = "?op=pref-feeds&method=rescore&quiet=1&ids=" + actid;
9a85081a 618
b4e75b2a
AD
619 new Ajax.Request("backend.php", {
620 parameters: query,
621 onComplete: function(transport) {
622 viewCurrentFeed();
623 } });
9a85081a
AD
624 }
625}
626
93f66472 627function hotkey_handler(e) {
93f66472
AD
628 try {
629
8386f861 630 if (e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA") return;
18606807 631
e331188f 632 var keycode = false;
93f66472
AD
633 var shift_key = false;
634
78935092 635 var cmdline = $('cmdline');
93f66472
AD
636
637 try {
638 shift_key = e.shiftKey;
639 } catch (e) {
640
641 }
009646d2 642
93f66472
AD
643 if (window.event) {
644 keycode = window.event.keyCode;
645 } else if (e) {
646 keycode = e.which;
647 }
648
eec498c3 649 var keychar = String.fromCharCode(keycode);
c177f2e6 650
93f66472
AD
651 if (keycode == 27) { // escape
652 if (Element.visible("hotkey_help_overlay")) {
653 Element.hide("hotkey_help_overlay");
654 }
655 hotkey_prefix = false;
009646d2 656 }
93f66472 657
93f66472 658 if (keycode == 16) return; // ignore lone shift
ac743c83 659 if (keycode == 17) return; // ignore lone ctrl
93f66472 660
2bb3f957 661 if ((keycode == 70 || keycode == 67 || keycode == 71 || keycode == 65)
fe3320d2 662 && !hotkey_prefix) {
344702be 663
164469f9
AD
664 var date = new Date();
665 var ts = Math.round(date.getTime() / 1000);
666
93f66472 667 hotkey_prefix = keycode;
164469f9 668 hotkey_prefix_pressed = ts;
78935092
AD
669
670 cmdline.innerHTML = keychar;
671 Element.show(cmdline);
672
84c7b824 673 console.log("KP: PREFIX=" + keycode + " CHAR=" + keychar + " TS=" + ts);
344702be 674 return true;
93f66472
AD
675 }
676
677 if (Element.visible("hotkey_help_overlay")) {
678 Element.hide("hotkey_help_overlay");
679 }
680
681 /* Global hotkeys */
682
78935092
AD
683 Element.hide(cmdline);
684
93f66472
AD
685 if (!hotkey_prefix) {
686
0dfc968b
AD
687 if (keycode == 27) { // escape
688 closeArticlePanel();
689 return;
690 }
691
fe66e229
CC
692 if (keycode == 69) { // e
693 var id = getActiveArticleId();
694 emailArticle(id);
695 }
696
eec498c3 697 if ((keycode == 191 || keychar == '?') && shift_key) { // ?
6802e1be
AD
698
699 new Ajax.Request("backend.php", {
700 parameters: "?op=backend&method=help&topic=main",
701 onComplete: function(transport) {
702 $("hotkey_help_overlay").innerHTML = transport.responseText;
703 Effect.Appear("hotkey_help_overlay", {duration : 0.3});
704 } });
eec498c3 705 return false;
93f66472 706 }
60ea2377 707
eec498c3 708 if (keycode == 191 || keychar == '/') { // /
973fe3c6 709 search();
eec498c3 710 return false;
93f66472
AD
711 }
712
4c58e285 713 if (keycode == 74 && !shift_key) { // j
d026d372 714 var rv = dijit.byId("feedTree").getPreviousFeed(
69de6b46
AD
715 getActiveFeedId(), activeFeedIsCat());
716
717 if (rv) viewfeed(rv[0], '', rv[1]);
718
19d7bfcd 719 return;
93f66472 720 }
009646d2 721
93f66472 722 if (keycode == 75) { // k
d026d372 723 var rv = dijit.byId("feedTree").getNextFeed(
69de6b46
AD
724 getActiveFeedId(), activeFeedIsCat());
725
726 if (rv) viewfeed(rv[0], '', rv[1]);
727
19d7bfcd 728 return;
93f66472
AD
729 }
730
a411875b 731 if (shift_key && keycode == 40) { // shift-down
62f2d58f 732 catchupRelativeToArticle(1);
19d7bfcd 733 return;
62f2d58f
AD
734 }
735
a411875b 736 if (shift_key && keycode == 38) { // shift-up
62f2d58f 737 catchupRelativeToArticle(0);
19d7bfcd 738 return;
62f2d58f
AD
739 }
740
a411875b 741 if (shift_key && keycode == 78) { // N
009646d2 742 scrollArticle(50);
a411875b
AD
743 return;
744 }
745
746 if (shift_key && keycode == 80) { // P
009646d2 747 scrollArticle(-50);
a411875b
AD
748 return;
749 }
750
0129090b 751 if (keycode == 68 && shift_key) { // shift-D
1ede5814 752 dismissSelectedArticles();
9ad53991 753 return;
1ede5814
AD
754 }
755
756 if (keycode == 88 && shift_key) { // shift-X
757 dismissReadArticles();
9ad53991 758 return;
0129090b 759 }
a411875b 760
93f66472
AD
761 if (keycode == 78 || keycode == 40) { // n, down
762 if (typeof moveToPost != 'undefined') {
314fcd2b 763 moveToPost('next');
dad14b51 764 return false;
93f66472
AD
765 }
766 }
009646d2 767
93f66472
AD
768 if (keycode == 80 || keycode == 38) { // p, up
769 if (typeof moveToPost != 'undefined') {
314fcd2b 770 moveToPost('prev');
dad14b51 771 return false;
93f66472
AD
772 }
773 }
774
775 if (keycode == 83 && shift_key) { // S
ac743c83 776 selectionTogglePublished(undefined, false, true);
19d7bfcd 777 return;
93f66472
AD
778 }
779
780 if (keycode == 83) { // s
ac743c83 781 selectionToggleMarked(undefined, false, true);
19d7bfcd 782 return;
93f66472
AD
783 }
784
93f66472 785 if (keycode == 85) { // u
e331188f 786 selectionToggleUnread(undefined, false, true);
19d7bfcd 787 return;
93f66472
AD
788 }
789
314fcd2b 790 if (keycode == 84 && shift_key) { // T
93f66472
AD
791 var id = getActiveArticleId();
792 if (id) {
793 editArticleTags(id, getActiveFeedId(), isCdmMode());
19d7bfcd 794 return;
93f66472
AD
795 }
796 }
797
314fcd2b
AD
798 if (keycode == 9) { // tab
799 var id = getArticleUnderPointer();
009646d2 800 if (id) {
acac8448 801 var cb = $("RCHK-" + id);
93f66472
AD
802
803 if (cb) {
804 cb.checked = !cb.checked;
805 toggleSelectRowById(cb, "RROW-" + id);
eec498c3 806 return false;
93f66472
AD
807 }
808 }
314fcd2b 809 }
93f66472
AD
810
811 if (keycode == 79) { // o
812 if (getActiveArticleId()) {
813 openArticleInNewWindow(getActiveArticleId());
19d7bfcd 814 return;
93f66472
AD
815 }
816 }
817
c1780289
AD
818 if (keycode == 81 && shift_key) { // Q
819 if (typeof catchupAllFeeds != 'undefined') {
820 catchupAllFeeds();
36cebe0f 821 return;
c1780289
AD
822 }
823 }
824
9ad53991 825 if (keycode == 88 && !shift_key) { // x
9bbbc82c 826 if (activeFeedIsCat()) {
7613280a 827 dijit.byId("feedTree").collapseCat(getActiveFeedId());
9ad53991 828 return;
9bbbc82c
AD
829 }
830 }
93f66472
AD
831 }
832
2bb3f957
AD
833 /* Prefix a */
834
835 if (hotkey_prefix == 65) { // a
836 hotkey_prefix = false;
837
838 if (keycode == 65) { // a
839 selectArticles('all');
840 return;
841 }
842
843 if (keycode == 85) { // u
844 selectArticles('unread');
845 return;
846 }
847
848 if (keycode == 73) { // i
849 selectArticles('invert');
850 return;
851 }
852
853 if (keycode == 78) { // n
854 selectArticles('none');
855 return;
856 }
857
858 }
859
93f66472
AD
860 /* Prefix f */
861
009646d2 862 if (hotkey_prefix == 70) { // f
93f66472
AD
863
864 hotkey_prefix = false;
865
617698d7
AD
866 if (keycode == 81) { // q
867 if (getActiveFeedId()) {
868 catchupCurrentFeed();
869 return;
870 }
871 }
872
873 if (keycode == 82) { // r
874 if (getActiveFeedId()) {
0569a712 875 viewfeed(getActiveFeedId(), '', activeFeedIsCat());
617698d7
AD
876 return;
877 }
878 }
879
93f66472 880 if (keycode == 65) { // a
eec498c3
AD
881 toggleDispRead();
882 return false;
93f66472
AD
883 }
884
93f66472
AD
885 if (keycode == 85) { // u
886 if (getActiveFeedId()) {
0569a712 887 viewfeed(getActiveFeedId(), '');
eec498c3 888 return false;
93f66472
AD
889 }
890 }
891
892 if (keycode == 69) { // e
33f31dfd
AD
893
894 if (activeFeedIsCat())
895 alert(__("You can't edit this kind of feed."));
896 else
897 editFeed(getActiveFeedId());
898 return;
899
eec498c3 900 return false;
93f66472
AD
901 }
902
903 if (keycode == 83) { // s
3393238d 904 quickAddFeed();
eec498c3 905 return false;
93f66472
AD
906 }
907
908 if (keycode == 67 && shift_key) { // C
909 if (typeof catchupAllFeeds != 'undefined') {
eec498c3
AD
910 catchupAllFeeds();
911 return false;
93f66472
AD
912 }
913 }
914
915 if (keycode == 67) { // c
916 if (getActiveFeedId()) {
eec498c3
AD
917 catchupCurrentFeed();
918 return false;
93f66472
AD
919 }
920 }
921
8a3e0b1a
AD
922 if (keycode == 88) { // x
923 reverseHeadlineOrder();
924 return;
925 }
93f66472
AD
926 }
927
928 /* Prefix c */
929
930 if (hotkey_prefix == 67) { // c
931 hotkey_prefix = false;
932
933 if (keycode == 70) { // f
db4e4539 934 quickAddFilter();
eec498c3 935 return false;
93f66472
AD
936 }
937
fc2732f4
AD
938 if (keycode == 76) { // l
939 addLabel();
940 return false;
941 }
942
93f66472
AD
943 if (keycode == 83) { // s
944 if (typeof collapse_feedlist != 'undefined') {
eec498c3
AD
945 collapse_feedlist();
946 return false;
93f66472
AD
947 }
948 }
949
a5550322 950 if (keycode == 77) { // m
6e88da82
AD
951 // TODO: sortable feedlist
952 return;
a5550322
AD
953 }
954
a411875b
AD
955 if (keycode == 78) { // n
956 catchupRelativeToArticle(1);
957 return;
958 }
959
960 if (keycode == 80) { // p
961 catchupRelativeToArticle(0);
962 return;
963 }
964
965
93f66472
AD
966 }
967
968 /* Prefix g */
969
970 if (hotkey_prefix == 71) { // g
971
972 hotkey_prefix = false;
973
49f4a7e9
AD
974
975 if (keycode == 65) { // a
976 viewfeed(-4);
977 return false;
978 }
979
93f66472 980 if (keycode == 83) { // s
eec498c3
AD
981 viewfeed(-1);
982 return false;
93f66472
AD
983 }
984
985 if (keycode == 80 && shift_key) { // P
eec498c3
AD
986 gotoPreferences();
987 return false;
93f66472
AD
988 }
989
990 if (keycode == 80) { // p
eec498c3
AD
991 viewfeed(-2);
992 return false;
93f66472
AD
993 }
994
995 if (keycode == 70) { // f
eec498c3
AD
996 viewfeed(-3);
997 return false;
93f66472
AD
998 }
999
e31ed61a
AD
1000 if (keycode == 84) { // t
1001 displayDlg("printTagCloud");
eec498c3 1002 return false;
3a391f67 1003 }
43319e5e
AD
1004 }
1005
1006 /* Cmd */
93f66472 1007
009646d2 1008 if (hotkey_prefix == 224 || hotkey_prefix == 91) { // f
43319e5e
AD
1009 hotkey_prefix = false;
1010 return;
93f66472
AD
1011 }
1012
93f66472 1013 if (hotkey_prefix) {
84c7b824 1014 console.log("KP: PREFIX=" + hotkey_prefix + " CODE=" + keycode + " CHAR=" + keychar);
93f66472 1015 } else {
84c7b824 1016 console.log("KP: CODE=" + keycode + " CHAR=" + keychar);
93f66472
AD
1017 }
1018
1019
1020 } catch (e) {
1021 exception_error("hotkey_handler", e);
1022 }
1023}
61a20560 1024
a5819bb3
AD
1025function inPreferences() {
1026 return false;
1027}
8a3e0b1a
AD
1028
1029function reverseHeadlineOrder() {
1030 try {
1031
f30ef1fa 1032 var query_str = "?op=rpc&method=togglepref&key=REVERSE_HEADLINES";
8a3e0b1a
AD
1033
1034 new Ajax.Request("backend.php", {
1035 parameters: query_str,
009646d2 1036 onComplete: function(transport) {
8a3e0b1a
AD
1037 viewCurrentFeed();
1038 } });
1039
1040 } catch (e) {
1041 exception_error("reverseHeadlineOrder", e);
1042 }
1043}
fe1087fb 1044
997429c2 1045function scheduleFeedUpdate(id, is_cat) {
428b704d 1046 try {
997429c2
AD
1047 if (!id) {
1048 id = getActiveFeedId();
1049 is_cat = activeFeedIsCat();
1050 }
428b704d 1051
997429c2 1052 if (!id) {
428b704d
AD
1053 alert(__("Please select some feed first."));
1054 return;
1055 }
1056
f30ef1fa 1057 var query = "?op=rpc&method=scheduleFeedUpdate&id=" +
997429c2
AD
1058 param_escape(id) +
1059 "&is_cat=" + param_escape(is_cat);
428b704d
AD
1060
1061 console.log(query);
1062
1063 new Ajax.Request("backend.php", {
1064 parameters: query,
009646d2 1065 onComplete: function(transport) {
74d12bab 1066 handle_rpc_json(transport);
428b704d 1067
74d12bab
AD
1068 var reply = JSON.parse(transport.responseText);
1069 var message = reply['message'];
428b704d 1070
74d12bab
AD
1071 if (message) {
1072 notify_info(message);
1073 return;
428b704d
AD
1074 }
1075
428b704d
AD
1076 } });
1077
1078
1079 } catch (e) {
1080 exception_error("scheduleFeedUpdate", e);
1081 }
1082}
63855db1
AD
1083
1084function newVersionDlg() {
1085 try {
3f363052 1086 var query = "backend.php?op=dlg&method=newVersion";
63855db1
AD
1087
1088 if (dijit.byId("newVersionDlg"))
1089 dijit.byId("newVersionDlg").destroyRecursive();
1090
1091 dialog = new dijit.Dialog({
1092 id: "newVersionDlg",
1093 title: __("New version available!"),
1094 style: "width: 600px",
1095 href: query,
1096 });
1097
1098 dialog.show();
1099
1100 } catch (e) {
1101 exception_error("newVersionDlg", e);
1102 }
1103}
563b9c78
AD
1104
1105function handle_rpc_json(transport, scheduled_call) {
1106 try {
1107 var reply = JSON.parse(transport.responseText);
1108
1109 if (reply) {
1110
1111 var error = reply['error'];
1112
1113 if (error) {
1114 var code = error['code'];
1115 var msg = error['msg'];
009646d2
AD
1116
1117 console.warn("[handle_rpc_json] received fatal error " + code + "/" + msg);
1118
563b9c78
AD
1119 if (code != 0) {
1120 fatalError(code, msg);
1121 return false;
1122 }
1123 }
1124
1125 var seq = reply['seq'];
1126
1127 if (seq) {
1128 if (get_seq() != seq) {
009646d2 1129 console.log("[handle_rpc_json] sequence mismatch: " + seq +
563b9c78
AD
1130 " (want: " + get_seq() + ")");
1131 return true;
1132 }
1133 }
1134
1135 var message = reply['message'];
1136
1137 if (message) {
1138 if (message == "UPDATE_COUNTERS") {
1139 console.log("need to refresh counters...");
1140 setInitParam("last_article_id", -1);
1141 _force_scheduled_update = true;
1142 }
1143 }
1144
1145 var counters = reply['counters'];
009646d2 1146
563b9c78
AD
1147 if (counters)
1148 parse_counters(counters, scheduled_call);
1149
1150 var runtime_info = reply['runtime-info'];;
1151
1152 if (runtime_info)
1153 parse_runtime_info(runtime_info);
1154
1155 hideOrShowFeeds(getInitParam("hide_read_feeds") == 1);
1156
1157 } else {
1158 notify_error("Error communicating with server.");
1159 }
1160
1161 } catch (e) {
beb119a2
AD
1162 notify_error("Error communicating with server.");
1163 console.log(e);
1164 //exception_error("handle_rpc_json", e, transport);
563b9c78
AD
1165 }
1166
1167 return true;
1168}
1169