1 var article_cache
= new Array();
3 var _active_article_id
= 0;
5 var vgroup_last_feed
= false;
6 var post_under_pointer
= false;
8 var last_requested_article
= false;
10 var catchup_id_batch
= [];
11 var catchup_timeout_id
= false;
13 var cids_requested
= [];
14 var loaded_article_ids
= [];
15 var _last_headlines_update
= 0;
17 var has_storage
= 'sessionStorage' in window
&& window
['sessionStorage'] !== null;
19 function headlines_callback2(transport
, offset
, background
, infscroll_req
) {
21 handle_rpc_json(transport
);
23 console
.log("headlines_callback2 [offset=" + offset
+ "] B:" + background
+ " I:" + infscroll_req
);
31 reply
= JSON
.parse(transport
.responseText
);
38 is_cat
= reply
['headlines']['is_cat'];
39 feed_id
= reply
['headlines']['id'];
42 var content
= reply
['headlines']['content'];
44 content
= content
+ "<div id='headlines-spacer'></div>";
48 if (feed_id
!= getActiveFeedId() || is_cat
!= activeFeedIsCat())
51 /* dijit.getEnclosingWidget(
52 document.forms["main_toolbar_form"].update).attr('disabled',
53 is_cat || feed_id <= 0); */
56 if (infscroll_req
== false) {
57 $("headlines-frame").scrollTop
= 0;
59 $("floatingTitle").style
.visibility
= "hidden";
60 $("floatingTitle").setAttribute("rowid", 0);
61 $("floatingTitle").innerHTML
= "";
65 $("headlines-frame").removeClassName("cdm");
66 $("headlines-frame").removeClassName("normal");
68 $("headlines-frame").addClassName(isCdmMode() ? "cdm" : "normal");
70 var headlines_count
= reply
['headlines-info']['count'];
72 vgroup_last_feed
= reply
['headlines-info']['vgroup_last_feed'];
74 if (parseInt(headlines_count
) < 30) {
75 _infscroll_disable
= 1;
77 _infscroll_disable
= 0;
80 var counters
= reply
['counters'];
81 var articles
= reply
['articles'];
82 //var runtime_info = reply['runtime-info'];
84 if (infscroll_req
== false) {
85 loaded_article_ids
= [];
87 dijit
.byId("headlines-frame").attr('content',
88 reply
['headlines']['content']);
90 //dijit.byId("headlines-toolbar").attr('content',
91 // reply['headlines']['toolbar']);
93 dojo
.html
.set($("headlines-toolbar"),
94 reply
['headlines']['toolbar'],
95 {parseContent
: true});
97 $$("#headlines-frame > div[id*=RROW]").each(function(row
) {
98 if (loaded_article_ids
.indexOf(row
.id
) != -1) {
99 row
.parentNode
.removeChild(row
);
101 loaded_article_ids
.push(row
.id
);
105 var hsp
= $("headlines-spacer");
106 if (!hsp
) hsp
= new Element("DIV", {"id": "headlines-spacer"});
107 dijit
.byId('headlines-frame').domNode
.appendChild(hsp
);
111 if (_infscroll_disable
)
112 hsp
.innerHTML
= "<a href='#' onclick='openNextUnreadFeed()'>" +
113 __("Click to open next unread feed.") + "</a>";
116 $("feed_title").innerHTML
+= "<span id='cancel_search'>" +
117 " (<a href='#' onclick='cancelSearch()'>" + __("Cancel search") + "</a>)" +
123 if (headlines_count
> 0 && feed_id
== getActiveFeedId() && is_cat
== activeFeedIsCat()) {
124 console
.log("adding some more headlines: " + headlines_count
);
126 var c
= dijit
.byId("headlines-frame");
127 var ids
= getSelectedArticleIds2();
130 $("headlines-tmp").innerHTML
= reply
['headlines']['content'];
132 var hsp
= $("headlines-spacer");
135 c
.domNode
.removeChild(hsp
);
137 $$("#headlines-tmp > div").each(function(row
) {
138 if (row
.className
== 'cdmFeedTitle') {
139 row
.style
.display
= 'none';
140 c
.domNode
.appendChild(row
);
142 } else if (loaded_article_ids
.indexOf(row
.id
) == -1) {
143 row
.style
.display
= 'none';
144 c
.domNode
.appendChild(row
);
146 loaded_article_ids
.push(row
.id
);
148 row
.parentNode
.removeChild(row
);
152 if (!hsp
) hsp
= new Element("DIV", {"id": "headlines-spacer"});
154 // if (getInitParam("cdm_auto_catchup") == 1) {
155 c
.domNode
.appendChild(hsp
);
158 console
.log("added " + new_elems
.size() + " headlines");
160 if (new_elems
.size() == 0)
161 _infscroll_disable
= true;
163 console
.log("restore selected ids: " + ids
);
165 for (var i
= 0; i
< ids
.length
; i
++) {
166 markHeadline(ids
[i
]);
171 new_elems
.each(function(child
) {
172 dojo
.parser
.parse(child
);
174 if (!Element
.visible(child
))
175 new Effect
.Appear(child
, { duration
: 0.5 });
178 if (_infscroll_disable
) {
179 hsp
.innerHTML
= "<a href='#' onclick='openNextUnreadFeed()'>" +
180 __("Click to open next unread feed.") + "</a>";
184 console
.log("no new headlines received");
186 var top_id_changed
= reply
['headlines']['top_id_changed'];
187 console
.log("top id changed:" + top_id_changed
);
189 var hsp
= $("headlines-spacer");
192 if (top_id_changed
) {
193 hsp
.innerHTML
= "<a href='#' onclick='viewCurrentFeed()'>" +
194 __("New articles found, reload feed to continue.") + "</a>";
196 hsp
.innerHTML
= "<a href='#' onclick='openNextUnreadFeed()'>" +
197 __("Click to open next unread feed.") + "</a>";
206 for (var i
= 0; i
< articles
.length
; i
++) {
207 var a_id
= articles
[i
]['id'];
208 cache_set("article:" + a_id
, articles
[i
]['content']);
211 console
.log("no cached articles received");
215 parse_counters(counters
);
217 request_counters(true);
220 console
.error("Invalid object received: " + transport
.responseText
);
221 dijit
.byId("headlines-frame").attr('content', "<div class='whiteBox'>" +
222 __('Could not update headlines (invalid object received - see error console for details)') +
226 _infscroll_request_sent
= 0;
227 _last_headlines_update
= new Date().getTime();
229 unpackVisibleHeadlines();
231 // if we have some more space in the buffer, why not try to fill it
233 if (!_infscroll_disable
&& $("headlines-spacer") &&
234 $("headlines-spacer").offsetTop
< $("headlines-frame").offsetHeight
) {
236 window
.setTimeout(function() {
244 exception_error("headlines_callback2", e
, transport
);
248 function render_article(article
) {
250 dijit
.byId("headlines-wrap-inner").addChild(
251 dijit
.byId("content-insert"));
253 var c
= dijit
.byId("content-insert");
256 c
.domNode
.scrollTop
= 0;
259 PluginHost
.run(PluginHost
.HOOK_ARTICLE_RENDERED
, article
);
261 c
.attr('content', article
);
263 correctHeadlinesOffset(getActiveArticleId());
270 exception_error("render_article", e
);
274 function showArticleInHeadlines(id
, noexpand
) {
277 selectArticles("none");
279 var crow
= $("RROW-" + id
);
283 var article_is_unread
= crow
.hasClassName("Unread");
286 crow
.removeClassName("Unread");
287 crow
.addClassName("active");
289 selectArticles('none');
291 var view_mode
= false;
294 view_mode
= document
.forms
['main_toolbar_form'].view_mode
;
295 view_mode
= view_mode
[view_mode
.selectedIndex
].value
;
302 if (article_is_unread
&& !noexpand
)
303 _force_scheduled_update
= true;
306 exception_error("showArticleInHeadlines", e
);
310 function article_callback2(transport
, id
) {
312 console
.log("article_callback2 " + id
);
314 handle_rpc_json(transport
);
319 reply
= JSON
.parse(transport
.responseText
);
326 reply
.each(function(article
) {
327 if (getActiveArticleId() == article
['id']) {
328 render_article(article
['content']);
330 cids_requested
.remove(article
['id']);
332 cache_set("article:" + article
['id'], article
['content']);
335 // if (id != last_requested_article) {
336 // console.log("requested article id is out of sequence, aborting");
341 console
.error("Invalid object received: " + transport
.responseText
);
343 render_article("<div class='whiteBox'>" +
344 __('Could not display article (invalid object received - see error console for details)') + "</div>");
347 var unread_in_buffer
= $$("#headlines-frame > div[id*=RROW][class*=Unread]").length
348 request_counters(unread_in_buffer
== 0);
350 //headlines_scroll_handler($("headlines-frame"));
353 if (!_infscroll_disable &&
354 $$("#headlines-frame > div[id*=RROW]").last().hasClassName("Selected")) {
364 exception_error("article_callback2", e
, transport
);
368 function view(id
, activefeed
, noexpand
) {
370 var oldrow
= $("RROW-" + getActiveArticleId());
371 if (oldrow
) oldrow
.removeClassName("active");
373 var crow
= $("RROW-" + id
);
377 setActiveArticleId(id
);
378 showArticleInHeadlines(id
, noexpand
);
382 console
.log("loading article: " + id
);
384 var cached_article
= cache_get("article:" + id
);
386 console
.log("cache check result: " + (cached_article
!= false));
388 var query
= "?op=article&method=view&id=" + param_escape(id
);
390 var neighbor_ids
= getRelativePostIds(id
);
392 /* only request uncached articles */
394 var cids_to_request
= [];
396 for (var i
= 0; i
< neighbor_ids
.length
; i
++) {
397 if (cids_requested
.indexOf(neighbor_ids
[i
]) == -1)
398 if (!cache_get("article:" + neighbor_ids
[i
])) {
399 cids_to_request
.push(neighbor_ids
[i
]);
400 cids_requested
.push(neighbor_ids
[i
]);
404 console
.log("additional ids: " + cids_to_request
.toString());
406 query
= query
+ "&cids=" + cids_to_request
.toString();
408 var article_is_unread
= crow
.hasClassName("Unread");
410 setActiveArticleId(id
);
411 showArticleInHeadlines(id
);
413 if (cached_article
&& article_is_unread
) {
415 query
= query
+ "&mode=prefetch";
417 render_article(cached_article
);
419 } else if (cached_article
) {
421 query
= query
+ "&mode=prefetch_old";
422 render_article(cached_article
);
424 // if we don't need to request any relative ids, we might as well skip
425 // the server roundtrip altogether
426 if (cids_to_request
.length
== 0) {
429 if (!_infscroll_disable &&
430 $$("#headlines-frame > div[id*=RROW]").last().hasClassName("Selected")) {
438 //headlines_scroll_handler($("headlines-frame"));
444 last_requested_article
= id
;
448 if (article_is_unread
) {
449 decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
452 new Ajax
.Request("backend.php", {
454 onComplete: function(transport
) {
455 article_callback2(transport
, id
);
461 exception_error("view", e
);
465 function toggleMark(id
, client_only
) {
467 var query
= "?op=rpc&id=" + id
+ "&method=mark";
469 var row
= $("RROW-" + id
);
474 var row_imgs
= row
.getElementsByClassName("markedPic");
476 for (var i
= 0; i
< row_imgs
.length
; i
++)
477 imgs
.push(row_imgs
[i
]);
479 var ft
= $("floatingTitle");
481 if (ft
&& ft
.getAttribute("rowid") == "RROW-" + id
) {
482 var fte
= ft
.getElementsByClassName("markedPic");
484 for (var i
= 0; i
< fte
.length
; i
++)
488 for (i
= 0; i
< imgs
.length
; i
++) {
491 if (!row
.hasClassName("marked")) {
492 img
.src
= img
.src
.replace("mark_unset", "mark_set");
493 img
.alt
= __("Unstar article");
494 query
= query
+ "&mark=1";
496 img
.src
= img
.src
.replace("mark_set", "mark_unset");
497 img
.alt
= __("Star article");
498 query
= query
+ "&mark=0";
502 row
.toggleClassName("marked");
505 new Ajax
.Request("backend.php", {
507 onComplete: function(transport
) {
508 handle_rpc_json(transport
);
513 exception_error("toggleMark", e
);
517 function togglePub(id
, client_only
, no_effects
, note
) {
519 var query
= "?op=rpc&id=" + id
+ "&method=publ";
521 if (note
!= undefined) {
522 query
= query
+ "¬e=" + param_escape(note
);
524 query
= query
+ "¬e=undefined";
527 var row
= $("RROW-" + id
);
532 var row_imgs
= row
.getElementsByClassName("pubPic");
534 for (var i
= 0; i
< row_imgs
.length
; i
++)
535 imgs
.push(row_imgs
[i
]);
537 var ft
= $("floatingTitle");
539 if (ft
&& ft
.getAttribute("rowid") == "RROW-" + id
) {
540 var fte
= ft
.getElementsByClassName("pubPic");
542 for (var i
= 0; i
< fte
.length
; i
++)
546 for (i
= 0; i
< imgs
.length
; i
++) {
549 if (!row
.hasClassName("published") || note
!= undefined) {
550 img
.src
= img
.src
.replace("pub_unset", "pub_set");
551 img
.alt
= __("Unpublish article");
552 query
= query
+ "&pub=1";
554 img
.src
= img
.src
.replace("pub_set", "pub_unset");
555 img
.alt
= __("Publish article");
556 query
= query
+ "&pub=0";
560 if (note
!= undefined)
561 row
.addClassName("published");
563 row
.toggleClassName("published");
566 new Ajax
.Request("backend.php", {
568 onComplete: function(transport
) {
569 handle_rpc_json(transport
);
574 exception_error("togglePub", e
);
578 function moveToPost(mode
, noscroll
, noexpand
) {
582 var rows
= getVisibleArticleIds();
587 if (!$('RROW-' + getActiveArticleId())) {
588 setActiveArticleId(0);
591 if (!getActiveArticleId()) {
593 prev_id
= rows
[rows
.length
-1]
595 for (var i
= 0; i
< rows
.length
; i
++) {
596 if (rows
[i
] == getActiveArticleId()) {
598 // Account for adjacent identical article ids.
599 if (i
> 0) prev_id
= rows
[i
-1];
601 for (var j
= i
+1; j
< rows
.length
; j
++) {
602 if (rows
[j
] != getActiveArticleId()) {
612 if (mode
== "next") {
613 if (next_id
|| getActiveArticleId()) {
616 var article
= $("RROW-" + getActiveArticleId());
617 var ctr
= $("headlines-frame");
619 if (!noscroll
&& article
&& article
.offsetTop
+ article
.offsetHeight
>
620 ctr
.scrollTop
+ ctr
.offsetHeight
) {
622 scrollArticle(ctr
.offsetHeight
/4);
624 } else if (next_id
) {
625 cdmExpandArticle(next_id
, noexpand
);
626 cdmScrollToArticleId(next_id
, true);
629 } else if (next_id
) {
630 correctHeadlinesOffset(next_id
);
631 view(next_id
, getActiveFeedId(), noexpand
);
636 if (mode
== "prev") {
637 if (prev_id
|| getActiveArticleId()) {
640 var article
= $("RROW-" + getActiveArticleId());
641 var prev_article
= $("RROW-" + prev_id
);
642 var ctr
= $("headlines-frame");
644 if (!getInitParam("cdm_expanded")) {
646 if (!noscroll
&& article
&& article
.offsetTop
< ctr
.scrollTop
) {
647 scrollArticle(-ctr
.offsetHeight
/4);
649 cdmExpandArticle(prev_id
, noexpand
);
650 cdmScrollToArticleId(prev_id
, true);
654 if (!noscroll
&& article
&& article
.offsetTop
< ctr
.scrollTop
) {
655 scrollArticle(-ctr
.offsetHeight
/3);
656 } else if (!noscroll
&& prev_article
&&
657 prev_article
.offsetTop
< ctr
.scrollTop
) {
658 cdmExpandArticle(prev_id
, noexpand
);
659 scrollArticle(-ctr
.offsetHeight
/4);
660 } else if (prev_id
) {
661 cdmExpandArticle(prev_id
, noexpand
);
662 cdmScrollToArticleId(prev_id
, noscroll
);
666 } else if (prev_id
) {
667 correctHeadlinesOffset(prev_id
);
668 view(prev_id
, getActiveFeedId(), noexpand
);
674 exception_error("moveToPost", e
);
678 function toggleSelected(id
, force_on
) {
680 var row
= $("RROW-" + id
);
683 var cb
= dijit
.getEnclosingWidget(
684 row
.getElementsByClassName("rchk")[0]);
686 if (row
.hasClassName('Selected') && !force_on
) {
687 row
.removeClassName('Selected');
688 if (cb
) cb
.attr("checked", false);
690 row
.addClassName('Selected');
691 if (cb
) cb
.attr("checked", true);
695 updateSelectedPrompt();
697 exception_error("toggleSelected", e
);
701 function updateSelectedPrompt() {
703 var count
= getSelectedArticleIds2().size();
704 var elem
= $("selected_prompt");
707 elem
.innerHTML
= ngettext("%d article selected",
708 "%d articles selected", count
).replace("%d", count
);
717 exception_error("updateSelectedPrompt", e
);
721 function toggleUnread_afh(effect
) {
724 var elem
= effect
.element
;
725 elem
.style
.backgroundColor
= "";
728 exception_error("toggleUnread_afh", e
);
732 function toggleUnread(id
, cmode
, effect
) {
735 var row
= $("RROW-" + id
);
737 if (cmode
== undefined || cmode
== 2) {
738 if (row
.hasClassName("Unread")) {
739 row
.removeClassName("Unread");
742 row
.addClassName("Unread");
745 } else if (cmode
== 0) {
747 row
.removeClassName("Unread");
749 } else if (cmode
== 1) {
750 row
.addClassName("Unread");
753 if (cmode
== undefined) cmode
= 2;
755 var query
= "?op=rpc&method=catchupSelected" +
756 "&cmode=" + param_escape(cmode
) + "&ids=" + param_escape(id
);
758 // notify_progress("Loading, please wait...");
760 new Ajax
.Request("backend.php", {
762 onComplete: function(transport
) {
763 handle_rpc_json(transport
);
769 exception_error("toggleUnread", e
);
773 function selectionRemoveLabel(id
, ids
) {
776 if (!ids
) ids
= getSelectedArticleIds2();
778 if (ids
.length
== 0) {
779 alert(__("No articles are selected."));
783 var query
= "?op=article&method=removeFromLabel&ids=" +
784 param_escape(ids
.toString()) + "&lid=" + param_escape(id
);
788 new Ajax
.Request("backend.php", {
790 onComplete: function(transport
) {
791 handle_rpc_json(transport
);
792 show_labels_in_headlines(transport
);
796 exception_error("selectionAssignLabel", e
);
801 function selectionAssignLabel(id
, ids
) {
804 if (!ids
) ids
= getSelectedArticleIds2();
806 if (ids
.length
== 0) {
807 alert(__("No articles are selected."));
811 var query
= "?op=article&method=assignToLabel&ids=" +
812 param_escape(ids
.toString()) + "&lid=" + param_escape(id
);
816 new Ajax
.Request("backend.php", {
818 onComplete: function(transport
) {
819 handle_rpc_json(transport
);
820 show_labels_in_headlines(transport
);
824 exception_error("selectionAssignLabel", e
);
829 function selectionToggleUnread(set_state
, callback
, no_error
, ids
) {
831 var rows
= ids
? ids
: getSelectedArticleIds2();
833 if (rows
.length
== 0 && !no_error
) {
834 alert(__("No articles are selected."));
838 for (var i
= 0; i
< rows
.length
; i
++) {
839 var row
= $("RROW-" + rows
[i
]);
841 if (set_state
== undefined) {
842 if (row
.hasClassName("Unread")) {
843 row
.removeClassName("Unread");
845 row
.addClassName("Unread");
849 if (set_state
== false) {
850 row
.removeClassName("Unread");
853 if (set_state
== true) {
854 row
.addClassName("Unread");
859 updateFloatingTitle(true);
861 if (rows
.length
> 0) {
865 if (set_state
== undefined) {
867 } else if (set_state
== true) {
869 } else if (set_state
== false) {
873 var query
= "?op=rpc&method=catchupSelected" +
874 "&cmode=" + cmode
+ "&ids=" + param_escape(rows
.toString());
876 notify_progress("Loading, please wait...");
878 new Ajax
.Request("backend.php", {
880 onComplete: function(transport
) {
881 handle_rpc_json(transport
);
882 if (callback
) callback(transport
);
888 exception_error("selectionToggleUnread", e
);
893 function selectionToggleMarked(sel_state
, callback
, no_error
, ids
) {
896 var rows
= ids
? ids
: getSelectedArticleIds2();
898 if (rows
.length
== 0 && !no_error
) {
899 alert(__("No articles are selected."));
903 for (var i
= 0; i
< rows
.length
; i
++) {
904 toggleMark(rows
[i
], true, true);
907 if (rows
.length
> 0) {
909 var query
= "?op=rpc&method=markSelected&ids=" +
910 param_escape(rows
.toString()) + "&cmode=2";
912 new Ajax
.Request("backend.php", {
914 onComplete: function(transport
) {
915 handle_rpc_json(transport
);
916 if (callback
) callback(transport
);
922 exception_error("selectionToggleMarked", e
);
927 function selectionTogglePublished(sel_state
, callback
, no_error
, ids
) {
930 var rows
= ids
? ids
: getSelectedArticleIds2();
932 if (rows
.length
== 0 && !no_error
) {
933 alert(__("No articles are selected."));
937 for (var i
= 0; i
< rows
.length
; i
++) {
938 togglePub(rows
[i
], true, true);
941 if (rows
.length
> 0) {
943 var query
= "?op=rpc&method=publishSelected&ids=" +
944 param_escape(rows
.toString()) + "&cmode=2";
946 new Ajax
.Request("backend.php", {
948 onComplete: function(transport
) {
949 handle_rpc_json(transport
);
955 exception_error("selectionToggleMarked", e
);
959 function getSelectedArticleIds2() {
963 $$("#headlines-frame > div[id*=RROW][class*=Selected]").each(
965 rv
.push(child
.id
.replace("RROW-", ""));
971 function getLoadedArticleIds() {
974 var children
= $$("#headlines-frame > div[id*=RROW-]");
976 children
.each(function(child
) {
977 rv
.push(child
.id
.replace("RROW-", ""));
984 // mode = all,none,unread,invert,marked,published
985 function selectArticles(mode
, query
) {
988 if (!query
) query
= "#headlines-frame > div[id*=RROW]";
990 var children
= $$(query
);
992 children
.each(function(child
) {
993 var id
= child
.id
.replace("RROW-", "");
995 var cb
= dijit
.getEnclosingWidget(
996 child
.getElementsByClassName("rchk")[0]);
999 child
.addClassName("Selected");
1000 if (cb
) cb
.attr("checked", true);
1001 } else if (mode
== "unread") {
1002 if (child
.hasClassName("Unread")) {
1003 child
.addClassName("Selected");
1004 if (cb
) cb
.attr("checked", true);
1006 child
.removeClassName("Selected");
1007 if (cb
) cb
.attr("checked", false);
1009 } else if (mode
== "marked") {
1010 if (child
.hasClassName("marked")) {
1011 child
.addClassName("Selected");
1012 if (cb
) cb
.attr("checked", true);
1014 child
.removeClassName("Selected");
1015 if (cb
) cb
.attr("checked", false);
1017 } else if (mode
== "published") {
1018 if (child
.hasClassName("published")) {
1019 child
.addClassName("Selected");
1020 if (cb
) cb
.attr("checked", true);
1022 child
.removeClassName("Selected");
1023 if (cb
) cb
.attr("checked", false);
1026 } else if (mode
== "invert") {
1027 if (child
.hasClassName("Selected")) {
1028 child
.removeClassName("Selected");
1029 if (cb
) cb
.attr("checked", false);
1031 child
.addClassName("Selected");
1032 if (cb
) cb
.attr("checked", true);
1036 child
.removeClassName("Selected");
1037 if (cb
) cb
.attr("checked", false);
1041 updateSelectedPrompt();
1044 exception_error("selectArticles", e
);
1048 function deleteSelection() {
1052 var rows
= getSelectedArticleIds2();
1054 if (rows
.length
== 0) {
1055 alert(__("No articles are selected."));
1059 var fn
= getFeedName(getActiveFeedId(), activeFeedIsCat());
1062 if (getActiveFeedId() != 0) {
1063 str
= ngettext("Delete %d selected article in %s?", "Delete %d selected articles in %s?" , rows
.length
);
1065 str
= ngettext("Delete %d selected article?", "Delete %d selected articles?", rows
.length
);
1068 str
= str
.replace("%d", rows
.length
);
1069 str
= str
.replace("%s", fn
);
1071 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str
)) {
1075 query
= "?op=rpc&method=delete&ids=" + param_escape(rows
);
1079 new Ajax
.Request("backend.php", {
1081 onComplete: function(transport
) {
1082 handle_rpc_json(transport
);
1087 exception_error("deleteSelection", e
);
1091 function archiveSelection() {
1095 var rows
= getSelectedArticleIds2();
1097 if (rows
.length
== 0) {
1098 alert(__("No articles are selected."));
1102 var fn
= getFeedName(getActiveFeedId(), activeFeedIsCat());
1106 if (getActiveFeedId() != 0) {
1107 str
= ngettext("Archive %d selected article in %s?", "Archive %d selected articles in %s?", rows
.length
);
1110 str
= ngettext("Move %d archived article back?", "Move %d archived articles back?", rows
.length
);
1112 str
+= " " + __("Please note that unstarred articles might get purged on next feed update.");
1117 str
= str
.replace("%d", rows
.length
);
1118 str
= str
.replace("%s", fn
);
1120 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str
)) {
1124 query
= "?op=rpc&method="+op
+"&ids=" + param_escape(rows
);
1128 for (var i
= 0; i
< rows
.length
; i
++) {
1129 cache_delete("article:" + rows
[i
]);
1132 new Ajax
.Request("backend.php", {
1134 onComplete: function(transport
) {
1135 handle_rpc_json(transport
);
1140 exception_error("archiveSelection", e
);
1144 function catchupSelection() {
1148 var rows
= getSelectedArticleIds2();
1150 if (rows
.length
== 0) {
1151 alert(__("No articles are selected."));
1155 var fn
= getFeedName(getActiveFeedId(), activeFeedIsCat());
1157 var str
= ngettext("Mark %d selected article in %s as read?", "Mark %d selected articles in %s as read?", rows
.length
);
1159 str
= str
.replace("%d", rows
.length
);
1160 str
= str
.replace("%s", fn
);
1162 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str
)) {
1166 selectionToggleUnread(false, 'viewCurrentFeed()', true);
1169 exception_error("catchupSelection", e
);
1173 function editArticleTags(id
) {
1174 var query
= "backend.php?op=article&method=editArticleTags¶m=" + param_escape(id
);
1176 if (dijit
.byId("editTagsDlg"))
1177 dijit
.byId("editTagsDlg").destroyRecursive();
1179 dialog
= new dijit
.Dialog({
1181 title
: __("Edit article Tags"),
1182 style
: "width: 600px",
1183 execute: function() {
1184 if (this.validate()) {
1185 var query
= dojo
.objectToQuery(this.attr('value'));
1187 notify_progress("Saving article tags...", true);
1189 new Ajax
.Request("backend.php", {
1191 onComplete: function(transport
) {
1196 var data
= JSON
.parse(transport
.responseText
);
1203 var tags
= $("ATSTR-" + id
);
1204 var tooltip
= dijit
.byId("ATSTRTIP-" + id
);
1206 if (tags
) tags
.innerHTML
= data
.content
;
1207 if (tooltip
) tooltip
.attr('label', data
.content_full
);
1210 exception_error("editArticleTags/inner", e
);
1219 var tmph
= dojo
.connect(dialog
, 'onLoad', function() {
1220 dojo
.disconnect(tmph
);
1222 new Ajax
.Autocompleter('tags_str', 'tags_choices',
1223 "backend.php?op=article&method=completeTags",
1224 { tokens
: ',', paramName
: "search" });
1231 function cdmScrollToArticleId(id
, force
) {
1233 var ctr
= $("headlines-frame");
1234 var e
= $("RROW-" + id
);
1236 if (!e
|| !ctr
) return;
1238 if (force
|| e
.offsetTop
+e
.offsetHeight
> (ctr
.scrollTop
+ctr
.offsetHeight
) ||
1239 e
.offsetTop
< ctr
.scrollTop
) {
1241 // expanded cdm has a 4px margin now
1242 ctr
.scrollTop
= parseInt(e
.offsetTop
) - 4;
1246 exception_error("cdmScrollToArticleId", e
);
1250 function setActiveArticleId(id
) {
1251 _active_article_id
= id
;
1252 PluginHost
.run(PluginHost
.HOOK_ARTICLE_SET_ACTIVE
, _active_article_id
);
1255 function getActiveArticleId() {
1256 return _active_article_id
;
1259 function postMouseIn(e
, id
) {
1260 post_under_pointer
= id
;
1263 function postMouseOut(id
) {
1264 post_under_pointer
= false;
1267 function unpackVisibleHeadlines() {
1269 if (!isCdmMode() || !getInitParam("cdm_expanded")) return;
1271 $$("#headlines-frame > div[id*=RROW]").each(
1273 if (child
.offsetTop
<= $("headlines-frame").scrollTop
+
1274 $("headlines-frame").offsetHeight
) {
1276 var cencw
= $("CENCW-" + child
.id
.replace("RROW-", ""));
1279 PluginHost
.run(PluginHost
.HOOK_ARTICLE_RENDERED_CDM
, child
);
1281 cencw
.innerHTML
= htmlspecialchars_decode(cencw
.innerHTML
);
1282 cencw
.setAttribute('id', '');
1283 Element
.show(cencw
);
1290 exception_error("unpackVisibleHeadlines", e
);
1294 function headlines_scroll_handler(e
) {
1296 var hsp
= $("headlines-spacer");
1298 unpackVisibleHeadlines();
1300 // set topmost child in the buffer as active
1301 if (isCdmMode() && getInitParam("cdm_auto_catchup") == 1 &&
1302 getSelectedArticleIds2().length
<= 1 &&
1303 getInitParam("cdm_expanded")) {
1304 var rows
= $$("#headlines-frame > div[id*=RROW]");
1306 for (var i
= 0; i
< rows
.length
; i
++) {
1307 var child
= rows
[i
];
1309 if ($("headlines-frame").scrollTop
<= child
.offsetTop
&&
1310 child
.offsetTop
- $("headlines-frame").scrollTop
< 100 &&
1311 child
.id
.replace("RROW-", "") != _active_article_id
) {
1313 if (_active_article_id
) {
1314 var row
= $("RROW-" + _active_article_id
);
1315 if (row
) row
.removeClassName("active");
1318 _active_article_id
= child
.id
.replace("RROW-", "");
1319 showArticleInHeadlines(_active_article_id
, true);
1320 updateSelectedPrompt();
1326 if (!_infscroll_disable
) {
1327 if ((hsp
&& e
.scrollTop
+ e
.offsetHeight
>= hsp
.offsetTop
- hsp
.offsetHeight
) ||
1328 (e
.scrollHeight
!= 0 &&
1329 ((e
.scrollTop
+ e
.offsetHeight
) / e
.scrollHeight
>= 0.7))) {
1332 hsp
.innerHTML
= "<span class='loading'><img src='images/indicator_tiny.gif'> " +
1333 __("Loading, please wait...") + "</span>";
1335 loadMoreHeadlines();
1341 if (_infscroll_disable)
1342 hsp.innerHTML = "<a href='#' onclick='openNextUnreadFeed()'>" +
1343 __("Click to open next unread feed.") + "</a>";
1350 updateFloatingTitle();
1353 if (getInitParam("cdm_auto_catchup") == 1) {
1355 // let's get DOM some time to settle down
1356 var ts
= new Date().getTime();
1357 if (ts
- _last_headlines_update
< 100) return;
1359 $$("#headlines-frame > div[id*=RROW][class*=Unread]").each(
1361 if (child
.hasClassName("Unread") && $("headlines-frame").scrollTop
>
1362 (child
.offsetTop
+ child
.offsetHeight
/2)) {
1364 var id
= child
.id
.replace("RROW-", "");
1366 if (catchup_id_batch
.indexOf(id
) == -1)
1367 catchup_id_batch
.push(id
);
1369 //console.log("auto_catchup_batch: " + catchup_id_batch.toString());
1374 if (catchup_id_batch
.length
> 0) {
1375 window
.clearTimeout(catchup_timeout_id
);
1377 if (!_infscroll_request_sent
) {
1378 catchup_timeout_id
= window
.setTimeout('catchupBatchedArticles()',
1383 if (_infscroll_disable
) {
1384 var child
= $$("#headlines-frame div[id*=RROW]").last();
1386 if (child
&& $("headlines-frame").scrollTop
>
1387 (child
.offsetTop
+ child
.offsetHeight
- 50)) {
1389 console
.log("we seem to be at an end");
1391 if (getInitParam("on_catchup_show_next_feed") == "1") {
1392 openNextUnreadFeed();
1399 console
.warn("headlines_scroll_handler: " + e
);
1403 function openNextUnreadFeed() {
1405 var is_cat
= activeFeedIsCat();
1406 var nuf
= getNextUnreadFeed(getActiveFeedId(), is_cat
);
1407 if (nuf
) viewfeed(nuf
, '', is_cat
);
1409 exception_error("openNextUnreadFeed", e
);
1413 function catchupBatchedArticles() {
1415 if (catchup_id_batch
.length
> 0 && !_infscroll_request_sent
) {
1417 // make a copy of the array
1418 var batch
= catchup_id_batch
.slice();
1419 var query
= "?op=rpc&method=catchupSelected" +
1420 "&cmode=0&ids=" + param_escape(batch
.toString());
1424 new Ajax
.Request("backend.php", {
1426 onComplete: function(transport
) {
1427 handle_rpc_json(transport
);
1429 reply
= JSON
.parse(transport
.responseText
);
1430 var batch
= reply
.ids
;
1432 batch
.each(function(id
) {
1434 var elem
= $("RROW-" + id
);
1435 if (elem
) elem
.removeClassName("Unread");
1436 catchup_id_batch
.remove(id
);
1439 updateFloatingTitle(true);
1445 exception_error("catchupBatchedArticles", e
);
1449 function catchupRelativeToArticle(below
, id
) {
1453 if (!id
) id
= getActiveArticleId();
1456 alert(__("No article is selected."));
1460 var visible_ids
= getVisibleArticleIds();
1462 var ids_to_mark
= new Array();
1465 for (var i
= 0; i
< visible_ids
.length
; i
++) {
1466 if (visible_ids
[i
] != id
) {
1467 var e
= $("RROW-" + visible_ids
[i
]);
1469 if (e
&& e
.hasClassName("Unread")) {
1470 ids_to_mark
.push(visible_ids
[i
]);
1477 for (var i
= visible_ids
.length
-1; i
>= 0; i
--) {
1478 if (visible_ids
[i
] != id
) {
1479 var e
= $("RROW-" + visible_ids
[i
]);
1481 if (e
&& e
.hasClassName("Unread")) {
1482 ids_to_mark
.push(visible_ids
[i
]);
1490 if (ids_to_mark
.length
== 0) {
1491 alert(__("No articles found to mark"));
1493 var msg
= ngettext("Mark %d article as read?", "Mark %d articles as read?", ids_to_mark
.length
).replace("%d", ids_to_mark
.length
);
1495 if (getInitParam("confirm_feed_catchup") != 1 || confirm(msg
)) {
1497 for (var i
= 0; i
< ids_to_mark
.length
; i
++) {
1498 var e
= $("RROW-" + ids_to_mark
[i
]);
1499 e
.removeClassName("Unread");
1502 var query
= "?op=rpc&method=catchupSelected" +
1503 "&cmode=0" + "&ids=" + param_escape(ids_to_mark
.toString());
1505 new Ajax
.Request("backend.php", {
1507 onComplete: function(transport
) {
1508 handle_rpc_json(transport
);
1515 exception_error("catchupRelativeToArticle", e
);
1519 function cdmCollapseArticle(event
, id
, unmark
) {
1521 if (unmark
== undefined) unmark
= true;
1523 var row
= $("RROW-" + id
);
1524 var elem
= $("CICD-" + id
);
1527 var collapse
= $$("div#RROW-" + id
+
1528 " span[class='collapseBtn']")[0];
1531 Element
.show("CEXC-" + id
);
1532 Element
.hide(collapse
);
1535 row
.removeClassName("active");
1537 markHeadline(id
, false);
1539 if (id
== getActiveArticleId()) {
1540 setActiveArticleId(0);
1543 updateSelectedPrompt();
1546 if (event
) Event
.stop(event
);
1548 PluginHost
.run(PluginHost
.HOOK_ARTICLE_COLLAPSED
, id
);
1550 if (row
.offsetTop
< $("headlines-frame").scrollTop
)
1551 scrollToRowId(row
.id
);
1553 $("floatingTitle").style
.visibility
= "hidden";
1554 $("floatingTitle").setAttribute("rowid", false);
1558 exception_error("cdmCollapseArticle", e
);
1562 function cdmExpandArticle(id
, noexpand
) {
1564 console
.log("cdmExpandArticle " + id
);
1566 if (!$("RROW-" + id
)) return false;
1568 var oldrow
= $("RROW-" + getActiveArticleId());
1570 var elem
= $("CICD-" + getActiveArticleId());
1572 if (id
== getActiveArticleId() && Element
.visible(elem
))
1575 selectArticles("none");
1577 var old_offset
= $("RROW-" + id
).offsetTop
;
1579 if (getActiveArticleId() && elem
&& !getInitParam("cdm_expanded")) {
1580 var collapse
= $$("div#RROW-" + getActiveArticleId() +
1581 " span[class='collapseBtn']")[0];
1584 Element
.show("CEXC-" + getActiveArticleId());
1585 Element
.hide(collapse
);
1588 if (oldrow
) oldrow
.removeClassName("active");
1590 setActiveArticleId(id
);
1592 elem
= $("CICD-" + id
);
1594 var collapse
= $$("div#RROW-" + id
+
1595 " span[class='collapseBtn']")[0];
1597 var cencw
= $("CENCW-" + id
);
1599 if (!Element
.visible(elem
) && !noexpand
) {
1601 cencw
.innerHTML
= htmlspecialchars_decode(cencw
.innerHTML
);
1602 cencw
.setAttribute('id', '');
1603 Element
.show(cencw
);
1607 Element
.hide("CEXC-" + id
);
1608 Element
.show(collapse
);
1611 var new_offset
= $("RROW-" + id
).offsetTop
;
1613 if (old_offset
> new_offset
)
1614 $("headlines-frame").scrollTop
-= (old_offset
-new_offset
);
1617 toggleUnread(id
, 0, true);
1619 $("RROW-" + id
).addClassName("active");
1621 PluginHost
.run(PluginHost
.HOOK_ARTICLE_EXPANDED
, id
);
1624 exception_error("cdmExpandArticle", e
);
1630 function getArticleUnderPointer() {
1631 return post_under_pointer
;
1634 function scrollArticle(offset
) {
1637 var ci
= $("content-insert");
1639 ci
.scrollTop
+= offset
;
1642 var hi
= $("headlines-frame");
1644 hi
.scrollTop
+= offset
;
1649 exception_error("scrollArticle", e
);
1653 function show_labels_in_headlines(transport
) {
1655 var data
= JSON
.parse(transport
.responseText
);
1658 data
['info-for-headlines'].each(function(elem
) {
1659 $$(".HLLCTR-" + elem
.id
).each(function(ctr
) {
1660 ctr
.innerHTML
= elem
.labels
;
1665 exception_error("show_labels_in_headlines", e
);
1669 function dismissArticle(id
) {
1671 var elem
= $("RROW-" + id
);
1675 toggleUnread(id
, 0, true);
1677 new Effect
.Fade(elem
, {duration
: 0.5});
1679 // Remove the content, too
1680 var elem_content
= $("CICD-" + id
);
1682 Element
.remove(elem_content
);
1685 if (id
== getActiveArticleId()) {
1686 setActiveArticleId(0);
1690 exception_error("dismissArticle", e
);
1694 function dismissSelectedArticles() {
1697 var ids
= getVisibleArticleIds();
1701 for (var i
= 0; i
< ids
.length
; i
++) {
1702 var elem
= $("RROW-" + ids
[i
]);
1704 if (elem
.className
&& elem
.hasClassName("Selected") &&
1705 ids
[i
] != getActiveArticleId()) {
1706 new Effect
.Fade(elem
, {duration
: 0.5});
1709 // Remove the content, too
1710 var elem_content
= $("CICD-" + ids
[i
]);
1712 Element
.remove(elem_content
);
1720 selectionToggleUnread(false);
1724 exception_error("dismissSelectedArticles", e
);
1728 function dismissReadArticles() {
1731 var ids
= getVisibleArticleIds();
1734 for (var i
= 0; i
< ids
.length
; i
++) {
1735 var elem
= $("RROW-" + ids
[i
]);
1737 if (elem
.className
&& !elem
.hasClassName("Unread") &&
1738 !elem
.hasClassName("Selected")) {
1740 new Effect
.Fade(elem
, {duration
: 0.5});
1742 // Remove the content, too
1743 var elem_content
= $("CICD-" + ids
[i
]);
1745 Element
.remove(elem_content
);
1753 exception_error("dismissReadArticles", e
);
1757 function getVisibleArticleIds() {
1762 getLoadedArticleIds().each(function(id
) {
1763 var elem
= $("RROW-" + id
);
1764 if (elem
&& Element
.visible(elem
))
1769 exception_error("getVisibleArticleIds", e
);
1775 function cdmClicked(event
, id
) {
1777 //var shift_key = event.shiftKey;
1779 if (!event
.ctrlKey
) {
1781 if (!getInitParam("cdm_expanded")) {
1782 return cdmExpandArticle(id
);
1785 var elem
= $("RROW-" + getActiveArticleId());
1787 if (elem
) elem
.removeClassName("active");
1789 selectArticles("none");
1792 var elem
= $("RROW-" + id
);
1793 var article_is_unread
= elem
.hasClassName("Unread");
1795 elem
.removeClassName("Unread");
1796 elem
.addClassName("active");
1798 setActiveArticleId(id
);
1800 if (article_is_unread
) {
1801 decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
1802 updateFloatingTitle(true);
1805 var query
= "?op=rpc&method=catchupSelected" +
1806 "&cmode=0&ids=" + param_escape(id
);
1808 new Ajax
.Request("backend.php", {
1810 onComplete: function(transport
) {
1811 handle_rpc_json(transport
);
1814 return !event
.shiftKey
;
1817 } else if (event
.target
.parents(".cdmHeader").length
> 0) {
1819 toggleSelected(id
, true);
1821 var elem
= $("RROW-" + id
);
1822 var article_is_unread
= elem
.hasClassName("Unread");
1824 if (article_is_unread
) {
1825 decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
1828 toggleUnread(id
, 0, false);
1830 openArticleInNewWindow(id
);
1833 var unread_in_buffer
= $$("#headlines-frame > div[id*=RROW][class*=Unread]").length
1834 request_counters(unread_in_buffer
== 0);
1837 exception_error("cdmClicked");
1843 function hlClicked(event
, id
) {
1845 if (event
.which
== 2) {
1848 } else if (event
.ctrlKey
) {
1849 toggleSelected(id
, true);
1850 toggleUnread(id
, 0, false);
1851 openArticleInNewWindow(id
);
1859 exception_error("hlClicked");
1863 function getFirstVisibleHeadlineId() {
1864 var rows
= getVisibleArticleIds();
1869 function getLastVisibleHeadlineId() {
1870 var rows
= getVisibleArticleIds();
1871 return rows
[rows
.length
-1];
1874 function openArticleInNewWindow(id
) {
1875 toggleUnread(id
, 0, false);
1876 window
.open("backend.php?op=article&method=redirect&id=" + id
);
1879 function isCdmMode() {
1880 return getInitParam("combined_display_mode");
1883 function markHeadline(id
, marked
) {
1884 if (marked
== undefined) marked
= true;
1886 var row
= $("RROW-" + id
);
1888 var check
= dijit
.getEnclosingWidget(
1889 row
.getElementsByClassName("rchk")[0]);
1892 check
.attr("checked", marked
);
1896 row
.addClassName("Selected");
1898 row
.removeClassName("Selected");
1902 function getRelativePostIds(id
, limit
) {
1908 if (!limit
) limit
= 6; //3
1910 var ids
= getVisibleArticleIds();
1912 for (var i
= 0; i
< ids
.length
; i
++) {
1914 for (var k
= 1; k
<= limit
; k
++) {
1915 //if (i > k-1) tmp.push(ids[i-k]);
1916 if (i
< ids
.length
-k
) tmp
.push(ids
[i
+k
]);
1923 exception_error("getRelativePostIds", e
);
1929 function correctHeadlinesOffset(id
) {
1933 var container
= $("headlines-frame");
1934 var row
= $("RROW-" + id
);
1936 if (!container
|| !row
) return;
1938 var viewport
= container
.offsetHeight
;
1940 var rel_offset_top
= row
.offsetTop
- container
.scrollTop
;
1941 var rel_offset_bottom
= row
.offsetTop
+ row
.offsetHeight
- container
.scrollTop
;
1943 //console.log("Rtop: " + rel_offset_top + " Rbtm: " + rel_offset_bottom);
1944 //console.log("Vport: " + viewport);
1946 if (rel_offset_top
<= 0 || rel_offset_top
> viewport
) {
1947 container
.scrollTop
= row
.offsetTop
;
1948 } else if (rel_offset_bottom
> viewport
) {
1950 /* doesn't properly work with Opera in some cases because
1951 Opera fucks up element scrolling */
1953 container
.scrollTop
= row
.offsetTop
+ row
.offsetHeight
- viewport
;
1957 exception_error("correctHeadlinesOffset", e
);
1962 function headlineActionsChange(elem
) {
1965 elem
.attr('value', 'false');
1967 exception_error("headlineActionsChange", e
);
1971 function closeArticlePanel() {
1973 if (dijit
.byId("content-insert"))
1974 dijit
.byId("headlines-wrap-inner").removeChild(
1975 dijit
.byId("content-insert"));
1978 function initFloatingMenu() {
1980 if (dijit
.byId("floatingMenu"))
1981 dijit
.byId("floatingMenu").destroyRecursive();
1983 var menu
= new dijit
.Menu({
1985 targetNodeIds
: ["floatingTitle"]
1988 var id
= $("floatingTitle").getAttribute("rowid").replace("RROW-", "");
1990 headlinesMenuCommon(menu
, id
);
1994 exception_error("initFloatingMenu", e
);
1998 function headlinesMenuCommon(menu
, base_id
) {
2001 menu
.addChild(new dijit
.MenuItem({
2002 label
: __("Open original article"),
2003 onClick: function(event
) {
2004 openArticleInNewWindow(base_id
? base_id
: this.getParent().callerRowId
);
2007 menu
.addChild(new dijit
.MenuItem({
2008 label
: __("Display article URL"),
2009 onClick: function(event
) {
2010 displayArticleUrl(base_id
? base_id
: this.getParent().callerRowId
);
2013 menu
.addChild(new dijit
.MenuSeparator());
2015 menu
.addChild(new dijit
.MenuItem({
2016 label
: __("Toggle unread"),
2017 onClick: function(event
) {
2018 var ids
= getSelectedArticleIds2();
2020 var id
= (base_id
? base_id
: this.getParent().callerRowId
) + "";
2021 ids
= ids
.size() != 0 && ids
.indexOf(id
) != -1 ? ids
: [id
];
2023 selectionToggleUnread(undefined, false, true, ids
);
2026 menu
.addChild(new dijit
.MenuItem({
2027 label
: __("Toggle starred"),
2028 onClick: function(event
) {
2029 var ids
= getSelectedArticleIds2();
2031 var id
= (base_id
? base_id
: this.getParent().callerRowId
) + "";
2032 ids
= ids
.size() != 0 && ids
.indexOf(id
) != -1 ? ids
: [id
];
2034 selectionToggleMarked(undefined, false, true, ids
);
2037 menu
.addChild(new dijit
.MenuItem({
2038 label
: __("Toggle published"),
2039 onClick: function(event
) {
2040 var ids
= getSelectedArticleIds2();
2042 var id
= (base_id
? base_id
: this.getParent().callerRowId
) + "";
2043 ids
= ids
.size() != 0 && ids
.indexOf(id
) != -1 ? ids
: [id
];
2045 selectionTogglePublished(undefined, false, true, ids
);
2048 menu
.addChild(new dijit
.MenuSeparator());
2050 menu
.addChild(new dijit
.MenuItem({
2051 label
: __("Mark above as read"),
2052 onClick: function(event
) {
2053 catchupRelativeToArticle(0, base_id
? base_id
: this.getParent().callerRowId
);
2056 menu
.addChild(new dijit
.MenuItem({
2057 label
: __("Mark below as read"),
2058 onClick: function(event
) {
2059 catchupRelativeToArticle(1, base_id
? base_id
: this.getParent().callerRowId
);
2063 var labels
= dijit
.byId("feedTree").model
.getItemsInCategory(-2);
2067 menu
.addChild(new dijit
.MenuSeparator());
2069 var labelAddMenu
= new dijit
.Menu({ownerMenu
: menu
});
2070 var labelDelMenu
= new dijit
.Menu({ownerMenu
: menu
});
2072 labels
.each(function(label
) {
2073 var id
= label
.id
[0];
2074 var bare_id
= id
.substr(id
.indexOf(":")+1);
2075 var name
= label
.name
[0];
2077 bare_id
= feed_to_label_id(bare_id
);
2079 labelAddMenu
.addChild(new dijit
.MenuItem({
2082 onClick: function(event
) {
2083 var ids
= getSelectedArticleIds2();
2085 var id
= (base_id
? base_id
: this.getParent().ownerMenu
.callerRowId
) + "";
2087 ids
= ids
.size() != 0 && ids
.indexOf(id
) != -1 ? ids
: [id
];
2089 selectionAssignLabel(this.labelId
, ids
);
2092 labelDelMenu
.addChild(new dijit
.MenuItem({
2095 onClick: function(event
) {
2096 var ids
= getSelectedArticleIds2();
2098 var id
= (base_id
? base_id
: this.getParent().ownerMenu
.callerRowId
) + "";
2100 ids
= ids
.size() != 0 && ids
.indexOf(id
) != -1 ? ids
: [id
];
2102 selectionRemoveLabel(this.labelId
, ids
);
2107 menu
.addChild(new dijit
.PopupMenuItem({
2108 label
: __("Assign label"),
2109 popup
: labelAddMenu
,
2112 menu
.addChild(new dijit
.PopupMenuItem({
2113 label
: __("Remove label"),
2114 popup
: labelDelMenu
,
2121 exception_error("headlinesMenuCommon", e
);
2125 function initHeadlinesMenu() {
2127 if (dijit
.byId("headlinesMenu"))
2128 dijit
.byId("headlinesMenu").destroyRecursive();
2133 nodes
= $$("#headlines-frame > div[id*=RROW]");
2135 nodes
= $$("#headlines-frame span[id*=RTITLE]");
2138 nodes
.each(function(node
) {
2142 var menu
= new dijit
.Menu({
2143 id
: "headlinesMenu",
2147 var tmph
= dojo
.connect(menu
, '_openMyself', function (event
) {
2148 var callerNode
= event
.target
, match
= null, tries
= 0;
2150 while (match
== null && callerNode
&& tries
<= 3) {
2151 match
= callerNode
.id
.match("^[A-Z]+[-]([0-9]+)$");
2152 callerNode
= callerNode
.parentNode
;
2156 if (match
) this.callerRowId
= parseInt(match
[1]);
2160 headlinesMenuCommon(menu
, false);
2164 /* vgroup feed title menu */
2166 var nodes
= $$("#headlines-frame > div[class='cdmFeedTitle']");
2169 nodes
.each(function(node
) {
2173 if (ids
.length
> 0) {
2174 if (dijit
.byId("headlinesFeedTitleMenu"))
2175 dijit
.byId("headlinesFeedTitleMenu").destroyRecursive();
2177 var menu
= new dijit
.Menu({
2178 id
: "headlinesFeedTitleMenu",
2182 var tmph
= dojo
.connect(menu
, '_openMyself', function (event
) {
2183 var callerNode
= event
.target
, match
= null, tries
= 0;
2185 while (match
== null && callerNode
&& tries
<= 3) {
2186 console
.log(callerNode
.id
);
2188 match
= callerNode
.id
.match("^[A-Z]+[-]([0-9]+)$");
2189 callerNode
= callerNode
.parentNode
;
2192 console
.log(match
[1]);
2195 if (match
) this.callerRowId
= parseInt(match
[1]);
2199 menu
.addChild(new dijit
.MenuItem({
2200 label
: __("Select articles in group"),
2201 onClick: function(event
) {
2202 selectArticles("all",
2203 "#headlines-frame > div[id*=RROW]"+
2204 "[orig-feed-id='"+menu
.callerRowId
+"']");
2208 menu
.addChild(new dijit
.MenuItem({
2209 label
: __("Mark group as read"),
2210 onClick: function(event
) {
2211 selectArticles("none");
2212 selectArticles("all",
2213 "#headlines-frame > div[id*=RROW]"+
2214 "[orig-feed-id='"+menu
.callerRowId
+"']");
2220 menu
.addChild(new dijit
.MenuItem({
2221 label
: __("Mark feed as read"),
2222 onClick: function(event
) {
2223 catchupFeedInGroup(menu
.callerRowId
);
2231 exception_error("initHeadlinesMenu", e
);
2235 function cache_set(id
, obj
) {
2236 //console.log("cache_set: " + id);
2239 sessionStorage
[id
] = obj
;
2241 sessionStorage
.clear();
2245 function cache_get(id
) {
2247 return sessionStorage
[id
];
2250 function cache_clear() {
2252 sessionStorage
.clear();
2255 function cache_delete(id
) {
2257 sessionStorage
.removeItem(id
);
2260 function cancelSearch() {
2265 exception_error("cancelSearch", e
);
2269 function setSelectionScore() {
2271 var ids
= getSelectedArticleIds2();
2273 if (ids
.length
> 0) {
2276 var score
= prompt(__("Please enter new score for selected articles:"), score
);
2278 if (score
!= undefined) {
2279 var query
= "op=article&method=setScore&id=" + param_escape(ids
.toString()) +
2280 "&score=" + param_escape(score
);
2282 new Ajax
.Request("backend.php", {
2284 onComplete: function(transport
) {
2285 var reply
= JSON
.parse(transport
.responseText
);
2289 ids
.each(function(id
) {
2290 var row
= $("RROW-" + id
);
2293 var pic
= row
.getElementsByClassName("hlScorePic")[0];
2296 pic
.src
= pic
.src
.replace(/score_.*?\.png/,
2297 reply
["score_pic"]);
2298 pic
.setAttribute("score", score
);
2307 alert(__("No articles are selected."));
2310 exception_error("setSelectionScore", e
);
2314 function updateScore(id
) {
2316 var pic
= $$("#RROW-" + id
+ " .hlScorePic")[0];
2320 var query
= "op=article&method=getScore&id=" + param_escape(id
);
2322 new Ajax
.Request("backend.php", {
2324 onComplete: function(transport
) {
2325 console
.log(transport
.responseText
);
2327 var reply
= JSON
.parse(transport
.responseText
);
2330 pic
.src
= pic
.src
.replace(/score_.*?\.png/, reply
["score_pic"]);
2331 pic
.setAttribute("score", reply
["score"]);
2332 pic
.setAttribute("title", reply
["score"]);
2338 exception_error("updateScore", e
);
2342 function changeScore(id
, pic
) {
2344 var score
= pic
.getAttribute("score");
2346 var new_score
= prompt(__("Please enter new score for this article:"), score
);
2348 if (new_score
!= undefined) {
2350 var query
= "op=article&method=setScore&id=" + param_escape(id
) +
2351 "&score=" + param_escape(new_score
);
2353 new Ajax
.Request("backend.php", {
2355 onComplete: function(transport
) {
2356 var reply
= JSON
.parse(transport
.responseText
);
2359 pic
.src
= pic
.src
.replace(/score_.*?\.png/, reply
["score_pic"]);
2360 pic
.setAttribute("score", new_score
);
2361 pic
.setAttribute("title", new_score
);
2366 exception_error("changeScore", e
);
2370 function displayArticleUrl(id
) {
2372 var query
= "op=rpc&method=getlinktitlebyid&id=" + param_escape(id
);
2374 new Ajax
.Request("backend.php", {
2376 onComplete: function(transport
) {
2377 var reply
= JSON
.parse(transport
.responseText
);
2379 if (reply
&& reply
.link
) {
2380 prompt(__("Article URL:"), reply
.link
);
2384 exception_error("changeScore", e
);
2388 function openSelectedAttachment(elem
) {
2390 var url
= elem
[elem
.selectedIndex
].value
;
2394 elem
.selectedIndex
= 0;
2398 exception_error("openSelectedAttachment", e
);
2402 function scrollToRowId(id
) {
2407 $("headlines-frame").scrollTop
= row
.offsetTop
- 4;
2410 exception_error("scrollToRowId", e
);
2414 function updateFloatingTitle(unread_only
) {
2416 if (!isCdmMode()) return;
2418 var hf
= $("headlines-frame");
2420 var elems
= $$("#headlines-frame > div[id*=RROW]");
2422 for (var i
= 0; i
< elems
.length
; i
++) {
2424 var child
= elems
[i
];
2426 if (child
&& child
.offsetTop
+ child
.offsetHeight
> hf
.scrollTop
) {
2428 var header
= child
.getElementsByClassName("cdmHeader")[0];
2430 if (unread_only
|| child
.id
!= $("floatingTitle").getAttribute("rowid")) {
2431 if (child
.id
!= $("floatingTitle").getAttribute("rowid")) {
2432 $("floatingTitle").setAttribute("rowid", child
.id
);
2433 $("floatingTitle").innerHTML
= header
.innerHTML
;
2434 $("floatingTitle").firstChild
.innerHTML
= "<img class='anchor markedPic' src='images/page_white_go.png' onclick=\"scrollToRowId('"+child
.id
+"')\">" + $("floatingTitle").firstChild
.innerHTML
;
2438 var cb
= $$("#floatingTitle .dijitCheckBox")[0];
2441 cb
.parentNode
.removeChild(cb
);
2444 if (child
.hasClassName("Unread"))
2445 $("floatingTitle").addClassName("Unread");
2447 $("floatingTitle").removeClassName("Unread");
2449 PluginHost
.run(PluginHost
.HOOK_FLOATING_TITLE
, child
);
2452 $("floatingTitle").style
.marginRight
= hf
.offsetWidth
- child
.offsetWidth
+ "px";
2453 if (header
.offsetTop
+ header
.offsetHeight
< hf
.scrollTop
+ $("floatingTitle").offsetHeight
- 5 &&
2454 child
.offsetTop
+ child
.offsetHeight
>= hf
.scrollTop
+ $("floatingTitle").offsetHeight
- 5)
2455 $("floatingTitle").style
.visibility
= "visible";
2457 $("floatingTitle").style
.visibility
= "hidden";
2465 exception_error("updateFloatingTitle", e
);
2469 function cdmFooterClick(event
) {
2470 event
.stopPropagation();