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 Element
.hide("floatingTitle");
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 });
179 console
.log("no new headlines received");
181 var hsp
= $("headlines-spacer");
183 if (hsp
) hsp
.innerHTML
= "Click to open next unread feed.";
188 for (var i
= 0; i
< articles
.length
; i
++) {
189 var a_id
= articles
[i
]['id'];
190 cache_set("article:" + a_id
, articles
[i
]['content']);
193 console
.log("no cached articles received");
197 parse_counters(counters
);
199 request_counters(true);
202 console
.error("Invalid object received: " + transport
.responseText
);
203 dijit
.byId("headlines-frame").attr('content', "<div class='whiteBox'>" +
204 __('Could not update headlines (invalid object received - see error console for details)') +
208 _infscroll_request_sent
= 0;
209 _last_headlines_update
= new Date().getTime();
211 unpackVisibleHeadlines();
213 // if we have some more space in the buffer, why not try to fill it
215 if (!_infscroll_disable
&& $("headlines-spacer") &&
216 $("headlines-spacer").offsetTop
< $("headlines-frame").offsetHeight
) {
218 window
.setTimeout(function() {
226 exception_error("headlines_callback2", e
, transport
);
230 function render_article(article
) {
232 dijit
.byId("headlines-wrap-inner").addChild(
233 dijit
.byId("content-insert"));
235 var c
= dijit
.byId("content-insert");
238 c
.domNode
.scrollTop
= 0;
241 PluginHost
.run(PluginHost
.HOOK_ARTICLE_RENDERED
, article
);
243 c
.attr('content', article
);
245 correctHeadlinesOffset(getActiveArticleId());
252 exception_error("render_article", e
);
256 function showArticleInHeadlines(id
, noexpand
) {
259 selectArticles("none");
261 var crow
= $("RROW-" + id
);
265 var article_is_unread
= crow
.hasClassName("Unread");
268 crow
.removeClassName("Unread");
269 crow
.addClassName("active");
271 selectArticles('none');
273 var view_mode
= false;
276 view_mode
= document
.forms
['main_toolbar_form'].view_mode
;
277 view_mode
= view_mode
[view_mode
.selectedIndex
].value
;
284 if (article_is_unread
&& !noexpand
)
285 _force_scheduled_update
= true;
288 exception_error("showArticleInHeadlines", e
);
292 function article_callback2(transport
, id
) {
294 console
.log("article_callback2 " + id
);
296 handle_rpc_json(transport
);
301 reply
= JSON
.parse(transport
.responseText
);
308 reply
.each(function(article
) {
309 if (getActiveArticleId() == article
['id']) {
310 render_article(article
['content']);
312 cids_requested
.remove(article
['id']);
314 cache_set("article:" + article
['id'], article
['content']);
317 // if (id != last_requested_article) {
318 // console.log("requested article id is out of sequence, aborting");
323 console
.error("Invalid object received: " + transport
.responseText
);
325 render_article("<div class='whiteBox'>" +
326 __('Could not display article (invalid object received - see error console for details)') + "</div>");
329 var unread_in_buffer
= $$("#headlines-frame > div[id*=RROW][class*=Unread]").length
330 request_counters(unread_in_buffer
== 0);
332 //headlines_scroll_handler($("headlines-frame"));
335 if (!_infscroll_disable &&
336 $$("#headlines-frame > div[id*=RROW]").last().hasClassName("Selected")) {
346 exception_error("article_callback2", e
, transport
);
350 function view(id
, activefeed
, noexpand
) {
352 var oldrow
= $("RROW-" + getActiveArticleId());
353 if (oldrow
) oldrow
.removeClassName("active");
355 var crow
= $("RROW-" + id
);
359 setActiveArticleId(id
);
360 showArticleInHeadlines(id
, noexpand
);
364 console
.log("loading article: " + id
);
366 var cached_article
= cache_get("article:" + id
);
368 console
.log("cache check result: " + (cached_article
!= false));
370 var query
= "?op=article&method=view&id=" + param_escape(id
);
372 var neighbor_ids
= getRelativePostIds(id
);
374 /* only request uncached articles */
376 var cids_to_request
= [];
378 for (var i
= 0; i
< neighbor_ids
.length
; i
++) {
379 if (cids_requested
.indexOf(neighbor_ids
[i
]) == -1)
380 if (!cache_get("article:" + neighbor_ids
[i
])) {
381 cids_to_request
.push(neighbor_ids
[i
]);
382 cids_requested
.push(neighbor_ids
[i
]);
386 console
.log("additional ids: " + cids_to_request
.toString());
388 query
= query
+ "&cids=" + cids_to_request
.toString();
390 var article_is_unread
= crow
.hasClassName("Unread");
392 setActiveArticleId(id
);
393 showArticleInHeadlines(id
);
395 if (cached_article
&& article_is_unread
) {
397 query
= query
+ "&mode=prefetch";
399 render_article(cached_article
);
401 } else if (cached_article
) {
403 query
= query
+ "&mode=prefetch_old";
404 render_article(cached_article
);
406 // if we don't need to request any relative ids, we might as well skip
407 // the server roundtrip altogether
408 if (cids_to_request
.length
== 0) {
411 if (!_infscroll_disable &&
412 $$("#headlines-frame > div[id*=RROW]").last().hasClassName("Selected")) {
420 //headlines_scroll_handler($("headlines-frame"));
426 last_requested_article
= id
;
430 if (article_is_unread
) {
431 decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
434 new Ajax
.Request("backend.php", {
436 onComplete: function(transport
) {
437 article_callback2(transport
, id
);
443 exception_error("view", e
);
447 function toggleMark(id
, client_only
) {
449 var query
= "?op=rpc&id=" + id
+ "&method=mark";
451 var row
= $("RROW-" + id
);
456 var row_imgs
= row
.getElementsByClassName("markedPic");
458 for (var i
= 0; i
< row_imgs
.length
; i
++)
459 imgs
.push(row_imgs
[i
]);
461 var ft
= $("floatingTitle");
463 if (ft
&& ft
.getAttribute("rowid") == "RROW-" + id
) {
464 var fte
= ft
.getElementsByClassName("markedPic");
466 for (var i
= 0; i
< fte
.length
; i
++)
470 for (i
= 0; i
< imgs
.length
; i
++) {
473 if (!row
.hasClassName("marked")) {
474 img
.src
= img
.src
.replace("mark_unset", "mark_set");
475 img
.alt
= __("Unstar article");
476 query
= query
+ "&mark=1";
478 img
.src
= img
.src
.replace("mark_set", "mark_unset");
479 img
.alt
= __("Star article");
480 query
= query
+ "&mark=0";
484 row
.toggleClassName("marked");
487 new Ajax
.Request("backend.php", {
489 onComplete: function(transport
) {
490 handle_rpc_json(transport
);
495 exception_error("toggleMark", e
);
499 function togglePub(id
, client_only
, no_effects
, note
) {
501 var query
= "?op=rpc&id=" + id
+ "&method=publ";
503 if (note
!= undefined) {
504 query
= query
+ "¬e=" + param_escape(note
);
506 query
= query
+ "¬e=undefined";
509 var row
= $("RROW-" + id
);
514 var row_imgs
= row
.getElementsByClassName("pubPic");
516 for (var i
= 0; i
< row_imgs
.length
; i
++)
517 imgs
.push(row_imgs
[i
]);
519 var ft
= $("floatingTitle");
521 if (ft
&& ft
.getAttribute("rowid") == "RROW-" + id
) {
522 var fte
= ft
.getElementsByClassName("pubPic");
524 for (var i
= 0; i
< fte
.length
; i
++)
528 for (i
= 0; i
< imgs
.length
; i
++) {
531 if (!row
.hasClassName("published") || note
!= undefined) {
532 img
.src
= img
.src
.replace("pub_unset", "pub_set");
533 img
.alt
= __("Unpublish article");
534 query
= query
+ "&pub=1";
536 img
.src
= img
.src
.replace("pub_set", "pub_unset");
537 img
.alt
= __("Publish article");
538 query
= query
+ "&pub=0";
542 if (note
!= undefined)
543 row
.addClassName("published");
545 row
.toggleClassName("published");
548 new Ajax
.Request("backend.php", {
550 onComplete: function(transport
) {
551 handle_rpc_json(transport
);
556 exception_error("togglePub", e
);
560 function moveToPost(mode
, noscroll
, noexpand
) {
564 var rows
= getVisibleArticleIds();
569 if (!$('RROW-' + getActiveArticleId())) {
570 setActiveArticleId(0);
573 if (!getActiveArticleId()) {
575 prev_id
= rows
[rows
.length
-1]
577 for (var i
= 0; i
< rows
.length
; i
++) {
578 if (rows
[i
] == getActiveArticleId()) {
580 // Account for adjacent identical article ids.
581 if (i
> 0) prev_id
= rows
[i
-1];
583 for (var j
= i
+1; j
< rows
.length
; j
++) {
584 if (rows
[j
] != getActiveArticleId()) {
594 if (mode
== "next") {
595 if (next_id
|| getActiveArticleId()) {
598 var article
= $("RROW-" + getActiveArticleId());
599 var ctr
= $("headlines-frame");
601 if (!noscroll
&& article
&& article
.offsetTop
+ article
.offsetHeight
>
602 ctr
.scrollTop
+ ctr
.offsetHeight
) {
604 scrollArticle(ctr
.offsetHeight
/4);
606 } else if (next_id
) {
607 cdmExpandArticle(next_id
, noexpand
);
608 cdmScrollToArticleId(next_id
, true);
611 } else if (next_id
) {
612 correctHeadlinesOffset(next_id
);
613 view(next_id
, getActiveFeedId(), noexpand
);
618 if (mode
== "prev") {
619 if (prev_id
|| getActiveArticleId()) {
622 var article
= $("RROW-" + getActiveArticleId());
623 var prev_article
= $("RROW-" + prev_id
);
624 var ctr
= $("headlines-frame");
626 if (!getInitParam("cdm_expanded")) {
628 if (!noscroll
&& article
&& article
.offsetTop
< ctr
.scrollTop
) {
629 scrollArticle(-ctr
.offsetHeight
/4);
631 cdmExpandArticle(prev_id
, noexpand
);
632 cdmScrollToArticleId(prev_id
, true);
636 if (!noscroll
&& article
&& article
.offsetTop
< ctr
.scrollTop
) {
637 scrollArticle(-ctr
.offsetHeight
/3);
638 } else if (!noscroll
&& prev_article
&&
639 prev_article
.offsetTop
< ctr
.scrollTop
) {
640 cdmExpandArticle(prev_id
, noexpand
);
641 scrollArticle(-ctr
.offsetHeight
/4);
642 } else if (prev_id
) {
643 cdmExpandArticle(prev_id
, noexpand
);
644 cdmScrollToArticleId(prev_id
, noscroll
);
648 } else if (prev_id
) {
649 correctHeadlinesOffset(prev_id
);
650 view(prev_id
, getActiveFeedId(), noexpand
);
656 exception_error("moveToPost", e
);
660 function toggleSelected(id
, force_on
) {
662 var row
= $("RROW-" + id
);
665 var cb
= dijit
.getEnclosingWidget(
666 row
.getElementsByClassName("rchk")[0]);
668 if (row
.hasClassName('Selected') && !force_on
) {
669 row
.removeClassName('Selected');
670 if (cb
) cb
.attr("checked", false);
672 row
.addClassName('Selected');
673 if (cb
) cb
.attr("checked", true);
677 updateSelectedPrompt();
679 exception_error("toggleSelected", e
);
683 function updateSelectedPrompt() {
685 var count
= getSelectedArticleIds2().size();
686 var elem
= $("selected_prompt");
689 elem
.innerHTML
= ngettext("%d article selected",
690 "%d articles selected", count
).replace("%d", count
);
699 exception_error("updateSelectedPrompt", e
);
703 function toggleUnread_afh(effect
) {
706 var elem
= effect
.element
;
707 elem
.style
.backgroundColor
= "";
710 exception_error("toggleUnread_afh", e
);
714 function toggleUnread(id
, cmode
, effect
) {
717 var row
= $("RROW-" + id
);
719 if (cmode
== undefined || cmode
== 2) {
720 if (row
.hasClassName("Unread")) {
721 row
.removeClassName("Unread");
724 row
.addClassName("Unread");
727 } else if (cmode
== 0) {
729 row
.removeClassName("Unread");
731 } else if (cmode
== 1) {
732 row
.addClassName("Unread");
735 if (cmode
== undefined) cmode
= 2;
737 var query
= "?op=rpc&method=catchupSelected" +
738 "&cmode=" + param_escape(cmode
) + "&ids=" + param_escape(id
);
740 // notify_progress("Loading, please wait...");
742 new Ajax
.Request("backend.php", {
744 onComplete: function(transport
) {
745 handle_rpc_json(transport
);
751 exception_error("toggleUnread", e
);
755 function selectionRemoveLabel(id
, ids
) {
758 if (!ids
) ids
= getSelectedArticleIds2();
760 if (ids
.length
== 0) {
761 alert(__("No articles are selected."));
765 var query
= "?op=article&method=removeFromLabel&ids=" +
766 param_escape(ids
.toString()) + "&lid=" + param_escape(id
);
770 new Ajax
.Request("backend.php", {
772 onComplete: function(transport
) {
773 handle_rpc_json(transport
);
774 show_labels_in_headlines(transport
);
778 exception_error("selectionAssignLabel", e
);
783 function selectionAssignLabel(id
, ids
) {
786 if (!ids
) ids
= getSelectedArticleIds2();
788 if (ids
.length
== 0) {
789 alert(__("No articles are selected."));
793 var query
= "?op=article&method=assignToLabel&ids=" +
794 param_escape(ids
.toString()) + "&lid=" + param_escape(id
);
798 new Ajax
.Request("backend.php", {
800 onComplete: function(transport
) {
801 handle_rpc_json(transport
);
802 show_labels_in_headlines(transport
);
806 exception_error("selectionAssignLabel", e
);
811 function selectionToggleUnread(set_state
, callback
, no_error
, ids
) {
813 var rows
= ids
? ids
: getSelectedArticleIds2();
815 if (rows
.length
== 0 && !no_error
) {
816 alert(__("No articles are selected."));
820 for (var i
= 0; i
< rows
.length
; i
++) {
821 var row
= $("RROW-" + rows
[i
]);
823 if (set_state
== undefined) {
824 if (row
.hasClassName("Unread")) {
825 row
.removeClassName("Unread");
827 row
.addClassName("Unread");
831 if (set_state
== false) {
832 row
.removeClassName("Unread");
835 if (set_state
== true) {
836 row
.addClassName("Unread");
841 updateFloatingTitle(true);
843 if (rows
.length
> 0) {
847 if (set_state
== undefined) {
849 } else if (set_state
== true) {
851 } else if (set_state
== false) {
855 var query
= "?op=rpc&method=catchupSelected" +
856 "&cmode=" + cmode
+ "&ids=" + param_escape(rows
.toString());
858 notify_progress("Loading, please wait...");
860 new Ajax
.Request("backend.php", {
862 onComplete: function(transport
) {
863 handle_rpc_json(transport
);
864 if (callback
) callback(transport
);
870 exception_error("selectionToggleUnread", e
);
875 function selectionToggleMarked(sel_state
, callback
, no_error
, ids
) {
878 var rows
= ids
? ids
: getSelectedArticleIds2();
880 if (rows
.length
== 0 && !no_error
) {
881 alert(__("No articles are selected."));
885 for (var i
= 0; i
< rows
.length
; i
++) {
886 toggleMark(rows
[i
], true, true);
889 if (rows
.length
> 0) {
891 var query
= "?op=rpc&method=markSelected&ids=" +
892 param_escape(rows
.toString()) + "&cmode=2";
894 new Ajax
.Request("backend.php", {
896 onComplete: function(transport
) {
897 handle_rpc_json(transport
);
898 if (callback
) callback(transport
);
904 exception_error("selectionToggleMarked", e
);
909 function selectionTogglePublished(sel_state
, callback
, no_error
, ids
) {
912 var rows
= ids
? ids
: getSelectedArticleIds2();
914 if (rows
.length
== 0 && !no_error
) {
915 alert(__("No articles are selected."));
919 for (var i
= 0; i
< rows
.length
; i
++) {
920 togglePub(rows
[i
], true, true);
923 if (rows
.length
> 0) {
925 var query
= "?op=rpc&method=publishSelected&ids=" +
926 param_escape(rows
.toString()) + "&cmode=2";
928 new Ajax
.Request("backend.php", {
930 onComplete: function(transport
) {
931 handle_rpc_json(transport
);
937 exception_error("selectionToggleMarked", e
);
941 function getSelectedArticleIds2() {
945 $$("#headlines-frame > div[id*=RROW][class*=Selected]").each(
947 rv
.push(child
.id
.replace("RROW-", ""));
953 function getLoadedArticleIds() {
956 var children
= $$("#headlines-frame > div[id*=RROW-]");
958 children
.each(function(child
) {
959 rv
.push(child
.id
.replace("RROW-", ""));
966 // mode = all,none,unread,invert,marked,published
967 function selectArticles(mode
, query
) {
970 if (!query
) query
= "#headlines-frame > div[id*=RROW]";
972 var children
= $$(query
);
974 children
.each(function(child
) {
975 var id
= child
.id
.replace("RROW-", "");
977 var cb
= dijit
.getEnclosingWidget(
978 child
.getElementsByClassName("rchk")[0]);
981 child
.addClassName("Selected");
982 if (cb
) cb
.attr("checked", true);
983 } else if (mode
== "unread") {
984 if (child
.hasClassName("Unread")) {
985 child
.addClassName("Selected");
986 if (cb
) cb
.attr("checked", true);
988 child
.removeClassName("Selected");
989 if (cb
) cb
.attr("checked", false);
991 } else if (mode
== "marked") {
992 if (child
.hasClassName("marked")) {
993 child
.addClassName("Selected");
994 if (cb
) cb
.attr("checked", true);
996 child
.removeClassName("Selected");
997 if (cb
) cb
.attr("checked", false);
999 } else if (mode
== "published") {
1000 if (child
.hasClassName("published")) {
1001 child
.addClassName("Selected");
1002 if (cb
) cb
.attr("checked", true);
1004 child
.removeClassName("Selected");
1005 if (cb
) cb
.attr("checked", false);
1008 } else if (mode
== "invert") {
1009 if (child
.hasClassName("Selected")) {
1010 child
.removeClassName("Selected");
1011 if (cb
) cb
.attr("checked", false);
1013 child
.addClassName("Selected");
1014 if (cb
) cb
.attr("checked", true);
1018 child
.removeClassName("Selected");
1019 if (cb
) cb
.attr("checked", false);
1023 updateSelectedPrompt();
1026 exception_error("selectArticles", e
);
1030 function deleteSelection() {
1034 var rows
= getSelectedArticleIds2();
1036 if (rows
.length
== 0) {
1037 alert(__("No articles are selected."));
1041 var fn
= getFeedName(getActiveFeedId(), activeFeedIsCat());
1044 if (getActiveFeedId() != 0) {
1045 str
= ngettext("Delete %d selected article in %s?", "Delete %d selected articles in %s?" , rows
.length
);
1047 str
= ngettext("Delete %d selected article?", "Delete %d selected articles?", rows
.length
);
1050 str
= str
.replace("%d", rows
.length
);
1051 str
= str
.replace("%s", fn
);
1053 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str
)) {
1057 query
= "?op=rpc&method=delete&ids=" + param_escape(rows
);
1061 new Ajax
.Request("backend.php", {
1063 onComplete: function(transport
) {
1064 handle_rpc_json(transport
);
1069 exception_error("deleteSelection", e
);
1073 function archiveSelection() {
1077 var rows
= getSelectedArticleIds2();
1079 if (rows
.length
== 0) {
1080 alert(__("No articles are selected."));
1084 var fn
= getFeedName(getActiveFeedId(), activeFeedIsCat());
1088 if (getActiveFeedId() != 0) {
1089 str
= ngettext("Archive %d selected article in %s?", "Archive %d selected articles in %s?", rows
.length
);
1092 str
= ngettext("Move %d archived article back?", "Move %d archived articles back?", rows
.length
);
1094 str
+= " " + __("Please note that unstarred articles might get purged on next feed update.");
1099 str
= str
.replace("%d", rows
.length
);
1100 str
= str
.replace("%s", fn
);
1102 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str
)) {
1106 query
= "?op=rpc&method="+op
+"&ids=" + param_escape(rows
);
1110 for (var i
= 0; i
< rows
.length
; i
++) {
1111 cache_delete("article:" + rows
[i
]);
1114 new Ajax
.Request("backend.php", {
1116 onComplete: function(transport
) {
1117 handle_rpc_json(transport
);
1122 exception_error("archiveSelection", e
);
1126 function catchupSelection() {
1130 var rows
= getSelectedArticleIds2();
1132 if (rows
.length
== 0) {
1133 alert(__("No articles are selected."));
1137 var fn
= getFeedName(getActiveFeedId(), activeFeedIsCat());
1139 var str
= ngettext("Mark %d selected article in %s as read?", "Mark %d selected articles in %s as read?", rows
.length
);
1141 str
= str
.replace("%d", rows
.length
);
1142 str
= str
.replace("%s", fn
);
1144 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str
)) {
1148 selectionToggleUnread(false, 'viewCurrentFeed()', true);
1151 exception_error("catchupSelection", e
);
1155 function editArticleTags(id
) {
1156 var query
= "backend.php?op=article&method=editArticleTags¶m=" + param_escape(id
);
1158 if (dijit
.byId("editTagsDlg"))
1159 dijit
.byId("editTagsDlg").destroyRecursive();
1161 dialog
= new dijit
.Dialog({
1163 title
: __("Edit article Tags"),
1164 style
: "width: 600px",
1165 execute: function() {
1166 if (this.validate()) {
1167 var query
= dojo
.objectToQuery(this.attr('value'));
1169 notify_progress("Saving article tags...", true);
1171 new Ajax
.Request("backend.php", {
1173 onComplete: function(transport
) {
1178 var data
= JSON
.parse(transport
.responseText
);
1185 var tags
= $("ATSTR-" + id
);
1186 var tooltip
= dijit
.byId("ATSTRTIP-" + id
);
1188 if (tags
) tags
.innerHTML
= data
.content
;
1189 if (tooltip
) tooltip
.attr('label', data
.content_full
);
1192 exception_error("editArticleTags/inner", e
);
1201 var tmph
= dojo
.connect(dialog
, 'onLoad', function() {
1202 dojo
.disconnect(tmph
);
1204 new Ajax
.Autocompleter('tags_str', 'tags_choices',
1205 "backend.php?op=article&method=completeTags",
1206 { tokens
: ',', paramName
: "search" });
1213 function cdmScrollToArticleId(id
, force
) {
1215 var ctr
= $("headlines-frame");
1216 var e
= $("RROW-" + id
);
1218 if (!e
|| !ctr
) return;
1220 if (force
|| e
.offsetTop
+e
.offsetHeight
> (ctr
.scrollTop
+ctr
.offsetHeight
) ||
1221 e
.offsetTop
< ctr
.scrollTop
) {
1223 // expanded cdm has a 4px margin now
1224 ctr
.scrollTop
= parseInt(e
.offsetTop
) - 4;
1228 exception_error("cdmScrollToArticleId", e
);
1232 function setActiveArticleId(id
) {
1233 _active_article_id
= id
;
1234 PluginHost
.run(PluginHost
.HOOK_ARTICLE_SET_ACTIVE
, _active_article_id
);
1237 function getActiveArticleId() {
1238 return _active_article_id
;
1241 function postMouseIn(e
, id
) {
1242 post_under_pointer
= id
;
1245 function postMouseOut(id
) {
1246 post_under_pointer
= false;
1249 function unpackVisibleHeadlines() {
1251 if (!isCdmMode() || !getInitParam("cdm_expanded")) return;
1253 $$("#headlines-frame > div[id*=RROW]").each(
1255 if (child
.offsetTop
<= $("headlines-frame").scrollTop
+
1256 $("headlines-frame").offsetHeight
) {
1258 var cencw
= $("CENCW-" + child
.id
.replace("RROW-", ""));
1261 PluginHost
.run(PluginHost
.HOOK_ARTICLE_RENDERED_CDM
, child
);
1263 cencw
.innerHTML
= htmlspecialchars_decode(cencw
.innerHTML
);
1264 cencw
.setAttribute('id', '');
1265 Element
.show(cencw
);
1272 exception_error("unpackVisibleHeadlines", e
);
1276 function headlines_scroll_handler(e
) {
1278 var hsp
= $("headlines-spacer");
1280 unpackVisibleHeadlines();
1282 // set topmost child in the buffer as active
1283 if (isCdmMode() && getInitParam("cdm_auto_catchup") == 1 &&
1284 getSelectedArticleIds2().length
<= 1 &&
1285 getInitParam("cdm_expanded")) {
1286 var rows
= $$("#headlines-frame > div[id*=RROW]");
1288 for (var i
= 0; i
< rows
.length
; i
++) {
1289 var child
= rows
[i
];
1291 if ($("headlines-frame").scrollTop
<= child
.offsetTop
&&
1292 child
.offsetTop
- $("headlines-frame").scrollTop
< 100 &&
1293 child
.id
.replace("RROW-", "") != _active_article_id
) {
1295 if (_active_article_id
) {
1296 var row
= $("RROW-" + _active_article_id
);
1297 if (row
) row
.removeClassName("active");
1300 _active_article_id
= child
.id
.replace("RROW-", "");
1301 showArticleInHeadlines(_active_article_id
, true);
1302 updateSelectedPrompt();
1308 if (!_infscroll_disable
) {
1309 if ((hsp
&& e
.scrollTop
+ e
.offsetHeight
>= hsp
.offsetTop
- hsp
.offsetHeight
) ||
1310 (e
.scrollHeight
!= 0 &&
1311 ((e
.scrollTop
+ e
.offsetHeight
) / e
.scrollHeight
>= 0.7))) {
1314 hsp
.innerHTML
= "<img src='images/indicator_tiny.gif'> " +
1315 __("Loading, please wait...");
1317 loadMoreHeadlines();
1323 if (_infscroll_disable
)
1324 hsp
.innerHTML
= "<a href='#' onclick='openNextUnreadFeed()'>" +
1325 __("Click to open next unread feed.") + "</a>";
1331 updateFloatingTitle();
1334 if (getInitParam("cdm_auto_catchup") == 1) {
1336 // let's get DOM some time to settle down
1337 var ts
= new Date().getTime();
1338 if (ts
- _last_headlines_update
< 100) return;
1340 $$("#headlines-frame > div[id*=RROW][class*=Unread]").each(
1342 if (child
.hasClassName("Unread") && $("headlines-frame").scrollTop
>
1343 (child
.offsetTop
+ child
.offsetHeight
/2)) {
1345 var id
= child
.id
.replace("RROW-", "");
1347 if (catchup_id_batch
.indexOf(id
) == -1)
1348 catchup_id_batch
.push(id
);
1350 //console.log("auto_catchup_batch: " + catchup_id_batch.toString());
1355 if (catchup_id_batch
.length
> 0) {
1356 window
.clearTimeout(catchup_timeout_id
);
1358 if (!_infscroll_request_sent
) {
1359 catchup_timeout_id
= window
.setTimeout('catchupBatchedArticles()',
1364 if (_infscroll_disable
) {
1365 var child
= $$("#headlines-frame div[id*=RROW]").last();
1367 if (child
&& $("headlines-frame").scrollTop
>
1368 (child
.offsetTop
+ child
.offsetHeight
/2)) {
1370 console
.log("we seem to be at an end");
1372 if (getInitParam("on_catchup_show_next_feed") == "1") {
1373 openNextUnreadFeed();
1380 console
.warn("headlines_scroll_handler: " + e
);
1384 function openNextUnreadFeed() {
1386 var is_cat
= activeFeedIsCat();
1387 var nuf
= getNextUnreadFeed(getActiveFeedId(), is_cat
);
1388 if (nuf
) viewfeed(nuf
, '', is_cat
);
1390 exception_error("openNextUnreadFeed", e
);
1394 function catchupBatchedArticles() {
1396 if (catchup_id_batch
.length
> 0 && !_infscroll_request_sent
) {
1398 // make a copy of the array
1399 var batch
= catchup_id_batch
.slice();
1400 var query
= "?op=rpc&method=catchupSelected" +
1401 "&cmode=0&ids=" + param_escape(batch
.toString());
1405 new Ajax
.Request("backend.php", {
1407 onComplete: function(transport
) {
1408 handle_rpc_json(transport
);
1410 reply
= JSON
.parse(transport
.responseText
);
1411 var batch
= reply
.ids
;
1413 batch
.each(function(id
) {
1415 var elem
= $("RROW-" + id
);
1416 if (elem
) elem
.removeClassName("Unread");
1417 catchup_id_batch
.remove(id
);
1420 updateFloatingTitle(true);
1426 exception_error("catchupBatchedArticles", e
);
1430 function catchupRelativeToArticle(below
, id
) {
1434 if (!id
) id
= getActiveArticleId();
1437 alert(__("No article is selected."));
1441 var visible_ids
= getVisibleArticleIds();
1443 var ids_to_mark
= new Array();
1446 for (var i
= 0; i
< visible_ids
.length
; i
++) {
1447 if (visible_ids
[i
] != id
) {
1448 var e
= $("RROW-" + visible_ids
[i
]);
1450 if (e
&& e
.hasClassName("Unread")) {
1451 ids_to_mark
.push(visible_ids
[i
]);
1458 for (var i
= visible_ids
.length
-1; i
>= 0; i
--) {
1459 if (visible_ids
[i
] != id
) {
1460 var e
= $("RROW-" + visible_ids
[i
]);
1462 if (e
&& e
.hasClassName("Unread")) {
1463 ids_to_mark
.push(visible_ids
[i
]);
1471 if (ids_to_mark
.length
== 0) {
1472 alert(__("No articles found to mark"));
1474 var msg
= ngettext("Mark %d article as read?", "Mark %d articles as read?", ids_to_mark
.length
).replace("%d", ids_to_mark
.length
);
1476 if (getInitParam("confirm_feed_catchup") != 1 || confirm(msg
)) {
1478 for (var i
= 0; i
< ids_to_mark
.length
; i
++) {
1479 var e
= $("RROW-" + ids_to_mark
[i
]);
1480 e
.removeClassName("Unread");
1483 var query
= "?op=rpc&method=catchupSelected" +
1484 "&cmode=0" + "&ids=" + param_escape(ids_to_mark
.toString());
1486 new Ajax
.Request("backend.php", {
1488 onComplete: function(transport
) {
1489 handle_rpc_json(transport
);
1496 exception_error("catchupRelativeToArticle", e
);
1500 function cdmCollapseArticle(event
, id
, unmark
) {
1502 if (unmark
== undefined) unmark
= true;
1504 var row
= $("RROW-" + id
);
1505 var elem
= $("CICD-" + id
);
1508 var collapse
= $$("div#RROW-" + id
+
1509 " span[class='collapseBtn']")[0];
1512 Element
.show("CEXC-" + id
);
1513 Element
.hide(collapse
);
1516 row
.removeClassName("active");
1518 markHeadline(id
, false);
1520 if (id
== getActiveArticleId()) {
1521 setActiveArticleId(0);
1524 updateSelectedPrompt();
1527 if (event
) Event
.stop(event
);
1529 PluginHost
.run(PluginHost
.HOOK_ARTICLE_COLLAPSED
, id
);
1531 if (row
.offsetTop
< $("headlines-frame").scrollTop
)
1532 scrollToRowId(row
.id
);
1534 Element
.hide("floatingTitle");
1535 $("floatingTitle").setAttribute("rowid", false);
1539 exception_error("cdmCollapseArticle", e
);
1543 function cdmExpandArticle(id
, noexpand
) {
1545 console
.log("cdmExpandArticle " + id
);
1547 if (!$("RROW-" + id
)) return false;
1549 var oldrow
= $("RROW-" + getActiveArticleId());
1551 var elem
= $("CICD-" + getActiveArticleId());
1553 if (id
== getActiveArticleId() && Element
.visible(elem
))
1556 selectArticles("none");
1558 var old_offset
= $("RROW-" + id
).offsetTop
;
1560 if (getActiveArticleId() && elem
&& !getInitParam("cdm_expanded")) {
1561 var collapse
= $$("div#RROW-" + getActiveArticleId() +
1562 " span[class='collapseBtn']")[0];
1565 Element
.show("CEXC-" + getActiveArticleId());
1566 Element
.hide(collapse
);
1569 if (oldrow
) oldrow
.removeClassName("active");
1571 setActiveArticleId(id
);
1573 elem
= $("CICD-" + id
);
1575 var collapse
= $$("div#RROW-" + id
+
1576 " span[class='collapseBtn']")[0];
1578 var cencw
= $("CENCW-" + id
);
1580 if (!Element
.visible(elem
) && !noexpand
) {
1582 cencw
.innerHTML
= htmlspecialchars_decode(cencw
.innerHTML
);
1583 cencw
.setAttribute('id', '');
1584 Element
.show(cencw
);
1588 Element
.hide("CEXC-" + id
);
1589 Element
.show(collapse
);
1592 var new_offset
= $("RROW-" + id
).offsetTop
;
1594 if (old_offset
> new_offset
)
1595 $("headlines-frame").scrollTop
-= (old_offset
-new_offset
);
1598 toggleUnread(id
, 0, true);
1600 $("RROW-" + id
).addClassName("active");
1602 PluginHost
.run(PluginHost
.HOOK_ARTICLE_EXPANDED
, id
);
1605 exception_error("cdmExpandArticle", e
);
1611 function getArticleUnderPointer() {
1612 return post_under_pointer
;
1615 function scrollArticle(offset
) {
1618 var ci
= $("content-insert");
1620 ci
.scrollTop
+= offset
;
1623 var hi
= $("headlines-frame");
1625 hi
.scrollTop
+= offset
;
1630 exception_error("scrollArticle", e
);
1634 function show_labels_in_headlines(transport
) {
1636 var data
= JSON
.parse(transport
.responseText
);
1639 data
['info-for-headlines'].each(function(elem
) {
1640 $$(".HLLCTR-" + elem
.id
).each(function(ctr
) {
1641 ctr
.innerHTML
= elem
.labels
;
1646 exception_error("show_labels_in_headlines", e
);
1650 function dismissArticle(id
) {
1652 var elem
= $("RROW-" + id
);
1656 toggleUnread(id
, 0, true);
1658 new Effect
.Fade(elem
, {duration
: 0.5});
1660 // Remove the content, too
1661 var elem_content
= $("CICD-" + id
);
1663 Element
.remove(elem_content
);
1666 if (id
== getActiveArticleId()) {
1667 setActiveArticleId(0);
1671 exception_error("dismissArticle", e
);
1675 function dismissSelectedArticles() {
1678 var ids
= getVisibleArticleIds();
1682 for (var i
= 0; i
< ids
.length
; i
++) {
1683 var elem
= $("RROW-" + ids
[i
]);
1685 if (elem
.className
&& elem
.hasClassName("Selected") &&
1686 ids
[i
] != getActiveArticleId()) {
1687 new Effect
.Fade(elem
, {duration
: 0.5});
1690 // Remove the content, too
1691 var elem_content
= $("CICD-" + ids
[i
]);
1693 Element
.remove(elem_content
);
1701 selectionToggleUnread(false);
1705 exception_error("dismissSelectedArticles", e
);
1709 function dismissReadArticles() {
1712 var ids
= getVisibleArticleIds();
1715 for (var i
= 0; i
< ids
.length
; i
++) {
1716 var elem
= $("RROW-" + ids
[i
]);
1718 if (elem
.className
&& !elem
.hasClassName("Unread") &&
1719 !elem
.hasClassName("Selected")) {
1721 new Effect
.Fade(elem
, {duration
: 0.5});
1723 // Remove the content, too
1724 var elem_content
= $("CICD-" + ids
[i
]);
1726 Element
.remove(elem_content
);
1734 exception_error("dismissReadArticles", e
);
1738 function getVisibleArticleIds() {
1743 getLoadedArticleIds().each(function(id
) {
1744 var elem
= $("RROW-" + id
);
1745 if (elem
&& Element
.visible(elem
))
1750 exception_error("getVisibleArticleIds", e
);
1756 function cdmClicked(event
, id
) {
1758 //var shift_key = event.shiftKey;
1760 if (!event
.ctrlKey
) {
1762 if (!getInitParam("cdm_expanded")) {
1763 return cdmExpandArticle(id
);
1766 var elem
= $("RROW-" + getActiveArticleId());
1768 if (elem
) elem
.removeClassName("active");
1770 selectArticles("none");
1773 var elem
= $("RROW-" + id
);
1774 var article_is_unread
= elem
.hasClassName("Unread");
1776 elem
.removeClassName("Unread");
1777 elem
.addClassName("active");
1779 setActiveArticleId(id
);
1781 if (article_is_unread
) {
1782 decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
1783 updateFloatingTitle(true);
1786 var query
= "?op=rpc&method=catchupSelected" +
1787 "&cmode=0&ids=" + param_escape(id
);
1789 new Ajax
.Request("backend.php", {
1791 onComplete: function(transport
) {
1792 handle_rpc_json(transport
);
1795 return !event
.shiftKey
;
1798 } else if (event
.target
.parents(".cdmHeader").length
> 0) {
1800 toggleSelected(id
, true);
1802 var elem
= $("RROW-" + id
);
1803 var article_is_unread
= elem
.hasClassName("Unread");
1805 if (article_is_unread
) {
1806 decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
1809 toggleUnread(id
, 0, false);
1811 openArticleInNewWindow(id
);
1814 var unread_in_buffer
= $$("#headlines-frame > div[id*=RROW][class*=Unread]").length
1815 request_counters(unread_in_buffer
== 0);
1818 exception_error("cdmClicked");
1824 function hlClicked(event
, id
) {
1826 if (event
.which
== 2) {
1829 } else if (event
.ctrlKey
) {
1830 toggleSelected(id
, true);
1831 toggleUnread(id
, 0, false);
1832 openArticleInNewWindow(id
);
1840 exception_error("hlClicked");
1844 function getFirstVisibleHeadlineId() {
1845 var rows
= getVisibleArticleIds();
1850 function getLastVisibleHeadlineId() {
1851 var rows
= getVisibleArticleIds();
1852 return rows
[rows
.length
-1];
1855 function openArticleInNewWindow(id
) {
1856 toggleUnread(id
, 0, false);
1857 window
.open("backend.php?op=article&method=redirect&id=" + id
);
1860 function isCdmMode() {
1861 return getInitParam("combined_display_mode");
1864 function markHeadline(id
, marked
) {
1865 if (marked
== undefined) marked
= true;
1867 var row
= $("RROW-" + id
);
1869 var check
= dijit
.getEnclosingWidget(
1870 row
.getElementsByClassName("rchk")[0]);
1873 check
.attr("checked", marked
);
1877 row
.addClassName("Selected");
1879 row
.removeClassName("Selected");
1883 function getRelativePostIds(id
, limit
) {
1889 if (!limit
) limit
= 6; //3
1891 var ids
= getVisibleArticleIds();
1893 for (var i
= 0; i
< ids
.length
; i
++) {
1895 for (var k
= 1; k
<= limit
; k
++) {
1896 //if (i > k-1) tmp.push(ids[i-k]);
1897 if (i
< ids
.length
-k
) tmp
.push(ids
[i
+k
]);
1904 exception_error("getRelativePostIds", e
);
1910 function correctHeadlinesOffset(id
) {
1914 var container
= $("headlines-frame");
1915 var row
= $("RROW-" + id
);
1917 if (!container
|| !row
) return;
1919 var viewport
= container
.offsetHeight
;
1921 var rel_offset_top
= row
.offsetTop
- container
.scrollTop
;
1922 var rel_offset_bottom
= row
.offsetTop
+ row
.offsetHeight
- container
.scrollTop
;
1924 //console.log("Rtop: " + rel_offset_top + " Rbtm: " + rel_offset_bottom);
1925 //console.log("Vport: " + viewport);
1927 if (rel_offset_top
<= 0 || rel_offset_top
> viewport
) {
1928 container
.scrollTop
= row
.offsetTop
;
1929 } else if (rel_offset_bottom
> viewport
) {
1931 /* doesn't properly work with Opera in some cases because
1932 Opera fucks up element scrolling */
1934 container
.scrollTop
= row
.offsetTop
+ row
.offsetHeight
- viewport
;
1938 exception_error("correctHeadlinesOffset", e
);
1943 function headlineActionsChange(elem
) {
1946 elem
.attr('value', 'false');
1948 exception_error("headlineActionsChange", e
);
1952 function closeArticlePanel() {
1954 if (dijit
.byId("content-insert"))
1955 dijit
.byId("headlines-wrap-inner").removeChild(
1956 dijit
.byId("content-insert"));
1959 function initFloatingMenu() {
1961 if (dijit
.byId("floatingMenu"))
1962 dijit
.byId("floatingMenu").destroyRecursive();
1964 var menu
= new dijit
.Menu({
1966 targetNodeIds
: ["floatingTitle"]
1969 var id
= $("floatingTitle").getAttribute("rowid").replace("RROW-", "");
1971 headlinesMenuCommon(menu
, id
);
1975 exception_error("initFloatingMenu", e
);
1979 function headlinesMenuCommon(menu
, base_id
) {
1982 menu
.addChild(new dijit
.MenuItem({
1983 label
: __("Open original article"),
1984 onClick: function(event
) {
1985 openArticleInNewWindow(base_id
? base_id
: this.getParent().callerRowId
);
1988 menu
.addChild(new dijit
.MenuItem({
1989 label
: __("Display article URL"),
1990 onClick: function(event
) {
1991 displayArticleUrl(base_id
? base_id
: this.getParent().callerRowId
);
1994 menu
.addChild(new dijit
.MenuSeparator());
1996 menu
.addChild(new dijit
.MenuItem({
1997 label
: __("Toggle unread"),
1998 onClick: function(event
) {
1999 var ids
= getSelectedArticleIds2();
2001 var id
= (base_id
? base_id
: this.getParent().callerRowId
) + "";
2002 ids
= ids
.size() != 0 && ids
.indexOf(id
) != -1 ? ids
: [id
];
2004 selectionToggleUnread(undefined, false, true, ids
);
2007 menu
.addChild(new dijit
.MenuItem({
2008 label
: __("Toggle starred"),
2009 onClick: function(event
) {
2010 var ids
= getSelectedArticleIds2();
2012 var id
= (base_id
? base_id
: this.getParent().callerRowId
) + "";
2013 ids
= ids
.size() != 0 && ids
.indexOf(id
) != -1 ? ids
: [id
];
2015 selectionToggleMarked(undefined, false, true, ids
);
2018 menu
.addChild(new dijit
.MenuItem({
2019 label
: __("Toggle published"),
2020 onClick: function(event
) {
2021 var ids
= getSelectedArticleIds2();
2023 var id
= (base_id
? base_id
: this.getParent().callerRowId
) + "";
2024 ids
= ids
.size() != 0 && ids
.indexOf(id
) != -1 ? ids
: [id
];
2026 selectionTogglePublished(undefined, false, true, ids
);
2029 menu
.addChild(new dijit
.MenuSeparator());
2031 menu
.addChild(new dijit
.MenuItem({
2032 label
: __("Mark above as read"),
2033 onClick: function(event
) {
2034 catchupRelativeToArticle(0, base_id
? base_id
: this.getParent().callerRowId
);
2037 menu
.addChild(new dijit
.MenuItem({
2038 label
: __("Mark below as read"),
2039 onClick: function(event
) {
2040 catchupRelativeToArticle(1, base_id
? base_id
: this.getParent().callerRowId
);
2044 var labels
= dijit
.byId("feedTree").model
.getItemsInCategory(-2);
2048 menu
.addChild(new dijit
.MenuSeparator());
2050 var labelAddMenu
= new dijit
.Menu({ownerMenu
: menu
});
2051 var labelDelMenu
= new dijit
.Menu({ownerMenu
: menu
});
2053 labels
.each(function(label
) {
2054 var id
= label
.id
[0];
2055 var bare_id
= id
.substr(id
.indexOf(":")+1);
2056 var name
= label
.name
[0];
2058 bare_id
= feed_to_label_id(bare_id
);
2060 labelAddMenu
.addChild(new dijit
.MenuItem({
2063 onClick: function(event
) {
2064 var ids
= getSelectedArticleIds2();
2066 var id
= (base_id
? base_id
: this.getParent().ownerMenu
.callerRowId
) + "";
2068 ids
= ids
.size() != 0 && ids
.indexOf(id
) != -1 ? ids
: [id
];
2070 selectionAssignLabel(this.labelId
, ids
);
2073 labelDelMenu
.addChild(new dijit
.MenuItem({
2076 onClick: function(event
) {
2077 var ids
= getSelectedArticleIds2();
2079 var id
= (base_id
? base_id
: this.getParent().ownerMenu
.callerRowId
) + "";
2081 ids
= ids
.size() != 0 && ids
.indexOf(id
) != -1 ? ids
: [id
];
2083 selectionRemoveLabel(this.labelId
, ids
);
2088 menu
.addChild(new dijit
.PopupMenuItem({
2089 label
: __("Assign label"),
2090 popup
: labelAddMenu
,
2093 menu
.addChild(new dijit
.PopupMenuItem({
2094 label
: __("Remove label"),
2095 popup
: labelDelMenu
,
2102 exception_error("headlinesMenuCommon", e
);
2106 function initHeadlinesMenu() {
2108 if (dijit
.byId("headlinesMenu"))
2109 dijit
.byId("headlinesMenu").destroyRecursive();
2114 nodes
= $$("#headlines-frame > div[id*=RROW]");
2116 nodes
= $$("#headlines-frame span[id*=RTITLE]");
2119 nodes
.each(function(node
) {
2123 var menu
= new dijit
.Menu({
2124 id
: "headlinesMenu",
2128 var tmph
= dojo
.connect(menu
, '_openMyself', function (event
) {
2129 var callerNode
= event
.target
, match
= null, tries
= 0;
2131 while (match
== null && callerNode
&& tries
<= 3) {
2132 match
= callerNode
.id
.match("^[A-Z]+[-]([0-9]+)$");
2133 callerNode
= callerNode
.parentNode
;
2137 if (match
) this.callerRowId
= parseInt(match
[1]);
2141 headlinesMenuCommon(menu
, false);
2145 /* vgroup feed title menu */
2147 var nodes
= $$("#headlines-frame > div[class='cdmFeedTitle']");
2150 nodes
.each(function(node
) {
2154 if (ids
.length
> 0) {
2155 if (dijit
.byId("headlinesFeedTitleMenu"))
2156 dijit
.byId("headlinesFeedTitleMenu").destroyRecursive();
2158 var menu
= new dijit
.Menu({
2159 id
: "headlinesFeedTitleMenu",
2163 var tmph
= dojo
.connect(menu
, '_openMyself', function (event
) {
2164 var callerNode
= event
.target
, match
= null, tries
= 0;
2166 while (match
== null && callerNode
&& tries
<= 3) {
2167 console
.log(callerNode
.id
);
2169 match
= callerNode
.id
.match("^[A-Z]+[-]([0-9]+)$");
2170 callerNode
= callerNode
.parentNode
;
2173 console
.log(match
[1]);
2176 if (match
) this.callerRowId
= parseInt(match
[1]);
2180 menu
.addChild(new dijit
.MenuItem({
2181 label
: __("Select articles in group"),
2182 onClick: function(event
) {
2183 selectArticles("all",
2184 "#headlines-frame > div[id*=RROW]"+
2185 "[orig-feed-id='"+menu
.callerRowId
+"']");
2189 menu
.addChild(new dijit
.MenuItem({
2190 label
: __("Mark group as read"),
2191 onClick: function(event
) {
2192 selectArticles("none");
2193 selectArticles("all",
2194 "#headlines-frame > div[id*=RROW]"+
2195 "[orig-feed-id='"+menu
.callerRowId
+"']");
2201 menu
.addChild(new dijit
.MenuItem({
2202 label
: __("Mark feed as read"),
2203 onClick: function(event
) {
2204 catchupFeedInGroup(menu
.callerRowId
);
2212 exception_error("initHeadlinesMenu", e
);
2216 function cache_set(id
, obj
) {
2217 //console.log("cache_set: " + id);
2220 sessionStorage
[id
] = obj
;
2222 sessionStorage
.clear();
2226 function cache_get(id
) {
2228 return sessionStorage
[id
];
2231 function cache_clear() {
2233 sessionStorage
.clear();
2236 function cache_delete(id
) {
2238 sessionStorage
.removeItem(id
);
2241 function cancelSearch() {
2246 exception_error("cancelSearch", e
);
2250 function setSelectionScore() {
2252 var ids
= getSelectedArticleIds2();
2254 if (ids
.length
> 0) {
2257 var score
= prompt(__("Please enter new score for selected articles:"), score
);
2259 if (score
!= undefined) {
2260 var query
= "op=article&method=setScore&id=" + param_escape(ids
.toString()) +
2261 "&score=" + param_escape(score
);
2263 new Ajax
.Request("backend.php", {
2265 onComplete: function(transport
) {
2266 var reply
= JSON
.parse(transport
.responseText
);
2270 ids
.each(function(id
) {
2271 var row
= $("RROW-" + id
);
2274 var pic
= row
.getElementsByClassName("hlScorePic")[0];
2277 pic
.src
= pic
.src
.replace(/score_.*?\.png/,
2278 reply
["score_pic"]);
2279 pic
.setAttribute("score", score
);
2288 alert(__("No articles are selected."));
2291 exception_error("setSelectionScore", e
);
2295 function changeScore(id
, pic
) {
2297 var score
= pic
.getAttribute("score");
2299 var new_score
= prompt(__("Please enter new score for this article:"), score
);
2301 if (new_score
!= undefined) {
2303 var query
= "op=article&method=setScore&id=" + param_escape(id
) +
2304 "&score=" + param_escape(new_score
);
2306 new Ajax
.Request("backend.php", {
2308 onComplete: function(transport
) {
2309 var reply
= JSON
.parse(transport
.responseText
);
2312 pic
.src
= pic
.src
.replace(/score_.*?\.png/, reply
["score_pic"]);
2313 pic
.setAttribute("score", new_score
);
2318 exception_error("changeScore", e
);
2322 function displayArticleUrl(id
) {
2324 var query
= "op=rpc&method=getlinktitlebyid&id=" + param_escape(id
);
2326 new Ajax
.Request("backend.php", {
2328 onComplete: function(transport
) {
2329 var reply
= JSON
.parse(transport
.responseText
);
2331 if (reply
&& reply
.link
) {
2332 prompt(__("Article URL:"), reply
.link
);
2336 exception_error("changeScore", e
);
2340 function openSelectedAttachment(elem
) {
2342 var url
= elem
[elem
.selectedIndex
].value
;
2346 elem
.selectedIndex
= 0;
2350 exception_error("openSelectedAttachment", e
);
2354 function scrollToRowId(id
) {
2359 $("headlines-frame").scrollTop
= row
.offsetTop
;
2362 exception_error("scrollToRowId", e
);
2366 function updateFloatingTitle(unread_only
) {
2368 if (!isCdmMode()) return;
2370 var hf
= $("headlines-frame");
2372 var elems
= $$("#headlines-frame > div[id*=RROW]");
2374 for (var i
= 0; i
< elems
.length
; i
++) {
2376 var child
= elems
[i
];
2378 if (child
&& child
.offsetTop
+ child
.offsetHeight
> hf
.scrollTop
) {
2380 var header
= child
.getElementsByClassName("cdmHeader")[0];
2382 if (unread_only
|| child
.id
!= $("floatingTitle").getAttribute("rowid")) {
2383 if (child
.id
!= $("floatingTitle").getAttribute("rowid")) {
2384 $("floatingTitle").setAttribute("rowid", child
.id
);
2385 $("floatingTitle").innerHTML
= header
.innerHTML
;
2386 $("floatingTitle").firstChild
.innerHTML
= "<img class='anchor markedPic' src='images/page_white_go.png' onclick=\"scrollToRowId('"+child
.id
+"')\">" + $("floatingTitle").firstChild
.innerHTML
;
2390 var cb
= $$("#floatingTitle .dijitCheckBox")[0];
2393 cb
.parentNode
.removeChild(cb
);
2396 if (child
.hasClassName("Unread"))
2397 $("floatingTitle").addClassName("Unread");
2399 $("floatingTitle").removeClassName("Unread");
2401 PluginHost
.run(PluginHost
.HOOK_FLOATING_TITLE
, child
);
2404 if (child
.offsetTop
< hf
.scrollTop
- header
.offsetHeight
&&
2405 child
.offsetTop
+ child
.offsetHeight
- hf
.scrollTop
> header
.offsetHeight
)
2406 Element
.show("floatingTitle");
2408 Element
.hide("floatingTitle");
2416 exception_error("updateFloatingTitle", e
);