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;
17 var _catchup_request_sent
= false;
19 var has_storage
= 'sessionStorage' in window
&& window
['sessionStorage'] !== null;
21 function headlines_callback2(transport
, offset
, background
, infscroll_req
) {
22 handle_rpc_json(transport
);
24 console
.log("headlines_callback2 [offset=" + offset
+ "] B:" + background
+ " I:" + infscroll_req
);
32 reply
= JSON
.parse(transport
.responseText
);
39 is_cat
= reply
['headlines']['is_cat'];
40 feed_id
= reply
['headlines']['id'];
43 var content
= reply
['headlines']['content'];
45 content
= content
+ "<div id='headlines-spacer'></div>";
49 if (feed_id
!= -7 && (feed_id
!= getActiveFeedId() || is_cat
!= activeFeedIsCat()))
52 /* dijit.getEnclosingWidget(
53 document.forms["main_toolbar_form"].update).attr('disabled',
54 is_cat || feed_id <= 0); */
57 if (infscroll_req
== false) {
58 $("headlines-frame").scrollTop
= 0;
60 $("floatingTitle").style
.visibility
= "hidden";
61 $("floatingTitle").setAttribute("data-article-id", 0);
62 $("floatingTitle").innerHTML
= "";
66 $("headlines-frame").removeClassName("cdm");
67 $("headlines-frame").removeClassName("normal");
69 $("headlines-frame").addClassName(isCdmMode() ? "cdm" : "normal");
71 var headlines_count
= reply
['headlines-info']['count'];
73 vgroup_last_feed
= reply
['headlines-info']['vgroup_last_feed'];
75 if (parseInt(headlines_count
) < 30) {
76 _infscroll_disable
= 1;
78 _infscroll_disable
= 0;
81 current_first_id
= reply
['headlines']['first_id'];
82 var counters
= reply
['counters'];
83 var articles
= reply
['articles'];
84 //var runtime_info = reply['runtime-info'];
86 if (infscroll_req
== false) {
87 loaded_article_ids
= [];
89 dojo
.html
.set($("headlines-toolbar"),
90 reply
['headlines']['toolbar'],
91 {parseContent
: true});
93 /*dojo.html.set($("headlines-frame"),
94 reply['headlines']['content'],
95 {parseContent: true});
97 $$("#headlines-frame div[id*='RROW']").each(function(row) {
98 loaded_article_ids.push(row.id);
101 $("headlines-frame").innerHTML
= '';
103 var tmp
= new Element("div");
104 tmp
.innerHTML
= reply
['headlines']['content'];
105 dojo
.parser
.parse(tmp
);
107 while (tmp
.hasChildNodes()) {
108 var row
= tmp
.removeChild(tmp
.firstChild
);
110 if (loaded_article_ids
.indexOf(row
.id
) == -1 || row
.hasClassName("cdmFeedTitle")) {
111 dijit
.byId("headlines-frame").domNode
.appendChild(row
);
113 loaded_article_ids
.push(row
.id
);
117 var hsp
= $("headlines-spacer");
118 if (!hsp
) hsp
= new Element("DIV", {"id": "headlines-spacer"});
119 dijit
.byId('headlines-frame').domNode
.appendChild(hsp
);
123 if (_infscroll_disable
)
124 hsp
.innerHTML
= "<a href='#' onclick='openNextUnreadFeed()'>" +
125 __("Click to open next unread feed.") + "</a>";
128 $("feed_title").innerHTML
+= "<span id='cancel_search'>" +
129 " (<a href='#' onclick='cancelSearch()'>" + __("Cancel search") + "</a>)" +
135 if (headlines_count
> 0 && feed_id
== getActiveFeedId() && is_cat
== activeFeedIsCat()) {
136 console
.log("adding some more headlines: " + headlines_count
);
138 var c
= dijit
.byId("headlines-frame");
139 var ids
= getSelectedArticleIds2();
141 var hsp
= $("headlines-spacer");
144 c
.domNode
.removeChild(hsp
);
146 var tmp
= new Element("div");
147 tmp
.innerHTML
= reply
['headlines']['content'];
148 dojo
.parser
.parse(tmp
);
150 while (tmp
.hasChildNodes()) {
151 var row
= tmp
.removeChild(tmp
.firstChild
);
153 if (loaded_article_ids
.indexOf(row
.id
) == -1 || row
.hasClassName("cdmFeedTitle")) {
154 dijit
.byId("headlines-frame").domNode
.appendChild(row
);
156 loaded_article_ids
.push(row
.id
);
160 if (!hsp
) hsp
= new Element("DIV", {"id": "headlines-spacer"});
161 c
.domNode
.appendChild(hsp
);
163 if (headlines_count
< 30) _infscroll_disable
= true;
165 console
.log("restore selected ids: " + ids
);
167 for (var i
= 0; i
< ids
.length
; i
++) {
168 markHeadline(ids
[i
]);
173 if (_infscroll_disable
) {
174 hsp
.innerHTML
= "<a href='#' onclick='openNextUnreadFeed()'>" +
175 __("Click to open next unread feed.") + "</a>";
179 console
.log("no new headlines received");
181 var first_id_changed
= reply
['headlines']['first_id_changed'];
182 console
.log("first id changed:" + first_id_changed
);
184 var hsp
= $("headlines-spacer");
187 if (first_id_changed
) {
188 hsp
.innerHTML
= "<a href='#' onclick='viewCurrentFeed()'>" +
189 __("New articles found, reload feed to continue.") + "</a>";
191 hsp
.innerHTML
= "<a href='#' onclick='openNextUnreadFeed()'>" +
192 __("Click to open next unread feed.") + "</a>";
201 for (var i
= 0; i
< articles
.length
; i
++) {
202 var a_id
= articles
[i
]['id'];
203 cache_set("article:" + a_id
, articles
[i
]['content']);
206 console
.log("no cached articles received");
210 parse_counters(counters
);
212 request_counters(true);
215 console
.error("Invalid object received: " + transport
.responseText
);
216 dijit
.byId("headlines-frame").attr('content', "<div class='whiteBox'>" +
217 __('Could not update headlines (invalid object received - see error console for details)') +
221 _infscroll_request_sent
= 0;
222 _last_headlines_update
= new Date().getTime();
224 unpackVisibleHeadlines();
226 // if we have some more space in the buffer, why not try to fill it
228 if (!_infscroll_disable
&& $("headlines-spacer") &&
229 $("headlines-spacer").offsetTop
< $("headlines-frame").offsetHeight
) {
231 window
.setTimeout(function() {
239 function render_article(article
) {
240 cleanup_memory("content-insert");
242 dijit
.byId("headlines-wrap-inner").addChild(
243 dijit
.byId("content-insert"));
245 var c
= dijit
.byId("content-insert");
248 c
.domNode
.scrollTop
= 0;
251 c
.attr('content', article
);
252 PluginHost
.run(PluginHost
.HOOK_ARTICLE_RENDERED
, c
.domNode
);
254 correctHeadlinesOffset(getActiveArticleId());
261 function showArticleInHeadlines(id
, noexpand
) {
262 var row
= $("RROW-" + id
);
266 row
.removeClassName("Unread");
268 row
.addClassName("active");
270 selectArticles('none');
275 function article_callback2(transport
, id
) {
276 console
.log("article_callback2 " + id
);
278 handle_rpc_json(transport
);
283 reply
= JSON
.parse(transport
.responseText
);
290 reply
.each(function(article
) {
291 if (getActiveArticleId() == article
['id']) {
292 render_article(article
['content']);
294 cids_requested
.remove(article
['id']);
296 cache_set("article:" + article
['id'], article
['content']);
299 // if (id != last_requested_article) {
300 // console.log("requested article id is out of sequence, aborting");
305 console
.error("Invalid object received: " + transport
.responseText
);
307 render_article("<div class='whiteBox'>" +
308 __('Could not display article (invalid object received - see error console for details)') + "</div>");
311 var unread_in_buffer
= $$("#headlines-frame > div[id*=RROW][class*=Unread]").length
312 request_counters(unread_in_buffer
== 0);
317 function view(id
, activefeed
, noexpand
) {
318 var oldrow
= $("RROW-" + getActiveArticleId());
319 if (oldrow
) oldrow
.removeClassName("active");
321 var crow
= $("RROW-" + id
);
325 setActiveArticleId(id
);
326 showArticleInHeadlines(id
, noexpand
);
330 console
.log("loading article: " + id
);
332 var cached_article
= cache_get("article:" + id
);
334 console
.log("cache check result: " + (cached_article
!= false));
336 var query
= "?op=article&method=view&id=" + param_escape(id
);
338 var neighbor_ids
= getRelativePostIds(id
);
340 /* only request uncached articles */
342 var cids_to_request
= [];
344 for (var i
= 0; i
< neighbor_ids
.length
; i
++) {
345 if (cids_requested
.indexOf(neighbor_ids
[i
]) == -1)
346 if (!cache_get("article:" + neighbor_ids
[i
])) {
347 cids_to_request
.push(neighbor_ids
[i
]);
348 cids_requested
.push(neighbor_ids
[i
]);
352 console
.log("additional ids: " + cids_to_request
.toString());
354 query
= query
+ "&cids=" + cids_to_request
.toString();
356 var article_is_unread
= crow
.hasClassName("Unread");
358 setActiveArticleId(id
);
359 showArticleInHeadlines(id
);
361 if (cached_article
&& article_is_unread
) {
363 query
= query
+ "&mode=prefetch";
365 render_article(cached_article
);
367 } else if (cached_article
) {
369 query
= query
+ "&mode=prefetch_old";
370 render_article(cached_article
);
372 // if we don't need to request any relative ids, we might as well skip
373 // the server roundtrip altogether
374 if (cids_to_request
.length
== 0) {
379 last_requested_article
= id
;
383 if (article_is_unread
) {
384 decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
387 new Ajax
.Request("backend.php", {
389 onComplete: function(transport
) {
390 article_callback2(transport
, id
);
397 function toggleMark(id
, client_only
) {
398 var query
= "?op=rpc&id=" + id
+ "&method=mark";
400 var row
= $("RROW-" + id
);
405 var row_imgs
= row
.getElementsByClassName("markedPic");
407 for (var i
= 0; i
< row_imgs
.length
; i
++)
408 imgs
.push(row_imgs
[i
]);
410 var ft
= $("floatingTitle");
412 if (ft
&& ft
.getAttribute("data-article-id") == id
) {
413 var fte
= ft
.getElementsByClassName("markedPic");
415 for (var i
= 0; i
< fte
.length
; i
++)
419 for (i
= 0; i
< imgs
.length
; i
++) {
422 if (!row
.hasClassName("marked")) {
423 img
.src
= img
.src
.replace("mark_unset", "mark_set");
424 img
.alt
= __("Unstar article");
425 query
= query
+ "&mark=1";
427 img
.src
= img
.src
.replace("mark_set", "mark_unset");
428 img
.alt
= __("Star article");
429 query
= query
+ "&mark=0";
433 row
.toggleClassName("marked");
436 new Ajax
.Request("backend.php", {
438 onComplete: function (transport
) {
439 handle_rpc_json(transport
);
445 function togglePub(id
, client_only
, no_effects
, note
) {
446 var query
= "?op=rpc&id=" + id
+ "&method=publ";
448 if (note
!= undefined) {
449 query
= query
+ "¬e=" + param_escape(note
);
451 query
= query
+ "¬e=undefined";
454 var row
= $("RROW-" + id
);
459 var row_imgs
= row
.getElementsByClassName("pubPic");
461 for (var i
= 0; i
< row_imgs
.length
; i
++)
462 imgs
.push(row_imgs
[i
]);
464 var ft
= $("floatingTitle");
466 if (ft
&& ft
.getAttribute("data-article-id") == id
) {
467 var fte
= ft
.getElementsByClassName("pubPic");
469 for (var i
= 0; i
< fte
.length
; i
++)
473 for (i
= 0; i
< imgs
.length
; i
++) {
476 if (!row
.hasClassName("published") || note
!= undefined) {
477 img
.src
= img
.src
.replace("pub_unset", "pub_set");
478 img
.alt
= __("Unpublish article");
479 query
= query
+ "&pub=1";
481 img
.src
= img
.src
.replace("pub_set", "pub_unset");
482 img
.alt
= __("Publish article");
483 query
= query
+ "&pub=0";
487 if (note
!= undefined)
488 row
.addClassName("published");
490 row
.toggleClassName("published");
493 new Ajax
.Request("backend.php", {
495 onComplete: function(transport
) {
496 handle_rpc_json(transport
);
502 function moveToPost(mode
, noscroll
, noexpand
) {
503 var rows
= getLoadedArticleIds();
508 if (!$('RROW-' + getActiveArticleId())) {
509 setActiveArticleId(0);
512 if (!getActiveArticleId()) {
514 prev_id
= rows
[rows
.length
-1]
516 for (var i
= 0; i
< rows
.length
; i
++) {
517 if (rows
[i
] == getActiveArticleId()) {
519 // Account for adjacent identical article ids.
520 if (i
> 0) prev_id
= rows
[i
-1];
522 for (var j
= i
+1; j
< rows
.length
; j
++) {
523 if (rows
[j
] != getActiveArticleId()) {
533 console
.log("cur: " + getActiveArticleId() + " next: " + next_id
);
535 if (mode
== "next") {
536 if (next_id
|| getActiveArticleId()) {
539 var article
= $("RROW-" + getActiveArticleId());
540 var ctr
= $("headlines-frame");
542 if (!noscroll
&& article
&& article
.offsetTop
+ article
.offsetHeight
>
543 ctr
.scrollTop
+ ctr
.offsetHeight
) {
545 scrollArticle(ctr
.offsetHeight
/4);
547 } else if (next_id
) {
548 cdmExpandArticle(next_id
, noexpand
);
549 cdmScrollToArticleId(next_id
, true);
552 } else if (next_id
) {
553 correctHeadlinesOffset(next_id
);
554 view(next_id
, getActiveFeedId(), noexpand
);
559 if (mode
== "prev") {
560 if (prev_id
|| getActiveArticleId()) {
563 var article
= $("RROW-" + getActiveArticleId());
564 var prev_article
= $("RROW-" + prev_id
);
565 var ctr
= $("headlines-frame");
567 if (!getInitParam("cdm_expanded")) {
569 if (!noscroll
&& article
&& article
.offsetTop
< ctr
.scrollTop
) {
570 scrollArticle(-ctr
.offsetHeight
/4);
572 cdmExpandArticle(prev_id
, noexpand
);
573 cdmScrollToArticleId(prev_id
, true);
577 if (!noscroll
&& article
&& article
.offsetTop
< ctr
.scrollTop
) {
578 scrollArticle(-ctr
.offsetHeight
/3);
579 } else if (!noscroll
&& prev_article
&&
580 prev_article
.offsetTop
< ctr
.scrollTop
) {
581 cdmExpandArticle(prev_id
, noexpand
);
582 scrollArticle(-ctr
.offsetHeight
/4);
583 } else if (prev_id
) {
584 cdmExpandArticle(prev_id
, noexpand
);
585 cdmScrollToArticleId(prev_id
, noscroll
);
589 } else if (prev_id
) {
590 correctHeadlinesOffset(prev_id
);
591 view(prev_id
, getActiveFeedId(), noexpand
);
598 function toggleSelected(id
, force_on
) {
599 var row
= $("RROW-" + id
);
602 var cb
= dijit
.getEnclosingWidget(
603 row
.getElementsByClassName("rchk")[0]);
605 if (row
.hasClassName('Selected') && !force_on
) {
606 row
.removeClassName('Selected');
607 if (cb
) cb
.attr("checked", false);
609 row
.addClassName('Selected');
610 if (cb
) cb
.attr("checked", true);
614 updateSelectedPrompt();
617 function updateSelectedPrompt() {
618 var count
= getSelectedArticleIds2().size();
619 var elem
= $("selected_prompt");
622 elem
.innerHTML
= ngettext("%d article selected",
623 "%d articles selected", count
).replace("%d", count
);
633 function toggleUnread(id
, cmode
, effect
) {
634 var row
= $("RROW-" + id
);
636 var tmpClassName
= row
.className
;
638 if (cmode
== undefined || cmode
== 2) {
639 if (row
.hasClassName("Unread")) {
640 row
.removeClassName("Unread");
643 row
.addClassName("Unread");
646 } else if (cmode
== 0) {
648 row
.removeClassName("Unread");
650 } else if (cmode
== 1) {
651 row
.addClassName("Unread");
654 if (cmode
== undefined) cmode
= 2;
656 var query
= "?op=rpc&method=catchupSelected" +
657 "&cmode=" + param_escape(cmode
) + "&ids=" + param_escape(id
);
659 // notify_progress("Loading, please wait...");
661 if (tmpClassName
!= row
.className
) {
662 new Ajax
.Request("backend.php", {
664 onComplete: function (transport
) {
665 handle_rpc_json(transport
);
673 function selectionRemoveLabel(id
, ids
) {
674 if (!ids
) ids
= getSelectedArticleIds2();
676 if (ids
.length
== 0) {
677 alert(__("No articles are selected."));
681 var query
= "?op=article&method=removeFromLabel&ids=" +
682 param_escape(ids
.toString()) + "&lid=" + param_escape(id
);
686 new Ajax
.Request("backend.php", {
688 onComplete: function(transport
) {
689 handle_rpc_json(transport
);
690 show_labels_in_headlines(transport
);
695 function selectionAssignLabel(id
, ids
) {
696 if (!ids
) ids
= getSelectedArticleIds2();
698 if (ids
.length
== 0) {
699 alert(__("No articles are selected."));
703 var query
= "?op=article&method=assignToLabel&ids=" +
704 param_escape(ids
.toString()) + "&lid=" + param_escape(id
);
708 new Ajax
.Request("backend.php", {
710 onComplete: function(transport
) {
711 handle_rpc_json(transport
);
712 show_labels_in_headlines(transport
);
716 function selectionToggleUnread(set_state
, callback
, no_error
, ids
) {
717 var rows
= ids
? ids
: getSelectedArticleIds2();
719 if (rows
.length
== 0 && !no_error
) {
720 alert(__("No articles are selected."));
724 for (var i
= 0; i
< rows
.length
; i
++) {
725 var row
= $("RROW-" + rows
[i
]);
727 if (set_state
== undefined) {
728 if (row
.hasClassName("Unread")) {
729 row
.removeClassName("Unread");
731 row
.addClassName("Unread");
735 if (set_state
== false) {
736 row
.removeClassName("Unread");
739 if (set_state
== true) {
740 row
.addClassName("Unread");
745 updateFloatingTitle(true);
747 if (rows
.length
> 0) {
751 if (set_state
== undefined) {
753 } else if (set_state
== true) {
755 } else if (set_state
== false) {
759 var query
= "?op=rpc&method=catchupSelected" +
760 "&cmode=" + cmode
+ "&ids=" + param_escape(rows
.toString());
762 notify_progress("Loading, please wait...");
764 new Ajax
.Request("backend.php", {
766 onComplete: function(transport
) {
767 handle_rpc_json(transport
);
768 if (callback
) callback(transport
);
775 function selectionToggleMarked(sel_state
, callback
, no_error
, ids
) {
776 var rows
= ids
? ids
: getSelectedArticleIds2();
778 if (rows
.length
== 0 && !no_error
) {
779 alert(__("No articles are selected."));
783 for (var i
= 0; i
< rows
.length
; i
++) {
784 toggleMark(rows
[i
], true, true);
787 if (rows
.length
> 0) {
789 var query
= "?op=rpc&method=markSelected&ids=" +
790 param_escape(rows
.toString()) + "&cmode=2";
792 new Ajax
.Request("backend.php", {
794 onComplete: function(transport
) {
795 handle_rpc_json(transport
);
796 if (callback
) callback(transport
);
803 function selectionTogglePublished(sel_state
, callback
, no_error
, ids
) {
804 var rows
= ids
? ids
: getSelectedArticleIds2();
806 if (rows
.length
== 0 && !no_error
) {
807 alert(__("No articles are selected."));
811 for (var i
= 0; i
< rows
.length
; i
++) {
812 togglePub(rows
[i
], true, true);
815 if (rows
.length
> 0) {
817 var query
= "?op=rpc&method=publishSelected&ids=" +
818 param_escape(rows
.toString()) + "&cmode=2";
820 new Ajax
.Request("backend.php", {
822 onComplete: function(transport
) {
823 handle_rpc_json(transport
);
829 function getSelectedArticleIds2() {
833 $$("#headlines-frame > div[id*=RROW][class*=Selected]").each(
835 rv
.push(child
.getAttribute("data-article-id"));
841 function getLoadedArticleIds() {
844 var children
= $$("#headlines-frame > div[id*=RROW-]");
846 children
.each(function(child
) {
847 if (Element
.visible(child
)) {
848 rv
.push(child
.getAttribute("data-article-id"));
856 // mode = all,none,unread,invert,marked,published
857 function selectArticles(mode
, query
) {
858 if (!query
) query
= "#headlines-frame > div[id*=RROW]";
860 var children
= $$(query
);
862 children
.each(function(child
) {
863 var id
= child
.getAttribute("data-article-id");
865 var cb
= dijit
.getEnclosingWidget(
866 child
.getElementsByClassName("rchk")[0]);
869 child
.addClassName("Selected");
870 if (cb
) cb
.attr("checked", true);
871 } else if (mode
== "unread") {
872 if (child
.hasClassName("Unread")) {
873 child
.addClassName("Selected");
874 if (cb
) cb
.attr("checked", true);
876 child
.removeClassName("Selected");
877 if (cb
) cb
.attr("checked", false);
879 } else if (mode
== "marked") {
880 if (child
.hasClassName("marked")) {
881 child
.addClassName("Selected");
882 if (cb
) cb
.attr("checked", true);
884 child
.removeClassName("Selected");
885 if (cb
) cb
.attr("checked", false);
887 } else if (mode
== "published") {
888 if (child
.hasClassName("published")) {
889 child
.addClassName("Selected");
890 if (cb
) cb
.attr("checked", true);
892 child
.removeClassName("Selected");
893 if (cb
) cb
.attr("checked", false);
896 } else if (mode
== "invert") {
897 if (child
.hasClassName("Selected")) {
898 child
.removeClassName("Selected");
899 if (cb
) cb
.attr("checked", false);
901 child
.addClassName("Selected");
902 if (cb
) cb
.attr("checked", true);
906 child
.removeClassName("Selected");
907 if (cb
) cb
.attr("checked", false);
911 updateSelectedPrompt();
914 function deleteSelection() {
916 var rows
= getSelectedArticleIds2();
918 if (rows
.length
== 0) {
919 alert(__("No articles are selected."));
923 var fn
= getFeedName(getActiveFeedId(), activeFeedIsCat());
926 if (getActiveFeedId() != 0) {
927 str
= ngettext("Delete %d selected article in %s?", "Delete %d selected articles in %s?", rows
.length
);
929 str
= ngettext("Delete %d selected article?", "Delete %d selected articles?", rows
.length
);
932 str
= str
.replace("%d", rows
.length
);
933 str
= str
.replace("%s", fn
);
935 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str
)) {
939 query
= "?op=rpc&method=delete&ids=" + param_escape(rows
);
943 new Ajax
.Request("backend.php", {
945 onComplete: function (transport
) {
946 handle_rpc_json(transport
);
952 function archiveSelection() {
954 var rows
= getSelectedArticleIds2();
956 if (rows
.length
== 0) {
957 alert(__("No articles are selected."));
961 var fn
= getFeedName(getActiveFeedId(), activeFeedIsCat());
965 if (getActiveFeedId() != 0) {
966 str
= ngettext("Archive %d selected article in %s?", "Archive %d selected articles in %s?", rows
.length
);
969 str
= ngettext("Move %d archived article back?", "Move %d archived articles back?", rows
.length
);
971 str
+= " " + __("Please note that unstarred articles might get purged on next feed update.");
976 str
= str
.replace("%d", rows
.length
);
977 str
= str
.replace("%s", fn
);
979 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str
)) {
983 query
= "?op=rpc&method="+op
+"&ids=" + param_escape(rows
);
987 for (var i
= 0; i
< rows
.length
; i
++) {
988 cache_delete("article:" + rows
[i
]);
991 new Ajax
.Request("backend.php", {
993 onComplete: function(transport
) {
994 handle_rpc_json(transport
);
1000 function catchupSelection() {
1002 var rows
= getSelectedArticleIds2();
1004 if (rows
.length
== 0) {
1005 alert(__("No articles are selected."));
1009 var fn
= getFeedName(getActiveFeedId(), activeFeedIsCat());
1011 var str
= ngettext("Mark %d selected article in %s as read?", "Mark %d selected articles in %s as read?", rows
.length
);
1013 str
= str
.replace("%d", rows
.length
);
1014 str
= str
.replace("%s", fn
);
1016 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str
)) {
1020 selectionToggleUnread(false, 'viewCurrentFeed()', true);
1023 function editArticleTags(id
) {
1024 var query
= "backend.php?op=article&method=editArticleTags¶m=" + param_escape(id
);
1026 if (dijit
.byId("editTagsDlg"))
1027 dijit
.byId("editTagsDlg").destroyRecursive();
1029 dialog
= new dijit
.Dialog({
1031 title
: __("Edit article Tags"),
1032 style
: "width: 600px",
1033 execute: function() {
1034 if (this.validate()) {
1035 var query
= dojo
.objectToQuery(this.attr('value'));
1037 notify_progress("Saving article tags...", true);
1039 new Ajax
.Request("backend.php", {
1041 onComplete: function(transport
) {
1046 var data
= JSON
.parse(transport
.responseText
);
1053 var tags
= $("ATSTR-" + id
);
1054 var tooltip
= dijit
.byId("ATSTRTIP-" + id
);
1056 if (tags
) tags
.innerHTML
= data
.content
;
1057 if (tooltip
) tooltip
.attr('label', data
.content_full
);
1069 var tmph
= dojo
.connect(dialog
, 'onLoad', function() {
1070 dojo
.disconnect(tmph
);
1072 new Ajax
.Autocompleter('tags_str', 'tags_choices',
1073 "backend.php?op=article&method=completeTags",
1074 { tokens
: ',', paramName
: "search" });
1081 function cdmScrollToArticleId(id
, force
) {
1082 var ctr
= $("headlines-frame");
1083 var e
= $("RROW-" + id
);
1085 if (!e
|| !ctr
) return;
1087 if (force
|| e
.offsetTop
+e
.offsetHeight
> (ctr
.scrollTop
+ctr
.offsetHeight
) ||
1088 e
.offsetTop
< ctr
.scrollTop
) {
1090 // expanded cdm has a 4px margin now
1091 ctr
.scrollTop
= parseInt(e
.offsetTop
) - 4;
1095 function setActiveArticleId(id
) {
1096 console
.log("setActiveArticleId:" + id
);
1098 _active_article_id
= id
;
1099 PluginHost
.run(PluginHost
.HOOK_ARTICLE_SET_ACTIVE
, _active_article_id
);
1102 function getActiveArticleId() {
1103 return _active_article_id
;
1106 function postMouseIn(e
, id
) {
1107 post_under_pointer
= id
;
1110 function postMouseOut(id
) {
1111 post_under_pointer
= false;
1114 function unpackVisibleHeadlines() {
1115 if (!isCdmMode() || !getInitParam("cdm_expanded")) return;
1117 $$("#headlines-frame span.cencw[id]").each(
1119 var row
= $("RROW-" + child
.id
.replace("CENCW-", ""));
1121 if (row
&& row
.offsetTop
<= $("headlines-frame").scrollTop
+
1122 $("headlines-frame").offsetHeight
) {
1124 //console.log("unpacking: " + child.id);
1126 child
.innerHTML
= htmlspecialchars_decode(child
.innerHTML
);
1127 child
.removeAttribute('id');
1129 PluginHost
.run(PluginHost
.HOOK_ARTICLE_RENDERED_CDM
, row
);
1131 Element
.show(child
);
1137 function headlines_scroll_handler(e
) {
1140 // rate-limit in case of smooth scrolling and similar abominations
1141 if (Math
.max(e
.scrollTop
, _headlines_scroll_offset
) - Math
.min(e
.scrollTop
, _headlines_scroll_offset
) < 25) {
1145 _headlines_scroll_offset
= e
.scrollTop
;
1147 var hsp
= $("headlines-spacer");
1149 unpackVisibleHeadlines();
1151 // set topmost child in the buffer as active
1152 if (isCdmMode() && getInitParam("cdm_auto_catchup") == 1 &&
1153 getSelectedArticleIds2().length
<= 1 &&
1154 getInitParam("cdm_expanded")) {
1156 var rows
= $$("#headlines-frame > div[id*=RROW]");
1158 for (var i
= 0; i
< rows
.length
; i
++) {
1159 var child
= rows
[i
];
1161 if ($("headlines-frame").scrollTop
<= child
.offsetTop
&&
1162 child
.offsetTop
- $("headlines-frame").scrollTop
< 100 &&
1163 child
.getAttribute("data-article-id") != _active_article_id
) {
1165 if (_active_article_id
) {
1166 var row
= $("RROW-" + _active_article_id
);
1167 if (row
) row
.removeClassName("active");
1170 _active_article_id
= child
.getAttribute("data-article-id");
1171 showArticleInHeadlines(_active_article_id
, true);
1172 updateSelectedPrompt();
1178 if (!_infscroll_disable
) {
1179 if (hsp
&& hsp
.offsetTop
- 250 <= e
.scrollTop
+ e
.offsetHeight
) {
1181 hsp
.innerHTML
= "<span class='loading'><img src='images/indicator_tiny.gif'> " +
1182 __("Loading, please wait...") + "</span>";
1184 loadMoreHeadlines();
1191 updateFloatingTitle();
1194 catchupCurrentBatchIfNeeded();
1196 if (getInitParam("cdm_auto_catchup") == 1) {
1198 // let's get DOM some time to settle down
1199 var ts
= new Date().getTime();
1200 if (ts
- _last_headlines_update
< 100) return;
1202 $$("#headlines-frame > div[id*=RROW][class*=Unread]").each(
1204 if (child
.hasClassName("Unread") && $("headlines-frame").scrollTop
>
1205 (child
.offsetTop
+ child
.offsetHeight
/2)) {
1207 var id
= child
.getAttribute("data-article-id")
1209 if (catchup_id_batch
.indexOf(id
) == -1)
1210 catchup_id_batch
.push(id
);
1212 //console.log("auto_catchup_batch: " + catchup_id_batch.toString());
1217 if (_infscroll_disable
) {
1218 var child
= $$("#headlines-frame div[id*=RROW]").last();
1220 if (child
&& $("headlines-frame").scrollTop
>
1221 (child
.offsetTop
+ child
.offsetHeight
- 50)) {
1223 console
.log("we seem to be at an end");
1225 if (getInitParam("on_catchup_show_next_feed") == "1") {
1226 openNextUnreadFeed();
1233 console
.warn("headlines_scroll_handler: " + e
);
1237 function openNextUnreadFeed() {
1238 var is_cat
= activeFeedIsCat();
1239 var nuf
= getNextUnreadFeed(getActiveFeedId(), is_cat
);
1240 if (nuf
) viewfeed({feed
: nuf
, is_cat
: is_cat
});
1243 function catchupBatchedArticles() {
1244 if (catchup_id_batch
.length
> 0 && !_infscroll_request_sent
&& !_catchup_request_sent
) {
1246 console
.log("catchupBatchedArticles: working");
1248 // make a copy of the array
1249 var batch
= catchup_id_batch
.slice();
1250 var query
= "?op=rpc&method=catchupSelected" +
1251 "&cmode=0&ids=" + param_escape(batch
.toString());
1255 _catchup_request_sent
= true;
1257 new Ajax
.Request("backend.php", {
1259 onComplete: function (transport
) {
1260 handle_rpc_json(transport
);
1262 _catchup_request_sent
= false;
1264 reply
= JSON
.parse(transport
.responseText
);
1265 var batch
= reply
.ids
;
1267 batch
.each(function (id
) {
1269 var elem
= $("RROW-" + id
);
1270 if (elem
) elem
.removeClassName("Unread");
1271 catchup_id_batch
.remove(id
);
1274 updateFloatingTitle(true);
1281 function catchupRelativeToArticle(below
, id
) {
1283 if (!id
) id
= getActiveArticleId();
1286 alert(__("No article is selected."));
1290 var visible_ids
= getLoadedArticleIds();
1292 var ids_to_mark
= new Array();
1295 for (var i
= 0; i
< visible_ids
.length
; i
++) {
1296 if (visible_ids
[i
] != id
) {
1297 var e
= $("RROW-" + visible_ids
[i
]);
1299 if (e
&& e
.hasClassName("Unread")) {
1300 ids_to_mark
.push(visible_ids
[i
]);
1307 for (var i
= visible_ids
.length
- 1; i
>= 0; i
--) {
1308 if (visible_ids
[i
] != id
) {
1309 var e
= $("RROW-" + visible_ids
[i
]);
1311 if (e
&& e
.hasClassName("Unread")) {
1312 ids_to_mark
.push(visible_ids
[i
]);
1320 if (ids_to_mark
.length
== 0) {
1321 alert(__("No articles found to mark"));
1323 var msg
= ngettext("Mark %d article as read?", "Mark %d articles as read?", ids_to_mark
.length
).replace("%d", ids_to_mark
.length
);
1325 if (getInitParam("confirm_feed_catchup") != 1 || confirm(msg
)) {
1327 for (var i
= 0; i
< ids_to_mark
.length
; i
++) {
1328 var e
= $("RROW-" + ids_to_mark
[i
]);
1329 e
.removeClassName("Unread");
1332 var query
= "?op=rpc&method=catchupSelected" +
1333 "&cmode=0" + "&ids=" + param_escape(ids_to_mark
.toString());
1335 new Ajax
.Request("backend.php", {
1337 onComplete: function (transport
) {
1338 handle_rpc_json(transport
);
1346 function cdmCollapseArticle(event
, id
, unmark
) {
1347 if (unmark
== undefined) unmark
= true;
1349 var row
= $("RROW-" + id
);
1350 var elem
= $("CICD-" + id
);
1353 var collapse
= row
.select("span[class='collapseBtn']")[0];
1356 Element
.show("CEXC-" + id
);
1357 Element
.hide(collapse
);
1360 row
.removeClassName("active");
1362 markHeadline(id
, false);
1364 if (id
== getActiveArticleId()) {
1365 setActiveArticleId(0);
1368 updateSelectedPrompt();
1371 if (event
) Event
.stop(event
);
1373 PluginHost
.run(PluginHost
.HOOK_ARTICLE_COLLAPSED
, id
);
1375 if (row
.offsetTop
< $("headlines-frame").scrollTop
)
1376 scrollToRowId(row
.id
);
1378 $("floatingTitle").style
.visibility
= "hidden";
1379 $("floatingTitle").setAttribute("data-article-id", 0);
1383 function cdmExpandArticle(id
, noexpand
) {
1384 console
.log("cdmExpandArticle " + id
);
1386 var row
= $("RROW-" + id
);
1388 if (!row
) return false;
1390 var oldrow
= $("RROW-" + getActiveArticleId());
1392 var elem
= $("CICD-" + getActiveArticleId());
1394 if (id
== getActiveArticleId() && Element
.visible(elem
))
1397 selectArticles("none");
1399 var old_offset
= row
.offsetTop
;
1401 if (getActiveArticleId() && elem
&& !getInitParam("cdm_expanded")) {
1402 var collapse
= oldrow
.select("span[class='collapseBtn']")[0];
1405 Element
.show("CEXC-" + getActiveArticleId());
1406 Element
.hide(collapse
);
1409 if (oldrow
) oldrow
.removeClassName("active");
1411 setActiveArticleId(id
);
1413 elem
= $("CICD-" + id
);
1415 var collapse
= row
.select("span[class='collapseBtn']")[0];
1417 var cencw
= $("CENCW-" + id
);
1419 if (!Element
.visible(elem
) && !noexpand
) {
1421 cencw
.innerHTML
= htmlspecialchars_decode(cencw
.innerHTML
);
1422 cencw
.setAttribute('id', '');
1423 Element
.show(cencw
);
1427 Element
.hide("CEXC-" + id
);
1428 Element
.show(collapse
);
1431 var new_offset
= row
.offsetTop
;
1433 if (old_offset
> new_offset
)
1434 $("headlines-frame").scrollTop
-= (old_offset
- new_offset
);
1437 if (catchup_id_batch
.indexOf(id
) == -1)
1438 catchup_id_batch
.push(id
);
1440 catchupCurrentBatchIfNeeded();
1444 row
.addClassName("active");
1446 PluginHost
.run(PluginHost
.HOOK_ARTICLE_EXPANDED
, id
);
1451 function getArticleUnderPointer() {
1452 return post_under_pointer
;
1455 function scrollArticle(offset
) {
1457 var ci
= $("content-insert");
1459 ci
.scrollTop
+= offset
;
1462 var hi
= $("headlines-frame");
1464 hi
.scrollTop
+= offset
;
1470 function show_labels_in_headlines(transport
) {
1471 var data
= JSON
.parse(transport
.responseText
);
1474 data
['info-for-headlines'].each(function (elem
) {
1475 $$(".HLLCTR-" + elem
.id
).each(function (ctr
) {
1476 ctr
.innerHTML
= elem
.labels
;
1482 function cdmClicked(event
, id
) {
1483 //var shift_key = event.shiftKey;
1485 if (!event
.ctrlKey
&& !event
.metaKey
) {
1487 if (!getInitParam("cdm_expanded")) {
1488 return cdmExpandArticle(id
);
1491 var elem
= $("RROW-" + getActiveArticleId());
1493 if (elem
) elem
.removeClassName("active");
1495 selectArticles("none");
1498 var elem
= $("RROW-" + id
);
1499 var article_is_unread
= elem
.hasClassName("Unread");
1501 elem
.removeClassName("Unread");
1502 elem
.addClassName("active");
1504 setActiveArticleId(id
);
1506 if (article_is_unread
) {
1507 decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
1508 updateFloatingTitle(true);
1511 var query
= "?op=rpc&method=catchupSelected" +
1512 "&cmode=0&ids=" + param_escape(id
);
1514 new Ajax
.Request("backend.php", {
1516 onComplete: function (transport
) {
1517 handle_rpc_json(transport
);
1521 return !event
.shiftKey
;
1524 } else if (event
.target
.parents(".cdmHeader").length
> 0) {
1526 toggleSelected(id
, true);
1528 var elem
= $("RROW-" + id
);
1529 var article_is_unread
= elem
.hasClassName("Unread");
1531 if (article_is_unread
) {
1532 decrementFeedCounter(getActiveFeedId(), activeFeedIsCat());
1535 toggleUnread(id
, 0, false);
1537 openArticleInNewWindow(id
);
1540 var unread_in_buffer
= $$("#headlines-frame > div[id*=RROW][class*=Unread]").length
1541 request_counters(unread_in_buffer
== 0);
1546 function hlClicked(event
, id
) {
1547 if (event
.which
== 2) {
1550 } else if (event
.ctrlKey
|| event
.metaKey
) {
1551 toggleSelected(id
, true);
1552 toggleUnread(id
, 0, false);
1553 openArticleInNewWindow(id
);
1561 function openArticleInNewWindow(id
) {
1562 toggleUnread(id
, 0, false);
1564 var w
= window
.open("");
1566 w
.location
= "backend.php?op=article&method=redirect&id=" + id
;
1569 function isCdmMode() {
1570 return getInitParam("combined_display_mode");
1573 function markHeadline(id
, marked
) {
1574 if (marked
== undefined) marked
= true;
1576 var row
= $("RROW-" + id
);
1578 var check
= dijit
.getEnclosingWidget(
1579 row
.getElementsByClassName("rchk")[0]);
1582 check
.attr("checked", marked
);
1586 row
.addClassName("Selected");
1588 row
.removeClassName("Selected");
1592 function getRelativePostIds(id
, limit
) {
1596 if (!limit
) limit
= 6; //3
1598 var ids
= getLoadedArticleIds();
1600 for (var i
= 0; i
< ids
.length
; i
++) {
1602 for (var k
= 1; k
<= limit
; k
++) {
1603 //if (i > k-1) tmp.push(ids[i-k]);
1604 if (i
< ids
.length
- k
) tmp
.push(ids
[i
+ k
]);
1613 function correctHeadlinesOffset(id
) {
1615 var container
= $("headlines-frame");
1616 var row
= $("RROW-" + id
);
1618 if (!container
|| !row
) return;
1620 var viewport
= container
.offsetHeight
;
1622 var rel_offset_top
= row
.offsetTop
- container
.scrollTop
;
1623 var rel_offset_bottom
= row
.offsetTop
+ row
.offsetHeight
- container
.scrollTop
;
1625 //console.log("Rtop: " + rel_offset_top + " Rbtm: " + rel_offset_bottom);
1626 //console.log("Vport: " + viewport);
1628 if (rel_offset_top
<= 0 || rel_offset_top
> viewport
) {
1629 container
.scrollTop
= row
.offsetTop
;
1630 } else if (rel_offset_bottom
> viewport
) {
1632 /* doesn't properly work with Opera in some cases because
1633 Opera fucks up element scrolling */
1635 container
.scrollTop
= row
.offsetTop
+ row
.offsetHeight
- viewport
;
1639 function headlineActionsChange(elem
) {
1641 elem
.attr('value', 'false');
1644 function closeArticlePanel() {
1646 if (dijit
.byId("content-insert"))
1647 dijit
.byId("headlines-wrap-inner").removeChild(
1648 dijit
.byId("content-insert"));
1651 function initFloatingMenu() {
1652 if (!dijit
.byId("floatingMenu")) {
1654 var menu
= new dijit
.Menu({
1656 targetNodeIds
: ["floatingTitle"]
1659 headlinesMenuCommon(menu
);
1665 function headlinesMenuCommon(menu
) {
1667 menu
.addChild(new dijit
.MenuItem({
1668 label
: __("Open original article"),
1669 onClick: function (event
) {
1670 openArticleInNewWindow(this.getParent().currentTarget
.getAttribute("data-article-id"));
1674 menu
.addChild(new dijit
.MenuItem({
1675 label
: __("Display article URL"),
1676 onClick: function (event
) {
1677 displayArticleUrl(this.getParent().currentTarget
.getAttribute("data-article-id"));
1681 menu
.addChild(new dijit
.MenuSeparator());
1683 menu
.addChild(new dijit
.MenuItem({
1684 label
: __("Toggle unread"),
1685 onClick: function (event
) {
1687 var ids
= getSelectedArticleIds2();
1689 var id
= (this.getParent().currentTarget
.getAttribute("data-article-id")) + "";
1690 ids
= ids
.size() != 0 && ids
.indexOf(id
) != -1 ? ids
: [id
];
1692 selectionToggleUnread(undefined, false, true, ids
);
1696 menu
.addChild(new dijit
.MenuItem({
1697 label
: __("Toggle starred"),
1698 onClick: function (event
) {
1699 var ids
= getSelectedArticleIds2();
1701 var id
= (this.getParent().currentTarget
.getAttribute("data-article-id")) + "";
1702 ids
= ids
.size() != 0 && ids
.indexOf(id
) != -1 ? ids
: [id
];
1704 selectionToggleMarked(undefined, false, true, ids
);
1708 menu
.addChild(new dijit
.MenuItem({
1709 label
: __("Toggle published"),
1710 onClick: function (event
) {
1711 var ids
= getSelectedArticleIds2();
1713 var id
= (this.getParent().currentTarget
.getAttribute("data-article-id")) + "";
1714 ids
= ids
.size() != 0 && ids
.indexOf(id
) != -1 ? ids
: [id
];
1716 selectionTogglePublished(undefined, false, true, ids
);
1720 menu
.addChild(new dijit
.MenuSeparator());
1722 menu
.addChild(new dijit
.MenuItem({
1723 label
: __("Mark above as read"),
1724 onClick: function (event
) {
1725 catchupRelativeToArticle(0, this.getParent().currentTarget
.getAttribute("data-article-id"));
1729 menu
.addChild(new dijit
.MenuItem({
1730 label
: __("Mark below as read"),
1731 onClick: function (event
) {
1732 catchupRelativeToArticle(1, this.getParent().currentTarget
.getAttribute("data-article-id"));
1737 var labels
= dijit
.byId("feedTree").model
.getItemsInCategory(-2);
1741 menu
.addChild(new dijit
.MenuSeparator());
1743 var labelAddMenu
= new dijit
.Menu({ownerMenu
: menu
});
1744 var labelDelMenu
= new dijit
.Menu({ownerMenu
: menu
});
1746 labels
.each(function (label
) {
1747 var id
= label
.id
[0];
1748 var bare_id
= id
.substr(id
.indexOf(":") + 1);
1749 var name
= label
.name
[0];
1751 bare_id
= feed_to_label_id(bare_id
);
1753 labelAddMenu
.addChild(new dijit
.MenuItem({
1756 onClick: function (event
) {
1758 var ids
= getSelectedArticleIds2();
1760 var id
= (this.getParent().ownerMenu
.currentTarget
.getAttribute("data-article-id")) + "";
1762 ids
= ids
.size() != 0 && ids
.indexOf(id
) != -1 ? ids
: [id
];
1764 selectionAssignLabel(this.labelId
, ids
);
1768 labelDelMenu
.addChild(new dijit
.MenuItem({
1771 onClick: function (event
) {
1772 var ids
= getSelectedArticleIds2();
1774 var id
= (this.getParent().ownerMenu
.currentTarget
.getAttribute("data-article-id")) + "";
1776 ids
= ids
.size() != 0 && ids
.indexOf(id
) != -1 ? ids
: [id
];
1778 selectionRemoveLabel(this.labelId
, ids
);
1784 menu
.addChild(new dijit
.PopupMenuItem({
1785 label
: __("Assign label"),
1789 menu
.addChild(new dijit
.PopupMenuItem({
1790 label
: __("Remove label"),
1797 function initHeadlinesMenu() {
1798 if (!dijit
.byId("headlinesMenu")) {
1800 var menu
= new dijit
.Menu({
1801 id
: "headlinesMenu",
1802 targetNodeIds
: ["headlines-frame"],
1803 selector
: ".hlMenuAttach"
1806 headlinesMenuCommon(menu
);
1811 /* vgroup feed title menu */
1813 if (!dijit
.byId("headlinesFeedTitleMenu")) {
1815 var menu
= new dijit
.Menu({
1816 id
: "headlinesFeedTitleMenu",
1817 targetNodeIds
: ["headlines-frame"],
1818 selector
: "div.cdmFeedTitle"
1821 menu
.addChild(new dijit
.MenuItem({
1822 label
: __("Select articles in group"),
1823 onClick: function (event
) {
1824 selectArticles("all",
1825 "#headlines-frame > div[id*=RROW]" +
1826 "[data-orig-feed-id='" + this.getParent().currentTarget
.getAttribute("data-feed-id") + "']");
1831 menu
.addChild(new dijit
.MenuItem({
1832 label
: __("Mark group as read"),
1833 onClick: function (event
) {
1834 selectArticles("none");
1835 selectArticles("all",
1836 "#headlines-frame > div[id*=RROW]" +
1837 "[data-orig-feed-id='" + this.getParent().currentTarget
.getAttribute("data-feed-id") + "']");
1843 menu
.addChild(new dijit
.MenuItem({
1844 label
: __("Mark feed as read"),
1845 onClick: function (event
) {
1846 catchupFeedInGroup(this.getParent().currentTarget
.getAttribute("data-feed-id"));
1850 menu
.addChild(new dijit
.MenuItem({
1851 label
: __("Edit feed"),
1852 onClick: function (event
) {
1853 editFeed(this.getParent().currentTarget
.getAttribute("data-feed-id"));
1861 function cache_set(id
, obj
) {
1862 //console.log("cache_set: " + id);
1865 sessionStorage
[id
] = obj
;
1867 sessionStorage
.clear();
1871 function cache_get(id
) {
1873 return sessionStorage
[id
];
1876 function cache_clear() {
1878 sessionStorage
.clear();
1881 function cache_delete(id
) {
1883 sessionStorage
.removeItem(id
);
1886 function cancelSearch() {
1891 function setSelectionScore() {
1892 var ids
= getSelectedArticleIds2();
1894 if (ids
.length
> 0) {
1897 var score
= prompt(__("Please enter new score for selected articles:"), score
);
1899 if (score
!= undefined) {
1900 var query
= "op=article&method=setScore&id=" + param_escape(ids
.toString()) +
1901 "&score=" + param_escape(score
);
1903 new Ajax
.Request("backend.php", {
1905 onComplete: function (transport
) {
1906 var reply
= JSON
.parse(transport
.responseText
);
1910 ids
.each(function (id
) {
1911 var row
= $("RROW-" + id
);
1914 var pic
= row
.getElementsByClassName("hlScorePic")[0];
1917 pic
.src
= pic
.src
.replace(/score_.*?\.png/,
1918 reply
["score_pic"]);
1919 pic
.setAttribute("score", score
);
1929 alert(__("No articles are selected."));
1933 function updateScore(id
) {
1934 var pic
= $$("#RROW-" + id
+ " .hlScorePic")[0];
1938 var query
= "op=article&method=getScore&id=" + param_escape(id
);
1940 new Ajax
.Request("backend.php", {
1942 onComplete: function (transport
) {
1943 console
.log(transport
.responseText
);
1945 var reply
= JSON
.parse(transport
.responseText
);
1948 pic
.src
= pic
.src
.replace(/score_.*?\.png/, reply
["score_pic"]);
1949 pic
.setAttribute("score", reply
["score"]);
1950 pic
.setAttribute("title", reply
["score"]);
1957 function changeScore(id
, pic
) {
1958 var score
= pic
.getAttribute("score");
1960 var new_score
= prompt(__("Please enter new score for this article:"), score
);
1962 if (new_score
!= undefined) {
1964 var query
= "op=article&method=setScore&id=" + param_escape(id
) +
1965 "&score=" + param_escape(new_score
);
1967 new Ajax
.Request("backend.php", {
1969 onComplete: function (transport
) {
1970 var reply
= JSON
.parse(transport
.responseText
);
1973 pic
.src
= pic
.src
.replace(/score_.*?\.png/, reply
["score_pic"]);
1974 pic
.setAttribute("score", new_score
);
1975 pic
.setAttribute("title", new_score
);
1982 function displayArticleUrl(id
) {
1983 var query
= "op=rpc&method=getlinktitlebyid&id=" + param_escape(id
);
1985 new Ajax
.Request("backend.php", {
1987 onComplete: function (transport
) {
1988 var reply
= JSON
.parse(transport
.responseText
);
1990 if (reply
&& reply
.link
) {
1991 prompt(__("Article URL:"), reply
.link
);
1997 function scrollToRowId(id
) {
2001 $("headlines-frame").scrollTop
= row
.offsetTop
- 4;
2004 function updateFloatingTitle(unread_only
) {
2005 if (!isCdmMode()) return;
2007 var hf
= $("headlines-frame");
2009 var elems
= $$("#headlines-frame > div[id*=RROW]");
2011 for (var i
= 0; i
< elems
.length
; i
++) {
2013 var child
= elems
[i
];
2015 if (child
&& child
.offsetTop
+ child
.offsetHeight
> hf
.scrollTop
) {
2017 var header
= child
.getElementsByClassName("cdmHeader")[0];
2019 if (unread_only
|| child
.getAttribute("data-article-id") != $("floatingTitle").getAttribute("data-article-id")) {
2020 if (child
.getAttribute("data-article-id") != $("floatingTitle").getAttribute("data-article-id")) {
2022 $("floatingTitle").setAttribute("data-article-id", child
.getAttribute("data-article-id"));
2023 $("floatingTitle").innerHTML
= header
.innerHTML
;
2024 $("floatingTitle").firstChild
.innerHTML
= "<img class='anchor markedPic' src='images/page_white_go.png' onclick=\"scrollToRowId('" + child
.id
+ "')\">" + $("floatingTitle").firstChild
.innerHTML
;
2028 var cb
= $$("#floatingTitle .dijitCheckBox")[0];
2031 cb
.parentNode
.removeChild(cb
);
2034 if (child
.hasClassName("Unread"))
2035 $("floatingTitle").addClassName("Unread");
2037 $("floatingTitle").removeClassName("Unread");
2039 PluginHost
.run(PluginHost
.HOOK_FLOATING_TITLE
, child
);
2042 $("floatingTitle").style
.marginRight
= hf
.offsetWidth
- child
.offsetWidth
+ "px";
2043 if (header
.offsetTop
+ header
.offsetHeight
< hf
.scrollTop
+ $("floatingTitle").offsetHeight
- 5 &&
2044 child
.offsetTop
+ child
.offsetHeight
>= hf
.scrollTop
+ $("floatingTitle").offsetHeight
- 5)
2045 $("floatingTitle").style
.visibility
= "visible";
2047 $("floatingTitle").style
.visibility
= "hidden";
2055 function catchupCurrentBatchIfNeeded() {
2056 if (catchup_id_batch
.length
> 0) {
2057 window
.clearTimeout(catchup_timeout_id
);
2058 catchup_timeout_id
= window
.setTimeout(catchupBatchedArticles
, 1000);
2060 if (catchup_id_batch
.length
>= 10) {
2061 catchupBatchedArticles();
2066 function cdmFooterClick(event
) {
2067 event
.stopPropagation();