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