1 var _active_article_id
= 0;
3 var vgroup_last_feed
= false;
4 var post_under_pointer
= false;
6 var last_requested_article
= false;
8 var catchup_id_batch
= [];
9 var catchup_timeout_id
= false;
11 var cids_requested
= [];
12 var loaded_article_ids
= [];
13 var _last_headlines_update
= 0;
14 var _headlines_scroll_offset
= 0;
15 var current_first_id
= 0;
16 var last_search_query
;
18 var _catchup_request_sent
= false;
20 var has_storage
= 'sessionStorage' in window
&& window
['sessionStorage'] !== null;
22 function headlines_callback2(transport
, offset
, background
, infscroll_req
) {
23 handle_rpc_json(transport
);
25 console
.log("headlines_callback2 [offset=" + offset
+ "] B:" + background
+ " I:" + infscroll_req
);
33 reply
= JSON
.parse(transport
.responseText
);
40 is_cat
= reply
['headlines']['is_cat'];
41 feed_id
= reply
['headlines']['id'];
42 last_search_query
= reply
['headlines']['search_query'];
45 var content
= reply
['headlines']['content'];
47 content
= content
+ "<div id='headlines-spacer'></div>";
51 if (feed_id
!= -7 && (feed_id
!= getActiveFeedId() || is_cat
!= activeFeedIsCat()))
54 /* dijit.getEnclosingWidget(
55 document.forms["main_toolbar_form"].update).attr('disabled',
56 is_cat || feed_id <= 0); */
59 if (infscroll_req
== false) {
60 $("headlines-frame").scrollTop
= 0;
62 $("floatingTitle").style
.visibility
= "hidden";
63 $("floatingTitle").setAttribute("data-article-id", 0);
64 $("floatingTitle").innerHTML
= "";
68 $("headlines-frame").removeClassName("cdm");
69 $("headlines-frame").removeClassName("normal");
71 $("headlines-frame").addClassName(isCdmMode() ? "cdm" : "normal");
73 var headlines_count
= reply
['headlines-info']['count'];
75 vgroup_last_feed
= reply
['headlines-info']['vgroup_last_feed'];
77 if (parseInt(headlines_count
) < 30) {
78 _infscroll_disable
= 1;
80 _infscroll_disable
= 0;
83 current_first_id
= reply
['headlines']['first_id'];
84 var counters
= reply
['counters'];
85 var articles
= reply
['articles'];
86 //var runtime_info = reply['runtime-info'];
88 if (infscroll_req
== false) {
89 loaded_article_ids
= [];
91 dojo
.html
.set($("headlines-toolbar"),
92 reply
['headlines']['toolbar'],
93 {parseContent
: true});
95 /*dojo.html.set($("headlines-frame"),
96 reply['headlines']['content'],
97 {parseContent: true});
99 $$("#headlines-frame div[id*='RROW']").each(function(row) {
100 loaded_article_ids.push(row.id);
103 $("headlines-frame").innerHTML
= '';
105 var tmp
= new Element("div");
106 tmp
.innerHTML
= reply
['headlines']['content'];
107 dojo
.parser
.parse(tmp
);
109 while (tmp
.hasChildNodes()) {
110 var row
= tmp
.removeChild(tmp
.firstChild
);
112 if (loaded_article_ids
.indexOf(row
.id
) == -1 || row
.hasClassName("cdmFeedTitle")) {
113 dijit
.byId("headlines-frame").domNode
.appendChild(row
);
115 loaded_article_ids
.push(row
.id
);
119 var hsp
= $("headlines-spacer");
120 if (!hsp
) hsp
= new Element("DIV", {"id": "headlines-spacer"});
121 dijit
.byId('headlines-frame').domNode
.appendChild(hsp
);
125 if (_infscroll_disable
)
126 hsp
.innerHTML
= "<a href='#' onclick='openNextUnreadFeed()'>" +
127 __("Click to open next unread feed.") + "</a>";
130 $("feed_title").innerHTML
+= "<span id='cancel_search'>" +
131 " (<a href='#' onclick='cancelSearch()'>" + __("Cancel search") + "</a>)" +
137 if (headlines_count
> 0 && feed_id
== getActiveFeedId() && is_cat
== activeFeedIsCat()) {
138 console
.log("adding some more headlines: " + headlines_count
);
140 var c
= dijit
.byId("headlines-frame");
141 var ids
= getSelectedArticleIds2();
143 var hsp
= $("headlines-spacer");
146 c
.domNode
.removeChild(hsp
);
148 var tmp
= new Element("div");
149 tmp
.innerHTML
= reply
['headlines']['content'];
150 dojo
.parser
.parse(tmp
);
152 while (tmp
.hasChildNodes()) {
153 var row
= tmp
.removeChild(tmp
.firstChild
);
155 if (loaded_article_ids
.indexOf(row
.id
) == -1 || row
.hasClassName("cdmFeedTitle")) {
156 dijit
.byId("headlines-frame").domNode
.appendChild(row
);
158 loaded_article_ids
.push(row
.id
);
162 if (!hsp
) hsp
= new Element("DIV", {"id": "headlines-spacer"});
163 c
.domNode
.appendChild(hsp
);
165 if (headlines_count
< 30) _infscroll_disable
= true;
167 console
.log("restore selected ids: " + ids
);
169 for (var i
= 0; i
< ids
.length
; i
++) {
170 markHeadline(ids
[i
]);
175 if (_infscroll_disable
) {
176 hsp
.innerHTML
= "<a href='#' onclick='openNextUnreadFeed()'>" +
177 __("Click to open next unread feed.") + "</a>";
181 console
.log("no new headlines received");
183 var first_id_changed
= reply
['headlines']['first_id_changed'];
184 console
.log("first id changed:" + first_id_changed
);
186 var hsp
= $("headlines-spacer");
189 if (first_id_changed
) {
190 hsp
.innerHTML
= "<a href='#' onclick='viewCurrentFeed()'>" +
191 __("New articles found, reload feed to continue.") + "</a>";
193 hsp
.innerHTML
= "<a href='#' onclick='openNextUnreadFeed()'>" +
194 __("Click to open next unread feed.") + "</a>";
203 for (var i
= 0; i
< articles
.length
; i
++) {
204 var a_id
= articles
[i
]['id'];
205 cache_set("article:" + a_id
, articles
[i
]['content']);
208 console
.log("no cached articles received");
212 parse_counters(counters
);
214 request_counters(true);
217 console
.error("Invalid object received: " + transport
.responseText
);
218 dijit
.byId("headlines-frame").attr('content', "<div class='whiteBox'>" +
219 __('Could not update headlines (invalid object received - see error console for details)') +
223 _infscroll_request_sent
= 0;
224 _last_headlines_update
= new Date().getTime();
226 unpackVisibleHeadlines();
228 // if we have some more space in the buffer, why not try to fill it
230 if (!_infscroll_disable
&& $("headlines-spacer") &&
231 $("headlines-spacer").offsetTop
< $("headlines-frame").offsetHeight
) {
233 window
.setTimeout(function() {
241 function render_article(article
) {
242 cleanup_memory("content-insert");
244 dijit
.byId("headlines-wrap-inner").addChild(
245 dijit
.byId("content-insert"));
247 var c
= dijit
.byId("content-insert");
250 c
.domNode
.scrollTop
= 0;
253 c
.attr('content', article
);
254 PluginHost
.run(PluginHost
.HOOK_ARTICLE_RENDERED
, c
.domNode
);
256 correctHeadlinesOffset(getActiveArticleId());
263 function showArticleInHeadlines(id
, noexpand
) {
264 var row
= $("RROW-" + id
);
268 row
.removeClassName("Unread");
270 row
.addClassName("active");
272 selectArticles('none');
277 function article_callback2(transport
, id
) {
278 console
.log("article_callback2 " + id
);
280 handle_rpc_json(transport
);
285 reply
= JSON
.parse(transport
.responseText
);
292 reply
.each(function(article
) {
293 if (getActiveArticleId() == article
['id']) {
294 render_article(article
['content']);
296 cids_requested
.remove(article
['id']);
298 cache_set("article:" + article
['id'], article
['content']);
301 // if (id != last_requested_article) {
302 // console.log("requested article id is out of sequence, aborting");
307 console
.error("Invalid object received: " + transport
.responseText
);
309 render_article("<div class='whiteBox'>" +
310 __('Could not display article (invalid object received - see error console for details)') + "</div>");
313 var unread_in_buffer
= $$("#headlines-frame > div[id*=RROW][class*=Unread]").length
314 request_counters(unread_in_buffer
== 0);
319 function view(id
, activefeed
, noexpand
) {
320 var oldrow
= $("RROW-" + getActiveArticleId());
321 if (oldrow
) oldrow
.removeClassName("active");
323 var crow
= $("RROW-" + id
);
327 setActiveArticleId(id
);
328 showArticleInHeadlines(id
, noexpand
);
332 console
.log("loading article: " + id
);
334 var cached_article
= cache_get("article:" + id
);
336 console
.log("cache check result: " + (cached_article
!= false));
338 var query
= "?op=article&method=view&id=" + param_escape(id
);
340 var neighbor_ids
= getRelativePostIds(id
);
342 /* only request uncached articles */
344 var cids_to_request
= [];
346 for (var i
= 0; i
< neighbor_ids
.length
; i
++) {
347 if (cids_requested
.indexOf(neighbor_ids
[i
]) == -1)
348 if (!cache_get("article:" + neighbor_ids
[i
])) {
349 cids_to_request
.push(neighbor_ids
[i
]);
350 cids_requested
.push(neighbor_ids
[i
]);
354 console
.log("additional ids: " + cids_to_request
.toString());
356 query
= query
+ "&cids=" + cids_to_request
.toString();
358 var article_is_unread
= crow
.hasClassName("Unread");
360 setActiveArticleId(id
);
361 showArticleInHeadlines(id
);
363 if (cached_article
&& article_is_unread
) {
365 query
= query
+ "&mode=prefetch";
367 render_article(cached_article
);
369 } else if (cached_article
) {
371 query
= query
+ "&mode=prefetch_old";
372 render_article(cached_article
);
374 // if we don't need to request any relative ids, we might as well skip
375 // the server roundtrip altogether
376 if (cids_to_request
.length
== 0) {
381 last_requested_article
= id
;
385 if (article_is_unread
) {
386 decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
389 new Ajax
.Request("backend.php", {
391 onComplete: function(transport
) {
392 article_callback2(transport
, id
);
399 function toggleMark(id
, client_only
) {
400 var query
= "?op=rpc&id=" + id
+ "&method=mark";
402 var row
= $("RROW-" + id
);
407 var row_imgs
= row
.getElementsByClassName("markedPic");
409 for (var i
= 0; i
< row_imgs
.length
; i
++)
410 imgs
.push(row_imgs
[i
]);
412 var ft
= $("floatingTitle");
414 if (ft
&& ft
.getAttribute("data-article-id") == id
) {
415 var fte
= ft
.getElementsByClassName("markedPic");
417 for (var i
= 0; i
< fte
.length
; i
++)
421 for (i
= 0; i
< imgs
.length
; i
++) {
424 if (!row
.hasClassName("marked")) {
425 img
.src
= img
.src
.replace("mark_unset", "mark_set");
426 img
.alt
= __("Unstar article");
427 query
= query
+ "&mark=1";
429 img
.src
= img
.src
.replace("mark_set", "mark_unset");
430 img
.alt
= __("Star article");
431 query
= query
+ "&mark=0";
435 row
.toggleClassName("marked");
438 new Ajax
.Request("backend.php", {
440 onComplete: function (transport
) {
441 handle_rpc_json(transport
);
447 function togglePub(id
, client_only
, no_effects
, note
) {
448 var query
= "?op=rpc&id=" + id
+ "&method=publ";
450 if (note
!= undefined) {
451 query
= query
+ "¬e=" + param_escape(note
);
453 query
= query
+ "¬e=undefined";
456 var row
= $("RROW-" + id
);
461 var row_imgs
= row
.getElementsByClassName("pubPic");
463 for (var i
= 0; i
< row_imgs
.length
; i
++)
464 imgs
.push(row_imgs
[i
]);
466 var ft
= $("floatingTitle");
468 if (ft
&& ft
.getAttribute("data-article-id") == id
) {
469 var fte
= ft
.getElementsByClassName("pubPic");
471 for (var i
= 0; i
< fte
.length
; i
++)
475 for (i
= 0; i
< imgs
.length
; i
++) {
478 if (!row
.hasClassName("published") || note
!= undefined) {
479 img
.src
= img
.src
.replace("pub_unset", "pub_set");
480 img
.alt
= __("Unpublish article");
481 query
= query
+ "&pub=1";
483 img
.src
= img
.src
.replace("pub_set", "pub_unset");
484 img
.alt
= __("Publish article");
485 query
= query
+ "&pub=0";
489 if (note
!= undefined)
490 row
.addClassName("published");
492 row
.toggleClassName("published");
495 new Ajax
.Request("backend.php", {
497 onComplete: function(transport
) {
498 handle_rpc_json(transport
);
504 function moveToPost(mode
, noscroll
, noexpand
) {
505 var rows
= getLoadedArticleIds();
510 if (!$('RROW-' + getActiveArticleId())) {
511 setActiveArticleId(0);
514 if (!getActiveArticleId()) {
516 prev_id
= rows
[rows
.length
-1]
518 for (var i
= 0; i
< rows
.length
; i
++) {
519 if (rows
[i
] == getActiveArticleId()) {
521 // Account for adjacent identical article ids.
522 if (i
> 0) prev_id
= rows
[i
-1];
524 for (var j
= i
+1; j
< rows
.length
; j
++) {
525 if (rows
[j
] != getActiveArticleId()) {
535 console
.log("cur: " + getActiveArticleId() + " next: " + next_id
);
537 if (mode
== "next") {
538 if (next_id
|| getActiveArticleId()) {
541 var article
= $("RROW-" + getActiveArticleId());
542 var ctr
= $("headlines-frame");
544 if (!noscroll
&& article
&& article
.offsetTop
+ article
.offsetHeight
>
545 ctr
.scrollTop
+ ctr
.offsetHeight
) {
547 scrollArticle(ctr
.offsetHeight
/4);
549 } else if (next_id
) {
550 cdmExpandArticle(next_id
, noexpand
);
551 cdmScrollToArticleId(next_id
, true);
554 } else if (next_id
) {
555 correctHeadlinesOffset(next_id
);
556 view(next_id
, getActiveFeedId(), noexpand
);
561 if (mode
== "prev") {
562 if (prev_id
|| getActiveArticleId()) {
565 var article
= $("RROW-" + getActiveArticleId());
566 var prev_article
= $("RROW-" + prev_id
);
567 var ctr
= $("headlines-frame");
569 if (!getInitParam("cdm_expanded")) {
571 if (!noscroll
&& article
&& article
.offsetTop
< ctr
.scrollTop
) {
572 scrollArticle(-ctr
.offsetHeight
/4);
574 cdmExpandArticle(prev_id
, noexpand
);
575 cdmScrollToArticleId(prev_id
, true);
579 if (!noscroll
&& article
&& article
.offsetTop
< ctr
.scrollTop
) {
580 scrollArticle(-ctr
.offsetHeight
/3);
581 } else if (!noscroll
&& prev_article
&&
582 prev_article
.offsetTop
< ctr
.scrollTop
) {
583 cdmExpandArticle(prev_id
, noexpand
);
584 scrollArticle(-ctr
.offsetHeight
/4);
585 } else if (prev_id
) {
586 cdmExpandArticle(prev_id
, noexpand
);
587 cdmScrollToArticleId(prev_id
, noscroll
);
591 } else if (prev_id
) {
592 correctHeadlinesOffset(prev_id
);
593 view(prev_id
, getActiveFeedId(), noexpand
);
600 function toggleSelected(id
, force_on
) {
601 var row
= $("RROW-" + id
);
604 var cb
= dijit
.getEnclosingWidget(
605 row
.getElementsByClassName("rchk")[0]);
607 if (row
.hasClassName('Selected') && !force_on
) {
608 row
.removeClassName('Selected');
609 if (cb
) cb
.attr("checked", false);
611 row
.addClassName('Selected');
612 if (cb
) cb
.attr("checked", true);
616 updateSelectedPrompt();
619 function updateSelectedPrompt() {
620 var count
= getSelectedArticleIds2().size();
621 var elem
= $("selected_prompt");
624 elem
.innerHTML
= ngettext("%d article selected",
625 "%d articles selected", count
).replace("%d", count
);
635 function toggleUnread(id
, cmode
, effect
) {
636 var row
= $("RROW-" + id
);
638 var tmpClassName
= row
.className
;
640 if (cmode
== undefined || cmode
== 2) {
641 if (row
.hasClassName("Unread")) {
642 row
.removeClassName("Unread");
645 row
.addClassName("Unread");
648 } else if (cmode
== 0) {
650 row
.removeClassName("Unread");
652 } else if (cmode
== 1) {
653 row
.addClassName("Unread");
656 if (cmode
== undefined) cmode
= 2;
658 var query
= "?op=rpc&method=catchupSelected" +
659 "&cmode=" + param_escape(cmode
) + "&ids=" + param_escape(id
);
661 // notify_progress("Loading, please wait...");
663 if (tmpClassName
!= row
.className
) {
664 new Ajax
.Request("backend.php", {
666 onComplete: function (transport
) {
667 handle_rpc_json(transport
);
675 function selectionRemoveLabel(id
, ids
) {
676 if (!ids
) ids
= getSelectedArticleIds2();
678 if (ids
.length
== 0) {
679 alert(__("No articles are selected."));
683 var query
= "?op=article&method=removeFromLabel&ids=" +
684 param_escape(ids
.toString()) + "&lid=" + param_escape(id
);
688 new Ajax
.Request("backend.php", {
690 onComplete: function(transport
) {
691 handle_rpc_json(transport
);
692 show_labels_in_headlines(transport
);
697 function selectionAssignLabel(id
, ids
) {
698 if (!ids
) ids
= getSelectedArticleIds2();
700 if (ids
.length
== 0) {
701 alert(__("No articles are selected."));
705 var query
= "?op=article&method=assignToLabel&ids=" +
706 param_escape(ids
.toString()) + "&lid=" + param_escape(id
);
710 new Ajax
.Request("backend.php", {
712 onComplete: function(transport
) {
713 handle_rpc_json(transport
);
714 show_labels_in_headlines(transport
);
718 function selectionToggleUnread(set_state
, callback
, no_error
, ids
) {
719 var rows
= ids
? ids
: getSelectedArticleIds2();
721 if (rows
.length
== 0 && !no_error
) {
722 alert(__("No articles are selected."));
726 for (var i
= 0; i
< rows
.length
; i
++) {
727 var row
= $("RROW-" + rows
[i
]);
729 if (set_state
== undefined) {
730 if (row
.hasClassName("Unread")) {
731 row
.removeClassName("Unread");
733 row
.addClassName("Unread");
737 if (set_state
== false) {
738 row
.removeClassName("Unread");
741 if (set_state
== true) {
742 row
.addClassName("Unread");
747 updateFloatingTitle(true);
749 if (rows
.length
> 0) {
753 if (set_state
== undefined) {
755 } else if (set_state
== true) {
757 } else if (set_state
== false) {
761 var query
= "?op=rpc&method=catchupSelected" +
762 "&cmode=" + cmode
+ "&ids=" + param_escape(rows
.toString());
764 notify_progress("Loading, please wait...");
766 new Ajax
.Request("backend.php", {
768 onComplete: function(transport
) {
769 handle_rpc_json(transport
);
770 if (callback
) callback(transport
);
777 function selectionToggleMarked(sel_state
, callback
, no_error
, ids
) {
778 var rows
= ids
? ids
: getSelectedArticleIds2();
780 if (rows
.length
== 0 && !no_error
) {
781 alert(__("No articles are selected."));
785 for (var i
= 0; i
< rows
.length
; i
++) {
786 toggleMark(rows
[i
], true, true);
789 if (rows
.length
> 0) {
791 var query
= "?op=rpc&method=markSelected&ids=" +
792 param_escape(rows
.toString()) + "&cmode=2";
794 new Ajax
.Request("backend.php", {
796 onComplete: function(transport
) {
797 handle_rpc_json(transport
);
798 if (callback
) callback(transport
);
805 function selectionTogglePublished(sel_state
, callback
, no_error
, ids
) {
806 var rows
= ids
? ids
: getSelectedArticleIds2();
808 if (rows
.length
== 0 && !no_error
) {
809 alert(__("No articles are selected."));
813 for (var i
= 0; i
< rows
.length
; i
++) {
814 togglePub(rows
[i
], true, true);
817 if (rows
.length
> 0) {
819 var query
= "?op=rpc&method=publishSelected&ids=" +
820 param_escape(rows
.toString()) + "&cmode=2";
822 new Ajax
.Request("backend.php", {
824 onComplete: function(transport
) {
825 handle_rpc_json(transport
);
831 function getSelectedArticleIds2() {
835 $$("#headlines-frame > div[id*=RROW][class*=Selected]").each(
837 rv
.push(child
.getAttribute("data-article-id"));
843 function getLoadedArticleIds() {
846 var children
= $$("#headlines-frame > div[id*=RROW-]");
848 children
.each(function(child
) {
849 if (Element
.visible(child
)) {
850 rv
.push(child
.getAttribute("data-article-id"));
858 // mode = all,none,unread,invert,marked,published
859 function selectArticles(mode
, query
) {
860 if (!query
) query
= "#headlines-frame > div[id*=RROW]";
862 var children
= $$(query
);
864 children
.each(function(child
) {
865 var id
= child
.getAttribute("data-article-id");
867 var cb
= dijit
.getEnclosingWidget(
868 child
.getElementsByClassName("rchk")[0]);
871 child
.addClassName("Selected");
872 if (cb
) cb
.attr("checked", true);
873 } else if (mode
== "unread") {
874 if (child
.hasClassName("Unread")) {
875 child
.addClassName("Selected");
876 if (cb
) cb
.attr("checked", true);
878 child
.removeClassName("Selected");
879 if (cb
) cb
.attr("checked", false);
881 } else if (mode
== "marked") {
882 if (child
.hasClassName("marked")) {
883 child
.addClassName("Selected");
884 if (cb
) cb
.attr("checked", true);
886 child
.removeClassName("Selected");
887 if (cb
) cb
.attr("checked", false);
889 } else if (mode
== "published") {
890 if (child
.hasClassName("published")) {
891 child
.addClassName("Selected");
892 if (cb
) cb
.attr("checked", true);
894 child
.removeClassName("Selected");
895 if (cb
) cb
.attr("checked", false);
898 } else if (mode
== "invert") {
899 if (child
.hasClassName("Selected")) {
900 child
.removeClassName("Selected");
901 if (cb
) cb
.attr("checked", false);
903 child
.addClassName("Selected");
904 if (cb
) cb
.attr("checked", true);
908 child
.removeClassName("Selected");
909 if (cb
) cb
.attr("checked", false);
913 updateSelectedPrompt();
916 function deleteSelection() {
918 var rows
= getSelectedArticleIds2();
920 if (rows
.length
== 0) {
921 alert(__("No articles are selected."));
925 var fn
= getFeedName(getActiveFeedId(), activeFeedIsCat());
928 if (getActiveFeedId() != 0) {
929 str
= ngettext("Delete %d selected article in %s?", "Delete %d selected articles in %s?", rows
.length
);
931 str
= ngettext("Delete %d selected article?", "Delete %d selected articles?", rows
.length
);
934 str
= str
.replace("%d", rows
.length
);
935 str
= str
.replace("%s", fn
);
937 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str
)) {
941 query
= "?op=rpc&method=delete&ids=" + param_escape(rows
);
945 new Ajax
.Request("backend.php", {
947 onComplete: function (transport
) {
948 handle_rpc_json(transport
);
954 function archiveSelection() {
956 var rows
= getSelectedArticleIds2();
958 if (rows
.length
== 0) {
959 alert(__("No articles are selected."));
963 var fn
= getFeedName(getActiveFeedId(), activeFeedIsCat());
967 if (getActiveFeedId() != 0) {
968 str
= ngettext("Archive %d selected article in %s?", "Archive %d selected articles in %s?", rows
.length
);
971 str
= ngettext("Move %d archived article back?", "Move %d archived articles back?", rows
.length
);
973 str
+= " " + __("Please note that unstarred articles might get purged on next feed update.");
978 str
= str
.replace("%d", rows
.length
);
979 str
= str
.replace("%s", fn
);
981 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str
)) {
985 query
= "?op=rpc&method="+op
+"&ids=" + param_escape(rows
);
989 for (var i
= 0; i
< rows
.length
; i
++) {
990 cache_delete("article:" + rows
[i
]);
993 new Ajax
.Request("backend.php", {
995 onComplete: function(transport
) {
996 handle_rpc_json(transport
);
1002 function catchupSelection() {
1004 var rows
= getSelectedArticleIds2();
1006 if (rows
.length
== 0) {
1007 alert(__("No articles are selected."));
1011 var fn
= getFeedName(getActiveFeedId(), activeFeedIsCat());
1013 var str
= ngettext("Mark %d selected article in %s as read?", "Mark %d selected articles in %s as read?", rows
.length
);
1015 str
= str
.replace("%d", rows
.length
);
1016 str
= str
.replace("%s", fn
);
1018 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str
)) {
1022 selectionToggleUnread(false, 'viewCurrentFeed()', true);
1025 function editArticleTags(id
) {
1026 var query
= "backend.php?op=article&method=editArticleTags¶m=" + param_escape(id
);
1028 if (dijit
.byId("editTagsDlg"))
1029 dijit
.byId("editTagsDlg").destroyRecursive();
1031 dialog
= new dijit
.Dialog({
1033 title
: __("Edit article Tags"),
1034 style
: "width: 600px",
1035 execute: function() {
1036 if (this.validate()) {
1037 var query
= dojo
.objectToQuery(this.attr('value'));
1039 notify_progress("Saving article tags...", true);
1041 new Ajax
.Request("backend.php", {
1043 onComplete: function(transport
) {
1048 var data
= JSON
.parse(transport
.responseText
);
1055 var tags
= $("ATSTR-" + id
);
1056 var tooltip
= dijit
.byId("ATSTRTIP-" + id
);
1058 if (tags
) tags
.innerHTML
= data
.content
;
1059 if (tooltip
) tooltip
.attr('label', data
.content_full
);
1071 var tmph
= dojo
.connect(dialog
, 'onLoad', function() {
1072 dojo
.disconnect(tmph
);
1074 new Ajax
.Autocompleter('tags_str', 'tags_choices',
1075 "backend.php?op=article&method=completeTags",
1076 { tokens
: ',', paramName
: "search" });
1083 function cdmScrollToArticleId(id
, force
) {
1084 var ctr
= $("headlines-frame");
1085 var e
= $("RROW-" + id
);
1087 if (!e
|| !ctr
) return;
1089 if (force
|| e
.offsetTop
+e
.offsetHeight
> (ctr
.scrollTop
+ctr
.offsetHeight
) ||
1090 e
.offsetTop
< ctr
.scrollTop
) {
1092 // expanded cdm has a 4px margin now
1093 ctr
.scrollTop
= parseInt(e
.offsetTop
) - 4;
1097 function setActiveArticleId(id
) {
1098 console
.log("setActiveArticleId:" + id
);
1100 _active_article_id
= id
;
1101 PluginHost
.run(PluginHost
.HOOK_ARTICLE_SET_ACTIVE
, _active_article_id
);
1104 function getActiveArticleId() {
1105 return _active_article_id
;
1108 function postMouseIn(e
, id
) {
1109 post_under_pointer
= id
;
1112 function postMouseOut(id
) {
1113 post_under_pointer
= false;
1116 function unpackVisibleHeadlines() {
1117 if (!isCdmMode() || !getInitParam("cdm_expanded")) return;
1119 $$("#headlines-frame span.cencw[id]").each(
1121 var row
= $("RROW-" + child
.id
.replace("CENCW-", ""));
1123 if (row
&& row
.offsetTop
<= $("headlines-frame").scrollTop
+
1124 $("headlines-frame").offsetHeight
) {
1126 //console.log("unpacking: " + child.id);
1128 child
.innerHTML
= htmlspecialchars_decode(child
.innerHTML
);
1129 child
.removeAttribute('id');
1131 PluginHost
.run(PluginHost
.HOOK_ARTICLE_RENDERED_CDM
, row
);
1133 Element
.show(child
);
1139 function headlines_scroll_handler(e
) {
1142 // rate-limit in case of smooth scrolling and similar abominations
1143 if (Math
.max(e
.scrollTop
, _headlines_scroll_offset
) - Math
.min(e
.scrollTop
, _headlines_scroll_offset
) < 25) {
1147 _headlines_scroll_offset
= e
.scrollTop
;
1149 var hsp
= $("headlines-spacer");
1151 unpackVisibleHeadlines();
1153 // set topmost child in the buffer as active
1154 if (isCdmMode() && getInitParam("cdm_auto_catchup") == 1 &&
1155 getSelectedArticleIds2().length
<= 1 &&
1156 getInitParam("cdm_expanded")) {
1158 var rows
= $$("#headlines-frame > div[id*=RROW]");
1160 for (var i
= 0; i
< rows
.length
; i
++) {
1161 var child
= rows
[i
];
1163 if ($("headlines-frame").scrollTop
<= child
.offsetTop
&&
1164 child
.offsetTop
- $("headlines-frame").scrollTop
< 100 &&
1165 child
.getAttribute("data-article-id") != _active_article_id
) {
1167 if (_active_article_id
) {
1168 var row
= $("RROW-" + _active_article_id
);
1169 if (row
) row
.removeClassName("active");
1172 _active_article_id
= child
.getAttribute("data-article-id");
1173 showArticleInHeadlines(_active_article_id
, true);
1174 updateSelectedPrompt();
1180 if (!_infscroll_disable
) {
1181 if (hsp
&& hsp
.offsetTop
- 250 <= e
.scrollTop
+ e
.offsetHeight
) {
1183 hsp
.innerHTML
= "<span class='loading'><img src='images/indicator_tiny.gif'> " +
1184 __("Loading, please wait...") + "</span>";
1186 loadMoreHeadlines();
1193 updateFloatingTitle();
1196 catchupCurrentBatchIfNeeded();
1198 if (getInitParam("cdm_auto_catchup") == 1) {
1200 // let's get DOM some time to settle down
1201 var ts
= new Date().getTime();
1202 if (ts
- _last_headlines_update
< 100) return;
1204 $$("#headlines-frame > div[id*=RROW][class*=Unread]").each(
1206 if (child
.hasClassName("Unread") && $("headlines-frame").scrollTop
>
1207 (child
.offsetTop
+ child
.offsetHeight
/2)) {
1209 var id
= child
.getAttribute("data-article-id")
1211 if (catchup_id_batch
.indexOf(id
) == -1)
1212 catchup_id_batch
.push(id
);
1214 //console.log("auto_catchup_batch: " + catchup_id_batch.toString());
1219 if (_infscroll_disable
) {
1220 var child
= $$("#headlines-frame div[id*=RROW]").last();
1222 if (child
&& $("headlines-frame").scrollTop
>
1223 (child
.offsetTop
+ child
.offsetHeight
- 50)) {
1225 console
.log("we seem to be at an end");
1227 if (getInitParam("on_catchup_show_next_feed") == "1") {
1228 openNextUnreadFeed();
1235 console
.warn("headlines_scroll_handler: " + e
);
1239 function openNextUnreadFeed() {
1240 var is_cat
= activeFeedIsCat();
1241 var nuf
= getNextUnreadFeed(getActiveFeedId(), is_cat
);
1242 if (nuf
) viewfeed({feed
: nuf
, is_cat
: is_cat
});
1245 function catchupBatchedArticles() {
1246 if (catchup_id_batch
.length
> 0 && !_infscroll_request_sent
&& !_catchup_request_sent
) {
1248 console
.log("catchupBatchedArticles: working");
1250 // make a copy of the array
1251 var batch
= catchup_id_batch
.slice();
1252 var query
= "?op=rpc&method=catchupSelected" +
1253 "&cmode=0&ids=" + param_escape(batch
.toString());
1257 _catchup_request_sent
= true;
1259 new Ajax
.Request("backend.php", {
1261 onComplete: function (transport
) {
1262 handle_rpc_json(transport
);
1264 _catchup_request_sent
= false;
1266 reply
= JSON
.parse(transport
.responseText
);
1267 var batch
= reply
.ids
;
1269 batch
.each(function (id
) {
1271 var elem
= $("RROW-" + id
);
1272 if (elem
) elem
.removeClassName("Unread");
1273 catchup_id_batch
.remove(id
);
1276 updateFloatingTitle(true);
1283 function catchupRelativeToArticle(below
, id
) {
1285 if (!id
) id
= getActiveArticleId();
1288 alert(__("No article is selected."));
1292 var visible_ids
= getLoadedArticleIds();
1294 var ids_to_mark
= new Array();
1297 for (var i
= 0; i
< visible_ids
.length
; i
++) {
1298 if (visible_ids
[i
] != id
) {
1299 var e
= $("RROW-" + visible_ids
[i
]);
1301 if (e
&& e
.hasClassName("Unread")) {
1302 ids_to_mark
.push(visible_ids
[i
]);
1309 for (var i
= visible_ids
.length
- 1; i
>= 0; i
--) {
1310 if (visible_ids
[i
] != id
) {
1311 var e
= $("RROW-" + visible_ids
[i
]);
1313 if (e
&& e
.hasClassName("Unread")) {
1314 ids_to_mark
.push(visible_ids
[i
]);
1322 if (ids_to_mark
.length
== 0) {
1323 alert(__("No articles found to mark"));
1325 var msg
= ngettext("Mark %d article as read?", "Mark %d articles as read?", ids_to_mark
.length
).replace("%d", ids_to_mark
.length
);
1327 if (getInitParam("confirm_feed_catchup") != 1 || confirm(msg
)) {
1329 for (var i
= 0; i
< ids_to_mark
.length
; i
++) {
1330 var e
= $("RROW-" + ids_to_mark
[i
]);
1331 e
.removeClassName("Unread");
1334 var query
= "?op=rpc&method=catchupSelected" +
1335 "&cmode=0" + "&ids=" + param_escape(ids_to_mark
.toString());
1337 new Ajax
.Request("backend.php", {
1339 onComplete: function (transport
) {
1340 handle_rpc_json(transport
);
1348 function cdmCollapseArticle(event
, id
, unmark
) {
1349 if (unmark
== undefined) unmark
= true;
1351 var row
= $("RROW-" + id
);
1352 var elem
= $("CICD-" + id
);
1355 var collapse
= row
.select("span[class='collapseBtn']")[0];
1358 Element
.show("CEXC-" + id
);
1359 Element
.hide(collapse
);
1362 row
.removeClassName("active");
1364 markHeadline(id
, false);
1366 if (id
== getActiveArticleId()) {
1367 setActiveArticleId(0);
1370 updateSelectedPrompt();
1373 if (event
) Event
.stop(event
);
1375 PluginHost
.run(PluginHost
.HOOK_ARTICLE_COLLAPSED
, id
);
1377 if (row
.offsetTop
< $("headlines-frame").scrollTop
)
1378 scrollToRowId(row
.id
);
1380 $("floatingTitle").style
.visibility
= "hidden";
1381 $("floatingTitle").setAttribute("data-article-id", 0);
1385 function cdmExpandArticle(id
, noexpand
) {
1386 console
.log("cdmExpandArticle " + id
);
1388 var row
= $("RROW-" + id
);
1390 if (!row
) return false;
1392 var oldrow
= $("RROW-" + getActiveArticleId());
1394 var elem
= $("CICD-" + getActiveArticleId());
1396 if (id
== getActiveArticleId() && Element
.visible(elem
))
1399 selectArticles("none");
1401 var old_offset
= row
.offsetTop
;
1403 if (getActiveArticleId() && elem
&& !getInitParam("cdm_expanded")) {
1404 var collapse
= oldrow
.select("span[class='collapseBtn']")[0];
1407 Element
.show("CEXC-" + getActiveArticleId());
1408 Element
.hide(collapse
);
1411 if (oldrow
) oldrow
.removeClassName("active");
1413 setActiveArticleId(id
);
1415 elem
= $("CICD-" + id
);
1417 var collapse
= row
.select("span[class='collapseBtn']")[0];
1419 var cencw
= $("CENCW-" + id
);
1421 if (!Element
.visible(elem
) && !noexpand
) {
1423 cencw
.innerHTML
= htmlspecialchars_decode(cencw
.innerHTML
);
1424 cencw
.setAttribute('id', '');
1425 Element
.show(cencw
);
1429 Element
.hide("CEXC-" + id
);
1430 Element
.show(collapse
);
1433 var new_offset
= row
.offsetTop
;
1435 if (old_offset
> new_offset
)
1436 $("headlines-frame").scrollTop
-= (old_offset
- new_offset
);
1439 if (catchup_id_batch
.indexOf(id
) == -1)
1440 catchup_id_batch
.push(id
);
1442 catchupCurrentBatchIfNeeded();
1446 row
.addClassName("active");
1448 PluginHost
.run(PluginHost
.HOOK_ARTICLE_EXPANDED
, id
);
1453 function getArticleUnderPointer() {
1454 return post_under_pointer
;
1457 function scrollArticle(offset
) {
1459 var ci
= $("content-insert");
1461 ci
.scrollTop
+= offset
;
1464 var hi
= $("headlines-frame");
1466 hi
.scrollTop
+= offset
;
1472 function show_labels_in_headlines(transport
) {
1473 var data
= JSON
.parse(transport
.responseText
);
1476 data
['info-for-headlines'].each(function (elem
) {
1477 $$(".HLLCTR-" + elem
.id
).each(function (ctr
) {
1478 ctr
.innerHTML
= elem
.labels
;
1484 function cdmClicked(event
, id
, in_body
) {
1485 //var shift_key = event.shiftKey;
1487 if (!event
.ctrlKey
&& !event
.metaKey
) {
1489 if (!getInitParam("cdm_expanded")) {
1490 return cdmExpandArticle(id
);
1493 var elem
= $("RROW-" + getActiveArticleId());
1495 if (elem
) elem
.removeClassName("active");
1497 selectArticles("none");
1500 var elem
= $("RROW-" + id
);
1501 var article_is_unread
= elem
.hasClassName("Unread");
1503 elem
.removeClassName("Unread");
1504 elem
.addClassName("active");
1506 setActiveArticleId(id
);
1508 if (article_is_unread
) {
1509 decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
1510 updateFloatingTitle(true);
1513 var query
= "?op=rpc&method=catchupSelected" +
1514 "&cmode=0&ids=" + param_escape(id
);
1516 new Ajax
.Request("backend.php", {
1518 onComplete: function (transport
) {
1519 handle_rpc_json(transport
);
1523 return !event
.shiftKey
;
1526 } else if (!in_body
) {
1528 toggleSelected(id
, true);
1530 var elem
= $("RROW-" + id
);
1531 var article_is_unread
= elem
.hasClassName("Unread");
1533 if (article_is_unread
) {
1534 decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
1537 toggleUnread(id
, 0, false);
1539 openArticleInNewWindow(id
);
1544 var unread_in_buffer
= $$("#headlines-frame > div[id*=RROW][class*=Unread]").length
1545 request_counters(unread_in_buffer
== 0);
1550 function hlClicked(event
, id
) {
1551 if (event
.which
== 2) {
1554 } else if (event
.ctrlKey
|| event
.metaKey
) {
1555 toggleSelected(id
, true);
1556 toggleUnread(id
, 0, false);
1557 openArticleInNewWindow(id
);
1565 function openArticleInNewWindow(id
) {
1566 toggleUnread(id
, 0, false);
1568 var w
= window
.open("");
1570 w
.location
= "backend.php?op=article&method=redirect&id=" + id
;
1573 function isCdmMode() {
1574 return getInitParam("combined_display_mode");
1577 function markHeadline(id
, marked
) {
1578 if (marked
== undefined) marked
= true;
1580 var row
= $("RROW-" + id
);
1582 var check
= dijit
.getEnclosingWidget(
1583 row
.getElementsByClassName("rchk")[0]);
1586 check
.attr("checked", marked
);
1590 row
.addClassName("Selected");
1592 row
.removeClassName("Selected");
1596 function getRelativePostIds(id
, limit
) {
1600 if (!limit
) limit
= 6; //3
1602 var ids
= getLoadedArticleIds();
1604 for (var i
= 0; i
< ids
.length
; i
++) {
1606 for (var k
= 1; k
<= limit
; k
++) {
1607 //if (i > k-1) tmp.push(ids[i-k]);
1608 if (i
< ids
.length
- k
) tmp
.push(ids
[i
+ k
]);
1617 function correctHeadlinesOffset(id
) {
1619 var container
= $("headlines-frame");
1620 var row
= $("RROW-" + id
);
1622 if (!container
|| !row
) return;
1624 var viewport
= container
.offsetHeight
;
1626 var rel_offset_top
= row
.offsetTop
- container
.scrollTop
;
1627 var rel_offset_bottom
= row
.offsetTop
+ row
.offsetHeight
- container
.scrollTop
;
1629 //console.log("Rtop: " + rel_offset_top + " Rbtm: " + rel_offset_bottom);
1630 //console.log("Vport: " + viewport);
1632 if (rel_offset_top
<= 0 || rel_offset_top
> viewport
) {
1633 container
.scrollTop
= row
.offsetTop
;
1634 } else if (rel_offset_bottom
> viewport
) {
1636 /* doesn't properly work with Opera in some cases because
1637 Opera fucks up element scrolling */
1639 container
.scrollTop
= row
.offsetTop
+ row
.offsetHeight
- viewport
;
1643 function headlineActionsChange(elem
) {
1645 elem
.attr('value', 'false');
1648 function closeArticlePanel() {
1650 if (dijit
.byId("content-insert"))
1651 dijit
.byId("headlines-wrap-inner").removeChild(
1652 dijit
.byId("content-insert"));
1655 function initFloatingMenu() {
1656 if (!dijit
.byId("floatingMenu")) {
1658 var menu
= new dijit
.Menu({
1660 targetNodeIds
: ["floatingTitle"]
1663 headlinesMenuCommon(menu
);
1669 function headlinesMenuCommon(menu
) {
1671 menu
.addChild(new dijit
.MenuItem({
1672 label
: __("Open original article"),
1673 onClick: function (event
) {
1674 openArticleInNewWindow(this.getParent().currentTarget
.getAttribute("data-article-id"));
1678 menu
.addChild(new dijit
.MenuItem({
1679 label
: __("Display article URL"),
1680 onClick: function (event
) {
1681 displayArticleUrl(this.getParent().currentTarget
.getAttribute("data-article-id"));
1685 menu
.addChild(new dijit
.MenuSeparator());
1687 menu
.addChild(new dijit
.MenuItem({
1688 label
: __("Toggle unread"),
1689 onClick: function (event
) {
1691 var ids
= getSelectedArticleIds2();
1693 var id
= (this.getParent().currentTarget
.getAttribute("data-article-id")) + "";
1694 ids
= ids
.size() != 0 && ids
.indexOf(id
) != -1 ? ids
: [id
];
1696 selectionToggleUnread(undefined, false, true, ids
);
1700 menu
.addChild(new dijit
.MenuItem({
1701 label
: __("Toggle starred"),
1702 onClick: function (event
) {
1703 var ids
= getSelectedArticleIds2();
1705 var id
= (this.getParent().currentTarget
.getAttribute("data-article-id")) + "";
1706 ids
= ids
.size() != 0 && ids
.indexOf(id
) != -1 ? ids
: [id
];
1708 selectionToggleMarked(undefined, false, true, ids
);
1712 menu
.addChild(new dijit
.MenuItem({
1713 label
: __("Toggle published"),
1714 onClick: function (event
) {
1715 var ids
= getSelectedArticleIds2();
1717 var id
= (this.getParent().currentTarget
.getAttribute("data-article-id")) + "";
1718 ids
= ids
.size() != 0 && ids
.indexOf(id
) != -1 ? ids
: [id
];
1720 selectionTogglePublished(undefined, false, true, ids
);
1724 menu
.addChild(new dijit
.MenuSeparator());
1726 menu
.addChild(new dijit
.MenuItem({
1727 label
: __("Mark above as read"),
1728 onClick: function (event
) {
1729 catchupRelativeToArticle(0, this.getParent().currentTarget
.getAttribute("data-article-id"));
1733 menu
.addChild(new dijit
.MenuItem({
1734 label
: __("Mark below as read"),
1735 onClick: function (event
) {
1736 catchupRelativeToArticle(1, this.getParent().currentTarget
.getAttribute("data-article-id"));
1741 var labels
= getInitParam("labels");
1745 menu
.addChild(new dijit
.MenuSeparator());
1747 var labelAddMenu
= new dijit
.Menu({ownerMenu
: menu
});
1748 var labelDelMenu
= new dijit
.Menu({ownerMenu
: menu
});
1750 labels
.each(function (label
) {
1751 var bare_id
= label
.id
;
1752 var name
= label
.caption
;
1754 labelAddMenu
.addChild(new dijit
.MenuItem({
1757 onClick: function (event
) {
1759 var ids
= getSelectedArticleIds2();
1761 var id
= (this.getParent().ownerMenu
.currentTarget
.getAttribute("data-article-id")) + "";
1763 ids
= ids
.size() != 0 && ids
.indexOf(id
) != -1 ? ids
: [id
];
1765 selectionAssignLabel(this.labelId
, ids
);
1769 labelDelMenu
.addChild(new dijit
.MenuItem({
1772 onClick: function (event
) {
1773 var ids
= getSelectedArticleIds2();
1775 var id
= (this.getParent().ownerMenu
.currentTarget
.getAttribute("data-article-id")) + "";
1777 ids
= ids
.size() != 0 && ids
.indexOf(id
) != -1 ? ids
: [id
];
1779 selectionRemoveLabel(this.labelId
, ids
);
1785 menu
.addChild(new dijit
.PopupMenuItem({
1786 label
: __("Assign label"),
1790 menu
.addChild(new dijit
.PopupMenuItem({
1791 label
: __("Remove label"),
1798 function initHeadlinesMenu() {
1799 if (!dijit
.byId("headlinesMenu")) {
1801 var menu
= new dijit
.Menu({
1802 id
: "headlinesMenu",
1803 targetNodeIds
: ["headlines-frame"],
1804 selector
: ".hlMenuAttach"
1807 headlinesMenuCommon(menu
);
1812 /* vgroup feed title menu */
1814 if (!dijit
.byId("headlinesFeedTitleMenu")) {
1816 var menu
= new dijit
.Menu({
1817 id
: "headlinesFeedTitleMenu",
1818 targetNodeIds
: ["headlines-frame"],
1819 selector
: "div.cdmFeedTitle"
1822 menu
.addChild(new dijit
.MenuItem({
1823 label
: __("Select articles in group"),
1824 onClick: function (event
) {
1825 selectArticles("all",
1826 "#headlines-frame > div[id*=RROW]" +
1827 "[data-orig-feed-id='" + this.getParent().currentTarget
.getAttribute("data-feed-id") + "']");
1832 menu
.addChild(new dijit
.MenuItem({
1833 label
: __("Mark group as read"),
1834 onClick: function (event
) {
1835 selectArticles("none");
1836 selectArticles("all",
1837 "#headlines-frame > div[id*=RROW]" +
1838 "[data-orig-feed-id='" + this.getParent().currentTarget
.getAttribute("data-feed-id") + "']");
1844 menu
.addChild(new dijit
.MenuItem({
1845 label
: __("Mark feed as read"),
1846 onClick: function (event
) {
1847 catchupFeedInGroup(this.getParent().currentTarget
.getAttribute("data-feed-id"));
1851 menu
.addChild(new dijit
.MenuItem({
1852 label
: __("Edit feed"),
1853 onClick: function (event
) {
1854 editFeed(this.getParent().currentTarget
.getAttribute("data-feed-id"));
1862 function cache_set(id
, obj
) {
1863 //console.log("cache_set: " + id);
1866 sessionStorage
[id
] = obj
;
1868 sessionStorage
.clear();
1872 function cache_get(id
) {
1874 return sessionStorage
[id
];
1877 function cache_clear() {
1879 sessionStorage
.clear();
1882 function cache_delete(id
) {
1884 sessionStorage
.removeItem(id
);
1887 function cancelSearch() {
1892 function setSelectionScore() {
1893 var ids
= getSelectedArticleIds2();
1895 if (ids
.length
> 0) {
1898 var score
= prompt(__("Please enter new score for selected articles:"), score
);
1900 if (score
!= undefined) {
1901 var query
= "op=article&method=setScore&id=" + param_escape(ids
.toString()) +
1902 "&score=" + param_escape(score
);
1904 new Ajax
.Request("backend.php", {
1906 onComplete: function (transport
) {
1907 var reply
= JSON
.parse(transport
.responseText
);
1911 ids
.each(function (id
) {
1912 var row
= $("RROW-" + id
);
1915 var pic
= row
.getElementsByClassName("hlScorePic")[0];
1918 pic
.src
= pic
.src
.replace(/score_.*?\.png/,
1919 reply
["score_pic"]);
1920 pic
.setAttribute("score", score
);
1930 alert(__("No articles are selected."));
1934 function updateScore(id
) {
1935 var pic
= $$("#RROW-" + id
+ " .hlScorePic")[0];
1939 var query
= "op=article&method=getScore&id=" + param_escape(id
);
1941 new Ajax
.Request("backend.php", {
1943 onComplete: function (transport
) {
1944 console
.log(transport
.responseText
);
1946 var reply
= JSON
.parse(transport
.responseText
);
1949 pic
.src
= pic
.src
.replace(/score_.*?\.png/, reply
["score_pic"]);
1950 pic
.setAttribute("score", reply
["score"]);
1951 pic
.setAttribute("title", reply
["score"]);
1958 function changeScore(id
, pic
) {
1959 var score
= pic
.getAttribute("score");
1961 var new_score
= prompt(__("Please enter new score for this article:"), score
);
1963 if (new_score
!= undefined) {
1965 var query
= "op=article&method=setScore&id=" + param_escape(id
) +
1966 "&score=" + param_escape(new_score
);
1968 new Ajax
.Request("backend.php", {
1970 onComplete: function (transport
) {
1971 var reply
= JSON
.parse(transport
.responseText
);
1974 pic
.src
= pic
.src
.replace(/score_.*?\.png/, reply
["score_pic"]);
1975 pic
.setAttribute("score", new_score
);
1976 pic
.setAttribute("title", new_score
);
1983 function displayArticleUrl(id
) {
1984 var query
= "op=rpc&method=getlinktitlebyid&id=" + param_escape(id
);
1986 new Ajax
.Request("backend.php", {
1988 onComplete: function (transport
) {
1989 var reply
= JSON
.parse(transport
.responseText
);
1991 if (reply
&& reply
.link
) {
1992 prompt(__("Article URL:"), reply
.link
);
1998 function scrollToRowId(id
) {
2002 $("headlines-frame").scrollTop
= row
.offsetTop
- 4;
2005 function updateFloatingTitle(unread_only
) {
2006 if (!isCdmMode()) return;
2008 var hf
= $("headlines-frame");
2010 var elems
= $$("#headlines-frame > div[id*=RROW]");
2012 for (var i
= 0; i
< elems
.length
; i
++) {
2014 var child
= elems
[i
];
2016 if (child
&& child
.offsetTop
+ child
.offsetHeight
> hf
.scrollTop
) {
2018 var header
= child
.getElementsByClassName("cdmHeader")[0];
2020 if (unread_only
|| child
.getAttribute("data-article-id") != $("floatingTitle").getAttribute("data-article-id")) {
2021 if (child
.getAttribute("data-article-id") != $("floatingTitle").getAttribute("data-article-id")) {
2023 $("floatingTitle").setAttribute("data-article-id", child
.getAttribute("data-article-id"));
2024 $("floatingTitle").innerHTML
= header
.innerHTML
;
2025 $("floatingTitle").firstChild
.innerHTML
= "<img class='anchor markedPic' src='images/page_white_go.png' onclick=\"scrollToRowId('" + child
.id
+ "')\">" + $("floatingTitle").firstChild
.innerHTML
;
2029 var cb
= $$("#floatingTitle .dijitCheckBox")[0];
2032 cb
.parentNode
.removeChild(cb
);
2035 if (child
.hasClassName("Unread"))
2036 $("floatingTitle").addClassName("Unread");
2038 $("floatingTitle").removeClassName("Unread");
2040 PluginHost
.run(PluginHost
.HOOK_FLOATING_TITLE
, child
);
2043 $("floatingTitle").style
.marginRight
= hf
.offsetWidth
- child
.offsetWidth
+ "px";
2044 if (header
.offsetTop
+ header
.offsetHeight
< hf
.scrollTop
+ $("floatingTitle").offsetHeight
- 5 &&
2045 child
.offsetTop
+ child
.offsetHeight
>= hf
.scrollTop
+ $("floatingTitle").offsetHeight
- 5)
2046 $("floatingTitle").style
.visibility
= "visible";
2048 $("floatingTitle").style
.visibility
= "hidden";
2056 function catchupCurrentBatchIfNeeded() {
2057 if (catchup_id_batch
.length
> 0) {
2058 window
.clearTimeout(catchup_timeout_id
);
2059 catchup_timeout_id
= window
.setTimeout(catchupBatchedArticles
, 1000);
2061 if (catchup_id_batch
.length
>= 10) {
2062 catchupBatchedArticles();
2067 function cdmFooterClick(event
) {
2068 event
.stopPropagation();