1 var active_post_id
= false;
2 var last_article_view
= false;
3 var active_real_feed_id
= false;
5 // FIXME: kludges, needs proper implementation
6 var _reload_feedlist_after_view
= false;
8 var _cdm_wd_timeout
= false;
9 var _cdm_wd_vishist
= new Array();
11 var article_cache
= new Array();
13 var vgroup_last_feed
= false;
14 var post_under_pointer
= false;
16 var last_requested_article
= false;
18 var preload_id_batch
= [];
19 var preload_timeout_id
= false;
23 function catchup_callback2(transport
, callback
) {
25 console
.log("catchup_callback2 " + transport
+ ", " + callback
);
27 handle_rpc_reply(transport
);
29 setTimeout(callback
, 10);
32 exception_error("catchup_callback2", e
, transport
);
36 function clean_feed_selections() {
38 var feeds
= $("feedList").getElementsByTagName("LI");
40 for (var i
= 0; i
< feeds
.length
; i
++) {
41 if (feeds
[i
].id
&& feeds
[i
].id
.match("FEEDR-")) {
42 feeds
[i
].className
= feeds
[i
].className
.replace("Selected", "");
44 if (feeds
[i
].id
&& feeds
[i
].id
.match("FCAT-")) {
45 feeds
[i
].className
= feeds
[i
].className
.replace("Selected", "");
49 exception_error("clean_feed_selections", e
);
53 function headlines_callback2(transport
, feed_cur_page
) {
56 if (!handle_rpc_reply(transport
)) return;
58 loading_set_progress(100);
60 console
.log("headlines_callback2 [page=" + feed_cur_page
+ "]");
62 if (!transport_error_check(transport
)) return;
64 clean_feed_selections();
69 if (transport
.responseXML
) {
70 var headlines
= transport
.responseXML
.getElementsByTagName("headlines")[0];
72 is_cat
= headlines
.getAttribute("is_cat");
73 feed_id
= headlines
.getAttribute("id");
74 setActiveFeedId(feed_id
, is_cat
);
78 var ll
= $('FLL-' + feed_id
);
81 var feedr
= $("FEEDR-" + feed_id
);
82 if (feedr
&& !feedr
.className
.match("Selected")) {
83 feedr
.className
= feedr
.className
+ "Selected";
85 if (feedr
&& ll
) feedr
.removeChild(ll
);
87 var feedr
= $("FCAT-" + feed_id
);
88 if (feedr
&& !feedr
.className
.match("Selected")) {
89 feedr
.className
= feedr
.className
+ "Selected";
92 var fcap
= $("FCAP-" + feed_id
);
93 if (fcap
&& ll
) fcap
.removeChild(ll
);
97 var img
= $('FIMG-' + feed_id
);
103 var f
= $("headlines-frame");
105 if (feed_cur_page
== 0) {
106 //console.log("resetting headlines scrollTop");
111 if (transport
.responseXML
) {
112 var response
= transport
.responseXML
;
114 var headlines
= response
.getElementsByTagName("headlines")[0];
115 var headlines_info
= response
.getElementsByTagName("headlines-info")[0];
118 headlines_info
= JSON
.parse(headlines_info
.firstChild
.nodeValue
);
120 console
.error("didn't find headlines-info object in response");
124 var headlines_count
= headlines_info
.count
;
125 var headlines_unread
= headlines_info
.unread
;
126 var disable_cache
= headlines_info
.disable_cache
;
128 vgroup_last_feed
= headlines_info
.vgroup_last_feed
;
130 if (headlines_count
== 0) {
131 _infscroll_disable
= 1;
133 _infscroll_disable
= 0;
136 var counters
= response
.getElementsByTagName("counters")[0];
137 var articles
= response
.getElementsByTagName("article");
138 var runtime_info
= response
.getElementsByTagName("runtime-info");
140 if (feed_cur_page
== 0) {
142 f
.innerHTML
= headlines
.firstChild
.nodeValue
;
144 var cache_prefix
= "";
152 cache_invalidate(cache_prefix
+ feed_id
);
154 if (!disable_cache
) {
155 cache_inject(cache_prefix
+ feed_id
,
156 headlines
.firstChild
.nodeValue
, headlines_unread
);
160 console
.warn("headlines_callback: returned no data");
161 f
.innerHTML
= "<div class='whiteBox'>" + __('Could not update headlines (missing XML data)') + "</div>";
166 if (headlines_count
> 0) {
167 console
.warn("adding some more headlines...");
169 var c
= $("headlinesList");
172 c
= $("headlinesInnerContainer");
175 var ids
= getSelectedArticleIds2();
177 c
.innerHTML
= c
.innerHTML
+ headlines
.firstChild
.nodeValue
;
179 console
.log("restore selected ids: " + ids
);
181 for (var i
= 0; i
< ids
.length
; i
++) {
182 markHeadline(ids
[i
]);
186 console
.log("no new headlines received");
189 console
.warn("headlines_callback: returned no data");
190 notify_error("Error while trying to load more headlines");
196 for (var i
= 0; i
< articles
.length
; i
++) {
197 var a_id
= articles
[i
].getAttribute("id");
198 //console.log("found id: " + a_id);
199 cache_inject(a_id
, articles
[i
].firstChild
.nodeValue
);
202 console
.log("no cached articles received");
206 parse_counters(counters
);
211 parse_runtime_info(runtime_info
[0]);
215 console
.warn("headlines_callback: returned no XML object");
216 f
.innerHTML
= "<div class='whiteBox'>" + __('Could not update headlines (missing XML object)') + "</div>";
220 if (_cdm_wd_timeout
) window
.clearTimeout(_cdm_wd_timeout
);
222 if (!$("headlinesList") &&
223 getActiveFeedId() != -3 &&
224 getInitParam("cdm_auto_catchup") == 1) {
225 console
.log("starting CDM watchdog");
226 _cdm_wd_timeout
= window
.setTimeout("cdmWatchdog()", 5000);
227 _cdm_wd_vishist
= new Array();
229 console
.log("not in CDM mode or watchdog disabled");
232 _feed_cur_page
= feed_cur_page
;
233 _infscroll_request_sent
= 0;
240 exception_error("headlines_callback2", e
, transport
);
244 function render_article(article
) {
246 var f
= $("content-frame");
251 var fi
= $("content-insert");
257 fi
.innerHTML
= article
;
259 // article.evalScripts();
262 exception_error("render_article", e
);
266 function showArticleInHeadlines(id
) {
270 cleanSelected("headlinesList");
272 var crow
= $("RROW-" + id
);
276 var article_is_unread
= crow
.className
.match("Unread");
278 crow
.className
= crow
.className
.replace("Unread", "");
280 selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', false);
282 var upd_img_pic
= $("FUPDPIC-" + id
);
284 var cache_prefix
= "";
286 if (activeFeedIsCat()) {
292 var view_mode
= false;
295 view_mode
= document
.forms
['main_toolbar_form'].view_mode
;
296 view_mode
= view_mode
[view_mode
.selectedIndex
].value
;
301 if (upd_img_pic
&& (upd_img_pic
.src
.match("updated.png") ||
302 upd_img_pic
.src
.match("fresh_sign.png"))) {
304 upd_img_pic
.src
= "images/blank_icon.gif";
306 cache_invalidate(cache_prefix
+ getActiveFeedId());
308 cache_inject(cache_prefix
+ getActiveFeedId(),
309 $("headlines-frame").innerHTML
,
310 get_feed_unread(getActiveFeedId()));
312 } else if (article_is_unread
&& view_mode
== "all_articles") {
314 cache_invalidate(cache_prefix
+ getActiveFeedId());
316 cache_inject(cache_prefix
+ getActiveFeedId(),
317 $("headlines-frame").innerHTML
,
318 get_feed_unread(getActiveFeedId())-1);
320 } else if (article_is_unread
) {
321 cache_invalidate(cache_prefix
+ getActiveFeedId());
327 exception_error("showArticleInHeadlines", e
);
331 function article_callback2(transport
, id
) {
333 console
.log("article_callback2 " + id
);
335 if (!handle_rpc_reply(transport
)) return;
337 if (transport
.responseXML
) {
339 if (!transport_error_check(transport
)) return;
341 /* var ll = $('LL-' + id);
342 var content = $('HLC-' + id);
344 if (ll && content) content.removeChild(ll); */
346 var upic
= $('FUPDPIC-' + id
);
349 upic
.src
= 'images/blank_icon.gif';
352 if (id
!= last_requested_article
) {
353 console
.log("requested article id is out of sequence, aborting");
359 //console.log("looking for articles to cache...");
361 var articles
= transport
.responseXML
.getElementsByTagName("article");
363 for (var i
= 0; i
< articles
.length
; i
++) {
364 var a_id
= articles
[i
].getAttribute("id");
366 //console.log("found id: " + a_id);
368 if (a_id
== active_post_id
) {
369 //console.log("active article, rendering...");
370 render_article(articles
[i
].firstChild
.nodeValue
);
373 cache_inject(a_id
, articles
[i
].firstChild
.nodeValue
);
377 showArticleInHeadlines(id
);
380 db
.execute("UPDATE articles SET unread = 0 WHERE id = ?", [id
]);
383 var reply
= transport
.responseXML
.firstChild
.firstChild
;
386 console
.warn("article_callback: returned no XML object");
387 //var f = $("content-frame");
388 //f.innerHTML = "<div class='whiteBox'>" + __('Could not display article (missing XML object)') + "</div>";
391 var date
= new Date();
392 last_article_view
= date
.getTime() / 1000;
394 if (_reload_feedlist_after_view
) {
395 setTimeout('updateFeedList(false, false)', 50);
396 _reload_feedlist_after_view
= false;
403 exception_error("article_callback2", e
, transport
);
409 console
.log("loading article: " + id
);
411 if (offline_mode
) return view_offline(id
);
413 var cached_article
= cache_find(id
);
415 console
.log("cache check result: " + (cached_article
!= false));
420 var query
= "?op=view&id=" + param_escape(id
);
422 var neighbor_ids
= getRelativePostIds(active_post_id
);
424 /* only request uncached articles */
426 var cids_to_request
= Array();
428 for (var i
= 0; i
< neighbor_ids
.length
; i
++) {
429 if (!cache_check(neighbor_ids
[i
])) {
430 cids_to_request
.push(neighbor_ids
[i
]);
434 console
.log("additional ids: " + cids_to_request
.toString());
436 /* additional info for piggyback counters */
438 if (tagsAreDisplayed()) {
439 query
= query
+ "&omode=lt";
441 query
= query
+ "&omode=flc";
444 query
= query
+ "&cids=" + cids_to_request
.toString();
446 var crow
= $("RROW-" + id
);
447 var article_is_unread
= crow
.className
.match("Unread");
449 showArticleInHeadlines(id
);
451 if (!cached_article
) {
453 var upic
= $('FUPDPIC-' + id
);
456 upic
.src
= getInitParam("sign_progress");
459 } else if (cached_article
&& article_is_unread
) {
461 query
= query
+ "&mode=prefetch";
463 render_article(cached_article
);
465 } else if (cached_article
) {
467 query
= query
+ "&mode=prefetch_old";
468 render_article(cached_article
);
474 last_requested_article
= id
;
476 new Ajax
.Request("backend.php", {
478 onComplete: function(transport
) {
479 article_callback2(transport
, id
);
485 exception_error("view", e
);
490 return toggleMark(id
);
494 return togglePub(id
);
497 function tMark_afh_off(effect
) {
499 var elem
= effect
.effects
[0].element
;
501 //console.log("tMark_afh_off : " + elem.id);
504 elem
.src
= elem
.src
.replace("mark_set", "mark_unset");
505 elem
.alt
= __("Star article");
510 exception_error("tMark_afh_off", e
);
514 function tPub_afh_off(effect
) {
516 var elem
= effect
.effects
[0].element
;
518 //console.log("tPub_afh_off : " + elem.id);
521 elem
.src
= elem
.src
.replace("pub_set", "pub_unset");
522 elem
.alt
= __("Publish article");
527 exception_error("tPub_afh_off", e
);
531 function toggleMark(id
, client_only
, no_effects
) {
535 var query
= "?op=rpc&id=" + id
+ "&subop=mark";
537 query
= query
+ "&afid=" + getActiveFeedId();
539 if (tagsAreDisplayed()) {
540 query
= query
+ "&omode=tl";
542 query
= query
+ "&omode=flc";
545 var mark_img
= $("FMPIC-" + id
);
547 if (!mark_img
) return;
549 var vfeedu
= $("FEEDU--1");
550 var crow
= $("RROW-" + id
);
552 if (mark_img
.src
.match("mark_unset")) {
553 mark_img
.src
= mark_img
.src
.replace("mark_unset", "mark_set");
554 mark_img
.alt
= __("Unstar article");
555 query
= query
+ "&mark=1";
558 db
.execute("UPDATE articles SET marked = 1 WHERE id = ?", [id
]);
562 mark_img
.alt
= __("Please wait...");
563 query
= query
+ "&mark=0";
565 if ($("headlinesList") && !no_effects
) {
566 Effect
.Puff(mark_img
, {duration
: 0.25, afterFinish
: tMark_afh_off
});
568 mark_img
.src
= mark_img
.src
.replace("mark_set", "mark_unset");
569 mark_img
.alt
= __("Star article");
573 db
.execute("UPDATE articles SET marked = 0 WHERE id = ?", [id
]);
578 if (!no_effects
) update_local_feedlist_counters();
581 //console.log(query);
583 new Ajax
.Request("backend.php", {
585 onComplete: function(transport
) {
586 handle_rpc_reply(transport
);
592 exception_error("toggleMark", e
);
596 function togglePub(id
, client_only
, no_effects
, note
) {
600 var query
= "?op=rpc&id=" + id
+ "&subop=publ";
602 query
= query
+ "&afid=" + getActiveFeedId();
604 if (note
!= undefined) {
605 query
= query
+ "¬e=" + param_escape(note
);
607 query
= query
+ "¬e=undefined";
610 if (tagsAreDisplayed()) {
611 query
= query
+ "&omode=tl";
613 query
= query
+ "&omode=flc";
616 var mark_img
= $("FPPIC-" + id
);
618 if (!mark_img
) return;
620 var vfeedu
= $("FEEDU--2");
621 var crow
= $("RROW-" + id
);
623 if (mark_img
.src
.match("pub_unset") || note
!= undefined) {
624 mark_img
.src
= mark_img
.src
.replace("pub_unset", "pub_set");
625 mark_img
.alt
= __("Unpublish article");
626 query
= query
+ "&pub=1";
629 mark_img
.alt
= __("Please wait...");
630 query
= query
+ "&pub=0";
632 if ($("headlinesList") && !no_effects
) {
633 Effect
.Puff(mark_img
, {duration
: 0.25, afterFinish
: tPub_afh_off
});
635 mark_img
.src
= mark_img
.src
.replace("pub_set", "pub_unset");
636 mark_img
.alt
= __("Publish article");
641 new Ajax
.Request("backend.php", {
643 onComplete: function(transport
) {
644 handle_rpc_reply(transport
);
646 var note
= transport
.responseXML
.getElementsByTagName("note")[0];
649 var note_id
= note
.getAttribute("id");
650 var note_size
= note
.getAttribute("size");
651 var note_content
= note
.firstChild
.nodeValue
;
653 var container
= $('POSTNOTE-' + note_id
);
655 cache_invalidate(note_id
);
658 if (note_size
== "0") {
659 Element
.hide(container
);
661 container
.innerHTML
= note_content
;
662 Element
.show(container
);
671 exception_error("togglePub", e
);
675 function correctHeadlinesOffset(id
) {
679 var hlist
= $("headlinesList");
680 var container
= $("headlinesInnerContainer");
681 var row
= $("RROW-" + id
);
683 var viewport
= container
.offsetHeight
;
685 var rel_offset_top
= row
.offsetTop
- container
.scrollTop
;
686 var rel_offset_bottom
= row
.offsetTop
+ row
.offsetHeight
- container
.scrollTop
;
688 console
.log("Rtop: " + rel_offset_top
+ " Rbtm: " + rel_offset_bottom
);
689 console
.log("Vport: " + viewport
);
691 if (rel_offset_top
<= 0 || rel_offset_top
> viewport
) {
692 container
.scrollTop
= row
.offsetTop
;
693 } else if (rel_offset_bottom
> viewport
) {
695 /* doesn't properly work with Opera in some cases because
696 Opera fucks up element scrolling */
698 container
.scrollTop
= row
.offsetTop
+ row
.offsetHeight
- viewport
;
702 exception_error("correctHeadlinesOffset", e
);
707 function moveToPost(mode
) {
714 rows
= cdmGetVisibleArticles();
716 rows
= getVisibleHeadlineIds();
722 if (!$('RROW-' + active_post_id
)) {
723 active_post_id
= false;
726 if (active_post_id
== false) {
727 next_id
= getFirstVisibleHeadlineId();
728 prev_id
= getLastVisibleHeadlineId();
730 for (var i
= 0; i
< rows
.length
; i
++) {
731 if (rows
[i
] == active_post_id
) {
738 if (mode
== "next") {
742 cdmExpandArticle(next_id
);
743 cdmScrollToArticleId(next_id
);
746 correctHeadlinesOffset(next_id
);
747 view(next_id
, getActiveFeedId());
752 if (mode
== "prev") {
755 cdmExpandArticle(prev_id
);
756 cdmScrollToArticleId(prev_id
);
758 correctHeadlinesOffset(prev_id
);
759 view(prev_id
, getActiveFeedId());
765 exception_error("moveToPost", e
);
769 function toggleSelected(id
) {
772 var cb
= $("RCHK-" + id
);
774 var row
= $("RROW-" + id
);
776 var nc
= row
.className
;
778 if (!nc
.match("Selected")) {
779 nc
= nc
+ "Selected";
784 // In CDM basically last selected article == active article
785 if (isCdmMode()) active_post_id
= id
;
787 nc
= nc
.replace("Selected", "");
797 exception_error("toggleSelected", e
);
801 function toggleUnread_afh(effect
) {
804 var elem
= effect
.element
;
805 elem
.style
.backgroundColor
= "";
808 exception_error("toggleUnread_afh", e
);
812 function toggleUnread(id
, cmode
, effect
) {
815 var row
= $("RROW-" + id
);
817 var nc
= row
.className
;
818 var is_selected
= row
.className
.match("Selected");
819 nc
= nc
.replace("Unread", "");
820 nc
= nc
.replace("Selected", "");
822 // since we are removing selection from the object, uncheck
823 // corresponding checkbox
825 var cb
= $("RCHK-" + id
);
830 // NOTE: I'm not sure that resetting selection here is a feature -fox
832 if (cmode
== undefined || cmode
== 2) {
833 if (row
.className
.match("Unread")) {
837 new Effect
.Highlight(row
, {duration
: 1, startcolor
: "#fff7d5",
838 afterFinish
: toggleUnread_afh
,
839 queue
: { position
:'end', scope
: 'TMRQ-' + id
, limit
: 1 } } );
843 row
.className
= nc
+ "Unread";
847 db
.execute("UPDATE articles SET unread = not unread "+
848 "WHERE id = ?", [id
]);
851 } else if (cmode
== 0) {
855 new Effect
.Highlight(row
, {duration
: 1, startcolor
: "#fff7d5",
856 afterFinish
: toggleUnread_afh
,
857 queue
: { position
:'end', scope
: 'TMRQ-' + id
, limit
: 1 } } );
861 db
.execute("UPDATE articles SET unread = 0 "+
862 "WHERE id = ?", [id
]);
865 } else if (cmode
== 1) {
866 row
.className
= nc
+ "Unread";
869 db
.execute("UPDATE articles SET unread = 1 "+
870 "WHERE id = ?", [id
]);
875 update_local_feedlist_counters();
877 // Disable unmarking as selected for the time being (16.05.08) -fox
878 if (is_selected
) row
.className
= row
.className
+ "Selected";
880 if (cmode
== undefined) cmode
= 2;
882 var query
= "?op=rpc&subop=catchupSelected" +
883 "&cmode=" + param_escape(cmode
) + "&ids=" + param_escape(id
);
885 // notify_progress("Loading, please wait...");
887 new Ajax
.Request("backend.php", {
889 onComplete: function(transport
) {
890 handle_rpc_reply(transport
);
896 exception_error("toggleUnread", e
);
900 function selectionRemoveLabel(id
) {
903 var ids
= getSelectedArticleIds2();
905 if (ids
.length
== 0) {
906 alert(__("No articles are selected."));
910 // var ok = confirm(__("Remove selected articles from label?"));
914 var query
= "?op=rpc&subop=removeFromLabel&ids=" +
915 param_escape(ids
.toString()) + "&lid=" + param_escape(id
);
919 // notify_progress("Loading, please wait...");
921 cache_invalidate("F:" + (-11 - id
));
923 new Ajax
.Request("backend.php", {
925 onComplete: function(transport
) {
926 show_labels_in_headlines(transport
);
927 handle_rpc_reply(transport
);
933 exception_error("selectionAssignLabel", e
);
938 function selectionAssignLabel(id
) {
941 var ids
= getSelectedArticleIds2();
943 if (ids
.length
== 0) {
944 alert(__("No articles are selected."));
948 // var ok = confirm(__("Assign selected articles to label?"));
952 cache_invalidate("F:" + (-11 - id
));
954 var query
= "?op=rpc&subop=assignToLabel&ids=" +
955 param_escape(ids
.toString()) + "&lid=" + param_escape(id
);
959 // notify_progress("Loading, please wait...");
961 new Ajax
.Request("backend.php", {
963 onComplete: function(transport
) {
964 show_labels_in_headlines(transport
);
965 handle_rpc_reply(transport
);
971 exception_error("selectionAssignLabel", e
);
976 function selectionToggleUnread(set_state
, callback_func
, no_error
) {
978 var rows
= getSelectedArticleIds2();
980 if (rows
.length
== 0 && !no_error
) {
981 alert(__("No articles are selected."));
985 for (i
= 0; i
< rows
.length
; i
++) {
986 var row
= $("RROW-" + rows
[i
]);
988 var nc
= row
.className
;
989 nc
= nc
.replace("Unread", "");
990 nc
= nc
.replace("Selected", "");
992 if (set_state
== undefined) {
993 if (row
.className
.match("Unread")) {
994 row
.className
= nc
+ "Selected";
996 row
.className
= nc
+ "UnreadSelected";
999 db
.execute("UPDATE articles SET unread = NOT unread WHERE id = ?",
1004 if (set_state
== false) {
1005 row
.className
= nc
+ "Selected";
1007 db
.execute("UPDATE articles SET unread = 0 WHERE id = ?",
1012 if (set_state
== true) {
1013 row
.className
= nc
+ "UnreadSelected";
1015 db
.execute("UPDATE articles SET unread = 1 WHERE id = ?",
1022 if (rows
.length
> 0) {
1024 update_local_feedlist_counters();
1028 if (set_state
== undefined) {
1030 } else if (set_state
== true) {
1032 } else if (set_state
== false) {
1036 var query
= "?op=rpc&subop=catchupSelected" +
1037 "&cmode=" + cmode
+ "&ids=" + param_escape(rows
.toString());
1039 notify_progress("Loading, please wait...");
1041 new Ajax
.Request("backend.php", {
1043 onComplete: function(transport
) {
1044 catchup_callback2(transport
, callback_func
);
1050 exception_error("selectionToggleUnread", e
);
1054 function selectionToggleMarked() {
1057 var rows
= getSelectedArticleIds2();
1059 if (rows
.length
== 0) {
1060 alert(__("No articles are selected."));
1064 for (i
= 0; i
< rows
.length
; i
++) {
1065 toggleMark(rows
[i
], true, true);
1068 update_local_feedlist_counters();
1070 if (rows
.length
> 0) {
1072 var query
= "?op=rpc&subop=markSelected&ids=" +
1073 param_escape(rows
.toString()) + "&cmode=2";
1075 query
= query
+ "&afid=" + getActiveFeedId();
1077 query
= query
+ "&omode=lc";
1079 new Ajax
.Request("backend.php", {
1081 onComplete: function(transport
) {
1082 handle_rpc_reply(transport
);
1088 exception_error("selectionToggleMarked", e
);
1092 function selectionTogglePublished() {
1095 var rows
= getSelectedArticleIds2();
1097 if (rows
.length
== 0) {
1098 alert(__("No articles are selected."));
1102 for (i
= 0; i
< rows
.length
; i
++) {
1103 togglePub(rows
[i
], true, true);
1106 if (rows
.length
> 0) {
1108 var query
= "?op=rpc&subop=publishSelected&ids=" +
1109 param_escape(rows
.toString()) + "&cmode=2";
1111 query
= query
+ "&afid=" + getActiveFeedId();
1113 query
= query
+ "&omode=lc";
1115 new Ajax
.Request("backend.php", {
1117 onComplete: function(transport
) {
1118 handle_rpc_reply(transport
);
1124 exception_error("selectionToggleMarked", e
);
1128 function cdmGetSelectedArticles() {
1129 var sel_articles
= new Array();
1130 var container
= $("headlinesInnerContainer");
1132 for (i
= 0; i
< container
.childNodes
.length
; i
++) {
1133 var child
= container
.childNodes
[i
];
1135 if (child
.id
&& child
.id
.match("RROW-") && child
.className
.match("Selected")) {
1136 var c_id
= child
.id
.replace("RROW-", "");
1137 sel_articles
.push(c_id
);
1141 return sel_articles
;
1144 function cdmGetVisibleArticles() {
1145 var sel_articles
= new Array();
1146 var container
= $("headlinesInnerContainer");
1148 if (!container
) return sel_articles
;
1150 for (i
= 0; i
< container
.childNodes
.length
; i
++) {
1151 var child
= container
.childNodes
[i
];
1153 if (child
.id
&& child
.id
.match("RROW-")) {
1154 var c_id
= child
.id
.replace("RROW-", "");
1155 sel_articles
.push(c_id
);
1159 return sel_articles
;
1162 function cdmGetUnreadArticles() {
1163 var sel_articles
= new Array();
1164 var container
= $("headlinesInnerContainer");
1166 for (i
= 0; i
< container
.childNodes
.length
; i
++) {
1167 var child
= container
.childNodes
[i
];
1169 if (child
.id
&& child
.id
.match("RROW-") && child
.className
.match("Unread")) {
1170 var c_id
= child
.id
.replace("RROW-", "");
1171 sel_articles
.push(c_id
);
1175 return sel_articles
;
1179 // mode = all,none,unread
1180 function cdmSelectArticles(mode
) {
1181 var container
= $("headlinesInnerContainer");
1183 for (i
= 0; i
< container
.childNodes
.length
; i
++) {
1184 var child
= container
.childNodes
[i
];
1186 if (child
.id
&& child
.id
.match("RROW-")) {
1187 var aid
= child
.id
.replace("RROW-", "");
1189 var cb
= $("RCHK-" + aid
);
1191 if (mode
== "all") {
1192 if (!child
.className
.match("Selected")) {
1193 child
.className
= child
.className
+ "Selected";
1196 } else if (mode
== "unread") {
1197 if (child
.className
.match("Unread") && !child
.className
.match("Selected")) {
1198 child
.className
= child
.className
+ "Selected";
1202 child
.className
= child
.className
.replace("Selected", "");
1209 function catchupPage() {
1211 var fn
= getFeedName(getActiveFeedId(), activeFeedIsCat());
1213 var str
= __("Mark all visible articles in %s as read?");
1215 str
= str
.replace("%s", fn
);
1217 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str
)) {
1221 if ($("headlinesList")) {
1222 selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', true, 'Unread', true);
1223 selectionToggleUnread(false, 'viewCurrentFeed()', true);
1224 selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', false);
1226 cdmSelectArticles('all');
1227 selectionToggleUnread(false, 'viewCurrentFeed()', true)
1228 cdmSelectArticles('none');
1232 function deleteSelection() {
1236 var rows
= getSelectedArticleIds2();
1238 if (rows
.length
== 0) {
1239 alert(__("No articles are selected."));
1243 var fn
= getFeedName(getActiveFeedId(), activeFeedIsCat());
1247 if (getActiveFeedId() != 0) {
1248 str
= __("Delete %d selected articles in %s?");
1250 str
= __("Delete %d selected articles?");
1253 str
= str
.replace("%d", rows
.length
);
1254 str
= str
.replace("%s", fn
);
1256 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str
)) {
1260 query
= "?op=rpc&subop=delete&ids=" + param_escape(rows
);
1264 new Ajax
.Request("backend.php", {
1266 onComplete: function(transport
) {
1271 exception_error("deleteSelection", e
);
1275 function archiveSelection() {
1279 var rows
= getSelectedArticleIds2();
1281 if (rows
.length
== 0) {
1282 alert(__("No articles are selected."));
1286 var fn
= getFeedName(getActiveFeedId(), activeFeedIsCat());
1290 if (getActiveFeedId() != 0) {
1291 str
= __("Archive %d selected articles in %s?");
1294 str
= __("Move %d archived articles back?");
1298 str
= str
.replace("%d", rows
.length
);
1299 str
= str
.replace("%s", fn
);
1301 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str
)) {
1305 query
= "?op=rpc&subop="+op
+"&ids=" + param_escape(rows
);
1309 for (var i
= 0; i
< rows
.length
; i
++) {
1310 cache_invalidate(rows
[i
]);
1313 new Ajax
.Request("backend.php", {
1315 onComplete: function(transport
) {
1320 exception_error("archiveSelection", e
);
1324 function catchupSelection() {
1328 var rows
= getSelectedArticleIds2();
1330 if (rows
.length
== 0) {
1331 alert(__("No articles are selected."));
1335 var fn
= getFeedName(getActiveFeedId(), activeFeedIsCat());
1337 var str
= __("Mark %d selected articles in %s as read?");
1339 str
= str
.replace("%d", rows
.length
);
1340 str
= str
.replace("%s", fn
);
1342 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str
)) {
1346 if ($("headlinesList")) {
1347 selectionToggleUnread(false, 'viewCurrentFeed()', true);
1349 selectionToggleUnread(false, 'viewCurrentFeed()', true)
1353 exception_error("catchupSelection", e
);
1357 function editArticleTags(id
, feed_id
, cdm_enabled
) {
1358 displayDlg('editArticleTags', id
,
1360 $("tags_str").focus();
1362 new Ajax
.Autocompleter('tags_str', 'tags_choices',
1363 "backend.php?op=rpc&subop=completeTags",
1364 { tokens
: ',', paramName
: "search" });
1368 function editTagsSave() {
1370 notify_progress("Saving article tags...");
1372 var form
= document
.forms
["tag_edit_form"];
1374 var query
= Form
.serialize("tag_edit_form");
1376 query
= "?op=rpc&subop=setArticleTags&" + query
;
1378 //console.log(query);
1380 new Ajax
.Request("backend.php", {
1382 onComplete: function(transport
) {
1384 //console.log("tags saved...");
1389 if (tagsAreDisplayed()) {
1390 _reload_feedlist_after_view
= true;
1393 if (transport
.responseXML
) {
1394 var tags_str
= transport
.responseXML
.getElementsByTagName("tags-str")[0];
1397 var id
= tags_str
.getAttribute("id");
1400 var tags
= $("ATSTR-" + id
);
1402 tags
.innerHTML
= tags_str
.firstChild
.nodeValue
;
1405 cache_invalidate(id
);
1411 exception_error("editTagsSave", e
);
1416 function editTagsInsert() {
1419 var form
= document
.forms
["tag_edit_form"];
1421 var found_tags
= form
.found_tags
;
1422 var tags_str
= form
.tags_str
;
1424 var tag
= found_tags
[found_tags
.selectedIndex
].value
;
1426 if (tags_str
.value
.length
> 0 &&
1427 tags_str
.value
.lastIndexOf(", ") != tags_str
.value
.length
- 2) {
1429 tags_str
.value
= tags_str
.value
+ ", ";
1432 tags_str
.value
= tags_str
.value
+ tag
+ ", ";
1434 found_tags
.selectedIndex
= 0;
1437 exception_error("editTagsInsert", e
);
1441 function cdmScrollViewport(where
) {
1442 console
.log("cdmScrollViewport: " + where
);
1444 var ctr
= $("headlinesInnerContainer");
1448 if (where
== "bottom") {
1449 ctr
.scrollTop
= ctr
.scrollHeight
;
1451 ctr
.scrollTop
= where
;
1455 function cdmArticleIsBelowViewport(id
) {
1457 var ctr
= $("headlinesInnerContainer");
1458 var e
= $("RROW-" + id
);
1460 if (!e
|| !ctr
) return;
1462 // article starts below viewport
1464 if (ctr
.scrollTop
< e
.offsetTop
) {
1471 exception_error("cdmArticleIsVisible", e
);
1475 function cdmArticleIsAboveViewport(id
) {
1477 var ctr
= $("headlinesInnerContainer");
1478 var e
= $("RROW-" + id
);
1480 if (!e
|| !ctr
) return;
1482 // article starts above viewport
1484 if (ctr
.scrollTop
> e
.offsetTop
+ e
.offsetHeight
) {
1491 exception_error("cdmArticleIsVisible", e
);
1495 function cdmScrollToArticleId(id
) {
1497 var ctr
= $("headlinesInnerContainer");
1498 var e
= $("RROW-" + id
);
1500 if (!e
|| !ctr
) return;
1502 ctr
.scrollTop
= e
.offsetTop
;
1505 exception_error("cdmScrollToArticleId", e
);
1509 function cdmArticleIsActuallyVisible(id
) {
1511 var ctr
= $("headlinesInnerContainer");
1512 var e
= $("RROW-" + id
);
1514 if (!e
|| !ctr
) return;
1516 // article fits in viewport OR article is longer than viewport and
1517 // its bottom is visible
1519 if (ctr
.scrollTop
<= e
.offsetTop
&& e
.offsetTop
+ e
.offsetHeight
<=
1520 ctr
.scrollTop
+ ctr
.offsetHeight
) {
1524 } else if (e
.offsetHeight
> ctr
.offsetHeight
&&
1525 e
.offsetTop
+ e
.offsetHeight
>= ctr
.scrollTop
&&
1526 e
.offsetTop
+ e
.offsetHeight
<= ctr
.scrollTop
+ ctr
.offsetHeight
) {
1535 exception_error("cdmArticleIsVisible", e
);
1539 function cdmWatchdog() {
1543 var ctr
= $("headlinesInnerContainer");
1547 var ids
= new Array();
1549 var e
= ctr
.firstChild
;
1552 if (e
.className
&& e
.className
== "cdmArticleUnread" && e
.id
&&
1553 e
.id
.match("RROW-")) {
1555 // article fits in viewport OR article is longer than viewport and
1556 // its bottom is visible
1558 if (ctr
.scrollTop
<= e
.offsetTop
&& e
.offsetTop
+ e
.offsetHeight
<=
1559 ctr
.scrollTop
+ ctr
.offsetHeight
) {
1561 // console.log(e.id + " is visible " + e.offsetTop + "." +
1562 // (e.offsetTop + e.offsetHeight) + " vs " + ctr.scrollTop + "." +
1563 // (ctr.scrollTop + ctr.offsetHeight));
1565 ids
.push(e
.id
.replace("RROW-", ""));
1567 } else if (e
.offsetHeight
> ctr
.offsetHeight
&&
1568 e
.offsetTop
+ e
.offsetHeight
>= ctr
.scrollTop
&&
1569 e
.offsetTop
+ e
.offsetHeight
<= ctr
.scrollTop
+ ctr
.offsetHeight
) {
1571 ids
.push(e
.id
.replace("RROW-", ""));
1575 // method 2: article bottom is visible and is in upper 1/2 of the viewport
1577 /* if (e.offsetTop + e.offsetHeight >= ctr.scrollTop &&
1578 e.offsetTop + e.offsetHeight <= ctr.scrollTop + ctr.offsetHeight/2) {
1580 ids.push(e.id.replace("RROW-", ""));
1589 console
.log("cdmWatchdog, ids= " + ids
.toString());
1591 if (ids
.length
> 0) {
1593 for (var i
= 0; i
< ids
.length
; i
++) {
1594 var e
= $("RROW-" + ids
[i
]);
1596 e
.className
= e
.className
.replace("Unread", "");
1600 var query
= "?op=rpc&subop=catchupSelected" +
1601 "&cmode=0" + "&ids=" + param_escape(ids
.toString());
1603 new Ajax
.Request("backend.php", {
1605 onComplete: function(transport
) {
1606 handle_rpc_reply(transport
);
1611 _cdm_wd_timeout
= window
.setTimeout("cdmWatchdog()", 4000);
1614 exception_error("cdmWatchdog", e
);
1620 function cache_inject(id
, article
, param
) {
1623 if (!cache_check_param(id
, param
)) {
1624 //console.log("cache_article: miss: " + id + " [p=" + param + "]");
1626 var date
= new Date();
1627 var ts
= Math
.round(date
.getTime() / 1000);
1631 db
.execute("INSERT INTO cache (id, article, param, added) VALUES (?, ?, ?, ?)",
1632 [id
, article
, param
, ts
]);
1637 cache_obj
["id"] = id
;
1638 cache_obj
["data"] = article
;
1639 cache_obj
["param"] = param
;
1641 if (param
) id
= id
+ ":" + param
;
1643 cache_added
["TS:" + id
] = ts
;
1645 if (has_local_storage())
1646 localStorage
.setItem(id
, JSON
.stringify(cache_obj
));
1648 article_cache
.push(cache_obj
);
1652 //console.log("cache_article: hit: " + id + " [p=" + param + "]");
1655 exception_error("cache_inject", e
);
1659 function cache_find(id
) {
1662 var rs
= db
.execute("SELECT article FROM cache WHERE id = ?", [id
]);
1665 if (rs
.isValidRow()) {
1666 var a
= rs
.field(0);
1675 if (has_local_storage()) {
1676 var cache_obj
= localStorage
.getItem(id
);
1679 cache_obj
= JSON
.parse(cache_obj
);
1682 return cache_obj
['data'];
1686 for (var i
= 0; i
< article_cache
.length
; i
++) {
1687 if (article_cache
[i
]["id"] == id
) {
1688 return article_cache
[i
]["data"];
1696 function cache_find_param(id
, param
) {
1699 var rs
= db
.execute("SELECT article FROM cache WHERE id = ? AND param = ?",
1703 if (rs
.isValidRow()) {
1713 if (has_local_storage()) {
1715 if (param
) id
= id
+ ":" + param
;
1717 var cache_obj
= localStorage
.getItem(id
);
1720 cache_obj
= JSON
.parse(cache_obj
);
1723 return cache_obj
['data'];
1727 for (var i
= 0; i
< article_cache
.length
; i
++) {
1728 if (article_cache
[i
]["id"] == id
&& article_cache
[i
]["param"] == param
) {
1729 return article_cache
[i
]["data"];
1737 function cache_check(id
) {
1740 var rs
= db
.execute("SELECT COUNT(*) AS c FROM cache WHERE id = ?",
1744 if (rs
.isValidRow()) {
1745 a
= rs
.field(0) != "0";
1753 if (has_local_storage()) {
1754 if (localStorage
.getItem(id
))
1757 for (var i
= 0; i
< article_cache
.length
; i
++) {
1758 if (article_cache
[i
]["id"] == id
) {
1767 function cache_check_param(id
, param
) {
1770 var rs
= db
.execute("SELECT COUNT(*) AS c FROM cache WHERE id = ? AND param = ?",
1774 if (rs
.isValidRow()) {
1775 a
= rs
.field(0) != "0";
1784 if (has_local_storage()) {
1786 if (param
) id
= id
+ ":" + param
;
1788 if (localStorage
.getItem(id
))
1792 for (var i
= 0; i
< article_cache
.length
; i
++) {
1793 if (article_cache
[i
]["id"] == id
&& article_cache
[i
]["param"] == param
) {
1802 function cache_expire() {
1804 var date
= new Date();
1805 var ts
= Math
.round(date
.getTime() / 1000);
1807 db
.execute("DELETE FROM cache WHERE added < ? - 1800 AND id LIKE 'FEEDLIST'", [ts
]);
1808 db
.execute("DELETE FROM cache WHERE added < ? - 600 AND (id LIKE 'F:%' OR id LIKE 'C:%')", [ts
]);
1809 db
.execute("DELETE FROM cache WHERE added < ? - 86400", [ts
]);
1813 if (has_local_storage()) {
1815 var date
= new Date();
1816 var timestamp
= Math
.round(date
.getTime() / 1000);
1818 for (var i
= 0; i
< localStorage
.length
; i
++) {
1820 var id
= localStorage
.key(i
);
1822 if (timestamp
- cache_added
["TS:" + id
] > 180) {
1823 localStorage
.removeItem(id
);
1828 while (article_cache
.length
> 25) {
1829 article_cache
.shift();
1835 function cache_flush() {
1837 db
.execute("DELETE FROM cache");
1838 } else if (has_local_storage()) {
1839 localStorage
.clear();
1841 article_cache
= new Array();
1845 function cache_invalidate(id
) {
1849 rs
= db
.execute("DELETE FROM cache WHERE id = ?", [id
]);
1850 return rs
.rowsAffected
!= 0;
1853 if (has_local_storage()) {
1857 for (var i
= 0; i
< localStorage
.length
; i
++) {
1858 var key
= localStorage
.key(i
);
1860 // console.warn("cache_invalidate: " + key_id + " cmp " + id);
1862 if (key
== id
|| key
.indexOf(id
+ ":") == 0) {
1863 localStorage
.removeItem(key
);
1874 while (i
< article_cache
.length
) {
1875 if (article_cache
[i
]["id"] == id
) {
1876 //console.log("cache_invalidate: removed id " + id);
1877 article_cache
.splice(i
, 1);
1885 //console.log("cache_invalidate: id not found: " + id);
1888 exception_error("cache_invalidate", e
);
1892 function getActiveArticleId() {
1893 return active_post_id
;
1896 function preloadBatchedArticles() {
1899 var query
= "?op=rpc&subop=getArticles&ids=" +
1900 preload_id_batch
.toString();
1902 new Ajax
.Request("backend.php", {
1904 onComplete: function(transport
) {
1906 preload_id_batch
= [];
1908 var articles
= transport
.responseXML
.getElementsByTagName("article");
1910 for (var i
= 0; i
< articles
.length
; i
++) {
1911 var id
= articles
[i
].getAttribute("id");
1912 if (!cache_check(id
)) {
1913 cache_inject(id
, articles
[i
].firstChild
.nodeValue
);
1914 console
.log("preloaded article: " + id
);
1920 exception_error("preloadBatchedArticles", e
);
1924 function preloadArticleUnderPointer(id
) {
1926 if (getInitParam("bw_limit") == "1") return;
1928 if (post_under_pointer
== id
&& !cache_check(id
)) {
1930 console
.log("trying to preload article " + id
);
1932 var neighbor_ids
= getRelativePostIds(id
, 1);
1934 /* only request uncached articles */
1936 if (preload_id_batch
.indexOf(id
) == -1) {
1937 for (var i
= 0; i
< neighbor_ids
.length
; i
++) {
1938 if (!cache_check(neighbor_ids
[i
])) {
1939 preload_id_batch
.push(neighbor_ids
[i
]);
1944 if (preload_id_batch
.indexOf(id
) == -1)
1945 preload_id_batch
.push(id
);
1947 //console.log("preload ids batch: " + preload_id_batch.toString());
1949 window
.clearTimeout(preload_timeout_id
);
1950 preload_batch_timeout_id
= window
.setTimeout('preloadBatchedArticles()', 1000);
1954 exception_error("preloadArticleUnderPointer", e
);
1958 function postMouseIn(id
) {
1960 if (post_under_pointer
!= id
) {
1961 post_under_pointer
= id
;
1963 window
.setTimeout("preloadArticleUnderPointer(" + id
+ ")", 250);
1968 exception_error("postMouseIn", e
);
1972 function postMouseOut(id
) {
1974 post_under_pointer
= false;
1976 exception_error("postMouseOut", e
);
1980 function headlines_scroll_handler() {
1983 var e
= $("headlinesInnerContainer");
1985 var toolbar_form
= document
.forms
["main_toolbar_form"];
1987 // console.log((e.scrollTop + e.offsetHeight) + " vs " + e.scrollHeight + " dis? " +
1988 // _infscroll_disable);
1990 if (e
.scrollTop
+ e
.offsetHeight
> e
.scrollHeight
- 100) {
1991 if (!_infscroll_disable
) {
1997 exception_error("headlines_scroll_handler", e
);
2001 function catchupRelativeToArticle(below
) {
2006 if (!getActiveArticleId()) {
2007 alert(__("No article is selected."));
2013 if ($("headlinesList")) {
2014 visible_ids
= getVisibleHeadlineIds();
2016 visible_ids
= cdmGetVisibleArticles();
2019 var ids_to_mark
= new Array();
2022 for (var i
= 0; i
< visible_ids
.length
; i
++) {
2023 if (visible_ids
[i
] != getActiveArticleId()) {
2024 var e
= $("RROW-" + visible_ids
[i
]);
2026 if (e
&& e
.className
.match("Unread")) {
2027 ids_to_mark
.push(visible_ids
[i
]);
2034 for (var i
= visible_ids
.length
-1; i
>= 0; i
--) {
2035 if (visible_ids
[i
] != getActiveArticleId()) {
2036 var e
= $("RROW-" + visible_ids
[i
]);
2038 if (e
&& e
.className
.match("Unread")) {
2039 ids_to_mark
.push(visible_ids
[i
]);
2047 if (ids_to_mark
.length
== 0) {
2048 alert(__("No articles found to mark"));
2050 var msg
= __("Mark %d article(s) as read?").replace("%d", ids_to_mark
.length
);
2052 if (getInitParam("confirm_feed_catchup") != 1 || confirm(msg
)) {
2054 for (var i
= 0; i
< ids_to_mark
.length
; i
++) {
2055 var e
= $("RROW-" + ids_to_mark
[i
]);
2056 e
.className
= e
.className
.replace("Unread", "");
2059 var query
= "?op=rpc&subop=catchupSelected" +
2060 "&cmode=0" + "&ids=" + param_escape(ids_to_mark
.toString());
2062 new Ajax
.Request("backend.php", {
2064 onComplete: function(transport
) {
2065 catchup_callback2(transport
);
2072 exception_error("catchupRelativeToArticle", e
);
2076 function cdmExpandArticle(id
) {
2079 var elem
= $("CICD-" + active_post_id
);
2081 if (id
== active_post_id
&& Element
.visible(elem
))
2084 cdmSelectArticles("none");
2086 var old_offset
= $("RROW-" + id
).offsetTop
;
2088 if (active_post_id
&& elem
) {
2090 Element
.show("CEXC-" + active_post_id
);
2093 active_post_id
= id
;
2095 elem
= $("CICD-" + id
);
2097 if (!Element
.visible(elem
)) {
2099 Element
.hide("CEXC-" + id
);
2102 var new_offset
= $("RROW-" + id
).offsetTop
;
2104 $("headlinesInnerContainer").scrollTop
+= (new_offset
-old_offset
);
2106 if ($("RROW-" + id
).offsetTop
!= old_offset
)
2107 $("headlinesInnerContainer").scrollTop
= new_offset
;
2109 toggleUnread(id
, 0, true);
2113 exception_error("cdmExpandArticle", e
);
2119 function fixHeadlinesOrder(ids
) {
2121 for (var i
= 0; i
< ids
.length
; i
++) {
2122 var e
= $("RROW-" + ids
[i
]);
2126 e
.className
= e
.className
.replace("even", "odd");
2128 e
.className
= e
.className
.replace("odd", "even");
2133 exception_error("fixHeadlinesOrder", e
);
2137 function hideReadHeadlines() {
2141 var vis_ids
= new Array();
2143 if ($("headlinesList")) {
2144 ids
= getVisibleHeadlineIds();
2146 ids
= cdmGetVisibleArticles();
2149 var read_headlines_visible
= true;
2151 for (var i
= 0; i
< ids
.length
; i
++) {
2152 var row
= $("RROW-" + ids
[i
]);
2154 if (row
&& row
.className
) {
2155 if (read_headlines_visible
) {
2156 if (row
.className
.match("Unread") || row
.className
.match("Selected")) {
2158 vis_ids
.push(ids
[i
]);
2160 //Effect.Fade(row, {duration : 0.3});
2165 vis_ids
.push(ids
[i
]);
2170 fixHeadlinesOrder(vis_ids
);
2172 read_headlines_visible
= !read_headlines_visible
;
2175 exception_error("hideReadHeadlines", e
);
2179 function invertHeadlineSelection() {
2181 var rows
= new Array();
2185 r
= document
.getElementsByTagName("TR");
2187 r
= document
.getElementsByTagName("DIV");
2190 for (var i
= 0; i
< r
.length
; i
++) {
2191 if (r
[i
].id
&& r
[i
].id
.match("RROW-")) {
2196 for (var i
= 0; i
< rows
.length
; i
++) {
2197 var nc
= rows
[i
].className
;
2198 var id
= rows
[i
].id
.replace("RROW-", "");
2199 var cb
= $("RCHK-" + id
);
2201 if (!rows
[i
].className
.match("Selected")) {
2202 nc
= nc
+ "Selected";
2205 nc
= nc
.replace("Selected", "");
2209 rows
[i
].className
= nc
;
2214 exception_error("invertHeadlineSelection", e
);
2218 function getArticleUnderPointer() {
2219 return post_under_pointer
;
2222 function zoomToArticle(id
) {
2224 var w
= window
.open("backend.php?op=view&mode=zoom&id=" + param_escape(id
),
2226 "status=0,toolbar=0,location=0,width=450,height=300,scrollbars=1,menubar=0");
2229 exception_error("zoomToArticle", e
);
2233 function scrollArticle(offset
) {
2236 var ci
= $("content-insert");
2238 ci
.scrollTop
+= offset
;
2241 var hi
= $("headlinesInnerContainer");
2243 hi
.scrollTop
+= offset
;
2248 exception_error("scrollArticle", e
);
2252 function show_labels_in_headlines(transport
) {
2254 if (transport
.responseXML
) {
2255 var info
= transport
.responseXML
.getElementsByTagName("info-for-headlines")[0];
2257 var elems
= info
.getElementsByTagName("entry");
2259 for (var l
= 0; l
< elems
.length
; l
++) {
2260 var e_id
= elems
[l
].getAttribute("id");
2264 var ctr
= $("HLLCTR-" + e_id
);
2267 ctr
.innerHTML
= elems
[l
].firstChild
.nodeValue
;
2275 exception_error("show_labels_in_headlines", e
);
2280 function toggleHeadlineActions() {
2282 var e
= $("headlineActionsBody");
2283 var p
= $("headlineActionsDrop");
2285 if (!Element
.visible(e
)) {
2292 e
.style
.left
= (p
.offsetLeft
+ 1) + "px";
2293 e
.style
.top
= (p
.offsetTop
+ p
.offsetHeight
+ 2) + "px";
2296 exception_error("toggleHeadlineActions", e
);
2300 function publishWithNote(id
, def_note
) {
2302 if (!def_note
) def_note
= '';
2304 var note
= prompt(__("Please enter a note for this article:"), def_note
);
2306 if (note
!= undefined) {
2307 togglePub(id
, false, false, note
);
2311 exception_error("publishWithNote", e
);
2315 function emailArticle(id
) {
2318 var ids
= getSelectedArticleIds2();
2320 if (ids
.length
== 0) {
2321 alert(__("No articles are selected."));
2325 id
= ids
.toString();
2328 displayDlg('emailArticle', id
,
2330 document
.forms
['article_email_form'].destination
.focus();
2332 new Ajax
.Autocompleter('destination', 'destination_choices',
2333 "backend.php?op=rpc&subop=completeEmails",
2334 { tokens
: '', paramName
: "search" });
2339 exception_error("emailArticle", e
);
2343 function emailArticleDo() {
2345 var f
= document
.forms
['article_email_form'];
2347 if (f
.destination
.value
== "") {
2348 alert("Please fill in the destination email.");
2352 if (f
.subject
.value
== "") {
2353 alert("Please fill in the subject.");
2357 var query
= Form
.serialize("article_email_form");
2359 // console.log(query);
2361 new Ajax
.Request("backend.php", {
2363 onComplete: function(transport
) {
2366 var error
= transport
.responseXML
.getElementsByTagName('error')[0];
2369 alert(__('Error sending email:') + ' ' + error
.firstChild
.nodeValue
);
2371 notify_info('Your message has been sent.');
2376 exception_error("sendEmailDo", e
);
2382 exception_error("emailArticleDo", e
);
2386 function cdmDismissArticle(id
) {
2388 var elem
= $("RROW-" + id
);
2390 toggleUnread(id
, 0, true);
2392 new Effect
.Fade(elem
, {duration
: 0.5});
2395 exception_error("cdmDismissArticle", e
);
2399 function cdmDismissSelectedArticles() {
2402 var ids
= getSelectedArticleIds2();
2404 for (var i
= 0; i
< ids
.length
; i
++) {
2405 var elem
= $("RROW-" + ids
[i
]);
2406 new Effect
.Fade(elem
, {duration
: 0.5});
2410 selectionToggleUnread(false);
2413 exception_error("cdmDismissArticle", e
);