]> git.wh0rd.org - tt-rss.git/blob - viewfeed.js
ae9e443e2c99503ae04219dc08d50b437730c03a
[tt-rss.git] / viewfeed.js
1 var active_post_id = false;
2 var last_article_view = false;
3 var active_real_feed_id = false;
4
5 var _tag_active_post_id = false;
6 var _tag_active_feed_id = false;
7 var _tag_active_cdm = false;
8
9 // FIXME: kludge, to restore scrollTop after tag editor terminates
10 var _tag_cdm_scroll = false;
11
12 // FIXME: kludges, needs proper implementation
13 var _reload_feedlist_after_view = false;
14
15 var _cdm_wd_timeout = false;
16 var _cdm_wd_vishist = new Array();
17
18 var article_cache = new Array();
19
20 var vgroup_last_feed = false;
21 var post_under_pointer = false;
22
23 var last_requested_article = false;
24
25 function catchup_callback() {
26 if (xmlhttp_rpc.readyState == 4) {
27 try {
28 debug("catchup_callback");
29 notify("");
30 all_counters_callback2(xmlhttp_rpc);
31 if (_catchup_callback_func) {
32 setTimeout(_catchup_callback_func, 10);
33 }
34 } catch (e) {
35 exception_error("catchup_callback", e);
36 }
37 }
38 }
39
40 function catchup_callback2(transport, callback) {
41 try {
42 debug("catchup_callback2 " + transport + ", " + callback);
43 notify("");
44 all_counters_callback2(transport);
45 if (callback) {
46 setTimeout(callback, 10);
47 }
48 } catch (e) {
49 exception_error("catchup_callback2", e);
50 }
51 }
52
53 function clean_feed_selections() {
54 try {
55 var feeds = document.getElementById("feedList").getElementsByTagName("LI");
56
57 for (var i = 0; i < feeds.length; i++) {
58 if (feeds[i].id && feeds[i].id.match("FEEDR-")) {
59 feeds[i].className = feeds[i].className.replace("Selected", "");
60 }
61 if (feeds[i].id && feeds[i].id.match("FCAT-")) {
62 feeds[i].className = feeds[i].className.replace("Selected", "");
63 }
64 }
65 } catch (e) {
66 exception_error("clean_feed_selections", e);
67 }
68 }
69
70 function headlines_callback2(transport, active_feed_id, is_cat, feed_cur_page) {
71 try {
72
73 loading_set_progress(100);
74
75 debug("headlines_callback2 [page=" + feed_cur_page + "]");
76
77 clean_feed_selections();
78
79 setActiveFeedId(active_feed_id);
80
81 if (is_cat != undefined) {
82 active_feed_is_cat = is_cat;
83 }
84
85 if (!is_cat) {
86 var feedr = document.getElementById("FEEDR-" + active_feed_id);
87 if (feedr && !feedr.className.match("Selected")) {
88 feedr.className = feedr.className + "Selected";
89 }
90 } else {
91 var feedr = document.getElementById("FCAT-" + active_feed_id);
92 if (feedr && !feedr.className.match("Selected")) {
93 feedr.className = feedr.className + "Selected";
94 }
95 }
96
97 var f = document.getElementById("headlines-frame");
98 try {
99 if (feed_cur_page == 0) {
100 debug("resetting headlines scrollTop");
101 f.scrollTop = 0;
102 }
103 } catch (e) { };
104
105 if (transport.responseXML) {
106 var headlines = transport.responseXML.getElementsByTagName("headlines")[0];
107 var headlines_count_obj = transport.responseXML.getElementsByTagName("headlines-count")[0];
108 var headlines_unread_obj = transport.responseXML.getElementsByTagName("headlines-unread")[0];
109 var disable_cache_obj = transport.responseXML.getElementsByTagName("disable-cache")[0];
110
111 var vgroup_last_feed_obj = transport.responseXML.getElementsByTagName("vgroup-last-feed")[0];
112
113 var headlines_count = headlines_count_obj.getAttribute("value");
114 var headlines_unread = headlines_unread_obj.getAttribute("value");
115 var disable_cache = disable_cache_obj.getAttribute("value") != "0";
116
117 vgroup_last_feed = vgroup_last_feed_obj.getAttribute("value");
118
119 if (headlines_count == 0) {
120 _infscroll_disable = 1;
121 } else {
122 _infscroll_disable = 0;
123 }
124
125 var counters = transport.responseXML.getElementsByTagName("counters")[0];
126 var articles = transport.responseXML.getElementsByTagName("article");
127 var runtime_info = transport.responseXML.getElementsByTagName("runtime-info");
128
129 if (feed_cur_page == 0) {
130 if (headlines) {
131 f.innerHTML = headlines.firstChild.nodeValue;
132
133 var cache_prefix = "";
134
135 if (is_cat) {
136 cache_prefix = "C:";
137 } else {
138 cache_prefix = "F:";
139 }
140
141 cache_invalidate(cache_prefix + active_feed_id);
142
143 if (!disable_cache) {
144 cache_inject(cache_prefix + active_feed_id,
145 headlines.firstChild.nodeValue, headlines_unread);
146 }
147
148 } else {
149 debug("headlines_callback: returned no data");
150 f.innerHTML = "<div class='whiteBox'>" + __('Could not update headlines (missing XML data)') + "</div>";
151
152 }
153 } else {
154 if (headlines) {
155 if (headlines_count > 0) {
156 debug("adding some more headlines...");
157
158 var c = document.getElementById("headlinesList");
159
160 if (!c) {
161 c = document.getElementById("headlinesInnerContainer");
162 }
163
164 var ids = getSelectedArticleIds2();
165
166 c.innerHTML = c.innerHTML + headlines.firstChild.nodeValue;
167
168 debug("restore selected ids: " + ids);
169
170 for (var i = 0; i < ids.length; i++) {
171 markHeadline(ids[i]);
172 }
173
174 subtoolbarSearch();
175
176 } else {
177 debug("no new headlines received");
178 }
179 } else {
180 debug("headlines_callback: returned no data");
181 notify_error("Error while trying to load more headlines");
182 }
183
184 }
185
186 if (articles) {
187 for (var i = 0; i < articles.length; i++) {
188 var a_id = articles[i].getAttribute("id");
189 debug("found id: " + a_id);
190 cache_inject(a_id, articles[i].firstChild.nodeValue);
191 }
192 } else {
193 debug("no cached articles received");
194 }
195
196 if (counters) {
197 debug("parsing piggybacked counters: " + counters);
198 parse_counters(counters, false);
199 } else {
200 debug("counters container not found in reply, requesting...");
201 request_counters();
202 }
203
204 if (runtime_info) {
205 debug("parsing runtime info: " + runtime_info[0]);
206 parse_runtime_info(runtime_info[0]);
207 } else {
208 debug("counters container not found in reply");
209 }
210
211 } else {
212 debug("headlines_callback: returned no XML object");
213 f.innerHTML = "<div class='whiteBox'>" + __('Could not update headlines (missing XML object)') + "</div>";
214 }
215
216 if (typeof correctPNG != 'undefined') {
217 correctPNG();
218 }
219
220 if (_cdm_wd_timeout) window.clearTimeout(_cdm_wd_timeout);
221
222 if (!document.getElementById("headlinesList") &&
223 getInitParam("cdm_auto_catchup") == 1) {
224 debug("starting CDM watchdog");
225 _cdm_wd_timeout = window.setTimeout("cdmWatchdog()", 5000);
226 _cdm_wd_vishist = new Array();
227 } else {
228 debug("not in CDM mode or watchdog disabled");
229 }
230
231 if (_tag_cdm_scroll) {
232 try {
233 document.getElementById("headlinesInnerContainer").scrollTop = _tag_cdm_scroll;
234 _tag_cdm_scroll = false;
235 debug("resetting headlinesInner scrollTop");
236
237 } catch (e) { }
238 }
239
240 _feed_cur_page = feed_cur_page;
241 _infscroll_request_sent = 0;
242
243 notify("");
244
245 remove_splash();
246
247 } catch (e) {
248 exception_error("headlines_callback2", e);
249 }
250 }
251
252 function render_article(article) {
253 try {
254 var f = document.getElementById("content-frame");
255 try {
256 f.scrollTop = 0;
257 } catch (e) { };
258
259 var fi = document.getElementById("content-insert");
260
261 fi.innerHTML = article;
262
263 } catch (e) {
264 exception_error("render_article", e);
265 }
266 }
267
268 function showArticleInHeadlines(id) {
269
270 try {
271
272 cleanSelected("headlinesList");
273
274 var crow = document.getElementById("RROW-" + id);
275
276 if (!crow) return;
277
278 var article_is_unread = crow.className.match("Unread");
279
280 crow.className = crow.className.replace("Unread", "");
281
282 selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', false);
283
284 var upd_img_pic = document.getElementById("FUPDPIC-" + id);
285
286 var cache_prefix = "";
287
288 if (activeFeedIsCat()) {
289 cache_prefix = "C:";
290 } else {
291 cache_prefix = "F:";
292 }
293
294 var view_mode = false;
295
296 try {
297 view_mode = document.forms['main_toolbar_form'].view_mode;
298 view_mode = view_mode[view_mode.selectedIndex].value;
299 } catch (e) {
300 exception_error("showArticleInHeadlines/viewmode", e, true);
301 }
302
303 if (upd_img_pic && upd_img_pic.src.match("updated.png")) {
304 upd_img_pic.src = "images/blank_icon.gif";
305
306 cache_invalidate(cache_prefix + getActiveFeedId());
307
308 cache_inject(cache_prefix + getActiveFeedId(),
309 document.getElementById("headlines-frame").innerHTML,
310 get_feed_unread(getActiveFeedId()));
311
312 } else if (article_is_unread && view_mode == "all_articles") {
313
314 cache_invalidate(cache_prefix + getActiveFeedId());
315
316 cache_inject(cache_prefix + getActiveFeedId(),
317 document.getElementById("headlines-frame").innerHTML,
318 get_feed_unread(getActiveFeedId())-1);
319
320 } else if (article_is_unread) {
321 cache_invalidate(cache_prefix + getActiveFeedId());
322 }
323
324 markHeadline(id);
325
326 } catch (e) {
327 exception_error("showArticleInHeadlines", e);
328 }
329 }
330
331 function article_callback2(transport, id, feed_id) {
332 try {
333 debug("article_callback2 " + id);
334
335 if (transport.responseXML) {
336
337 debug("looking for articles to cache...");
338
339 var articles = transport.responseXML.getElementsByTagName("article");
340
341 for (var i = 0; i < articles.length; i++) {
342 var a_id = articles[i].getAttribute("id");
343
344 debug("found id: " + a_id);
345
346 if (a_id == active_post_id) {
347 debug("active article, rendering...");
348 render_article(articles[i].firstChild.nodeValue);
349 }
350
351 cache_inject(a_id, articles[i].firstChild.nodeValue);
352 }
353
354 if (id != last_requested_article) {
355 debug("requested article id is out of sequence, aborting");
356 return;
357 }
358
359 active_real_feed_id = feed_id;
360 active_post_id = id;
361
362 showArticleInHeadlines(id);
363
364 var reply = transport.responseXML.firstChild.firstChild;
365
366 } else {
367 debug("article_callback: returned no XML object");
368 //var f = document.getElementById("content-frame");
369 //f.innerHTML = "<div class='whiteBox'>" + __('Could not display article (missing XML object)') + "</div>";
370 }
371
372 var date = new Date();
373 last_article_view = date.getTime() / 1000;
374
375 if (typeof correctPNG != 'undefined') {
376 correctPNG();
377 }
378
379 if (_reload_feedlist_after_view) {
380 setTimeout('updateFeedList(false, false)', 50);
381 _reload_feedlist_after_view = false;
382 } else {
383 var counters = transport.responseXML.getElementsByTagName("counters")[0];
384
385 if (counters) {
386 debug("parsing piggybacked counters: " + counters);
387 parse_counters(counters, false);
388 } else {
389 debug("counters container not found in reply, requesting...");
390 request_counters();
391 }
392 }
393
394 notify("");
395 } catch (e) {
396 exception_error("article_callback2", e);
397 }
398 }
399
400 function view(id, feed_id, skip_history) {
401
402 try {
403 debug("loading article: " + id + "/" + feed_id);
404
405 var cached_article = cache_find(id);
406
407 debug("cache check result: " + (cached_article != false));
408
409 enableHotkeys();
410
411 //setActiveFeedId(feed_id);
412
413 var query = "backend.php?op=view&id=" + param_escape(id) +
414 "&feed=" + param_escape(feed_id);
415
416 var date = new Date();
417
418 var neighbor_ids = getRelativePostIds(active_post_id);
419
420 /* only request uncached articles */
421
422 var cids_to_request = Array();
423
424 for (var i = 0; i < neighbor_ids.length; i++) {
425 if (!cache_check(neighbor_ids[i])) {
426 cids_to_request.push(neighbor_ids[i]);
427 }
428 }
429
430 debug("additional ids: " + cids_to_request.toString());
431
432 /* additional info for piggyback counters */
433
434 if (tagsAreDisplayed()) {
435 query = query + "&omode=lt";
436 } else {
437 query = query + "&omode=flc";
438 }
439
440 var date = new Date();
441 var timestamp = Math.round(date.getTime() / 1000);
442 query = query + "&ts=" + timestamp;
443
444 query = query + "&cids=" + cids_to_request.toString();
445
446 var crow = document.getElementById("RROW-" + id);
447 var article_is_unread = crow.className.match("Unread");
448
449 if (!async_counters_work) {
450 query = query + "&csync=true";
451 }
452
453 showArticleInHeadlines(id);
454
455 if (!cached_article) {
456
457 notify_progress("Loading, please wait...", true);
458
459 } else if (cached_article && article_is_unread) {
460
461 query = query + "&mode=prefetch";
462
463 render_article(cached_article);
464
465 } else if (cached_article) {
466
467 query = query + "&mode=prefetch_old";
468 render_article(cached_article);
469
470 }
471
472 cache_expire();
473
474 last_requested_article = id;
475
476 new Ajax.Request(query, {
477 onComplete: function(transport) {
478 article_callback2(transport, id, feed_id);
479 } });
480
481 return false;
482
483 } catch (e) {
484 exception_error("view", e);
485 }
486 }
487
488 function tMark(id) {
489 return toggleMark(id);
490 }
491
492 function tPub(id) {
493 return togglePub(id);
494 }
495
496 function tMark_afh_off(effect) {
497 try {
498 var elem = effect.effects[0].element;
499
500 debug("tMark_afh_off : " + elem.id);
501
502 if (elem) {
503 elem.src = elem.src.replace("mark_set", "mark_unset");
504 elem.alt = __("Star article");
505 Element.show(elem);
506 }
507
508 } catch (e) {
509 exception_error("tMark_afh_off", e);
510 }
511 }
512
513 function tPub_afh_off(effect) {
514 try {
515 var elem = effect.effects[0].element;
516
517 debug("tPub_afh_off : " + elem.id);
518
519 if (elem) {
520 elem.src = elem.src.replace("pub_set", "pub_unset");
521 elem.alt = __("Publish article");
522 Element.show(elem);
523 }
524
525 } catch (e) {
526 exception_error("tPub_afh_off", e);
527 }
528 }
529
530 function toggleMark(id, client_only, no_effects) {
531
532 try {
533
534 var query = "backend.php?op=rpc&id=" + id + "&subop=mark";
535
536 query = query + "&afid=" + getActiveFeedId();
537
538 if (tagsAreDisplayed()) {
539 query = query + "&omode=tl";
540 } else {
541 query = query + "&omode=flc";
542 }
543
544 var mark_img = document.getElementById("FMPIC-" + id);
545 var vfeedu = document.getElementById("FEEDU--1");
546 var crow = document.getElementById("RROW-" + id);
547
548 if (mark_img.src.match("mark_unset")) {
549 mark_img.src = mark_img.src.replace("mark_unset", "mark_set");
550 mark_img.alt = __("Unstar article");
551 query = query + "&mark=1";
552
553 } else {
554 //mark_img.src = "images/mark_unset.png";
555 mark_img.alt = __("Please wait...");
556 query = query + "&mark=0";
557
558 if (document.getElementById("headlinesList") && !no_effects) {
559 Effect.Puff(mark_img, {duration : 0.25, afterFinish: tMark_afh_off});
560 } else {
561 mark_img.src = mark_img.src.replace("mark_set", "mark_unset");
562 mark_img.alt = __("Star article");
563 }
564 }
565
566 if (!client_only) {
567 debug(query);
568
569 new Ajax.Request(query, {
570 onComplete: function(transport) {
571 all_counters_callback2(transport);
572 } });
573
574 }
575
576 } catch (e) {
577 exception_error("toggleMark", e);
578 }
579 }
580
581 function togglePub(id, client_only, no_effects) {
582
583 try {
584
585 var query = "backend.php?op=rpc&id=" + id + "&subop=publ";
586
587 query = query + "&afid=" + getActiveFeedId();
588
589 if (tagsAreDisplayed()) {
590 query = query + "&omode=tl";
591 } else {
592 query = query + "&omode=flc";
593 }
594
595 var mark_img = document.getElementById("FPPIC-" + id);
596 var vfeedu = document.getElementById("FEEDU--2");
597 var crow = document.getElementById("RROW-" + id);
598
599 if (mark_img.src.match("pub_unset")) {
600 mark_img.src = mark_img.src.replace("pub_unset", "pub_set");
601 mark_img.alt = __("Unpublish article");
602 query = query + "&pub=1";
603
604
605 } else {
606 //mark_img.src = "images/pub_unset.png";
607 mark_img.alt = __("Please wait...");
608 query = query + "&pub=0";
609
610 if (document.getElementById("headlinesList") && !no_effects) {
611 Effect.Puff(mark_img, {duration : 0.25, afterFinish: tPub_afh_off});
612 } else {
613 mark_img.src = mark_img.src.replace("pub_set", "pub_unset");
614 mark_img.alt = __("Publish article");
615 }
616 }
617
618 if (!client_only) {
619 new Ajax.Request(query, {
620 onComplete: function(transport) {
621 all_counters_callback2(transport);
622 } });
623 }
624
625 } catch (e) {
626
627 exception_error("togglePub", e);
628 }
629 }
630
631 function correctHeadlinesOffset(id) {
632
633 try {
634
635 var hlist = document.getElementById("headlinesList");
636 var container = document.getElementById("headlinesInnerContainer");
637 var row = document.getElementById("RROW-" + id);
638
639 var viewport = container.offsetHeight;
640
641 var rel_offset_top = row.offsetTop - container.scrollTop;
642 var rel_offset_bottom = row.offsetTop + row.offsetHeight - container.scrollTop;
643
644 debug("Rtop: " + rel_offset_top + " Rbtm: " + rel_offset_bottom);
645 debug("Vport: " + viewport);
646
647 if (rel_offset_top <= 0 || rel_offset_top > viewport) {
648 container.scrollTop = row.offsetTop;
649 } else if (rel_offset_bottom > viewport) {
650
651 /* doesn't properly work with Opera in some cases because
652 Opera fucks up element scrolling */
653
654 container.scrollTop = row.offsetTop + row.offsetHeight - viewport;
655 }
656
657 } catch (e) {
658 exception_error("correctHeadlinesOffset", e);
659 }
660
661 }
662
663 function moveToPost(mode) {
664
665 try {
666
667 var rows;
668
669 if (isCdmMode()) {
670 rows = cdmGetVisibleArticles();
671 } else {
672 rows = getVisibleHeadlineIds();
673 }
674
675 var prev_id = false;
676 var next_id = false;
677
678 if (!document.getElementById('RROW-' + active_post_id)) {
679 active_post_id = false;
680 }
681
682 if (active_post_id == false) {
683 next_id = getFirstVisibleHeadlineId();
684 prev_id = getLastVisibleHeadlineId();
685 } else {
686 for (var i = 0; i < rows.length; i++) {
687 if (rows[i] == active_post_id) {
688 prev_id = rows[i-1];
689 next_id = rows[i+1];
690 }
691 }
692 }
693
694 if (mode == "next") {
695 if (next_id) {
696 if (isCdmMode()) {
697
698 if (!cdmArticleIsActuallyVisible(next_id)) {
699 cdmScrollToArticleId(next_id);
700 }
701 cdmSelectArticles("none");
702 toggleUnread(next_id, 0, true);
703 toggleSelected(next_id);
704
705 } else {
706 correctHeadlinesOffset(next_id);
707 view(next_id, getActiveFeedId());
708 }
709 }
710 }
711
712 if (mode == "prev") {
713 if (prev_id) {
714 if (isCdmMode()) {
715 cdmScrollToArticleId(prev_id);
716 cdmSelectArticles("none");
717 toggleUnread(prev_id, 0, true);
718 toggleSelected(prev_id);
719 } else {
720 correctHeadlinesOffset(prev_id);
721 view(prev_id, getActiveFeedId());
722 }
723 }
724 }
725
726 } catch (e) {
727 exception_error("moveToPost", e);
728 }
729 }
730
731 function toggleSelected(id) {
732 try {
733
734 var cb = document.getElementById("RCHK-" + id);
735
736 var row = document.getElementById("RROW-" + id);
737 if (row) {
738 var nc = row.className;
739
740 if (!nc.match("Selected")) {
741 nc = nc + "Selected";
742 if (cb) {
743 cb.checked = true;
744 }
745
746 // In CDM basically last selected article == active article
747 if (isCdmMode()) active_post_id = id;
748 } else {
749 nc = nc.replace("Selected", "");
750 if (cb) {
751 cb.checked = false;
752 }
753
754 }
755
756 row.className = nc;
757 }
758 } catch (e) {
759 exception_error("toggleSelected", e);
760 }
761 }
762
763 function toggleUnread_afh(effect) {
764 try {
765
766 var elem = effect.element;
767 elem.style.backgroundColor = "";
768
769 } catch (e) {
770 exception_error("toggleUnread_afh", e);
771 }
772 }
773
774 function toggleUnread(id, cmode, effect) {
775 try {
776
777 var row = document.getElementById("RROW-" + id);
778 if (row) {
779 var nc = row.className;
780 var is_selected = row.className.match("Selected");
781 nc = nc.replace("Unread", "");
782 nc = nc.replace("Selected", "");
783
784 // since we are removing selection from the object, uncheck
785 // corresponding checkbox
786
787 var cb = document.getElementById("RCHK-" + id);
788 if (cb) {
789 cb.checked = false;
790 }
791
792 // NOTE: I'm not sure that resetting selection here is a feature -fox
793
794 if (cmode == undefined || cmode == 2) {
795 if (row.className.match("Unread")) {
796 row.className = nc;
797
798 if (effect) {
799 new Effect.Highlight(row, {duration: 1, startcolor: "#fff7d5",
800 afterFinish: toggleUnread_afh,
801 queue: { position:'end', scope: 'TMRQ-' + id, limit: 1 } } );
802 }
803
804 } else {
805 row.className = nc + "Unread";
806 }
807 } else if (cmode == 0) {
808 row.className = nc;
809
810 if (effect) {
811 new Effect.Highlight(row, {duration: 1, startcolor: "#fff7d5",
812 afterFinish: toggleUnread_afh,
813 queue: { position:'end', scope: 'TMRQ-' + id, limit: 1 } } );
814 }
815 } else if (cmode == 1) {
816 row.className = nc + "Unread";
817 }
818
819 // Disable unmarking as selected for the time being (16.05.08) -fox
820 if (is_selected) row.className = row.className + "Selected";
821
822 if (cmode == undefined) cmode = 2;
823
824 var query = "backend.php?op=rpc&subop=catchupSelected&ids=" +
825 param_escape(id) + "&cmode=" + param_escape(cmode);
826
827 // notify_progress("Loading, please wait...");
828
829 new Ajax.Request(query, {
830 onComplete: function(transport) {
831 all_counters_callback2(transport);
832 } });
833
834 }
835
836
837 } catch (e) {
838 exception_error("toggleUnread", e);
839 }
840 }
841
842 function selectionToggleUnread(cdm_mode, set_state, callback_func, no_error) {
843 try {
844 var rows;
845
846 if (cdm_mode) {
847 rows = cdmGetSelectedArticles();
848 } else {
849 rows = getSelectedTableRowIds("headlinesList", "RROW", "RCHK");
850 }
851
852 if (rows.length == 0 && !no_error) {
853 alert(__("No articles are selected."));
854 return;
855 }
856
857 for (i = 0; i < rows.length; i++) {
858 var row = document.getElementById("RROW-" + rows[i]);
859 if (row) {
860 var nc = row.className;
861 nc = nc.replace("Unread", "");
862 nc = nc.replace("Selected", "");
863
864 if (set_state == undefined) {
865 if (row.className.match("Unread")) {
866 row.className = nc + "Selected";
867 } else {
868 row.className = nc + "UnreadSelected";
869 }
870 }
871
872 if (set_state == false) {
873 row.className = nc + "Selected";
874 }
875
876 if (set_state == true) {
877 row.className = nc + "UnreadSelected";
878 }
879 }
880 }
881
882 if (rows.length > 0) {
883
884 var cmode = "";
885
886 if (set_state == undefined) {
887 cmode = "2";
888 } else if (set_state == true) {
889 cmode = "1";
890 } else if (set_state == false) {
891 cmode = "0";
892 }
893
894 var query = "backend.php?op=rpc&subop=catchupSelected&ids=" +
895 param_escape(rows.toString()) + "&cmode=" + cmode;
896
897 notify_progress("Loading, please wait...");
898
899 new Ajax.Request(query, {
900 onComplete: function(transport) {
901 catchup_callback2(transport, callback_func);
902 } });
903
904 }
905
906 } catch (e) {
907 exception_error("selectionToggleUnread", e);
908 }
909 }
910
911 function selectionToggleMarked(cdm_mode) {
912 try {
913
914 var rows;
915
916 if (cdm_mode) {
917 rows = cdmGetSelectedArticles();
918 } else {
919 rows = getSelectedTableRowIds("headlinesList", "RROW", "RCHK");
920 }
921
922 if (rows.length == 0) {
923 alert(__("No articles are selected."));
924 return;
925 }
926
927 for (i = 0; i < rows.length; i++) {
928 toggleMark(rows[i], true, true);
929 }
930
931 if (rows.length > 0) {
932
933 var query = "backend.php?op=rpc&subop=markSelected&ids=" +
934 param_escape(rows.toString()) + "&cmode=2";
935
936 query = query + "&afid=" + getActiveFeedId();
937
938 /* if (tagsAreDisplayed()) {
939 query = query + "&omode=tl";
940 } else {
941 query = query + "&omode=flc";
942 } */
943
944 query = query + "&omode=lc";
945
946 new Ajax.Request(query, {
947 onComplete: function(transport) {
948 all_counters_callback2(transport);
949 } });
950
951 }
952
953 } catch (e) {
954 exception_error("selectionToggleMarked", e);
955 }
956 }
957
958 function selectionTogglePublished(cdm_mode) {
959 try {
960
961 var rows;
962
963 if (cdm_mode) {
964 rows = cdmGetSelectedArticles();
965 } else {
966 rows = getSelectedTableRowIds("headlinesList", "RROW", "RCHK");
967 }
968
969 if (rows.length == 0) {
970 alert(__("No articles are selected."));
971 return;
972 }
973
974 for (i = 0; i < rows.length; i++) {
975 togglePub(rows[i], true, true);
976 }
977
978 if (rows.length > 0) {
979
980 var query = "backend.php?op=rpc&subop=publishSelected&ids=" +
981 param_escape(rows.toString()) + "&cmode=2";
982
983 query = query + "&afid=" + getActiveFeedId();
984
985 /* if (tagsAreDisplayed()) {
986 query = query + "&omode=tl";
987 } else {
988 query = query + "&omode=flc";
989 } */
990
991 query = query + "&omode=lc";
992
993 new Ajax.Request(query, {
994 onComplete: function(transport) {
995 all_counters_callback2(transport);
996 } });
997
998 }
999
1000 } catch (e) {
1001 exception_error("selectionToggleMarked", e);
1002 }
1003 }
1004
1005 function cdmGetSelectedArticles() {
1006 var sel_articles = new Array();
1007 var container = document.getElementById("headlinesInnerContainer");
1008
1009 for (i = 0; i < container.childNodes.length; i++) {
1010 var child = container.childNodes[i];
1011
1012 if (child.id && child.id.match("RROW-") && child.className.match("Selected")) {
1013 var c_id = child.id.replace("RROW-", "");
1014 sel_articles.push(c_id);
1015 }
1016 }
1017
1018 return sel_articles;
1019 }
1020
1021 function cdmGetVisibleArticles() {
1022 var sel_articles = new Array();
1023 var container = document.getElementById("headlinesInnerContainer");
1024
1025 if (!container) return sel_articles;
1026
1027 for (i = 0; i < container.childNodes.length; i++) {
1028 var child = container.childNodes[i];
1029
1030 if (child.id && child.id.match("RROW-")) {
1031 var c_id = child.id.replace("RROW-", "");
1032 sel_articles.push(c_id);
1033 }
1034 }
1035
1036 return sel_articles;
1037 }
1038
1039 function cdmGetUnreadArticles() {
1040 var sel_articles = new Array();
1041 var container = document.getElementById("headlinesInnerContainer");
1042
1043 for (i = 0; i < container.childNodes.length; i++) {
1044 var child = container.childNodes[i];
1045
1046 if (child.id && child.id.match("RROW-") && child.className.match("Unread")) {
1047 var c_id = child.id.replace("RROW-", "");
1048 sel_articles.push(c_id);
1049 }
1050 }
1051
1052 return sel_articles;
1053 }
1054
1055
1056 // mode = all,none,unread
1057 function cdmSelectArticles(mode) {
1058 var container = document.getElementById("headlinesInnerContainer");
1059
1060 for (i = 0; i < container.childNodes.length; i++) {
1061 var child = container.childNodes[i];
1062
1063 if (child.id && child.id.match("RROW-")) {
1064 var aid = child.id.replace("RROW-", "");
1065
1066 var cb = document.getElementById("RCHK-" + aid);
1067
1068 if (mode == "all") {
1069 if (!child.className.match("Selected")) {
1070 child.className = child.className + "Selected";
1071 cb.checked = true;
1072 }
1073 } else if (mode == "unread") {
1074 if (child.className.match("Unread") && !child.className.match("Selected")) {
1075 child.className = child.className + "Selected";
1076 cb.checked = true;
1077 }
1078 } else {
1079 child.className = child.className.replace("Selected", "");
1080 cb.checked = false;
1081 }
1082 }
1083 }
1084 }
1085
1086 function catchupPage() {
1087
1088 var fn = getFeedName(getActiveFeedId(), active_feed_is_cat);
1089
1090 var str = __("Mark all visible articles in %s as read?");
1091
1092 str = str.replace("%s", fn);
1093
1094 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
1095 return;
1096 }
1097
1098 if (document.getElementById("headlinesList")) {
1099 selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', true, 'Unread', true);
1100 selectionToggleUnread(false, false, 'viewCurrentFeed()', true);
1101 selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', false);
1102 } else {
1103 cdmSelectArticles('all');
1104 selectionToggleUnread(true, false, 'viewCurrentFeed()', true)
1105 cdmSelectArticles('none');
1106 }
1107 }
1108
1109 function catchupSelection() {
1110
1111 try {
1112
1113 var rows;
1114
1115 if (document.getElementById("headlinesList")) {
1116 rows = getSelectedTableRowIds("headlinesList", "RROW", "RCHK");
1117 } else {
1118 rows = cdmGetSelectedArticles();
1119 }
1120
1121 if (rows.length == 0) {
1122 alert(__("No articles are selected."));
1123 return;
1124 }
1125
1126
1127 var fn = getFeedName(getActiveFeedId(), active_feed_is_cat);
1128
1129 var str = __("Mark %d selected articles in %s as read?");
1130
1131 str = str.replace("%d", rows.length);
1132 str = str.replace("%s", fn);
1133
1134 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
1135 return;
1136 }
1137
1138 if (document.getElementById("headlinesList")) {
1139 selectionToggleUnread(false, false, 'viewCurrentFeed()', true);
1140 // selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', false);
1141 } else {
1142 selectionToggleUnread(true, false, 'viewCurrentFeed()', true)
1143 // cdmSelectArticles('none');
1144 }
1145
1146 } catch (e) {
1147 exception_error("catchupSelection", e);
1148 }
1149 }
1150
1151
1152 function labelFromSearch(search, search_mode, match_on, feed_id, is_cat) {
1153
1154 if (!xmlhttp_ready(xmlhttp_rpc)) {
1155 printLockingError();
1156 }
1157
1158 var title = prompt(__("Please enter label title:"), "");
1159
1160 if (title) {
1161
1162 var query = "backend.php?op=labelFromSearch&search=" + param_escape(search) +
1163 "&smode=" + param_escape(search_mode) + "&match=" + param_escape(match_on) +
1164 "&feed=" + param_escape(feed_id) + "&is_cat=" + param_escape(is_cat) +
1165 "&title=" + param_escape(title);
1166
1167 debug("LFS: " + query);
1168
1169 new Ajax.Request(query, {
1170 onComplete: function(transport) {
1171 dlg_frefresh_callback(transport);
1172 } });
1173 }
1174 }
1175
1176 function editArticleTags(id, feed_id, cdm_enabled) {
1177 _tag_active_post_id = id;
1178 _tag_active_feed_id = feed_id;
1179 _tag_active_cdm = cdm_enabled;
1180
1181 cache_invalidate(id);
1182
1183 try {
1184 _tag_cdm_scroll = document.getElementById("headlinesInnerContainer").scrollTop;
1185 } catch (e) { }
1186 displayDlg('editArticleTags', id);
1187 }
1188
1189
1190 function tag_saved_callback(transport) {
1191 try {
1192 debug("in tag_saved_callback");
1193
1194 closeInfoBox();
1195 notify("");
1196
1197 if (tagsAreDisplayed()) {
1198 _reload_feedlist_after_view = true;
1199 }
1200
1201 if (!_tag_active_cdm) {
1202 if (active_post_id == _tag_active_post_id) {
1203 debug("reloading current article");
1204 view(_tag_active_post_id, _tag_active_feed_id);
1205 }
1206 } else {
1207 debug("reloading current feed");
1208 viewCurrentFeed();
1209 }
1210
1211 } catch (e) {
1212 exception_error("catchup_callback", e);
1213 }
1214 }
1215
1216 function editTagsSave() {
1217
1218 notify_progress("Saving article tags...");
1219
1220 var form = document.forms["tag_edit_form"];
1221
1222 var query = Form.serialize("tag_edit_form");
1223
1224 query = "backend.php?op=rpc&subop=setArticleTags&" + query;
1225
1226 debug(query);
1227
1228 new Ajax.Request(query, {
1229 onComplete: function(transport) {
1230 tag_saved_callback(transport);
1231 } });
1232
1233 }
1234
1235 function editTagsInsert() {
1236 try {
1237
1238 var form = document.forms["tag_edit_form"];
1239
1240 var found_tags = form.found_tags;
1241 var tags_str = form.tags_str;
1242
1243 var tag = found_tags[found_tags.selectedIndex].value;
1244
1245 if (tags_str.value.length > 0 &&
1246 tags_str.value.lastIndexOf(", ") != tags_str.value.length - 2) {
1247
1248 tags_str.value = tags_str.value + ", ";
1249 }
1250
1251 tags_str.value = tags_str.value + tag + ", ";
1252
1253 found_tags.selectedIndex = 0;
1254
1255 } catch (e) {
1256 exception_error("editTagsInsert", e);
1257 }
1258 }
1259
1260 function cdmScrollViewport(where) {
1261 debug("cdmScrollViewport: " + where);
1262
1263 var ctr = document.getElementById("headlinesInnerContainer");
1264
1265 if (!ctr) return;
1266
1267 if (where == "bottom") {
1268 ctr.scrollTop = ctr.scrollHeight;
1269 } else {
1270 ctr.scrollTop = where;
1271 }
1272 }
1273
1274 function cdmArticleIsBelowViewport(id) {
1275 try {
1276 var ctr = document.getElementById("headlinesInnerContainer");
1277 var e = document.getElementById("RROW-" + id);
1278
1279 if (!e || !ctr) return;
1280
1281 // article starts below viewport
1282
1283 if (ctr.scrollTop < e.offsetTop) {
1284 return true;
1285 } else {
1286 return false;
1287 }
1288
1289 } catch (e) {
1290 exception_error("cdmArticleIsVisible", e);
1291 }
1292 }
1293
1294 function cdmArticleIsAboveViewport(id) {
1295 try {
1296 var ctr = document.getElementById("headlinesInnerContainer");
1297 var e = document.getElementById("RROW-" + id);
1298
1299 if (!e || !ctr) return;
1300
1301 // article starts above viewport
1302
1303 if (ctr.scrollTop > e.offsetTop + e.offsetHeight) {
1304 return true;
1305 } else {
1306 return false;
1307 }
1308
1309 } catch (e) {
1310 exception_error("cdmArticleIsVisible", e);
1311 }
1312 }
1313
1314 function cdmScrollToArticleId(id) {
1315 try {
1316 var ctr = document.getElementById("headlinesInnerContainer");
1317 var e = document.getElementById("RROW-" + id);
1318
1319 if (!e || !ctr) return;
1320
1321 ctr.scrollTop = e.offsetTop;
1322
1323 } catch (e) {
1324 exception_error("cdmScrollToArticleId", e);
1325 }
1326 }
1327
1328 function cdmArticleIsActuallyVisible(id) {
1329 try {
1330 var ctr = document.getElementById("headlinesInnerContainer");
1331 var e = document.getElementById("RROW-" + id);
1332
1333 if (!e || !ctr) return;
1334
1335 // article fits in viewport OR article is longer than viewport and
1336 // its bottom is visible
1337
1338 if (ctr.scrollTop <= e.offsetTop && e.offsetTop + e.offsetHeight <=
1339 ctr.scrollTop + ctr.offsetHeight) {
1340
1341 return true;
1342
1343 } else if (e.offsetHeight > ctr.offsetHeight &&
1344 e.offsetTop + e.offsetHeight >= ctr.scrollTop &&
1345 e.offsetTop + e.offsetHeight <= ctr.scrollTop + ctr.offsetHeight) {
1346
1347 return true;
1348
1349 }
1350
1351 return false;
1352
1353 } catch (e) {
1354 exception_error("cdmArticleIsVisible", e);
1355 }
1356 }
1357
1358 function cdmWatchdog() {
1359
1360 try {
1361
1362 var ctr = document.getElementById("headlinesInnerContainer");
1363
1364 if (!ctr) return;
1365
1366 var ids = new Array();
1367
1368 var e = ctr.firstChild;
1369
1370 while (e) {
1371 if (e.className && e.className == "cdmArticleUnread" && e.id &&
1372 e.id.match("RROW-")) {
1373
1374 // article fits in viewport OR article is longer than viewport and
1375 // its bottom is visible
1376
1377 if (ctr.scrollTop <= e.offsetTop && e.offsetTop + e.offsetHeight <=
1378 ctr.scrollTop + ctr.offsetHeight) {
1379
1380 // debug(e.id + " is visible " + e.offsetTop + "." +
1381 // (e.offsetTop + e.offsetHeight) + " vs " + ctr.scrollTop + "." +
1382 // (ctr.scrollTop + ctr.offsetHeight));
1383
1384 ids.push(e.id.replace("RROW-", ""));
1385
1386 } else if (e.offsetHeight > ctr.offsetHeight &&
1387 e.offsetTop + e.offsetHeight >= ctr.scrollTop &&
1388 e.offsetTop + e.offsetHeight <= ctr.scrollTop + ctr.offsetHeight) {
1389
1390 ids.push(e.id.replace("RROW-", ""));
1391
1392 }
1393
1394 // method 2: article bottom is visible and is in upper 1/2 of the viewport
1395
1396 /* if (e.offsetTop + e.offsetHeight >= ctr.scrollTop &&
1397 e.offsetTop + e.offsetHeight <= ctr.scrollTop + ctr.offsetHeight/2) {
1398
1399 ids.push(e.id.replace("RROW-", ""));
1400
1401 } */
1402
1403 }
1404
1405 e = e.nextSibling;
1406 }
1407
1408 debug("cdmWatchdog, ids= " + ids.toString());
1409
1410 if (ids.length > 0) {
1411
1412 for (var i = 0; i < ids.length; i++) {
1413 var e = document.getElementById("RROW-" + ids[i]);
1414 if (e) {
1415 e.className = e.className.replace("Unread", "");
1416 }
1417 }
1418
1419 var query = "backend.php?op=rpc&subop=catchupSelected&ids=" +
1420 param_escape(ids.toString()) + "&cmode=0";
1421
1422 new Ajax.Request(query, {
1423 onComplete: function(transport) {
1424 all_counters_callback2(transport);
1425 } });
1426
1427 }
1428
1429 _cdm_wd_timeout = window.setTimeout("cdmWatchdog()", 4000);
1430
1431 } catch (e) {
1432 exception_error("cdmWatchdog", e);
1433 }
1434
1435 }
1436
1437
1438 function cache_inject(id, article, param) {
1439 if (!cache_check_param(id, param)) {
1440 debug("cache_article: miss: " + id + " [p=" + param + "]");
1441
1442 var cache_obj = new Array();
1443
1444 cache_obj["id"] = id;
1445 cache_obj["data"] = article;
1446 cache_obj["param"] = param;
1447
1448 article_cache.push(cache_obj);
1449
1450 } else {
1451 debug("cache_article: hit: " + id + " [p=" + param + "]");
1452 }
1453 }
1454
1455 function cache_find(id) {
1456 for (var i = 0; i < article_cache.length; i++) {
1457 if (article_cache[i]["id"] == id) {
1458 return article_cache[i]["data"];
1459 }
1460 }
1461 return false;
1462 }
1463
1464 function cache_find_param(id, param) {
1465 for (var i = 0; i < article_cache.length; i++) {
1466 if (article_cache[i]["id"] == id && article_cache[i]["param"] == param) {
1467 return article_cache[i]["data"];
1468 }
1469 }
1470 return false;
1471 }
1472
1473 function cache_check(id) {
1474 for (var i = 0; i < article_cache.length; i++) {
1475 if (article_cache[i]["id"] == id) {
1476 return true;
1477 }
1478 }
1479 return false;
1480 }
1481
1482 function cache_check_param(id, param) {
1483 for (var i = 0; i < article_cache.length; i++) {
1484
1485 // debug("cache_check_param " + article_cache[i]["id"] + ":" +
1486 // article_cache[i]["param"] + " vs " + id + ":" + param);
1487
1488 if (article_cache[i]["id"] == id && article_cache[i]["param"] == param) {
1489 return true;
1490 }
1491 }
1492 return false;
1493 }
1494
1495 function cache_expire() {
1496 while (article_cache.length > 25) {
1497 article_cache.shift();
1498 }
1499 }
1500
1501 function cache_empty() {
1502 article_cache = new Array();
1503 }
1504
1505 function cache_invalidate(id) {
1506 var i = 0
1507
1508 try {
1509
1510 while (i < article_cache.length) {
1511 if (article_cache[i]["id"] == id) {
1512 debug("cache_invalidate: removed id " + id);
1513 article_cache.splice(i, 1);
1514 return true;
1515 }
1516 i++;
1517 }
1518 debug("cache_invalidate: id not found: " + id);
1519 return false;
1520 } catch (e) {
1521 exception_error("cache_invalidate", e);
1522 }
1523 }
1524
1525 function getActiveArticleId() {
1526 return active_post_id;
1527 }
1528
1529 function cdmClicked(id) {
1530 try {
1531 var elem = document.getElementById("RROW-" + id);
1532
1533 if (elem) {
1534 var id = elem.id.replace("RROW-", "");
1535 active_post_id = id;
1536
1537 cdmSelectArticles("none");
1538 toggleUnread(id, 0, true);
1539 toggleSelected(id);
1540
1541 }
1542 } catch (e) {
1543 exception_error("cdmClicked", e);
1544 }
1545 }
1546
1547 function preload_article_callback(transport) {
1548 try {
1549 if (transport.responseXML) {
1550 var articles = transport.responseXML.getElementsByTagName("article");
1551
1552 for (var i = 0; i < articles.length; i++) {
1553 var id = articles[i].getAttribute("id");
1554 if (!cache_check(id)) {
1555 cache_inject(id, articles[i].firstChild.nodeValue);
1556 debug("preloaded article: " + id);
1557 }
1558 }
1559 }
1560 } catch (e) {
1561 exception_error("preload_article_callback", e);
1562 }
1563 }
1564
1565 function preloadArticleUnderPointer(id) {
1566 try {
1567 if (getInitParam("bw_limit") == "1") return;
1568
1569 if (post_under_pointer == id && !cache_check(id)) {
1570
1571 debug("trying to preload article " + id);
1572
1573 var neighbor_ids = getRelativePostIds(id, 1);
1574
1575 /* only request uncached articles */
1576
1577 var cids_to_request = Array();
1578
1579 for (var i = 0; i < neighbor_ids.length; i++) {
1580 if (!cache_check(neighbor_ids[i])) {
1581 cids_to_request.push(neighbor_ids[i]);
1582 }
1583 }
1584 debug("additional ids: " + cids_to_request.toString());
1585
1586 cids_to_request.push(id);
1587
1588 var query = "backend.php?op=rpc&subop=getArticles&ids=" +
1589 cids_to_request.toString();
1590 new Ajax.Request(query, {
1591 onComplete: function(transport) {
1592 preload_article_callback(transport);
1593 } });
1594 }
1595 } catch (e) {
1596 exception_error("preloadArticleUnderPointer", e);
1597 }
1598 }
1599
1600 function postMouseIn(id) {
1601 try {
1602 if (post_under_pointer != id) {
1603 post_under_pointer = id;
1604 if (!isCdmMode()) {
1605 window.setTimeout("preloadArticleUnderPointer(" + id + ")", 250);
1606 }
1607 }
1608
1609 } catch (e) {
1610 exception_error("postMouseIn", e);
1611 }
1612 }
1613
1614 function postMouseOut(id) {
1615 try {
1616 post_under_pointer = false;
1617 } catch (e) {
1618 exception_error("postMouseOut", e);
1619 }
1620 }
1621
1622 function headlines_scroll_handler() {
1623 try {
1624
1625 var e = document.getElementById("headlinesInnerContainer");
1626
1627 // don't do infinite scrolling when Limit == All
1628
1629 var toolbar_form = document.forms["main_toolbar_form"];
1630
1631 var limit = toolbar_form.limit[toolbar_form.limit.selectedIndex];
1632 if (limit.value != 0) {
1633
1634 debug((e.scrollTop + e.offsetHeight) + " vs " + e.scrollHeight + " dis? " +
1635 _infscroll_disable);
1636
1637 if (e.scrollTop + e.offsetHeight > e.scrollHeight - 100) {
1638 if (!_infscroll_disable) {
1639 debug("more cowbell!");
1640 viewNextFeedPage();
1641 }
1642 }
1643 }
1644
1645 } catch (e) {
1646 exception_error("headlines_scroll_handler", e);
1647 }
1648 }
1649
1650 function catchupRelativeToArticle(below) {
1651
1652 try {
1653
1654 if (!xmlhttp_ready(xmlhttp_rpc)) {
1655 printLockingError();
1656 }
1657
1658 if (!getActiveArticleId()) {
1659 alert(__("No article is selected."));
1660 return;
1661 }
1662
1663 var visible_ids;
1664
1665 if (document.getElementById("headlinesList")) {
1666 visible_ids = getVisibleHeadlineIds();
1667 } else {
1668 visible_ids = cdmGetVisibleArticles();
1669 }
1670
1671 var ids_to_mark = new Array();
1672
1673 if (!below) {
1674 for (var i = 0; i < visible_ids.length; i++) {
1675 if (visible_ids[i] != getActiveArticleId()) {
1676 var e = document.getElementById("RROW-" + visible_ids[i]);
1677
1678 if (e && e.className.match("Unread")) {
1679 ids_to_mark.push(visible_ids[i]);
1680 }
1681 } else {
1682 break;
1683 }
1684 }
1685 } else {
1686 for (var i = visible_ids.length-1; i >= 0; i--) {
1687 if (visible_ids[i] != getActiveArticleId()) {
1688 var e = document.getElementById("RROW-" + visible_ids[i]);
1689
1690 if (e && e.className.match("Unread")) {
1691 ids_to_mark.push(visible_ids[i]);
1692 }
1693 } else {
1694 break;
1695 }
1696 }
1697 }
1698
1699 if (ids_to_mark.length == 0) {
1700 alert(__("No articles found to mark"));
1701 } else {
1702 var msg = __("Mark %d article(s) as read?").replace("%d", ids_to_mark.length);
1703
1704 if (confirm(msg)) {
1705
1706 for (var i = 0; i < ids_to_mark.length; i++) {
1707 var e = document.getElementById("RROW-" + ids_to_mark[i]);
1708 e.className = e.className.replace("Unread", "");
1709 }
1710
1711 var query = "backend.php?op=rpc&subop=catchupSelected&ids=" +
1712 param_escape(ids_to_mark.toString()) + "&cmode=0";
1713
1714 new Ajax.Request(query, {
1715 onComplete: function(transport) {
1716 catchup_callback2(transport);
1717 } });
1718
1719 }
1720 }
1721
1722 } catch (e) {
1723 exception_error("catchupRelativeToArticle", e);
1724 }
1725 }
1726
1727 function cdmExpandArticle(a_id) {
1728 try {
1729 var id = 'CICD-' + a_id;
1730
1731 try {
1732 Element.hide("CEXC-" + a_id);
1733 } catch (e) { }
1734
1735 Effect.Appear(id, {duration : 0.5,
1736 beforeStart: function(effect) {
1737 var h_id = 'CICH-' + a_id;
1738 var h_elem = document.getElementById(h_id);
1739 if (h_elem) { h_elem.style.display = "none"; }
1740
1741 toggleUnread(a_id, 0);
1742 }});
1743
1744
1745 } catch (e) {
1746 exception_error("appearBlockElementF", e);
1747 }
1748
1749 }
1750
1751 function fixHeadlinesOrder(ids) {
1752 try {
1753 for (var i = 0; i < ids.length; i++) {
1754 var e = document.getElementById("RROW-" + ids[i]);
1755
1756 if (e) {
1757 if (i % 2 == 0) {
1758 e.className = e.className.replace("even", "odd");
1759 } else {
1760 e.className = e.className.replace("odd", "even");
1761 }
1762 }
1763 }
1764 } catch (e) {
1765 exception_error("fixHeadlinesOrder", e);
1766 }
1767 }
1768
1769 function subtoolbarSearch() {
1770 try {
1771
1772 var q = document.getElementById("subtoolbar_search_box");
1773
1774 if (!q) return;
1775
1776 q = q.value.toUpperCase();
1777
1778 var ids = false;
1779 var vis_ids = new Array();
1780
1781 if (document.getElementById("headlinesList")) {
1782 ids = getVisibleHeadlineIds();
1783 } else {
1784 ids = cdmGetVisibleArticles();
1785 }
1786
1787 for (var i = 0; i < ids.length; i++) {
1788 var title = document.getElementById("RTITLE-" + ids[i]);
1789
1790 if (title) {
1791 if (!title.innerHTML.toUpperCase().match(q)) {
1792 Element.hide(document.getElementById("RROW-" + ids[i]));
1793 } else {
1794 Element.show(document.getElementById("RROW-" + ids[i]));
1795 vis_ids.push(ids[i]);
1796 }
1797 }
1798 }
1799
1800 fixHeadlinesOrder(vis_ids);
1801
1802 } catch (e) {
1803 exception_error("subtoolbarSearch", e);
1804 }
1805 }
1806
1807 function hideReadHeadlines() {
1808 try {
1809
1810 var ids = false;
1811 var vis_ids = new Array();
1812
1813 if (document.getElementById("headlinesList")) {
1814 ids = getVisibleHeadlineIds();
1815 } else {
1816 ids = cdmGetVisibleArticles();
1817 }
1818
1819 var read_headlines_visible = true;
1820
1821 for (var i = 0; i < ids.length; i++) {
1822 var row = document.getElementById("RROW-" + ids[i]);
1823
1824 if (row && row.className) {
1825 if (read_headlines_visible) {
1826 if (row.className.match("Unread") || row.className.match("Selected")) {
1827 Element.show(row);
1828 vis_ids.push(ids[i]);
1829 } else {
1830 //Effect.Fade(row, {duration : 0.3});
1831 Element.hide(row);
1832 }
1833 } else {
1834 Element.show(row);
1835 vis_ids.push(ids[i]);
1836 }
1837 }
1838 }
1839
1840 fixHeadlinesOrder(vis_ids);
1841
1842 read_headlines_visible = !read_headlines_visible;
1843
1844 } catch (e) {
1845 exception_error("hideReadHeadlines", e);
1846 }
1847 }
1848
1849 function getArticleUnderPointer() {
1850 return post_under_pointer;
1851 }