]> git.wh0rd.org - tt-rss.git/blame - viewfeed.js
js: misc fixes, code cleanup
[tt-rss.git] / viewfeed.js
CommitLineData
bb7cface 1var active_post_id = false;
4b6206fa 2var last_article_view = false;
0b126ac2
AD
3var active_real_feed_id = false;
4
13f08f75 5// FIXME: kludges, needs proper implementation
0b126ac2 6var _reload_feedlist_after_view = false;
e08443c1 7
ba0978c8
AD
8var _cdm_wd_timeout = false;
9var _cdm_wd_vishist = new Array();
10
e097e8be
AD
11var article_cache = new Array();
12
081e527d 13var vgroup_last_feed = false;
314fcd2b 14var post_under_pointer = false;
081e527d 15
022d9e9e
AD
16var last_requested_article = false;
17
b39b57ac
AD
18var preload_id_batch = [];
19var preload_timeout_id = false;
20
21var cache_added = [];
22
1341ea0d
AD
23function catchup_callback2(transport, callback) {
24 try {
84c7b824 25 console.log("catchup_callback2 " + transport + ", " + callback);
1341ea0d 26 notify("");
f8fb4498 27 handle_rpc_reply(transport);
1341ea0d
AD
28 if (callback) {
29 setTimeout(callback, 10);
30 }
31 } catch (e) {
273d1e29 32 exception_error("catchup_callback2", e, transport);
1341ea0d
AD
33 }
34}
35
3d72bbdb 36function headlines_callback2(transport, feed_cur_page) {
e19c1824
AD
37 try {
38
f8fb4498 39 if (!handle_rpc_reply(transport)) return;
9ca945a6 40
730dbf19
AD
41 loading_set_progress(100);
42
84c7b824 43 console.log("headlines_callback2 [page=" + feed_cur_page + "]");
e19c1824 44
2184738a
AD
45 if (!transport_error_check(transport)) return;
46
e19c1824 47 clean_feed_selections();
3d72bbdb
AD
48
49 var is_cat = false;
50 var feed_id = false;
ac541432 51
3d72bbdb
AD
52 if (transport.responseXML) {
53 var headlines = transport.responseXML.getElementsByTagName("headlines")[0];
54 if (headlines) {
55 is_cat = headlines.getAttribute("is_cat");
56 feed_id = headlines.getAttribute("id");
57 setActiveFeedId(feed_id, is_cat);
58 }
6c3b0198 59 }
f46192bb 60
6e35a862
AD
61 var ll = $('FLL-' + feed_id);
62
2ab31493
AD
63 if (ll && ll.parentNode)
64 ll.parentNode.removeChild(ll);
65
6c3b0198 66 if (!is_cat) {
acac8448 67 var feedr = $("FEEDR-" + feed_id);
6c3b0198
AD
68 if (feedr && !feedr.className.match("Selected")) {
69 feedr.className = feedr.className + "Selected";
70 }
5ee9816c 71 } else {
acac8448 72 var feedr = $("FCAT-" + feed_id);
5ee9816c
AD
73 if (feedr && !feedr.className.match("Selected")) {
74 feedr.className = feedr.className + "Selected";
75 }
6c3b0198 76 }
6e35a862 77
105b61b7
AD
78 var img = $('FIMG-' + feed_id);
79
80 if (img && !is_cat) {
81 img.src = img.alt;
105b61b7
AD
82 }
83
acac8448 84 var f = $("headlines-frame");
6c3b0198
AD
85 try {
86 if (feed_cur_page == 0) {
f8fb4498 87 //console.log("resetting headlines scrollTop");
6c3b0198 88 f.scrollTop = 0;
a49f5e05 89 }
6c3b0198
AD
90 } catch (e) { };
91
92 if (transport.responseXML) {
ffbe082d 93 var response = transport.responseXML;
e19c1824 94
ffbe082d
AD
95 var headlines = response.getElementsByTagName("headlines")[0];
96 var headlines_info = response.getElementsByTagName("headlines-info")[0];
081e527d 97
ffbe082d
AD
98 if (headlines_info)
99 headlines_info = JSON.parse(headlines_info.firstChild.nodeValue);
f8fb4498
AD
100 else {
101 console.error("didn't find headlines-info object in response");
102 return;
103 }
e19c1824 104
ffbe082d
AD
105 var headlines_count = headlines_info.count;
106 var headlines_unread = headlines_info.unread;
107 var disable_cache = headlines_info.disable_cache;
108
109 vgroup_last_feed = headlines_info.vgroup_last_feed;
081e527d 110
587bef10
AD
111 if (headlines_count == 0) {
112 _infscroll_disable = 1;
113 } else {
114 _infscroll_disable = 0;
115 }
116
ffbe082d
AD
117 var counters = response.getElementsByTagName("counters")[0];
118 var articles = response.getElementsByTagName("article");
119 var runtime_info = response.getElementsByTagName("runtime-info");
6c3b0198
AD
120
121 if (feed_cur_page == 0) {
122 if (headlines) {
123 f.innerHTML = headlines.firstChild.nodeValue;
e19c1824 124
dd5865d4
AD
125 var cache_prefix = "";
126
127 if (is_cat) {
128 cache_prefix = "C:";
129 } else {
130 cache_prefix = "F:";
131 }
132
3d72bbdb 133 cache_invalidate(cache_prefix + feed_id);
7e8832b3 134
52d7e7da 135 if (!disable_cache) {
3d72bbdb 136 cache_inject(cache_prefix + feed_id,
52d7e7da
AD
137 headlines.firstChild.nodeValue, headlines_unread);
138 }
e19c1824 139
6c3b0198 140 } else {
f8fb4498 141 console.warn("headlines_callback: returned no data");
6c3b0198
AD
142 f.innerHTML = "<div class='whiteBox'>" + __('Could not update headlines (missing XML data)') + "</div>";
143
144 }
145 } else {
146 if (headlines) {
147 if (headlines_count > 0) {
5ae8f858 148 console.log("adding some more headlines...");
6c3b0198 149
acac8448 150 var c = $("headlinesList");
6c3b0198
AD
151
152 if (!c) {
acac8448 153 c = $("headlinesInnerContainer");
6c3b0198 154 }
c32cd48a
AD
155
156 var ids = getSelectedArticleIds2();
6c3b0198
AD
157
158 c.innerHTML = c.innerHTML + headlines.firstChild.nodeValue;
c32cd48a 159
84c7b824 160 console.log("restore selected ids: " + ids);
c32cd48a
AD
161
162 for (var i = 0; i < ids.length; i++) {
163 markHeadline(ids[i]);
164 }
165
6c3b0198 166 } else {
84c7b824 167 console.log("no new headlines received");
29dfb258 168 }
29dfb258 169 } else {
f8fb4498 170 console.warn("headlines_callback: returned no data");
6c3b0198
AD
171 notify_error("Error while trying to load more headlines");
172 }
730dbf19 173
6c3b0198
AD
174 }
175
176 if (articles) {
177 for (var i = 0; i < articles.length; i++) {
178 var a_id = articles[i].getAttribute("id");
f8fb4498 179 //console.log("found id: " + a_id);
6c3b0198 180 cache_inject(a_id, articles[i].firstChild.nodeValue);
ac541432 181 }
007a38d4 182 } else {
84c7b824 183 console.log("no cached articles received");
961f4c73 184 }
d36f5607
AD
185
186 if (counters)
187 parse_counters(counters);
188 else
189 request_counters();
f8fb4498 190
6c3b0198 191 if (runtime_info) {
6c3b0198 192 parse_runtime_info(runtime_info[0]);
f8fb4498 193 }
6c3b0198 194
3de0261a 195 } else {
f8fb4498 196 console.warn("headlines_callback: returned no XML object");
6c3b0198 197 f.innerHTML = "<div class='whiteBox'>" + __('Could not update headlines (missing XML object)') + "</div>";
3de0261a 198 }
6c3b0198 199
5225d420 200
6c3b0198
AD
201 if (_cdm_wd_timeout) window.clearTimeout(_cdm_wd_timeout);
202
e69fb880 203 if (isCdmMode() &&
a969b30b 204 getActiveFeedId() != -3 &&
6c3b0198 205 getInitParam("cdm_auto_catchup") == 1) {
84c7b824 206 console.log("starting CDM watchdog");
6c3b0198
AD
207 _cdm_wd_timeout = window.setTimeout("cdmWatchdog()", 5000);
208 _cdm_wd_vishist = new Array();
ac7bcd71 209 } else {
84c7b824 210 console.log("not in CDM mode or watchdog disabled");
ba0978c8 211 }
6c3b0198 212
6c3b0198 213 _feed_cur_page = feed_cur_page;
82764a41
AD
214 _infscroll_request_sent = 0;
215
6c3b0198 216 notify("");
730dbf19
AD
217
218 remove_splash();
219
6c3b0198 220 } catch (e) {
273d1e29 221 exception_error("headlines_callback2", e, transport);
6b4163cb
AD
222 }
223}
224
e097e8be
AD
225function render_article(article) {
226 try {
acac8448 227 var f = $("content-frame");
44cc6f20
AD
228 try {
229 f.scrollTop = 0;
230 } catch (e) { };
e097e8be 231
acac8448 232 var fi = $("content-insert");
17042fc0 233
e5ebee09
AD
234 try {
235 fi.scrollTop = 0;
236 } catch (e) { };
95f67d2e 237
17042fc0 238 fi.innerHTML = article;
95f67d2e 239
51682b23 240// article.evalScripts();
e097e8be
AD
241
242 } catch (e) {
243 exception_error("render_article", e);
244 }
245}
246
71d277de 247function showArticleInHeadlines(id) {
e097e8be 248
868d0ed2 249 try {
e097e8be 250
868d0ed2 251 cleanSelected("headlinesList");
71d277de 252
acac8448 253 var crow = $("RROW-" + id);
76283a4c
AD
254
255 if (!crow) return;
256
868d0ed2
AD
257 var article_is_unread = crow.className.match("Unread");
258
259 crow.className = crow.className.replace("Unread", "");
fdcdf2de 260
e69fb880
AD
261 selectArticles('none');
262
acac8448 263 var upd_img_pic = $("FUPDPIC-" + id);
ebda016b 264
fdcdf2de 265 var cache_prefix = "";
ebda016b 266
fdcdf2de
AD
267 if (activeFeedIsCat()) {
268 cache_prefix = "C:";
269 } else {
270 cache_prefix = "F:";
271 }
11063ec6
AD
272
273 var view_mode = false;
274
275 try {
276 view_mode = document.forms['main_toolbar_form'].view_mode;
277 view_mode = view_mode[view_mode.selectedIndex].value;
278 } catch (e) {
273d1e29 279 //
11063ec6
AD
280 }
281
784ac51f
AD
282 if (upd_img_pic && (upd_img_pic.src.match("updated.png") ||
283 upd_img_pic.src.match("fresh_sign.png"))) {
284
fdcdf2de 285 upd_img_pic.src = "images/blank_icon.gif";
ebda016b
AD
286
287 cache_invalidate(cache_prefix + getActiveFeedId());
ce411c4b
AD
288
289 cache_inject(cache_prefix + getActiveFeedId(),
acac8448 290 $("headlines-frame").innerHTML,
ce411c4b 291 get_feed_unread(getActiveFeedId()));
fdcdf2de 292
11063ec6 293 } else if (article_is_unread && view_mode == "all_articles") {
fdcdf2de
AD
294
295 cache_invalidate(cache_prefix + getActiveFeedId());
296
297 cache_inject(cache_prefix + getActiveFeedId(),
acac8448 298 $("headlines-frame").innerHTML,
fdcdf2de
AD
299 get_feed_unread(getActiveFeedId())-1);
300
3de99e6b
AD
301 } else if (article_is_unread) {
302 cache_invalidate(cache_prefix + getActiveFeedId());
868d0ed2 303 }
e097e8be 304
4c009c78
AD
305 markHeadline(id);
306
ac49453b
AD
307 if (article_is_unread)
308 _force_scheduled_update = true;
309
868d0ed2
AD
310 } catch (e) {
311 exception_error("showArticleInHeadlines", e);
312 }
71d277de 313}
e097e8be 314
a491a7f1 315function article_callback2(transport, id) {
71d277de 316 try {
84c7b824 317 console.log("article_callback2 " + id);
e097e8be 318
f8fb4498 319 if (!handle_rpc_reply(transport)) return;
9ca945a6 320
71d277de 321 if (transport.responseXML) {
e097e8be 322
2184738a
AD
323 if (!transport_error_check(transport)) return;
324
b1039124 325/* var ll = $('LL-' + id);
6e35a862
AD
326 var content = $('HLC-' + id);
327
b1039124 328 if (ll && content) content.removeChild(ll); */
6e35a862 329
b1039124
AD
330 var upic = $('FUPDPIC-' + id);
331
332 if (upic) {
333 upic.src = 'images/blank_icon.gif';
334 }
335
6e35a862 336 if (id != last_requested_article) {
84c7b824 337 console.log("requested article id is out of sequence, aborting");
6e35a862
AD
338 return;
339 }
340
6e35a862
AD
341 active_post_id = id;
342
f8fb4498 343 //console.log("looking for articles to cache...");
71d277de
AD
344
345 var articles = transport.responseXML.getElementsByTagName("article");
346
347 for (var i = 0; i < articles.length; i++) {
348 var a_id = articles[i].getAttribute("id");
349
f8fb4498 350 //console.log("found id: " + a_id);
71d277de
AD
351
352 if (a_id == active_post_id) {
f8fb4498 353 //console.log("active article, rendering...");
71d277de 354 render_article(articles[i].firstChild.nodeValue);
e097e8be 355 }
71d277de
AD
356
357 cache_inject(a_id, articles[i].firstChild.nodeValue);
e097e8be 358 }
fbcabe1e 359
fbcabe1e
AD
360
361 showArticleInHeadlines(id);
362
2f71f07b
AD
363 if (db) {
364 db.execute("UPDATE articles SET unread = 0 WHERE id = ?", [id]);
365 }
366
fbcabe1e 367 var reply = transport.responseXML.firstChild.firstChild;
71d277de
AD
368
369 } else {
f8fb4498 370 console.warn("article_callback: returned no XML object");
acac8448 371 //var f = $("content-frame");
17042fc0 372 //f.innerHTML = "<div class='whiteBox'>" + __('Could not display article (missing XML object)') + "</div>";
e097e8be 373 }
4b6206fa
AD
374
375 var date = new Date();
376 last_article_view = date.getTime() / 1000;
377
0b126ac2
AD
378 if (_reload_feedlist_after_view) {
379 setTimeout('updateFeedList(false, false)', 50);
380 _reload_feedlist_after_view = false;
381 } else {
f8fb4498 382 request_counters();
0b126ac2 383 }
9ec58704
AD
384
385 notify("");
71d277de 386 } catch (e) {
273d1e29 387 exception_error("article_callback2", e, transport);
6b4163cb
AD
388 }
389}
390
a491a7f1 391function view(id) {
ee1f45f4 392 try {
84c7b824 393 console.log("loading article: " + id);
12e55b90 394
a491a7f1 395 if (offline_mode) return view_offline(id);
45a6446d 396
e097e8be
AD
397 var cached_article = cache_find(id);
398
84c7b824 399 console.log("cache check result: " + (cached_article != false));
ee1f45f4 400
ee1f45f4 401 enableHotkeys();
664306d3
AD
402 hideAuxDlg();
403
a491a7f1 404 var query = "?op=view&id=" + param_escape(id);
6b4163cb 405
71d277de 406 var neighbor_ids = getRelativePostIds(active_post_id);
e097e8be 407
71d277de 408 /* only request uncached articles */
e097e8be 409
71d277de 410 var cids_to_request = Array();
5a94a953 411
71d277de
AD
412 for (var i = 0; i < neighbor_ids.length; i++) {
413 if (!cache_check(neighbor_ids[i])) {
414 cids_to_request.push(neighbor_ids[i]);
5a94a953 415 }
71d277de 416 }
5a94a953 417
84c7b824 418 console.log("additional ids: " + cids_to_request.toString());
b39b57ac 419
71d277de 420 /* additional info for piggyback counters */
e097e8be 421
71d277de
AD
422 if (tagsAreDisplayed()) {
423 query = query + "&omode=lt";
424 } else {
425 query = query + "&omode=flc";
426 }
e097e8be 427
71d277de 428 query = query + "&cids=" + cids_to_request.toString();
e097e8be 429
acac8448 430 var crow = $("RROW-" + id);
71d277de 431 var article_is_unread = crow.className.match("Unread");
e097e8be 432
3f70f90f
AD
433 showArticleInHeadlines(id);
434
71d277de 435 if (!cached_article) {
e097e8be 436
b1039124
AD
437 var upic = $('FUPDPIC-' + id);
438
439 if (upic) {
883fee8d 440 upic.src = getInitParam("sign_progress");
6e35a862 441 }
e097e8be 442
71d277de 443 } else if (cached_article && article_is_unread) {
addb5836 444
71d277de 445 query = query + "&mode=prefetch";
addb5836 446
71d277de 447 render_article(cached_article);
addb5836 448
71d277de 449 } else if (cached_article) {
e097e8be 450
71d277de
AD
451 query = query + "&mode=prefetch_old";
452 render_article(cached_article);
997d9d7c 453
71d277de 454 }
e097e8be 455
71d277de 456 cache_expire();
86173d9a 457
022d9e9e
AD
458 last_requested_article = id;
459
b4e75b2a
AD
460 new Ajax.Request("backend.php", {
461 parameters: query,
71d277de 462 onComplete: function(transport) {
a491a7f1 463 article_callback2(transport, id);
71d277de 464 } });
6b4163cb 465
a7764e51
AD
466 return false;
467
ee1f45f4
AD
468 } catch (e) {
469 exception_error("view", e);
470 }
f0601b87
AD
471}
472
67343d9f
AD
473function tMark(id) {
474 return toggleMark(id);
475}
476
e4f4b46f
AD
477function tPub(id) {
478 return togglePub(id);
479}
480
6b0f49f9
AD
481function tMark_afh_off(effect) {
482 try {
483 var elem = effect.effects[0].element;
484
f8fb4498 485 //console.log("tMark_afh_off : " + elem.id);
6b0f49f9
AD
486
487 if (elem) {
f5e0338d
AD
488 elem.src = elem.src.replace("mark_set", "mark_unset");
489 elem.alt = __("Star article");
6b0f49f9
AD
490 Element.show(elem);
491 }
492
493 } catch (e) {
494 exception_error("tMark_afh_off", e);
495 }
496}
497
498function tPub_afh_off(effect) {
499 try {
500 var elem = effect.effects[0].element;
501
f8fb4498 502 //console.log("tPub_afh_off : " + elem.id);
6b0f49f9
AD
503
504 if (elem) {
f5e0338d
AD
505 elem.src = elem.src.replace("pub_set", "pub_unset");
506 elem.alt = __("Publish article");
6b0f49f9
AD
507 Element.show(elem);
508 }
509
510 } catch (e) {
511 exception_error("tPub_afh_off", e);
512 }
513}
e4f4b46f 514
f5e0338d 515function toggleMark(id, client_only, no_effects) {
f0601b87 516
b685ba25 517 try {
254e0e4b 518
b4e75b2a 519 var query = "?op=rpc&id=" + id + "&subop=mark";
b685ba25
AD
520
521 query = query + "&afid=" + getActiveFeedId();
522
523 if (tagsAreDisplayed()) {
524 query = query + "&omode=tl";
525 } else {
526 query = query + "&omode=flc";
7ba176d2 527 }
b685ba25 528
acac8448 529 var mark_img = $("FMPIC-" + id);
56ff7564
AD
530
531 if (!mark_img) return;
532
acac8448
AD
533 var vfeedu = $("FEEDU--1");
534 var crow = $("RROW-" + id);
b685ba25 535
f5e0338d
AD
536 if (mark_img.src.match("mark_unset")) {
537 mark_img.src = mark_img.src.replace("mark_unset", "mark_set");
538 mark_img.alt = __("Unstar article");
b685ba25 539 query = query + "&mark=1";
ee8768db 540
2f71f07b
AD
541 if (db) {
542 db.execute("UPDATE articles SET marked = 1 WHERE id = ?", [id]);
543 }
544
b685ba25 545 } else {
f5e0338d 546 mark_img.alt = __("Please wait...");
b685ba25
AD
547 query = query + "&mark=0";
548
e69fb880 549 if (!isCdmMode() && !no_effects) {
b685ba25
AD
550 Effect.Puff(mark_img, {duration : 0.25, afterFinish: tMark_afh_off});
551 } else {
f5e0338d
AD
552 mark_img.src = mark_img.src.replace("mark_set", "mark_unset");
553 mark_img.alt = __("Star article");
b685ba25 554 }
2f71f07b
AD
555
556 if (db) {
557 db.execute("UPDATE articles SET marked = 0 WHERE id = ?", [id]);
558 }
559
ace1a6da 560 }
772bc83b 561
46b84d29 562 if (!no_effects) update_local_feedlist_counters();
c8a9fe5b 563
f5e0338d 564 if (!client_only) {
f8fb4498 565 //console.log(query);
36e05046 566
b4e75b2a
AD
567 new Ajax.Request("backend.php", {
568 parameters: query,
1341ea0d 569 onComplete: function(transport) {
f8fb4498 570 handle_rpc_reply(transport);
1341ea0d
AD
571 } });
572
f5e0338d 573 }
f0601b87 574
b685ba25
AD
575 } catch (e) {
576 exception_error("toggleMark", e);
577 }
f0601b87
AD
578}
579
c7e51de1 580function togglePub(id, client_only, no_effects, note) {
e4f4b46f 581
2bc2147f 582 try {
e4f4b46f 583
b4e75b2a 584 var query = "?op=rpc&id=" + id + "&subop=publ";
2bc2147f
AD
585
586 query = query + "&afid=" + getActiveFeedId();
c7e51de1
AD
587
588 if (note != undefined) {
589 query = query + "&note=" + param_escape(note);
590 } else {
591 query = query + "&note=undefined";
592 }
2bc2147f
AD
593
594 if (tagsAreDisplayed()) {
595 query = query + "&omode=tl";
596 } else {
597 query = query + "&omode=flc";
e4f4b46f 598 }
2bc2147f 599
acac8448 600 var mark_img = $("FPPIC-" + id);
56ff7564
AD
601
602 if (!mark_img) return;
603
acac8448
AD
604 var vfeedu = $("FEEDU--2");
605 var crow = $("RROW-" + id);
2bc2147f 606
c7e51de1 607 if (mark_img.src.match("pub_unset") || note != undefined) {
f5e0338d
AD
608 mark_img.src = mark_img.src.replace("pub_unset", "pub_set");
609 mark_img.alt = __("Unpublish article");
2bc2147f 610 query = query + "&pub=1";
ee8768db 611
e4f4b46f 612 } else {
f5e0338d 613 mark_img.alt = __("Please wait...");
2bc2147f
AD
614 query = query + "&pub=0";
615
e69fb880 616 if (!isCdmMode() && !no_effects) {
ace1a6da
AD
617 Effect.Puff(mark_img, {duration : 0.25, afterFinish: tPub_afh_off});
618 } else {
f5e0338d
AD
619 mark_img.src = mark_img.src.replace("pub_set", "pub_unset");
620 mark_img.alt = __("Publish article");
ace1a6da 621 }
e4f4b46f 622 }
b685ba25 623
f5e0338d 624 if (!client_only) {
b4e75b2a
AD
625 new Ajax.Request("backend.php", {
626 parameters: query,
1341ea0d 627 onComplete: function(transport) {
f8fb4498 628 handle_rpc_reply(transport);
a5819bb3
AD
629
630 var note = transport.responseXML.getElementsByTagName("note")[0];
631
632 if (note) {
633 var note_id = note.getAttribute("id");
634 var note_size = note.getAttribute("size");
635 var note_content = note.firstChild.nodeValue;
636
637 var container = $('POSTNOTE-' + note_id);
638
639 cache_invalidate(note_id);
640
641 if (container) {
642 if (note_size == "0") {
643 Element.hide(container);
644 } else {
645 container.innerHTML = note_content;
646 Element.show(container);
647 }
648 }
649 }
650
1341ea0d 651 } });
f5e0338d 652 }
b685ba25 653
2bc2147f 654 } catch (e) {
2bc2147f
AD
655 exception_error("togglePub", e);
656 }
e4f4b46f
AD
657}
658
ac162cbe
AD
659function correctHeadlinesOffset(id) {
660
661 try {
662
acac8448
AD
663 var hlist = $("headlinesList");
664 var container = $("headlinesInnerContainer");
665 var row = $("RROW-" + id);
ac162cbe
AD
666
667 var viewport = container.offsetHeight;
668
669 var rel_offset_top = row.offsetTop - container.scrollTop;
670 var rel_offset_bottom = row.offsetTop + row.offsetHeight - container.scrollTop;
671
84c7b824
AD
672 console.log("Rtop: " + rel_offset_top + " Rbtm: " + rel_offset_bottom);
673 console.log("Vport: " + viewport);
a5e46e0f 674
ac162cbe
AD
675 if (rel_offset_top <= 0 || rel_offset_top > viewport) {
676 container.scrollTop = row.offsetTop;
677 } else if (rel_offset_bottom > viewport) {
a5e46e0f
AD
678
679 /* doesn't properly work with Opera in some cases because
680 Opera fucks up element scrolling */
681
ac162cbe
AD
682 container.scrollTop = row.offsetTop + row.offsetHeight - viewport;
683 }
684
685 } catch (e) {
686 exception_error("correctHeadlinesOffset", e);
687 }
688
689}
690
bb7cface 691function moveToPost(mode) {
f0601b87 692
b8e6acea
AD
693 try {
694
e69fb880 695 var rows = getVisibleArticleIds();
5ad9d132 696
5ad9d132
AD
697 var prev_id = false;
698 var next_id = false;
b8e6acea 699
acac8448 700 if (!$('RROW-' + active_post_id)) {
5ad9d132
AD
701 active_post_id = false;
702 }
b8e6acea 703
5ad9d132
AD
704 if (active_post_id == false) {
705 next_id = getFirstVisibleHeadlineId();
706 prev_id = getLastVisibleHeadlineId();
707 } else {
708 for (var i = 0; i < rows.length; i++) {
709 if (rows[i] == active_post_id) {
710 prev_id = rows[i-1];
711 next_id = rows[i+1];
b8e6acea
AD
712 }
713 }
5ad9d132 714 }
b8e6acea 715
5ad9d132
AD
716 if (mode == "next") {
717 if (next_id) {
718 if (isCdmMode()) {
719
dad14b51
AD
720 cdmExpandArticle(next_id);
721 cdmScrollToArticleId(next_id);
5ad9d132
AD
722
723 } else {
b8e6acea
AD
724 correctHeadlinesOffset(next_id);
725 view(next_id, getActiveFeedId());
726 }
727 }
5ad9d132 728 }
b8e6acea 729
5ad9d132
AD
730 if (mode == "prev") {
731 if (prev_id) {
732 if (isCdmMode()) {
dad14b51 733 cdmExpandArticle(prev_id);
5ad9d132 734 cdmScrollToArticleId(prev_id);
5ad9d132 735 } else {
b8e6acea
AD
736 correctHeadlinesOffset(prev_id);
737 view(prev_id, getActiveFeedId());
738 }
5ad9d132
AD
739 }
740 }
741
b8e6acea 742 } catch (e) {
438f2ce9 743 exception_error("moveToPost", e);
bb7cface 744 }
b8e6acea
AD
745}
746
747function toggleSelected(id) {
748 try {
749
acac8448 750 var cb = $("RCHK-" + id);
5ad9d132 751
acac8448 752 var row = $("RROW-" + id);
b8e6acea
AD
753 if (row) {
754 var nc = row.className;
755
756 if (!nc.match("Selected")) {
757 nc = nc + "Selected";
5ad9d132
AD
758 if (cb) {
759 cb.checked = true;
760 }
761
762 // In CDM basically last selected article == active article
763 if (isCdmMode()) active_post_id = id;
b8e6acea
AD
764 } else {
765 nc = nc.replace("Selected", "");
5ad9d132
AD
766 if (cb) {
767 cb.checked = false;
768 }
769
b8e6acea 770 }
bb7cface 771
b8e6acea 772 row.className = nc;
bb7cface 773 }
b8e6acea 774 } catch (e) {
438f2ce9 775 exception_error("toggleSelected", e);
b8e6acea 776 }
bb7cface
AD
777}
778
0df009c3 779function toggleUnread_afh(effect) {
b8e6acea
AD
780 try {
781
782 var elem = effect.element;
0df009c3 783 elem.style.backgroundColor = "";
b8e6acea 784
b8e6acea 785 } catch (e) {
438f2ce9 786 exception_error("toggleUnread_afh", e);
b8e6acea 787 }
0df009c3 788}
b8e6acea
AD
789
790function toggleUnread(id, cmode, effect) {
5f51022a 791 try {
5f51022a 792
acac8448 793 var row = $("RROW-" + id);
5f51022a
AD
794 if (row) {
795 var nc = row.className;
93f66472 796 var is_selected = row.className.match("Selected");
5f51022a
AD
797 nc = nc.replace("Unread", "");
798 nc = nc.replace("Selected", "");
799
b8e6acea
AD
800 // since we are removing selection from the object, uncheck
801 // corresponding checkbox
802
acac8448 803 var cb = $("RCHK-" + id);
b8e6acea
AD
804 if (cb) {
805 cb.checked = false;
806 }
807
808 // NOTE: I'm not sure that resetting selection here is a feature -fox
809
a70ab740
AD
810 if (cmode == undefined || cmode == 2) {
811 if (row.className.match("Unread")) {
812 row.className = nc;
b8e6acea 813
0df009c3 814 if (effect) {
b8e6acea
AD
815 new Effect.Highlight(row, {duration: 1, startcolor: "#fff7d5",
816 afterFinish: toggleUnread_afh,
817 queue: { position:'end', scope: 'TMRQ-' + id, limit: 1 } } );
0df009c3 818 }
b8e6acea 819
a70ab740
AD
820 } else {
821 row.className = nc + "Unread";
822 }
1a003258
AD
823
824 if (db) {
825 db.execute("UPDATE articles SET unread = not unread "+
826 "WHERE id = ?", [id]);
827 }
828
a70ab740 829 } else if (cmode == 0) {
5f51022a 830 row.className = nc;
b8e6acea 831
54eb7d20 832 if (effect) {
b8e6acea 833 new Effect.Highlight(row, {duration: 1, startcolor: "#fff7d5",
54eb7d20 834 afterFinish: toggleUnread_afh,
b8e6acea 835 queue: { position:'end', scope: 'TMRQ-' + id, limit: 1 } } );
54eb7d20 836 }
1a003258
AD
837
838 if (db) {
839 db.execute("UPDATE articles SET unread = 0 "+
840 "WHERE id = ?", [id]);
841 }
842
a70ab740 843 } else if (cmode == 1) {
5f51022a 844 row.className = nc + "Unread";
1a003258
AD
845
846 if (db) {
847 db.execute("UPDATE articles SET unread = 1 "+
848 "WHERE id = ?", [id]);
849 }
850
5f51022a
AD
851 }
852
1a003258
AD
853 update_local_feedlist_counters();
854
93f66472
AD
855 // Disable unmarking as selected for the time being (16.05.08) -fox
856 if (is_selected) row.className = row.className + "Selected";
857
a70ab740 858 if (cmode == undefined) cmode = 2;
5f51022a 859
b4e75b2a
AD
860 var query = "?op=rpc&subop=catchupSelected" +
861 "&cmode=" + param_escape(cmode) + "&ids=" + param_escape(id);
5f51022a 862
1341ea0d 863// notify_progress("Loading, please wait...");
9ec58704 864
b4e75b2a
AD
865 new Ajax.Request("backend.php", {
866 parameters: query,
1341ea0d 867 onComplete: function(transport) {
f8fb4498 868 handle_rpc_reply(transport);
1341ea0d 869 } });
5f51022a
AD
870
871 }
872
5f51022a
AD
873 } catch (e) {
874 exception_error("toggleUnread", e);
875 }
876}
877
933ba4ee
AD
878function selectionRemoveLabel(id) {
879 try {
880
881 var ids = getSelectedArticleIds2();
882
883 if (ids.length == 0) {
884 alert(__("No articles are selected."));
885 return;
886 }
887
37843d70 888// var ok = confirm(__("Remove selected articles from label?"));
933ba4ee 889
37843d70 890// if (ok) {
933ba4ee 891
b4e75b2a 892 var query = "?op=rpc&subop=removeFromLabel&ids=" +
933ba4ee
AD
893 param_escape(ids.toString()) + "&lid=" + param_escape(id);
894
905ff52a
AD
895 console.log(query);
896
933ba4ee
AD
897// notify_progress("Loading, please wait...");
898
898e8562
AD
899 cache_invalidate("F:" + (-11 - id));
900
b4e75b2a
AD
901 new Ajax.Request("backend.php", {
902 parameters: query,
933ba4ee 903 onComplete: function(transport) {
1c9c6025 904 show_labels_in_headlines(transport);
f8fb4498 905 handle_rpc_reply(transport);
933ba4ee
AD
906 } });
907
37843d70 908// }
933ba4ee
AD
909
910 } catch (e) {
911 exception_error("selectionAssignLabel", e);
912
913 }
914}
915
b8a637f3
AD
916function selectionAssignLabel(id) {
917 try {
918
919 var ids = getSelectedArticleIds2();
920
921 if (ids.length == 0) {
922 alert(__("No articles are selected."));
923 return;
924 }
925
37843d70 926// var ok = confirm(__("Assign selected articles to label?"));
b8a637f3 927
37843d70 928// if (ok) {
b8a637f3 929
898e8562
AD
930 cache_invalidate("F:" + (-11 - id));
931
b4e75b2a 932 var query = "?op=rpc&subop=assignToLabel&ids=" +
b8a637f3
AD
933 param_escape(ids.toString()) + "&lid=" + param_escape(id);
934
905ff52a
AD
935 console.log(query);
936
b8a637f3
AD
937// notify_progress("Loading, please wait...");
938
b4e75b2a
AD
939 new Ajax.Request("backend.php", {
940 parameters: query,
b8a637f3 941 onComplete: function(transport) {
f9247195 942 show_labels_in_headlines(transport);
f8fb4498 943 handle_rpc_reply(transport);
b8a637f3
AD
944 } });
945
37843d70 946// }
b8a637f3
AD
947
948 } catch (e) {
949 exception_error("selectionAssignLabel", e);
950
951 }
952}
953
50eefedb 954function selectionToggleUnread(set_state, callback_func, no_error) {
1572afe5 955 try {
b83d72b1 956 var rows = getSelectedArticleIds2();
1572afe5 957
2228d0e4 958 if (rows.length == 0 && !no_error) {
9cc600d1
AD
959 alert(__("No articles are selected."));
960 return;
961 }
962
1572afe5 963 for (i = 0; i < rows.length; i++) {
acac8448 964 var row = $("RROW-" + rows[i]);
f1f2db64
AD
965 if (row) {
966 var nc = row.className;
967 nc = nc.replace("Unread", "");
968 nc = nc.replace("Selected", "");
969
a5ae125a
AD
970 if (set_state == undefined) {
971 if (row.className.match("Unread")) {
972 row.className = nc + "Selected";
973 } else {
974 row.className = nc + "UnreadSelected";
975 }
46b84d29
AD
976 if (db) {
977 db.execute("UPDATE articles SET unread = NOT unread WHERE id = ?",
978 [rows[i]]);
979 }
a5ae125a
AD
980 }
981
982 if (set_state == false) {
f1f2db64 983 row.className = nc + "Selected";
46b84d29
AD
984 if (db) {
985 db.execute("UPDATE articles SET unread = 0 WHERE id = ?",
986 [rows[i]]);
987 }
a5ae125a
AD
988 }
989
990 if (set_state == true) {
f1f2db64 991 row.className = nc + "UnreadSelected";
46b84d29
AD
992 if (db) {
993 db.execute("UPDATE articles SET unread = 1 WHERE id = ?",
994 [rows[i]]);
995 }
f1f2db64
AD
996 }
997 }
1572afe5
AD
998 }
999
1000 if (rows.length > 0) {
1001
46b84d29
AD
1002 update_local_feedlist_counters();
1003
b47b5af7
AD
1004 var cmode = "";
1005
1006 if (set_state == undefined) {
1007 cmode = "2";
1008 } else if (set_state == true) {
1009 cmode = "1";
1010 } else if (set_state == false) {
1011 cmode = "0";
1012 }
1013
b4e75b2a
AD
1014 var query = "?op=rpc&subop=catchupSelected" +
1015 "&cmode=" + cmode + "&ids=" + param_escape(rows.toString());
1572afe5 1016
9ec58704
AD
1017 notify_progress("Loading, please wait...");
1018
b4e75b2a
AD
1019 new Ajax.Request("backend.php", {
1020 parameters: query,
1341ea0d
AD
1021 onComplete: function(transport) {
1022 catchup_callback2(transport, callback_func);
1023 } });
1572afe5
AD
1024
1025 }
1026
1027 } catch (e) {
83f043bb 1028 exception_error("selectionToggleUnread", e);
1572afe5
AD
1029 }
1030}
1031
50eefedb 1032function selectionToggleMarked() {
1572afe5 1033 try {
1572afe5 1034
b83d72b1 1035 var rows = getSelectedArticleIds2();
386cbf27 1036
9cc600d1
AD
1037 if (rows.length == 0) {
1038 alert(__("No articles are selected."));
1039 return;
1040 }
1041
1572afe5 1042 for (i = 0; i < rows.length; i++) {
f5e0338d 1043 toggleMark(rows[i], true, true);
1572afe5
AD
1044 }
1045
46b84d29
AD
1046 update_local_feedlist_counters();
1047
1572afe5
AD
1048 if (rows.length > 0) {
1049
b4e75b2a 1050 var query = "?op=rpc&subop=markSelected&ids=" +
1572afe5
AD
1051 param_escape(rows.toString()) + "&cmode=2";
1052
2bc2147f
AD
1053 query = query + "&afid=" + getActiveFeedId();
1054
1341ea0d 1055 query = query + "&omode=lc";
2bc2147f 1056
b4e75b2a
AD
1057 new Ajax.Request("backend.php", {
1058 parameters: query,
1341ea0d 1059 onComplete: function(transport) {
f8fb4498 1060 handle_rpc_reply(transport);
1341ea0d 1061 } });
1572afe5
AD
1062
1063 }
1064
1065 } catch (e) {
83f043bb 1066 exception_error("selectionToggleMarked", e);
1572afe5
AD
1067 }
1068}
1069
50eefedb 1070function selectionTogglePublished() {
e4f4b46f 1071 try {
e4f4b46f 1072
b83d72b1 1073 var rows = getSelectedArticleIds2();
e4f4b46f
AD
1074
1075 if (rows.length == 0) {
1076 alert(__("No articles are selected."));
1077 return;
1078 }
1079
1080 for (i = 0; i < rows.length; i++) {
f5e0338d 1081 togglePub(rows[i], true, true);
e4f4b46f
AD
1082 }
1083
1084 if (rows.length > 0) {
1085
b4e75b2a 1086 var query = "?op=rpc&subop=publishSelected&ids=" +
e4f4b46f
AD
1087 param_escape(rows.toString()) + "&cmode=2";
1088
2bc2147f
AD
1089 query = query + "&afid=" + getActiveFeedId();
1090
1341ea0d 1091 query = query + "&omode=lc";
2bc2147f 1092
b4e75b2a
AD
1093 new Ajax.Request("backend.php", {
1094 parameters: query,
1341ea0d 1095 onComplete: function(transport) {
f8fb4498 1096 handle_rpc_reply(transport);
1341ea0d 1097 } });
e4f4b46f
AD
1098
1099 }
1100
1101 } catch (e) {
1102 exception_error("selectionToggleMarked", e);
1103 }
1104}
1105
e69fb880 1106function getSelectedArticleIds2() {
386cbf27 1107 var sel_articles = new Array();
386cbf27 1108
e69fb880
AD
1109 var children;
1110
1111 if (isCdmMode())
1112 var children = $("headlinesInnerContainer").childNodes;
1113 else
1114 var children = $("headlinesList").rows;
1115
1116 for (i = 0; i < children.length; i++) {
1117 var child = children[i];
386cbf27 1118
02895941 1119 if (child.id && child.id.match("RROW-") && child.className.match("Selected")) {
386cbf27
AD
1120 var c_id = child.id.replace("RROW-", "");
1121 sel_articles.push(c_id);
1122 }
1123 }
1124
1125 return sel_articles;
1126}
1127
e69fb880 1128function getLoadedArticleIds() {
8be83f42 1129 var sel_articles = new Array();
8be83f42 1130
e69fb880
AD
1131 if (isCdmMode())
1132 var children = $("headlinesInnerContainer").childNodes;
1133 else
1134 var children = $("headlinesList").rows;
3a40e8a2 1135
e69fb880 1136 if (!children) return sel_articles;
8be83f42 1137
e69fb880
AD
1138 for (i = 0; i < children.length; i++) {
1139 var child = children[i];
8be83f42 1140
e69fb880 1141 if (child.id && child.id.match("RROW-")) {
8be83f42
AD
1142 var c_id = child.id.replace("RROW-", "");
1143 sel_articles.push(c_id);
1144 }
1145 }
1146
1147 return sel_articles;
1148}
1149
e69fb880
AD
1150// mode = all,none,unread,invert
1151function selectArticles(mode) {
1152 try {
8be83f42 1153
e69fb880
AD
1154 var children;
1155
1156 if (isCdmMode())
1157 var children = $("headlinesInnerContainer").childNodes;
1158 else
1159 var children = $("headlinesList").rows;
06d1a1c1 1160
e69fb880
AD
1161 for (i = 0; i < children.length; i++) {
1162 var child = children[i];
1163
1164 if (child.id && child.id.match("RROW-")) {
1165 var aid = child.id.replace("RROW-", "");
1166
1167 var cb = $("RCHK-" + aid);
1168
1169 if (mode == "all") {
1170 if (!child.className.match("Selected")) {
1171 child.className = child.className + "Selected";
1172 cb.checked = true;
1173 }
1174 } else if (mode == "unread") {
1175 if (child.className.match("Unread") && !child.className.match("Selected")) {
1176 child.className = child.className + "Selected";
1177 cb.checked = true;
1178 }
1179 } else if (mode == "invert") {
1180 if (child.className.match("Selected")) {
1181 child.className = child.className.replace("Selected", "");
1182 cb.checked = false;
1183 } else {
1184 child.className = child.className + "Selected";
1185 cb.checked = true;
1186 }
06d1a1c1 1187
e69fb880
AD
1188 } else {
1189 child.className = child.className.replace("Selected", "");
1190 cb.checked = false;
386cbf27 1191 }
e69fb880
AD
1192 }
1193 }
1194
1195 } catch (e) {
1196 exception_error("selectArticles", e);
386cbf27
AD
1197 }
1198}
1199
98bea1b1 1200function catchupPage() {
b47b5af7 1201
3d72bbdb 1202 var fn = getFeedName(getActiveFeedId(), activeFeedIsCat());
8a5b4579 1203
a5ae125a
AD
1204 var str = __("Mark all visible articles in %s as read?");
1205
1206 str = str.replace("%s", fn);
8a5b4579
AD
1207
1208 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
1209 return;
1210 }
1211
e69fb880
AD
1212 selectArticles('all');
1213 selectionToggleUnread(false, 'viewCurrentFeed()', true)
1214 selectArticles('none');
98bea1b1
AD
1215}
1216
e04c18a2
AD
1217function deleteSelection() {
1218
1219 try {
e04c18a2 1220
b83d72b1
AD
1221 var rows = getSelectedArticleIds2();
1222
e04c18a2
AD
1223 if (rows.length == 0) {
1224 alert(__("No articles are selected."));
1225 return;
1226 }
1227
e04c18a2
AD
1228 var fn = getFeedName(getActiveFeedId(), activeFeedIsCat());
1229 var str;
1230 var op;
1231
1232 if (getActiveFeedId() != 0) {
1233 str = __("Delete %d selected articles in %s?");
1234 } else {
1235 str = __("Delete %d selected articles?");
1236 }
1237
1238 str = str.replace("%d", rows.length);
1239 str = str.replace("%s", fn);
1240
1241 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
1242 return;
1243 }
1244
b4e75b2a 1245 query = "?op=rpc&subop=delete&ids=" + param_escape(rows);
e04c18a2 1246
84c7b824 1247 console.log(query);
e04c18a2 1248
b4e75b2a
AD
1249 new Ajax.Request("backend.php", {
1250 parameters: query,
e04c18a2
AD
1251 onComplete: function(transport) {
1252 viewCurrentFeed();
1253 } });
1254
1255 } catch (e) {
a12eb9c3 1256 exception_error("deleteSelection", e);
e04c18a2
AD
1257 }
1258}
1259
1260function archiveSelection() {
1261
1262 try {
1263
b83d72b1
AD
1264 var rows = getSelectedArticleIds2();
1265
e04c18a2
AD
1266 if (rows.length == 0) {
1267 alert(__("No articles are selected."));
1268 return;
1269 }
1270
e04c18a2
AD
1271 var fn = getFeedName(getActiveFeedId(), activeFeedIsCat());
1272 var str;
1273 var op;
1274
1275 if (getActiveFeedId() != 0) {
1276 str = __("Archive %d selected articles in %s?");
1277 op = "archive";
1278 } else {
1279 str = __("Move %d archived articles back?");
1280 op = "unarchive";
1281 }
1282
1283 str = str.replace("%d", rows.length);
1284 str = str.replace("%s", fn);
1285
1286 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
1287 return;
1288 }
1289
b4e75b2a 1290 query = "?op=rpc&subop="+op+"&ids=" + param_escape(rows);
e04c18a2 1291
84c7b824 1292 console.log(query);
e04c18a2 1293
a12eb9c3
AD
1294 for (var i = 0; i < rows.length; i++) {
1295 cache_invalidate(rows[i]);
1296 }
1297
b4e75b2a
AD
1298 new Ajax.Request("backend.php", {
1299 parameters: query,
e04c18a2
AD
1300 onComplete: function(transport) {
1301 viewCurrentFeed();
1302 } });
1303
1304 } catch (e) {
1305 exception_error("archiveSelection", e);
1306 }
1307}
1308
a5ae125a
AD
1309function catchupSelection() {
1310
1311 try {
1312
b83d72b1
AD
1313 var rows = getSelectedArticleIds2();
1314
a5ae125a
AD
1315 if (rows.length == 0) {
1316 alert(__("No articles are selected."));
1317 return;
1318 }
1319
3d72bbdb 1320 var fn = getFeedName(getActiveFeedId(), activeFeedIsCat());
a5ae125a 1321
ba5fac1b 1322 var str = __("Mark %d selected articles in %s as read?");
a5ae125a 1323
ba5fac1b 1324 str = str.replace("%d", rows.length);
a5ae125a
AD
1325 str = str.replace("%s", fn);
1326
1327 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
1328 return;
1329 }
1330
acac8448 1331 if ($("headlinesList")) {
50eefedb 1332 selectionToggleUnread(false, 'viewCurrentFeed()', true);
a5ae125a 1333 } else {
50eefedb 1334 selectionToggleUnread(false, 'viewCurrentFeed()', true)
a5ae125a
AD
1335 }
1336
1337 } catch (e) {
1338 exception_error("catchupSelection", e);
1339 }
1340}
1341
13f08f75 1342function editArticleTags(id, feed_id, cdm_enabled) {
542aebac
AL
1343 displayDlg('editArticleTags', id,
1344 function () {
126cd3c8
AD
1345 $("tags_str").focus();
1346
1347 new Ajax.Autocompleter('tags_str', 'tags_choices',
542aebac
AL
1348 "backend.php?op=rpc&subop=completeTags",
1349 { tokens: ',', paramName: "search" });
1350 });
0b126ac2
AD
1351}
1352
0b126ac2
AD
1353function editTagsSave() {
1354
42c32916 1355 notify_progress("Saving article tags...");
88040f57 1356
0b126ac2
AD
1357 var form = document.forms["tag_edit_form"];
1358
1359 var query = Form.serialize("tag_edit_form");
1360
b4e75b2a 1361 query = "?op=rpc&subop=setArticleTags&" + query;
14b6c54b 1362
f8fb4498 1363 //console.log(query);
14b6c54b 1364
b4e75b2a
AD
1365 new Ajax.Request("backend.php", {
1366 parameters: query,
2ef1af84 1367 onComplete: function(transport) {
a5819bb3 1368 try {
f8fb4498 1369 //console.log("tags saved...");
a5819bb3
AD
1370
1371 closeInfoBox();
1372 notify("");
1373
1374 if (tagsAreDisplayed()) {
1375 _reload_feedlist_after_view = true;
1376 }
1377
1378 if (transport.responseXML) {
1379 var tags_str = transport.responseXML.getElementsByTagName("tags-str")[0];
1380
1381 if (tags_str) {
1382 var id = tags_str.getAttribute("id");
1383
1384 if (id) {
1385 var tags = $("ATSTR-" + id);
1386 if (tags) {
1387 tags.innerHTML = tags_str.firstChild.nodeValue;
1388 }
bd3f2ade
AD
1389
1390 cache_invalidate(id);
a5819bb3
AD
1391 }
1392 }
1393 }
1394
1395 } catch (e) {
1396 exception_error("editTagsSave", e);
1397 }
2ef1af84 1398 } });
0b126ac2 1399}
d62a3b63
AD
1400
1401function editTagsInsert() {
1402 try {
1403
1404 var form = document.forms["tag_edit_form"];
1405
1406 var found_tags = form.found_tags;
1407 var tags_str = form.tags_str;
1408
1409 var tag = found_tags[found_tags.selectedIndex].value;
1410
1411 if (tags_str.value.length > 0 &&
1412 tags_str.value.lastIndexOf(", ") != tags_str.value.length - 2) {
1413
1414 tags_str.value = tags_str.value + ", ";
1415 }
1416
1417 tags_str.value = tags_str.value + tag + ", ";
1418
1419 found_tags.selectedIndex = 0;
1420
1421 } catch (e) {
438f2ce9 1422 exception_error("editTagsInsert", e);
d62a3b63
AD
1423 }
1424}
ba0978c8 1425
b8e6acea
AD
1426function cdmScrollToArticleId(id) {
1427 try {
acac8448
AD
1428 var ctr = $("headlinesInnerContainer");
1429 var e = $("RROW-" + id);
b8e6acea
AD
1430
1431 if (!e || !ctr) return;
1432
1433 ctr.scrollTop = e.offsetTop;
1434
1435 } catch (e) {
438f2ce9 1436 exception_error("cdmScrollToArticleId", e);
b8e6acea
AD
1437 }
1438}
1439
ba0978c8
AD
1440function cdmWatchdog() {
1441
1442 try {
1443
acac8448 1444 var ctr = $("headlinesInnerContainer");
ba0978c8 1445
9acd22e8
AD
1446 if (!ctr) return;
1447
ba0978c8
AD
1448 var ids = new Array();
1449
1450 var e = ctr.firstChild;
1451
1452 while (e) {
1453 if (e.className && e.className == "cdmArticleUnread" && e.id &&
1454 e.id.match("RROW-")) {
1455
1456 // article fits in viewport OR article is longer than viewport and
1457 // its bottom is visible
1458
1459 if (ctr.scrollTop <= e.offsetTop && e.offsetTop + e.offsetHeight <=
1460 ctr.scrollTop + ctr.offsetHeight) {
1461
84c7b824 1462// console.log(e.id + " is visible " + e.offsetTop + "." +
ba0978c8
AD
1463// (e.offsetTop + e.offsetHeight) + " vs " + ctr.scrollTop + "." +
1464// (ctr.scrollTop + ctr.offsetHeight));
1465
1466 ids.push(e.id.replace("RROW-", ""));
1467
1468 } else if (e.offsetHeight > ctr.offsetHeight &&
1469 e.offsetTop + e.offsetHeight >= ctr.scrollTop &&
1470 e.offsetTop + e.offsetHeight <= ctr.scrollTop + ctr.offsetHeight) {
1471
1472 ids.push(e.id.replace("RROW-", ""));
1473
1474 }
1475
c50e2b30
AD
1476 // method 2: article bottom is visible and is in upper 1/2 of the viewport
1477
1478/* if (e.offsetTop + e.offsetHeight >= ctr.scrollTop &&
1479 e.offsetTop + e.offsetHeight <= ctr.scrollTop + ctr.offsetHeight/2) {
1480
1481 ids.push(e.id.replace("RROW-", ""));
1482
1483 } */
1484
ba0978c8
AD
1485 }
1486
1487 e = e.nextSibling;
1488 }
1489
84c7b824 1490 console.log("cdmWatchdog, ids= " + ids.toString());
ba0978c8 1491
1341ea0d 1492 if (ids.length > 0) {
ba0978c8
AD
1493
1494 for (var i = 0; i < ids.length; i++) {
acac8448 1495 var e = $("RROW-" + ids[i]);
ba0978c8
AD
1496 if (e) {
1497 e.className = e.className.replace("Unread", "");
1498 }
1499 }
1500
b4e75b2a
AD
1501 var query = "?op=rpc&subop=catchupSelected" +
1502 "&cmode=0" + "&ids=" + param_escape(ids.toString());
ba0978c8 1503
b4e75b2a
AD
1504 new Ajax.Request("backend.php", {
1505 parameters: query,
1341ea0d 1506 onComplete: function(transport) {
f8fb4498 1507 handle_rpc_reply(transport);
1341ea0d 1508 } });
ba0978c8
AD
1509
1510 }
1511
c50e2b30 1512 _cdm_wd_timeout = window.setTimeout("cdmWatchdog()", 4000);
ba0978c8
AD
1513
1514 } catch (e) {
438f2ce9 1515 exception_error("cdmWatchdog", e);
ba0978c8
AD
1516 }
1517
1518}
e097e8be
AD
1519
1520
e19c1824 1521function cache_inject(id, article, param) {
b39b57ac 1522
fb456d28
AD
1523 try {
1524 if (!cache_check_param(id, param)) {
f8fb4498 1525 //console.log("cache_article: miss: " + id + " [p=" + param + "]");
e097e8be 1526
b39b57ac
AD
1527 var date = new Date();
1528 var ts = Math.round(date.getTime() / 1000);
1529
1530 if (db) {
e097e8be 1531
fb456d28
AD
1532 db.execute("INSERT INTO cache (id, article, param, added) VALUES (?, ?, ?, ?)",
1533 [id, article, param, ts]);
1534 } else {
1535
ff0010c1 1536 var cache_obj = {};
fb456d28
AD
1537
1538 cache_obj["id"] = id;
1539 cache_obj["data"] = article;
1540 cache_obj["param"] = param;
ff0010c1
AD
1541
1542 if (param) id = id + ":" + param;
1543
b39b57ac
AD
1544 cache_added["TS:" + id] = ts;
1545
ff0010c1
AD
1546 if (has_local_storage())
1547 localStorage.setItem(id, JSON.stringify(cache_obj));
1548 else
1549 article_cache.push(cache_obj);
fb456d28
AD
1550 }
1551
1552 } else {
f8fb4498 1553 //console.log("cache_article: hit: " + id + " [p=" + param + "]");
fb456d28
AD
1554 }
1555 } catch (e) {
1556 exception_error("cache_inject", e);
e097e8be
AD
1557 }
1558}
1559
1560function cache_find(id) {
fb456d28
AD
1561
1562 if (db) {
31234407 1563 var rs = db.execute("SELECT article FROM cache WHERE id = ?", [id]);
03c96380 1564 var a = false;
31234407
AD
1565
1566 if (rs.isValidRow()) {
03c96380 1567 var a = rs.field(0);
31234407 1568 }
fb456d28 1569
03c96380
AD
1570 rs.close();
1571
1572 return a;
1573
fb456d28 1574 } else {
ff0010c1
AD
1575
1576 if (has_local_storage()) {
1577 var cache_obj = localStorage.getItem(id);
1578
1579 if (cache_obj) {
1580 cache_obj = JSON.parse(cache_obj);
1581
1582 if (cache_obj)
1583 return cache_obj['data'];
1584 }
1585
1586 } else {
1587 for (var i = 0; i < article_cache.length; i++) {
1588 if (article_cache[i]["id"] == id) {
1589 return article_cache[i]["data"];
1590 }
fb456d28 1591 }
fed4387d 1592 }
e097e8be 1593 }
fed4387d 1594 return false;
e097e8be
AD
1595}
1596
5d17ead9 1597function cache_find_param(id, param) {
fb456d28
AD
1598
1599 if (db) {
1600 var rs = db.execute("SELECT article FROM cache WHERE id = ? AND param = ?",
1601 [id, param]);
03c96380 1602 var a = false;
fb456d28
AD
1603
1604 if (rs.isValidRow()) {
03c96380 1605 a = rs.field(0);
fb456d28
AD
1606 }
1607
03c96380
AD
1608 rs.close();
1609
1610 return a;
1611
fb456d28 1612 } else {
ff0010c1
AD
1613
1614 if (has_local_storage()) {
b39b57ac
AD
1615
1616 if (param) id = id + ":" + param;
1617
1618 var cache_obj = localStorage.getItem(id);
ff0010c1
AD
1619
1620 if (cache_obj) {
1621 cache_obj = JSON.parse(cache_obj);
1622
1623 if (cache_obj)
1624 return cache_obj['data'];
1625 }
1626
1627 } else {
1628 for (var i = 0; i < article_cache.length; i++) {
1629 if (article_cache[i]["id"] == id && article_cache[i]["param"] == param) {
1630 return article_cache[i]["data"];
1631 }
fb456d28 1632 }
e19c1824
AD
1633 }
1634 }
1635 return false;
1636}
1637
e097e8be 1638function cache_check(id) {
fb456d28
AD
1639
1640 if (db) {
1641 var rs = db.execute("SELECT COUNT(*) AS c FROM cache WHERE id = ?",
1642 [id]);
03c96380 1643 var a = false;
fb456d28
AD
1644
1645 if (rs.isValidRow()) {
03c96380 1646 a = rs.field(0) != "0";
fb456d28
AD
1647 }
1648
03c96380
AD
1649 rs.close();
1650
1651 return a;
1652
fb456d28 1653 } else {
b39b57ac 1654 if (has_local_storage()) {
ff0010c1 1655 if (localStorage.getItem(id))
b39b57ac 1656 return true;
ff0010c1
AD
1657 } else {
1658 for (var i = 0; i < article_cache.length; i++) {
1659 if (article_cache[i]["id"] == id) {
1660 return true;
1661 }
fb456d28 1662 }
fed4387d
AD
1663 }
1664 }
1665 return false;
e097e8be
AD
1666}
1667
e19c1824 1668function cache_check_param(id, param) {
5d17ead9 1669
fb456d28
AD
1670 if (db) {
1671 var rs = db.execute("SELECT COUNT(*) AS c FROM cache WHERE id = ? AND param = ?",
1672 [id, param]);
03c96380 1673 var a = false;
5d17ead9 1674
fb456d28 1675 if (rs.isValidRow()) {
03c96380 1676 a = rs.field(0) != "0";
fb456d28
AD
1677 }
1678
03c96380
AD
1679 rs.close();
1680
1681 return a;
1682
fb456d28 1683 } else {
ff0010c1 1684
b39b57ac
AD
1685 if (has_local_storage()) {
1686
1687 if (param) id = id + ":" + param;
1688
1689 if (localStorage.getItem(id))
1690 return true;
1691
ff0010c1
AD
1692 } else {
1693 for (var i = 0; i < article_cache.length; i++) {
1694 if (article_cache[i]["id"] == id && article_cache[i]["param"] == param) {
1695 return true;
1696 }
fb456d28 1697 }
e19c1824
AD
1698 }
1699 }
1700 return false;
1701}
1702
e097e8be 1703function cache_expire() {
31234407
AD
1704 if (db) {
1705 var date = new Date();
1706 var ts = Math.round(date.getTime() / 1000);
1707
e0999d95
AD
1708 db.execute("DELETE FROM cache WHERE added < ? - 1800 AND id LIKE 'FEEDLIST'", [ts]);
1709 db.execute("DELETE FROM cache WHERE added < ? - 600 AND (id LIKE 'F:%' OR id LIKE 'C:%')", [ts]);
1710 db.execute("DELETE FROM cache WHERE added < ? - 86400", [ts]);
1711
31234407
AD
1712
1713 } else {
ff0010c1 1714 if (has_local_storage()) {
b39b57ac
AD
1715
1716 var date = new Date();
1717 var timestamp = Math.round(date.getTime() / 1000);
1718
905ff52a 1719 for (var i = 0; i < localStorage.length; i++) {
23d064cc 1720
905ff52a 1721 var id = localStorage.key(i);
23d064cc 1722
905ff52a
AD
1723 if (timestamp - cache_added["TS:" + id] > 180) {
1724 localStorage.removeItem(id);
b39b57ac 1725 }
ff0010c1 1726 }
b39b57ac 1727
ff0010c1
AD
1728 } else {
1729 while (article_cache.length > 25) {
1730 article_cache.shift();
1731 }
fb456d28 1732 }
fed4387d 1733 }
e097e8be 1734}
b07b61da 1735
641444d3 1736function cache_flush() {
5225d420
AD
1737 if (db) {
1738 db.execute("DELETE FROM cache");
1739 } else if (has_local_storage()) {
1740 localStorage.clear();
1741 } else {
1742 article_cache = new Array();
1743 }
3c2d7945
AD
1744}
1745
b07b61da 1746function cache_invalidate(id) {
c1b18749
AD
1747 try {
1748
fb456d28
AD
1749 if (db) {
1750 rs = db.execute("DELETE FROM cache WHERE id = ?", [id]);
1751 return rs.rowsAffected != 0;
1752 } else {
1753
ff0010c1 1754 if (has_local_storage()) {
fb456d28 1755
b39b57ac
AD
1756 var found = false;
1757
905ff52a
AD
1758 for (var i = 0; i < localStorage.length; i++) {
1759 var key = localStorage.key(i);
b39b57ac
AD
1760
1761// console.warn("cache_invalidate: " + key_id + " cmp " + id);
ff0010c1 1762
905ff52a
AD
1763 if (key == id || key.indexOf(id + ":") == 0) {
1764 localStorage.removeItem(key);
b39b57ac
AD
1765 found = true;
1766 break;
b39b57ac 1767 }
ff0010c1 1768 }
b39b57ac 1769
b39b57ac
AD
1770 return found;
1771
ff0010c1
AD
1772 } else {
1773 var i = 0
1774
1775 while (i < article_cache.length) {
1776 if (article_cache[i]["id"] == id) {
f8fb4498 1777 //console.log("cache_invalidate: removed id " + id);
ff0010c1
AD
1778 article_cache.splice(i, 1);
1779 return true;
1780 }
1781 i++;
fb456d28 1782 }
c1b18749 1783 }
b07b61da 1784 }
fb456d28 1785
f8fb4498 1786 //console.log("cache_invalidate: id not found: " + id);
c1b18749
AD
1787 return false;
1788 } catch (e) {
1789 exception_error("cache_invalidate", e);
b07b61da 1790 }
b07b61da 1791}
298f3f78
AD
1792
1793function getActiveArticleId() {
1794 return active_post_id;
1795}
e4914b62 1796
b39b57ac
AD
1797function preloadBatchedArticles() {
1798 try {
1799
1800 var query = "?op=rpc&subop=getArticles&ids=" +
1801 preload_id_batch.toString();
1802
1803 new Ajax.Request("backend.php", {
1804 parameters: query,
1805 onComplete: function(transport) {
1806
1807 preload_id_batch = [];
1808
1809 var articles = transport.responseXML.getElementsByTagName("article");
1810
1811 for (var i = 0; i < articles.length; i++) {
1812 var id = articles[i].getAttribute("id");
1813 if (!cache_check(id)) {
1814 cache_inject(id, articles[i].firstChild.nodeValue);
1815 console.log("preloaded article: " + id);
1816 }
1817 }
1818 } });
1819
1820 } catch (e) {
1821 exception_error("preloadBatchedArticles", e);
1822 }
1823}
1824
aa0fa9df
AD
1825function preloadArticleUnderPointer(id) {
1826 try {
a598370d
AD
1827 if (getInitParam("bw_limit") == "1") return;
1828
b2bb787c 1829 if (post_under_pointer == id && !cache_check(id)) {
aa0fa9df 1830
84c7b824 1831 console.log("trying to preload article " + id);
aa0fa9df
AD
1832
1833 var neighbor_ids = getRelativePostIds(id, 1);
1834
1835 /* only request uncached articles */
1836
b39b57ac
AD
1837 if (preload_id_batch.indexOf(id) == -1) {
1838 for (var i = 0; i < neighbor_ids.length; i++) {
1839 if (!cache_check(neighbor_ids[i])) {
1840 preload_id_batch.push(neighbor_ids[i]);
1841 }
aa0fa9df
AD
1842 }
1843 }
aa0fa9df 1844
b39b57ac
AD
1845 if (preload_id_batch.indexOf(id) == -1)
1846 preload_id_batch.push(id);
aa0fa9df 1847
f8fb4498 1848 //console.log("preload ids batch: " + preload_id_batch.toString());
b4e75b2a 1849
b39b57ac
AD
1850 window.clearTimeout(preload_timeout_id);
1851 preload_batch_timeout_id = window.setTimeout('preloadBatchedArticles()', 1000);
a5819bb3 1852
aa0fa9df
AD
1853 }
1854 } catch (e) {
1855 exception_error("preloadArticleUnderPointer", e);
1856 }
1857}
1858
314fcd2b
AD
1859function postMouseIn(id) {
1860 try {
aa0fa9df
AD
1861 if (post_under_pointer != id) {
1862 post_under_pointer = id;
1863 if (!isCdmMode()) {
1864 window.setTimeout("preloadArticleUnderPointer(" + id + ")", 250);
1865 }
1866 }
1867
314fcd2b
AD
1868 } catch (e) {
1869 exception_error("postMouseIn", e);
1870 }
1871}
1872
1873function postMouseOut(id) {
1874 try {
1875 post_under_pointer = false;
1876 } catch (e) {
1877 exception_error("postMouseOut", e);
1878 }
1879}
1880
ac541432
AD
1881function headlines_scroll_handler() {
1882 try {
1883
acac8448 1884 var e = $("headlinesInnerContainer");
ac541432 1885
4764c27e
AD
1886 var toolbar_form = document.forms["main_toolbar_form"];
1887
dad14b51
AD
1888// console.log((e.scrollTop + e.offsetHeight) + " vs " + e.scrollHeight + " dis? " +
1889// _infscroll_disable);
587bef10 1890
6f068202
AD
1891 if (e.scrollTop + e.offsetHeight > e.scrollHeight - 100) {
1892 if (!_infscroll_disable) {
6f068202 1893 viewNextFeedPage();
29dfb258 1894 }
ac541432
AD
1895 }
1896
1897 } catch (e) {
1898 exception_error("headlines_scroll_handler", e);
1899 }
1900}
8be83f42
AD
1901
1902function catchupRelativeToArticle(below) {
1903
1904 try {
1905
49fd1e94 1906
8be83f42
AD
1907 if (!getActiveArticleId()) {
1908 alert(__("No article is selected."));
1909 return;
1910 }
1911
e69fb880 1912 var visible_ids = getVisibleArticleIds();
8be83f42
AD
1913
1914 var ids_to_mark = new Array();
1915
1916 if (!below) {
1917 for (var i = 0; i < visible_ids.length; i++) {
1918 if (visible_ids[i] != getActiveArticleId()) {
acac8448 1919 var e = $("RROW-" + visible_ids[i]);
8be83f42
AD
1920
1921 if (e && e.className.match("Unread")) {
1922 ids_to_mark.push(visible_ids[i]);
1923 }
1924 } else {
1925 break;
1926 }
1927 }
1928 } else {
1929 for (var i = visible_ids.length-1; i >= 0; i--) {
1930 if (visible_ids[i] != getActiveArticleId()) {
acac8448 1931 var e = $("RROW-" + visible_ids[i]);
8be83f42
AD
1932
1933 if (e && e.className.match("Unread")) {
1934 ids_to_mark.push(visible_ids[i]);
1935 }
1936 } else {
1937 break;
1938 }
1939 }
1940 }
1941
1942 if (ids_to_mark.length == 0) {
1943 alert(__("No articles found to mark"));
1944 } else {
1945 var msg = __("Mark %d article(s) as read?").replace("%d", ids_to_mark.length);
1946
fb45339a 1947 if (getInitParam("confirm_feed_catchup") != 1 || confirm(msg)) {
8be83f42
AD
1948
1949 for (var i = 0; i < ids_to_mark.length; i++) {
acac8448 1950 var e = $("RROW-" + ids_to_mark[i]);
8be83f42
AD
1951 e.className = e.className.replace("Unread", "");
1952 }
1953
b4e75b2a
AD
1954 var query = "?op=rpc&subop=catchupSelected" +
1955 "&cmode=0" + "&ids=" + param_escape(ids_to_mark.toString());
8be83f42 1956
b4e75b2a
AD
1957 new Ajax.Request("backend.php", {
1958 parameters: query,
5fe7767c
AD
1959 onComplete: function(transport) {
1960 catchup_callback2(transport);
1961 } });
1962
8be83f42
AD
1963 }
1964 }
1965
1966 } catch (e) {
1967 exception_error("catchupRelativeToArticle", e);
1968 }
1969}
a04c8e8d 1970
dad14b51 1971function cdmExpandArticle(id) {
a04c8e8d 1972 try {
a04c8e8d 1973
e69fb880
AD
1974 hideAuxDlg();
1975
dad14b51 1976 var elem = $("CICD-" + active_post_id);
3cd4239a 1977
dad14b51
AD
1978 if (id == active_post_id && Element.visible(elem))
1979 return true;
1980
e69fb880 1981 selectArticles("none");
dad14b51
AD
1982
1983 var old_offset = $("RROW-" + id).offsetTop;
1984
5ae8f858 1985 if (active_post_id && elem && !getInitParam("cdm_expanded")) {
dad14b51
AD
1986 Element.hide(elem);
1987 Element.show("CEXC-" + active_post_id);
1988 }
a04c8e8d 1989
dad14b51 1990 active_post_id = id;
a04c8e8d 1991
dad14b51
AD
1992 elem = $("CICD-" + id);
1993
1994 if (!Element.visible(elem)) {
1995 Element.show(elem);
1996 Element.hide("CEXC-" + id);
1997 }
1998
1999 var new_offset = $("RROW-" + id).offsetTop;
2000
2001 $("headlinesInnerContainer").scrollTop += (new_offset-old_offset);
2002
2003 if ($("RROW-" + id).offsetTop != old_offset)
2004 $("headlinesInnerContainer").scrollTop = new_offset;
2005
2006 toggleUnread(id, 0, true);
2007 toggleSelected(id);
a04c8e8d
AD
2008
2009 } catch (e) {
d5ed5446 2010 exception_error("cdmExpandArticle", e);
a04c8e8d
AD
2011 }
2012
dad14b51 2013 return false;
a04c8e8d
AD
2014}
2015
3818a89b
AD
2016function fixHeadlinesOrder(ids) {
2017 try {
2018 for (var i = 0; i < ids.length; i++) {
acac8448 2019 var e = $("RROW-" + ids[i]);
3818a89b
AD
2020
2021 if (e) {
2022 if (i % 2 == 0) {
2023 e.className = e.className.replace("even", "odd");
2024 } else {
2025 e.className = e.className.replace("odd", "even");
2026 }
2027 }
2028 }
2029 } catch (e) {
2030 exception_error("fixHeadlinesOrder", e);
2031 }
2032}
2033
e75d70b5
AD
2034function invertHeadlineSelection() {
2035 try {
2036 var rows = new Array();
2037 var r = false;
2038
2039 if (!isCdmMode()) {
2040 r = document.getElementsByTagName("TR");
2041 } else {
2042 r = document.getElementsByTagName("DIV");
2043 }
2044
2045 for (var i = 0; i < r.length; i++) {
2046 if (r[i].id && r[i].id.match("RROW-")) {
2047 rows.push(r[i]);
2048 }
2049 }
2050
2051 for (var i = 0; i < rows.length; i++) {
2052 var nc = rows[i].className;
2053 var id = rows[i].id.replace("RROW-", "");
acac8448 2054 var cb = $("RCHK-" + id);
e75d70b5
AD
2055
2056 if (!rows[i].className.match("Selected")) {
2057 nc = nc + "Selected";
2058 cb.checked = true;
2059 } else {
2060 nc = nc.replace("Selected", "");
2061 cb.checked = false;
2062 }
2063
2064 rows[i].className = nc;
2065
2066 }
2067
2068 } catch (e) {
2069 exception_error("invertHeadlineSelection", e);
2070 }
2071}
2072
314fcd2b
AD
2073function getArticleUnderPointer() {
2074 return post_under_pointer;
7a822893 2075}
eedfb635
AD
2076
2077function zoomToArticle(id) {
2078 try {
2079 var w = window.open("backend.php?op=view&mode=zoom&id=" + param_escape(id),
2080 "ttrss_zoom_" + id,
2081 "status=0,toolbar=0,location=0,width=450,height=300,scrollbars=1,menubar=0");
2082
2083 } catch (e) {
2084 exception_error("zoomToArticle", e);
2085 }
2086}
a411875b
AD
2087
2088function scrollArticle(offset) {
2089 try {
2090 if (!isCdmMode()) {
acac8448 2091 var ci = $("content-insert");
a411875b
AD
2092 if (ci) {
2093 ci.scrollTop += offset;
2094 }
2095 } else {
acac8448 2096 var hi = $("headlinesInnerContainer");
a411875b
AD
2097 if (hi) {
2098 hi.scrollTop += offset;
2099 }
2100
2101 }
2102 } catch (e) {
2103 exception_error("scrollArticle", e);
2104 }
2105}
f9247195
AD
2106
2107function show_labels_in_headlines(transport) {
2108 try {
2109 if (transport.responseXML) {
2110 var info = transport.responseXML.getElementsByTagName("info-for-headlines")[0];
2111
2112 var elems = info.getElementsByTagName("entry");
2113
2114 for (var l = 0; l < elems.length; l++) {
2115 var e_id = elems[l].getAttribute("id");
2116
2117 if (e_id) {
2118
acac8448 2119 var ctr = $("HLLCTR-" + e_id);
f9247195
AD
2120
2121 if (ctr) {
2122 ctr.innerHTML = elems[l].firstChild.nodeValue;
2123 }
2124 }
2125
2126 }
2127
2128 }
2129 } catch (e) {
2130 exception_error("show_labels_in_headlines", e);
2131
2132 }
2133}
bf3c9838
AD
2134
2135function toggleHeadlineActions() {
2136 try {
acac8448
AD
2137 var e = $("headlineActionsBody");
2138 var p = $("headlineActionsDrop");
bf3c9838
AD
2139
2140 if (!Element.visible(e)) {
2141 Element.show(e);
2142 } else {
2143 Element.hide(e);
2144 }
2145
b62f6ff4 2146 e.scrollTop = 0;
bf3c9838 2147 e.style.left = (p.offsetLeft + 1) + "px";
b4dc02e2 2148 e.style.top = (p.offsetTop + p.offsetHeight + 2) + "px";
bf3c9838
AD
2149
2150 } catch (e) {
2151 exception_error("toggleHeadlineActions", e);
2152 }
2153}
c7e51de1
AD
2154
2155function publishWithNote(id, def_note) {
2156 try {
2157 if (!def_note) def_note = '';
2158
2159 var note = prompt(__("Please enter a note for this article:"), def_note);
2160
2161 if (note != undefined) {
2162 togglePub(id, false, false, note);
2163 }
2164
2165 } catch (e) {
2166 exception_error("publishWithNote", e);
2167 }
2168}
31a53903
AD
2169
2170function emailArticle(id) {
2171 try {
f72a7b66
AD
2172 if (!id) {
2173 var ids = getSelectedArticleIds2();
2174
2175 if (ids.length == 0) {
2176 alert(__("No articles are selected."));
2177 return;
2178 }
2179
2180 id = ids.toString();
2181 }
2182
31a53903
AD
2183 displayDlg('emailArticle', id,
2184 function () {
2185 document.forms['article_email_form'].destination.focus();
2186
2187 new Ajax.Autocompleter('destination', 'destination_choices',
2188 "backend.php?op=rpc&subop=completeEmails",
2189 { tokens: '', paramName: "search" });
2190
2191 });
2192
2193 } catch (e) {
2194 exception_error("emailArticle", e);
2195 }
2196}
2197
f72a7b66 2198function emailArticleDo() {
31a53903
AD
2199 try {
2200 var f = document.forms['article_email_form'];
2201
2202 if (f.destination.value == "") {
2203 alert("Please fill in the destination email.");
2204 return;
2205 }
2206
2207 if (f.subject.value == "") {
2208 alert("Please fill in the subject.");
2209 return;
2210 }
2211
2212 var query = Form.serialize("article_email_form");
2213
2214// console.log(query);
2215
2216 new Ajax.Request("backend.php", {
2217 parameters: query,
2218 onComplete: function(transport) {
2219 try {
2220
2221 var error = transport.responseXML.getElementsByTagName('error')[0];
2222
2223 if (error) {
2224 alert(__('Error sending email:') + ' ' + error.firstChild.nodeValue);
2225 } else {
2226 notify_info('Your message has been sent.');
2227 closeInfoBox();
2228 }
2229
2230 } catch (e) {
2231 exception_error("sendEmailDo", e);
2232 }
2233
2234 } });
2235
2236 } catch (e) {
2237 exception_error("emailArticleDo", e);
2238 }
2239}
dad14b51 2240
1ede5814 2241function dismissArticle(id) {
dad14b51
AD
2242 try {
2243 var elem = $("RROW-" + id);
2244
2245 toggleUnread(id, 0, true);
2246
2247 new Effect.Fade(elem, {duration : 0.5});
2248
2249 } catch (e) {
1ede5814 2250 exception_error("dismissArticle", e);
dad14b51
AD
2251 }
2252}
bfa0e792 2253
1ede5814 2254function dismissSelectedArticles() {
bfa0e792
AD
2255 try {
2256
e69fb880
AD
2257 var ids = getVisibleArticleIds();
2258 var tmp = [];
2259 var sel = [];
bfa0e792
AD
2260
2261 for (var i = 0; i < ids.length; i++) {
2262 var elem = $("RROW-" + ids[i]);
e69fb880
AD
2263
2264 if (elem.className && elem.className.match("Selected")) {
2265 new Effect.Fade(elem, {duration : 0.5});
2266 sel.push(ids[i]);
2267 } else {
2268 tmp.push(ids[i]);
2269 }
bfa0e792
AD
2270 }
2271
e69fb880 2272 if (sel.length > 0)
bfa0e792
AD
2273 selectionToggleUnread(false);
2274
e69fb880
AD
2275 fixHeadlinesOrder(tmp);
2276
bfa0e792 2277 } catch (e) {
1ede5814 2278 exception_error("dismissSelectedArticles", e);
bfa0e792
AD
2279 }
2280}
1ede5814
AD
2281
2282function dismissReadArticles() {
2283 try {
2284
2285 var ids = getVisibleArticleIds();
e69fb880 2286 var tmp = [];
1ede5814
AD
2287
2288 for (var i = 0; i < ids.length; i++) {
2289 var elem = $("RROW-" + ids[i]);
2290
2291 if (elem.className && !elem.className.match("Unread") &&
2292 !elem.className.match("Selected")) {
2293
2294 new Effect.Fade(elem, {duration : 0.5});
e69fb880
AD
2295 } else {
2296 tmp.push(ids[i]);
1ede5814
AD
2297 }
2298 }
2299
e69fb880
AD
2300 fixHeadlinesOrder(tmp);
2301
1ede5814
AD
2302 } catch (e) {
2303 exception_error("dismissSelectedArticles", e);
2304 }
2305}
2306
2307function getVisibleArticleIds() {
e69fb880
AD
2308 var ids = [];
2309
1ede5814 2310 try {
e69fb880
AD
2311 var tmp = getLoadedArticleIds();
2312
2313 for (var i = 0; i < tmp.length; i++) {
2314 var elem = $("RROW-" + tmp[i]);
2315 if (elem && Element.visible(elem))
2316 ids.push(tmp[i]);
1ede5814 2317 }
e69fb880 2318
1ede5814 2319 } catch (e) {
e69fb880 2320 exception_error("getVisibleArticleIds", e);
1ede5814 2321 }
e69fb880
AD
2322
2323 return ids;
1ede5814
AD
2324}
2325
2326function cdmClicked(event, id) {
2327 try {
2328 var shift_key = event.shiftKey;
2329
e69fb880
AD
2330 hideAuxDlg();
2331
1ede5814 2332 if (!event.ctrlKey) {
e69fb880 2333 selectArticles("none");
1ede5814
AD
2334 toggleSelected(id);
2335
2336 var elem = $("RROW-" + id);
2337
2338 if (elem)
2339 elem.className = elem.className.replace("Unread", "");
2340
2341 var query = "?op=rpc&subop=catchupSelected" +
2342 "&cmode=0&ids=" + param_escape(id);
2343
2344 new Ajax.Request("backend.php", {
2345 parameters: query,
2346 onComplete: function(transport) {
2347 handle_rpc_reply(transport);
2348 } });
2349
a627ae35 2350 return true;
1ede5814
AD
2351 } else {
2352 toggleSelected(id);
2353 }
2354
2355 } catch (e) {
2356 exception_error("cdmClicked");
2357 }
2358
2359 return false;
2360}
2361
2362function hlClicked(event, id) {
2363 try {
2364 var shift_key = event.shiftKey;
2365
2366 if (!event.ctrlKey) {
2367 view(id);
3974aad8 2368 return true;
1ede5814
AD
2369 } else {
2370 toggleSelected(id);
3974aad8 2371 return false;
1ede5814
AD
2372 }
2373
2374 } catch (e) {
2375 exception_error("hlClicked");
2376 }
2377
2378 return false;
2379}
e69fb880
AD
2380
2381function getFirstVisibleHeadlineId() {
2382 var rows = getVisibleArticleIds();
2383 return rows[0];
2384
2385}
2386
2387function getLastVisibleHeadlineId() {
2388 var rows = getVisibleArticleIds();
2389 return rows[rows.length-1];
2390}
2391
2392// this only searches loaded headlines list, not in CDM
2393function getRelativePostIds(id, limit) {
2394
2395 if (!limit) limit = 3;
2396
2397 //console.log("getRelativePostIds: " + id + " limit=" + limit);
2398
2399 var ids = new Array();
2400 var container = $("headlinesList");
2401
2402 if (container) {
2403 var rows = container.rows;
2404
2405 for (var i = 0; i < rows.length; i++) {
2406 var r_id = rows[i].id.replace("RROW-", "");
2407
2408 if (r_id == id) {
2409 for (var k = 1; k <= limit; k++) {
2410 var nid = false;
2411
2412 if (i > k-1) var nid = rows[i-k].id.replace("RROW-", "");
2413 if (nid) ids.push(nid);
2414
2415 if (i < rows.length-k) nid = rows[i+k].id.replace("RROW-", "");
2416 if (nid) ids.push(nid);
2417 }
2418
2419 return ids;
2420 }
2421 }
2422 }
2423
2424 return false;
2425}
2426
2427function openArticleInNewWindow(id) {
2428 try {
2429 console.log("openArticleInNewWindow: " + id);
2430
2431 var query = "?op=rpc&subop=getArticleLink&id=" + id;
2432 var wname = "ttrss_article_" + id;
2433
2434 console.log(query + " " + wname);
2435
2436 var w = window.open("", wname);
2437
2438 if (!w) notify_error("Failed to open window for the article");
2439
2440 new Ajax.Request("backend.php", {
2441 parameters: query,
2442 onComplete: function(transport) {
2443
2444 var link = transport.responseXML.getElementsByTagName("link")[0];
2445 var id = transport.responseXML.getElementsByTagName("id")[0];
2446
2447 console.log("open_article received link: " + link);
2448
2449 if (link && id) {
2450
2451 var wname = "ttrss_article_" + id.firstChild.nodeValue;
2452
2453 console.log("link url: " + link.firstChild.nodeValue + ", wname " + wname);
2454
2455 var w = window.open(link.firstChild.nodeValue, wname);
2456
2457 if (!w) { notify_error("Failed to load article in new window"); }
2458
2459 if (id) {
2460 id = id.firstChild.nodeValue;
2461 if (!$("headlinesList")) {
2462 window.setTimeout("toggleUnread(" + id + ", 0)", 100);
2463 }
2464 }
2465 } else {
2466 notify_error("Can't open article: received invalid article link");
2467 }
2468 } });
2469
2470 } catch (e) {
2471 exception_error("openArticleInNewWindow", e);
2472 }
2473}
2474
2475function isCdmMode() {
2476 return !$("headlinesList");
2477}
2478
2479function markHeadline(id) {
2480 var row = $("RROW-" + id);
2481 if (row) {
2482 var is_active = false;
2483
2484 if (row.className.match("Active")) {
2485 is_active = true;
2486 }
2487 row.className = row.className.replace("Selected", "");
2488 row.className = row.className.replace("Active", "");
2489 row.className = row.className.replace("Insensitive", "");
2490
2491 if (is_active) {
2492 row.className = row.className = "Active";
2493 }
2494
2495 var check = $("RCHK-" + id);
2496
2497 if (check) {
2498 check.checked = true;
2499 }
2500
2501 row.className = row.className + "Selected";
2502
2503 }
2504}
2505
2506