]> git.wh0rd.org - tt-rss.git/blame_incremental - viewfeed.js
add option to auto-expand CDM list (bump schema)
[tt-rss.git] / viewfeed.js
... / ...
CommitLineData
1var active_post_id = false;
2var last_article_view = false;
3var active_real_feed_id = false;
4
5var _tag_active_post_id = false;
6var _tag_active_feed_id = false;
7var _tag_active_cdm = false;
8
9// FIXME: kludge, to restore scrollTop after tag editor terminates
10var _tag_cdm_scroll = false;
11
12// FIXME: kludges, needs proper implementation
13var _reload_feedlist_after_view = false;
14
15var _cdm_wd_timeout = false;
16var _cdm_wd_vishist = new Array();
17
18var article_cache = new Array();
19
20function catchup_callback() {
21 if (xmlhttp_rpc.readyState == 4) {
22 try {
23 debug("catchup_callback");
24 notify("");
25 all_counters_callback2(xmlhttp_rpc);
26 if (_catchup_callback_func) {
27 setTimeout(_catchup_callback_func, 10);
28 }
29 } catch (e) {
30 exception_error("catchup_callback", e);
31 }
32 }
33}
34
35function catchup_callback2(transport, callback) {
36 try {
37 debug("catchup_callback2 " + transport + ", " + callback);
38 notify("");
39 all_counters_callback2(transport);
40 if (callback) {
41 setTimeout(callback, 10);
42 }
43 } catch (e) {
44 exception_error("catchup_callback2", e);
45 }
46}
47
48function headlines_callback2(transport, active_feed_id, is_cat, feed_cur_page) {
49 try {
50
51 debug("headlines_callback2 [page=" + feed_cur_page + "]");
52
53 var feeds = document.getElementById("feedList").getElementsByTagName("LI");
54
55 for (var i = 0; i < feeds.length; i++) {
56 if (feeds[i].id && feeds[i].id.match("FEEDR-")) {
57 feeds[i].className = feeds[i].className.replace("Selected", "");
58 }
59 }
60
61 setActiveFeedId(active_feed_id);
62
63 if (is_cat != undefined) {
64 active_feed_is_cat = is_cat;
65 }
66
67 if (!is_cat) {
68 var feedr = document.getElementById("FEEDR-" + active_feed_id);
69 if (feedr && !feedr.className.match("Selected")) {
70 feedr.className = feedr.className + "Selected";
71 }
72 }
73
74 var f = document.getElementById("headlines-frame");
75 try {
76 if (feed_cur_page == 0) {
77 debug("resetting headlines scrollTop");
78 f.scrollTop = 0;
79 }
80 } catch (e) { };
81
82 if (transport.responseXML) {
83 var headlines = transport.responseXML.getElementsByTagName("headlines")[0];
84 var headlines_count_obj = transport.responseXML.getElementsByTagName("headlines-count")[0];
85
86 var headlines_count = headlines_count_obj.getAttribute("value");
87
88 if (headlines_count == 0) _infscroll_disable = 1;
89
90 var counters = transport.responseXML.getElementsByTagName("counters")[0];
91 var articles = transport.responseXML.getElementsByTagName("article");
92 var runtime_info = transport.responseXML.getElementsByTagName("runtime-info");
93
94 if (feed_cur_page == 0) {
95 if (headlines) {
96 f.innerHTML = headlines.firstChild.nodeValue;
97 } else {
98 debug("headlines_callback: returned no data");
99 f.innerHTML = "<div class='whiteBox'>" + __('Could not update headlines (missing XML data)') + "</div>";
100
101 }
102 } else {
103 if (headlines) {
104 if (headlines_count > 0) {
105 debug("adding some more headlines...");
106
107 var c = document.getElementById("headlinesList");
108
109 if (!c) {
110 c = document.getElementById("headlinesInnerContainer");
111 }
112
113 var ids = getSelectedArticleIds2();
114
115 c.innerHTML = c.innerHTML + headlines.firstChild.nodeValue;
116
117 debug("restore selected ids: " + ids);
118
119 for (var i = 0; i < ids.length; i++) {
120 markHeadline(ids[i]);
121 }
122
123 } else {
124 debug("no new headlines received");
125 }
126 } else {
127 debug("headlines_callback: returned no data");
128 notify_error("Error while trying to load more headlines");
129 }
130
131 }
132
133 if (articles) {
134 for (var i = 0; i < articles.length; i++) {
135 var a_id = articles[i].getAttribute("id");
136 debug("found id: " + a_id);
137 cache_inject(a_id, articles[i].firstChild.nodeValue);
138 }
139 } else {
140 debug("no cached articles received");
141 }
142
143 if (counters) {
144 debug("parsing piggybacked counters: " + counters);
145 parse_counters(counters, false);
146 } else {
147 debug("counters container not found in reply");
148 }
149
150 if (runtime_info) {
151 debug("parsing runtime info: " + runtime_info[0]);
152 parse_runtime_info(runtime_info[0]);
153 } else {
154 debug("counters container not found in reply");
155 }
156
157 } else {
158 debug("headlines_callback: returned no XML object");
159 f.innerHTML = "<div class='whiteBox'>" + __('Could not update headlines (missing XML object)') + "</div>";
160 }
161
162 if (typeof correctPNG != 'undefined') {
163 correctPNG();
164 }
165
166 if (_cdm_wd_timeout) window.clearTimeout(_cdm_wd_timeout);
167
168 if (!document.getElementById("headlinesList") &&
169 getInitParam("cdm_auto_catchup") == 1) {
170 debug("starting CDM watchdog");
171 _cdm_wd_timeout = window.setTimeout("cdmWatchdog()", 5000);
172 _cdm_wd_vishist = new Array();
173 } else {
174 debug("not in CDM mode or watchdog disabled");
175 }
176
177 if (_tag_cdm_scroll) {
178 try {
179 document.getElementById("headlinesInnerContainer").scrollTop = _tag_cdm_scroll;
180 _tag_cdm_scroll = false;
181 debug("resetting headlinesInner scrollTop");
182
183 } catch (e) { }
184 }
185
186 _feed_cur_page = feed_cur_page;
187 _infscroll_request_sent = 0;
188
189 notify("");
190 } catch (e) {
191 exception_error("headlines_callback2", e);
192 }
193}
194
195function render_article(article) {
196 try {
197 var f = document.getElementById("content-frame");
198 try {
199 f.scrollTop = 0;
200 } catch (e) { };
201
202 f.innerHTML = article;
203
204 } catch (e) {
205 exception_error("render_article", e);
206 }
207}
208
209function showArticleInHeadlines(id) {
210
211 try {
212
213 cleanSelected("headlinesList");
214
215 var crow = document.getElementById("RROW-" + id);
216
217 if (!crow) return;
218
219 var article_is_unread = crow.className.match("Unread");
220
221 crow.className = crow.className.replace("Unread", "");
222
223 var upd_img_pic = document.getElementById("FUPDPIC-" + id);
224
225 if (upd_img_pic) {
226 upd_img_pic.src = "images/blank_icon.gif";
227 }
228
229 selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', false);
230 markHeadline(id);
231
232 } catch (e) {
233 exception_error("showArticleInHeadlines", e);
234 }
235}
236
237function article_callback2(transport, id, feed_id) {
238 try {
239 debug("article_callback2 " + id);
240
241 if (transport.responseXML) {
242
243 active_real_feed_id = feed_id;
244 active_post_id = id;
245
246 showArticleInHeadlines(id);
247
248 var reply = transport.responseXML.firstChild.firstChild;
249
250 var articles = transport.responseXML.getElementsByTagName("article");
251
252 for (var i = 0; i < articles.length; i++) {
253 var a_id = articles[i].getAttribute("id");
254
255 debug("found id: " + a_id);
256
257 if (a_id == active_post_id) {
258 debug("active article, rendering...");
259 render_article(articles[i].firstChild.nodeValue);
260 }
261
262 cache_inject(a_id, articles[i].firstChild.nodeValue);
263 }
264
265 } else {
266 debug("article_callback: returned no XML object");
267 var f = document.getElementById("content-frame");
268 f.innerHTML = "<div class='whiteBox'>" + __('Could not display article (missing XML object)') + "</div>";
269 }
270
271 var date = new Date();
272 last_article_view = date.getTime() / 1000;
273
274 if (typeof correctPNG != 'undefined') {
275 correctPNG();
276 }
277
278 if (_reload_feedlist_after_view) {
279 setTimeout('updateFeedList(false, false)', 50);
280 _reload_feedlist_after_view = false;
281 } else {
282 var counters = transport.responseXML.getElementsByTagName("counters")[0];
283
284 if (counters) {
285 debug("parsing piggybacked counters: " + counters);
286 parse_counters(counters, false);
287 } else {
288 debug("counters container not found in reply");
289 }
290 }
291
292 notify("");
293 } catch (e) {
294 exception_error("article_callback2", e);
295 }
296}
297
298function view(id, feed_id, skip_history) {
299
300 try {
301 debug("loading article: " + id + "/" + feed_id);
302
303 var cached_article = cache_find(id);
304
305 debug("cache check result: " + (cached_article != false));
306
307 enableHotkeys();
308
309 //setActiveFeedId(feed_id);
310
311 var query = "backend.php?op=view&id=" + param_escape(id) +
312 "&feed=" + param_escape(feed_id);
313
314 var date = new Date();
315
316 var neighbor_ids = getRelativePostIds(active_post_id);
317
318 /* only request uncached articles */
319
320 var cids_to_request = Array();
321
322 for (var i = 0; i < neighbor_ids.length; i++) {
323 if (!cache_check(neighbor_ids[i])) {
324 cids_to_request.push(neighbor_ids[i]);
325 }
326 }
327
328 debug("additional ids: " + cids_to_request.toString());
329
330 /* additional info for piggyback counters */
331
332 if (tagsAreDisplayed()) {
333 query = query + "&omode=lt";
334 } else {
335 query = query + "&omode=flc";
336 }
337
338 var date = new Date();
339 var timestamp = Math.round(date.getTime() / 1000);
340 query = query + "&ts=" + timestamp;
341
342 query = query + "&cids=" + cids_to_request.toString();
343
344 var crow = document.getElementById("RROW-" + id);
345 var article_is_unread = crow.className.match("Unread");
346
347 showArticleInHeadlines(id);
348
349 if (!cached_article) {
350
351 notify_progress("Loading, please wait...");
352
353 } else if (cached_article && article_is_unread) {
354
355 query = query + "&mode=prefetch";
356
357 render_article(cached_article);
358
359 } else if (cached_article) {
360
361 query = query + "&mode=prefetch_old";
362 render_article(cached_article);
363 }
364
365 cache_expire();
366
367 new Ajax.Request(query, {
368 onComplete: function(transport) {
369 article_callback2(transport, id, feed_id);
370 } });
371
372 } catch (e) {
373 exception_error("view", e);
374 }
375}
376
377function tMark(id) {
378 return toggleMark(id);
379}
380
381function tPub(id) {
382 return togglePub(id);
383}
384
385function tMark_afh_off(effect) {
386 try {
387 var elem = effect.effects[0].element;
388
389 debug("tMark_afh_off : " + elem.id);
390
391 if (elem) {
392 elem.src = elem.src.replace("mark_set", "mark_unset");
393 elem.alt = __("Star article");
394 Element.show(elem);
395 }
396
397 } catch (e) {
398 exception_error("tMark_afh_off", e);
399 }
400}
401
402function tPub_afh_off(effect) {
403 try {
404 var elem = effect.effects[0].element;
405
406 debug("tPub_afh_off : " + elem.id);
407
408 if (elem) {
409 elem.src = elem.src.replace("pub_set", "pub_unset");
410 elem.alt = __("Publish article");
411 Element.show(elem);
412 }
413
414 } catch (e) {
415 exception_error("tPub_afh_off", e);
416 }
417}
418
419function toggleMark(id, client_only, no_effects) {
420
421 try {
422
423 var query = "backend.php?op=rpc&id=" + id + "&subop=mark";
424
425 query = query + "&afid=" + getActiveFeedId();
426
427 if (tagsAreDisplayed()) {
428 query = query + "&omode=tl";
429 } else {
430 query = query + "&omode=flc";
431 }
432
433 var mark_img = document.getElementById("FMPIC-" + id);
434 var vfeedu = document.getElementById("FEEDU--1");
435 var crow = document.getElementById("RROW-" + id);
436
437 if (mark_img.src.match("mark_unset")) {
438 mark_img.src = mark_img.src.replace("mark_unset", "mark_set");
439 mark_img.alt = __("Unstar article");
440 query = query + "&mark=1";
441
442/* if (vfeedu && crow.className.match("Unread")) {
443 vfeedu.innerHTML = (+vfeedu.innerHTML) + 1;
444 } */
445
446 } else {
447 //mark_img.src = "images/mark_unset.png";
448 mark_img.alt = __("Please wait...");
449 query = query + "&mark=0";
450
451/* if (vfeedu && crow.className.match("Unread")) {
452 vfeedu.innerHTML = (+vfeedu.innerHTML) - 1;
453 } */
454
455 if (document.getElementById("headlinesList") && !no_effects) {
456 Effect.Puff(mark_img, {duration : 0.25, afterFinish: tMark_afh_off});
457 } else {
458 mark_img.src = mark_img.src.replace("mark_set", "mark_unset");
459 mark_img.alt = __("Star article");
460 }
461 }
462
463/* var vfeedctr = document.getElementById("FEEDCTR--1");
464 var vfeedr = document.getElementById("FEEDR--1");
465
466 if (vfeedu && vfeedctr) {
467 if ((+vfeedu.innerHTML) > 0) {
468 if (crow.className.match("Unread") && !vfeedr.className.match("Unread")) {
469 vfeedr.className = vfeedr.className + "Unread";
470 vfeedctr.className = "odd";
471 }
472 } else {
473 vfeedctr.className = "invisible";
474 vfeedr.className = vfeedr.className.replace("Unread", "");
475 }
476 }
477
478 debug("toggle starred for aid " + id);
479
480 //new Ajax.Request(query); */
481
482 if (!client_only) {
483 debug(query);
484
485 new Ajax.Request(query, {
486 onComplete: function(transport) {
487 all_counters_callback2(transport);
488 } });
489
490 }
491
492 } catch (e) {
493 exception_error("toggleMark", e);
494 }
495}
496
497function togglePub(id, client_only, no_effects) {
498
499 try {
500
501 var query = "backend.php?op=rpc&id=" + id + "&subop=publ";
502
503 query = query + "&afid=" + getActiveFeedId();
504
505 if (tagsAreDisplayed()) {
506 query = query + "&omode=tl";
507 } else {
508 query = query + "&omode=flc";
509 }
510
511 var mark_img = document.getElementById("FPPIC-" + id);
512 var vfeedu = document.getElementById("FEEDU--2");
513 var crow = document.getElementById("RROW-" + id);
514
515 if (mark_img.src.match("pub_unset")) {
516 mark_img.src = mark_img.src.replace("pub_unset", "pub_set");
517 mark_img.alt = __("Unpublish article");
518 query = query + "&pub=1";
519
520/* if (vfeedu && crow.className.match("Unread")) {
521 vfeedu.innerHTML = (+vfeedu.innerHTML) + 1;
522 } */
523
524 } else {
525 //mark_img.src = "images/pub_unset.png";
526 mark_img.alt = __("Please wait...");
527 query = query + "&pub=0";
528
529/* if (vfeedu && crow.className.match("Unread")) {
530 vfeedu.innerHTML = (+vfeedu.innerHTML) - 1;
531 } */
532
533 if (document.getElementById("headlinesList") && !no_effects) {
534 Effect.Puff(mark_img, {duration : 0.25, afterFinish: tPub_afh_off});
535 } else {
536 mark_img.src = mark_img.src.replace("pub_set", "pub_unset");
537 mark_img.alt = __("Publish article");
538 }
539 }
540
541/* var vfeedctr = document.getElementById("FEEDCTR--2");
542 var vfeedr = document.getElementById("FEEDR--2");
543
544 if (vfeedu && vfeedctr) {
545 if ((+vfeedu.innerHTML) > 0) {
546 if (crow.className.match("Unread") && !vfeedr.className.match("Unread")) {
547 vfeedr.className = vfeedr.className + "Unread";
548 vfeedctr.className = "odd";
549 }
550 } else {
551 vfeedctr.className = "invisible";
552 vfeedr.className = vfeedr.className.replace("Unread", "");
553 }
554 }
555
556 debug("toggle published for aid " + id);
557
558 new Ajax.Request(query); */
559
560 if (!client_only) {
561 new Ajax.Request(query, {
562 onComplete: function(transport) {
563 all_counters_callback2(transport);
564 } });
565 }
566
567 } catch (e) {
568
569 exception_error("togglePub", e);
570 }
571}
572
573function correctHeadlinesOffset(id) {
574
575 try {
576
577 var hlist = document.getElementById("headlinesList");
578 var container = document.getElementById("headlinesInnerContainer");
579 var row = document.getElementById("RROW-" + id);
580
581 var viewport = container.offsetHeight;
582
583 var rel_offset_top = row.offsetTop - container.scrollTop;
584 var rel_offset_bottom = row.offsetTop + row.offsetHeight - container.scrollTop;
585
586 debug("Rtop: " + rel_offset_top + " Rbtm: " + rel_offset_bottom);
587 debug("Vport: " + viewport);
588
589 if (rel_offset_top <= 0 || rel_offset_top > viewport) {
590 container.scrollTop = row.offsetTop;
591 } else if (rel_offset_bottom > viewport) {
592
593 /* doesn't properly work with Opera in some cases because
594 Opera fucks up element scrolling */
595
596 container.scrollTop = row.offsetTop + row.offsetHeight - viewport;
597 }
598
599 } catch (e) {
600 exception_error("correctHeadlinesOffset", e);
601 }
602
603}
604
605function moveToPost(mode) {
606
607 // check for combined mode
608 if (!document.getElementById("headlinesList"))
609 return;
610
611 var rows = getVisibleHeadlineIds();
612
613 var prev_id = false;
614 var next_id = false;
615
616 if (!document.getElementById('RROW-' + active_post_id)) {
617 active_post_id = false;
618 }
619
620 if (active_post_id == false) {
621 next_id = getFirstVisibleHeadlineId();
622 prev_id = getLastVisibleHeadlineId();
623 } else {
624 for (var i = 0; i < rows.length; i++) {
625 if (rows[i] == active_post_id) {
626 prev_id = rows[i-1];
627 next_id = rows[i+1];
628 }
629 }
630 }
631
632 if (mode == "next") {
633 if (next_id) {
634 correctHeadlinesOffset(next_id);
635 view(next_id, getActiveFeedId());
636 }
637 }
638
639 if (mode == "prev") {
640 if (prev_id) {
641 correctHeadlinesOffset(prev_id);
642 view(prev_id, getActiveFeedId());
643 }
644 }
645}
646
647function toggleUnread(id, cmode) {
648 try {
649
650 var row = document.getElementById("RROW-" + id);
651 if (row) {
652 var nc = row.className;
653 nc = nc.replace("Unread", "");
654 nc = nc.replace("Selected", "");
655
656 if (row.className.match("Unread")) {
657 row.className = nc;
658 } else {
659 row.className = nc + "Unread";
660 }
661
662 if (!cmode) cmode = 2;
663
664 var query = "backend.php?op=rpc&subop=catchupSelected&ids=" +
665 param_escape(id) + "&cmode=" + param_escape(cmode);
666
667// notify_progress("Loading, please wait...");
668
669 new Ajax.Request(query, {
670 onComplete: function(transport) {
671 all_counters_callback2(transport);
672 } });
673
674 }
675
676
677 } catch (e) {
678 exception_error("toggleUnread", e);
679 }
680}
681
682function selectionToggleUnread(cdm_mode, set_state, callback_func, no_error) {
683 try {
684 var rows;
685
686 if (cdm_mode) {
687 rows = cdmGetSelectedArticles();
688 } else {
689 rows = getSelectedTableRowIds("headlinesList", "RROW", "RCHK");
690 }
691
692 if (rows.length == 0 && !no_error) {
693 alert(__("No articles are selected."));
694 return;
695 }
696
697 for (i = 0; i < rows.length; i++) {
698 var row = document.getElementById("RROW-" + rows[i]);
699 if (row) {
700 var nc = row.className;
701 nc = nc.replace("Unread", "");
702 nc = nc.replace("Selected", "");
703
704 if (set_state == undefined) {
705 if (row.className.match("Unread")) {
706 row.className = nc + "Selected";
707 } else {
708 row.className = nc + "UnreadSelected";
709 }
710 }
711
712 if (set_state == false) {
713 row.className = nc + "Selected";
714 }
715
716 if (set_state == true) {
717 row.className = nc + "UnreadSelected";
718 }
719 }
720 }
721
722 if (rows.length > 0) {
723
724 var cmode = "";
725
726 if (set_state == undefined) {
727 cmode = "2";
728 } else if (set_state == true) {
729 cmode = "1";
730 } else if (set_state == false) {
731 cmode = "0";
732 }
733
734 var query = "backend.php?op=rpc&subop=catchupSelected&ids=" +
735 param_escape(rows.toString()) + "&cmode=" + cmode;
736
737 notify_progress("Loading, please wait...");
738
739 new Ajax.Request(query, {
740 onComplete: function(transport) {
741 catchup_callback2(transport, callback_func);
742 } });
743
744 }
745
746 } catch (e) {
747 exception_error("selectionToggleUnread", e);
748 }
749}
750
751function selectionToggleMarked(cdm_mode) {
752 try {
753
754 var rows;
755
756 if (cdm_mode) {
757 rows = cdmGetSelectedArticles();
758 } else {
759 rows = getSelectedTableRowIds("headlinesList", "RROW", "RCHK");
760 }
761
762 if (rows.length == 0) {
763 alert(__("No articles are selected."));
764 return;
765 }
766
767 for (i = 0; i < rows.length; i++) {
768 toggleMark(rows[i], true, true);
769 }
770
771 if (rows.length > 0) {
772
773 var query = "backend.php?op=rpc&subop=markSelected&ids=" +
774 param_escape(rows.toString()) + "&cmode=2";
775
776 query = query + "&afid=" + getActiveFeedId();
777
778/* if (tagsAreDisplayed()) {
779 query = query + "&omode=tl";
780 } else {
781 query = query + "&omode=flc";
782 } */
783
784 query = query + "&omode=lc";
785
786 new Ajax.Request(query, {
787 onComplete: function(transport) {
788 all_counters_callback2(transport);
789 } });
790
791 }
792
793 } catch (e) {
794 exception_error("selectionToggleMarked", e);
795 }
796}
797
798function selectionTogglePublished(cdm_mode) {
799 try {
800
801 var rows;
802
803 if (cdm_mode) {
804 rows = cdmGetSelectedArticles();
805 } else {
806 rows = getSelectedTableRowIds("headlinesList", "RROW", "RCHK");
807 }
808
809 if (rows.length == 0) {
810 alert(__("No articles are selected."));
811 return;
812 }
813
814 for (i = 0; i < rows.length; i++) {
815 togglePub(rows[i], true, true);
816 }
817
818 if (rows.length > 0) {
819
820 var query = "backend.php?op=rpc&subop=publishSelected&ids=" +
821 param_escape(rows.toString()) + "&cmode=2";
822
823 query = query + "&afid=" + getActiveFeedId();
824
825/* if (tagsAreDisplayed()) {
826 query = query + "&omode=tl";
827 } else {
828 query = query + "&omode=flc";
829 } */
830
831 query = query + "&omode=lc";
832
833 new Ajax.Request(query, {
834 onComplete: function(transport) {
835 all_counters_callback2(transport);
836 } });
837
838 }
839
840 } catch (e) {
841 exception_error("selectionToggleMarked", e);
842 }
843}
844
845function cdmGetSelectedArticles() {
846 var sel_articles = new Array();
847 var container = document.getElementById("headlinesInnerContainer");
848
849 for (i = 0; i < container.childNodes.length; i++) {
850 var child = container.childNodes[i];
851
852 if (child.id.match("RROW-") && child.className.match("Selected")) {
853 var c_id = child.id.replace("RROW-", "");
854 sel_articles.push(c_id);
855 }
856 }
857
858 return sel_articles;
859}
860
861function cdmGetVisibleArticles() {
862 var sel_articles = new Array();
863 var container = document.getElementById("headlinesInnerContainer");
864
865 for (i = 0; i < container.childNodes.length; i++) {
866 var child = container.childNodes[i];
867
868 if (child.id.match("RROW-")) {
869 var c_id = child.id.replace("RROW-", "");
870 sel_articles.push(c_id);
871 }
872 }
873
874 return sel_articles;
875}
876
877function cdmGetUnreadArticles() {
878 var sel_articles = new Array();
879 var container = document.getElementById("headlinesInnerContainer");
880
881 for (i = 0; i < container.childNodes.length; i++) {
882 var child = container.childNodes[i];
883
884 if (child.id.match("RROW-") && child.className.match("Unread")) {
885 var c_id = child.id.replace("RROW-", "");
886 sel_articles.push(c_id);
887 }
888 }
889
890 return sel_articles;
891}
892
893
894// mode = all,none,unread
895function cdmSelectArticles(mode) {
896 var container = document.getElementById("headlinesInnerContainer");
897
898 for (i = 0; i < container.childNodes.length; i++) {
899 var child = container.childNodes[i];
900
901 if (child.id.match("RROW-")) {
902 var aid = child.id.replace("RROW-", "");
903
904 var cb = document.getElementById("RCHK-" + aid);
905
906 if (mode == "all") {
907 if (!child.className.match("Selected")) {
908 child.className = child.className + "Selected";
909 cb.checked = true;
910 }
911 } else if (mode == "unread") {
912 if (child.className.match("Unread") && !child.className.match("Selected")) {
913 child.className = child.className + "Selected";
914 cb.checked = true;
915 }
916 } else {
917 child.className = child.className.replace("Selected", "");
918 cb.checked = false;
919 }
920 }
921 }
922}
923
924function catchupPage() {
925
926 var fn = getFeedName(getActiveFeedId(), active_feed_is_cat);
927
928 var str = __("Mark all visible articles in %s as read?");
929
930 str = str.replace("%s", fn);
931
932 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
933 return;
934 }
935
936 if (document.getElementById("headlinesList")) {
937 selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', true, 'Unread', true);
938 selectionToggleUnread(false, false, 'viewCurrentFeed()', true);
939 selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', false);
940 } else {
941 cdmSelectArticles('all');
942 selectionToggleUnread(true, false, 'viewCurrentFeed()', true)
943 cdmSelectArticles('none');
944 }
945}
946
947function catchupSelection() {
948
949 try {
950
951 var rows;
952
953 if (document.getElementById("headlinesList")) {
954 rows = getSelectedTableRowIds("headlinesList", "RROW", "RCHK");
955 } else {
956 rows = cdmGetSelectedArticles();
957 }
958
959 if (rows.length == 0) {
960 alert(__("No articles are selected."));
961 return;
962 }
963
964
965 var fn = getFeedName(getActiveFeedId(), active_feed_is_cat);
966
967 var str = __("Mark %d selected articles in %s as read?");
968
969 str = str.replace("%d", rows.length);
970 str = str.replace("%s", fn);
971
972 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
973 return;
974 }
975
976 if (document.getElementById("headlinesList")) {
977 selectionToggleUnread(false, false, 'viewCurrentFeed()', true);
978 // selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', false);
979 } else {
980 selectionToggleUnread(true, false, 'viewCurrentFeed()', true)
981 // cdmSelectArticles('none');
982 }
983
984 } catch (e) {
985 exception_error("catchupSelection", e);
986 }
987}
988
989
990function labelFromSearch(search, search_mode, match_on, feed_id, is_cat) {
991
992 if (!xmlhttp_ready(xmlhttp_rpc)) {
993 printLockingError();
994 }
995
996 var title = prompt(__("Please enter label title:"), "");
997
998 if (title) {
999
1000 var query = "backend.php?op=labelFromSearch&search=" + param_escape(search) +
1001 "&smode=" + param_escape(search_mode) + "&match=" + param_escape(match_on) +
1002 "&feed=" + param_escape(feed_id) + "&is_cat=" + param_escape(is_cat) +
1003 "&title=" + param_escape(title);
1004
1005 debug("LFS: " + query);
1006
1007 new Ajax.Request(query, {
1008 onComplete: function(transport) {
1009 dlg_frefresh_callback(transport);
1010 } });
1011 }
1012}
1013
1014function editArticleTags(id, feed_id, cdm_enabled) {
1015 _tag_active_post_id = id;
1016 _tag_active_feed_id = feed_id;
1017 _tag_active_cdm = cdm_enabled;
1018
1019 cache_invalidate(id);
1020
1021 try {
1022 _tag_cdm_scroll = document.getElementById("headlinesInnerContainer").scrollTop;
1023 } catch (e) { }
1024 displayDlg('editArticleTags', id);
1025}
1026
1027
1028function tag_saved_callback(transport) {
1029 try {
1030 debug("in tag_saved_callback");
1031
1032 closeInfoBox();
1033 notify("");
1034
1035 if (tagsAreDisplayed()) {
1036 _reload_feedlist_after_view = true;
1037 }
1038
1039 if (!_tag_active_cdm) {
1040 if (active_post_id == _tag_active_post_id) {
1041 debug("reloading current article");
1042 view(_tag_active_post_id, _tag_active_feed_id);
1043 }
1044 } else {
1045 debug("reloading current feed");
1046 viewCurrentFeed();
1047 }
1048
1049 } catch (e) {
1050 exception_error("catchup_callback", e);
1051 }
1052}
1053
1054function editTagsSave() {
1055
1056 notify_progress("Saving article tags...");
1057
1058 var form = document.forms["tag_edit_form"];
1059
1060 var query = Form.serialize("tag_edit_form");
1061
1062 query = "backend.php?op=rpc&subop=setArticleTags&" + query;
1063
1064 debug(query);
1065
1066 new Ajax.Request(query, {
1067 onComplete: function(transport) {
1068 tag_saved_callback(transport);
1069 } });
1070
1071}
1072
1073function editTagsInsert() {
1074 try {
1075
1076 var form = document.forms["tag_edit_form"];
1077
1078 var found_tags = form.found_tags;
1079 var tags_str = form.tags_str;
1080
1081 var tag = found_tags[found_tags.selectedIndex].value;
1082
1083 if (tags_str.value.length > 0 &&
1084 tags_str.value.lastIndexOf(", ") != tags_str.value.length - 2) {
1085
1086 tags_str.value = tags_str.value + ", ";
1087 }
1088
1089 tags_str.value = tags_str.value + tag + ", ";
1090
1091 found_tags.selectedIndex = 0;
1092
1093 } catch (e) {
1094 exception_error(e, "editTagsInsert");
1095 }
1096}
1097
1098function cdmWatchdog() {
1099
1100 try {
1101
1102 var ctr = document.getElementById("headlinesInnerContainer");
1103
1104 if (!ctr) return;
1105
1106 var ids = new Array();
1107
1108 var e = ctr.firstChild;
1109
1110 while (e) {
1111 if (e.className && e.className == "cdmArticleUnread" && e.id &&
1112 e.id.match("RROW-")) {
1113
1114 // article fits in viewport OR article is longer than viewport and
1115 // its bottom is visible
1116
1117 if (ctr.scrollTop <= e.offsetTop && e.offsetTop + e.offsetHeight <=
1118 ctr.scrollTop + ctr.offsetHeight) {
1119
1120// debug(e.id + " is visible " + e.offsetTop + "." +
1121// (e.offsetTop + e.offsetHeight) + " vs " + ctr.scrollTop + "." +
1122// (ctr.scrollTop + ctr.offsetHeight));
1123
1124 ids.push(e.id.replace("RROW-", ""));
1125
1126 } else if (e.offsetHeight > ctr.offsetHeight &&
1127 e.offsetTop + e.offsetHeight >= ctr.scrollTop &&
1128 e.offsetTop + e.offsetHeight <= ctr.scrollTop + ctr.offsetHeight) {
1129
1130 ids.push(e.id.replace("RROW-", ""));
1131
1132 }
1133
1134 // method 2: article bottom is visible and is in upper 1/2 of the viewport
1135
1136/* if (e.offsetTop + e.offsetHeight >= ctr.scrollTop &&
1137 e.offsetTop + e.offsetHeight <= ctr.scrollTop + ctr.offsetHeight/2) {
1138
1139 ids.push(e.id.replace("RROW-", ""));
1140
1141 } */
1142
1143 }
1144
1145 e = e.nextSibling;
1146 }
1147
1148 debug("cdmWatchdog, ids= " + ids.toString());
1149
1150 if (ids.length > 0) {
1151
1152 for (var i = 0; i < ids.length; i++) {
1153 var e = document.getElementById("RROW-" + ids[i]);
1154 if (e) {
1155 e.className = e.className.replace("Unread", "");
1156 }
1157 }
1158
1159 var query = "backend.php?op=rpc&subop=catchupSelected&ids=" +
1160 param_escape(ids.toString()) + "&cmode=0";
1161
1162 new Ajax.Request(query, {
1163 onComplete: function(transport) {
1164 all_counters_callback2(transport);
1165 } });
1166
1167 }
1168
1169 _cdm_wd_timeout = window.setTimeout("cdmWatchdog()", 4000);
1170
1171 } catch (e) {
1172 exception_error(e, "cdmWatchdog");
1173 }
1174
1175}
1176
1177
1178function cache_inject(id, article) {
1179 if (!cache_check(id)) {
1180 debug("cache_article: miss: " + id);
1181
1182 var cache_obj = new Array();
1183
1184 cache_obj["id"] = id;
1185 cache_obj["data"] = article;
1186
1187 article_cache.push(cache_obj);
1188
1189 } else {
1190 debug("cache_article: hit: " + id);
1191 }
1192}
1193
1194function cache_find(id) {
1195 for (var i = 0; i < article_cache.length; i++) {
1196 if (article_cache[i]["id"] == id) {
1197 return article_cache[i]["data"];
1198 }
1199 }
1200 return false;
1201}
1202
1203function cache_check(id) {
1204 for (var i = 0; i < article_cache.length; i++) {
1205 if (article_cache[i]["id"] == id) {
1206 return true;
1207 }
1208 }
1209 return false;
1210}
1211
1212function cache_expire() {
1213 while (article_cache.length > 20) {
1214 article_cache.shift();
1215 }
1216}
1217
1218function cache_invalidate(id) {
1219 var i = 0
1220
1221 try {
1222
1223 while (i < article_cache.length) {
1224 if (article_cache[i]["id"] == id) {
1225 debug("cache_invalidate: removed id " + id);
1226 article_cache.splice(i, 1);
1227 return true;
1228 }
1229 i++;
1230 }
1231 debug("cache_invalidate: id not found: " + id);
1232 return false;
1233 } catch (e) {
1234 exception_error("cache_invalidate", e);
1235 }
1236}
1237
1238function getActiveArticleId() {
1239 return active_post_id;
1240}
1241
1242function cdmMouseIn(elem) {
1243 try {
1244 if (elem.id && elem.id.match("RROW-")) {
1245 var id = elem.id.replace("RROW-", "");
1246 active_post_id = id;
1247 }
1248 } catch (e) {
1249 exception_error("cdmMouseIn", e);
1250 }
1251
1252}
1253
1254function cdmMouseOut(elem) {
1255 active_post_id = false;
1256}
1257
1258function headlines_scroll_handler() {
1259 try {
1260
1261 var e = document.getElementById("headlinesInnerContainer");
1262
1263 // don't do infinite scrolling when Limit == All
1264
1265 var toolbar_form = document.forms["main_toolbar_form"];
1266
1267 var limit = toolbar_form.limit[toolbar_form.limit.selectedIndex];
1268 if (limit.value != 0) {
1269 if (e.scrollTop + e.offsetHeight > e.scrollHeight - 50) {
1270 if (!_infscroll_disable) {
1271 debug("more cowbell!");
1272 viewNextFeedPage();
1273 }
1274 }
1275 }
1276
1277 } catch (e) {
1278 exception_error("headlines_scroll_handler", e);
1279 }
1280}
1281
1282function catchupRelativeToArticle(below) {
1283
1284 try {
1285
1286 if (!xmlhttp_ready(xmlhttp_rpc)) {
1287 printLockingError();
1288 }
1289
1290 if (!getActiveArticleId()) {
1291 alert(__("No article is selected."));
1292 return;
1293 }
1294
1295 var visible_ids;
1296
1297 if (document.getElementById("headlinesList")) {
1298 visible_ids = getVisibleHeadlineIds();
1299 } else {
1300 visible_ids = cdmGetVisibleArticles();
1301 }
1302
1303 var ids_to_mark = new Array();
1304
1305 if (!below) {
1306 for (var i = 0; i < visible_ids.length; i++) {
1307 if (visible_ids[i] != getActiveArticleId()) {
1308 var e = document.getElementById("RROW-" + visible_ids[i]);
1309
1310 if (e && e.className.match("Unread")) {
1311 ids_to_mark.push(visible_ids[i]);
1312 }
1313 } else {
1314 break;
1315 }
1316 }
1317 } else {
1318 for (var i = visible_ids.length-1; i >= 0; i--) {
1319 if (visible_ids[i] != getActiveArticleId()) {
1320 var e = document.getElementById("RROW-" + visible_ids[i]);
1321
1322 if (e && e.className.match("Unread")) {
1323 ids_to_mark.push(visible_ids[i]);
1324 }
1325 } else {
1326 break;
1327 }
1328 }
1329 }
1330
1331 if (ids_to_mark.length == 0) {
1332 alert(__("No articles found to mark"));
1333 } else {
1334 var msg = __("Mark %d article(s) as read?").replace("%d", ids_to_mark.length);
1335
1336 if (confirm(msg)) {
1337
1338 for (var i = 0; i < ids_to_mark.length; i++) {
1339 var e = document.getElementById("RROW-" + ids_to_mark[i]);
1340 e.className = e.className.replace("Unread", "");
1341 }
1342
1343 var query = "backend.php?op=rpc&subop=catchupSelected&ids=" +
1344 param_escape(ids_to_mark.toString()) + "&cmode=0";
1345
1346 new Ajax.Request(query, {
1347 onComplete: function(transport) {
1348 catchup_callback2(transport);
1349 } });
1350
1351 }
1352 }
1353
1354 } catch (e) {
1355 exception_error("catchupRelativeToArticle", e);
1356 }
1357}