]> git.wh0rd.org - tt-rss.git/blame - viewfeed.js
make 'v' hotkey work in CDM mode
[tt-rss.git] / viewfeed.js
CommitLineData
bb7cface 1var active_post_id = false;
e08443c1 2var _catchup_callback_func = false;
4b6206fa 3var last_article_view = false;
0b126ac2
AD
4var active_real_feed_id = false;
5
6var _tag_active_post_id = false;
7var _tag_active_feed_id = false;
13f08f75 8var _tag_active_cdm = false;
0b126ac2 9
13f08f75
AD
10// FIXME: kludge, to restore scrollTop after tag editor terminates
11var _tag_cdm_scroll = false;
12
13// FIXME: kludges, needs proper implementation
0b126ac2 14var _reload_feedlist_after_view = false;
e08443c1 15
ba0978c8
AD
16var _cdm_wd_timeout = false;
17var _cdm_wd_vishist = new Array();
18
e097e8be
AD
19var article_cache = new Array();
20
e08443c1
AD
21function catchup_callback() {
22 if (xmlhttp_rpc.readyState == 4) {
8f3b99ba
AD
23 try {
24 debug("catchup_callback");
9ec58704 25 notify("");
8f3b99ba 26 all_counters_callback();
af6f8bf2
AD
27 if (_catchup_callback_func) {
28 setTimeout(_catchup_callback_func, 10);
29 }
8f3b99ba
AD
30 } catch (e) {
31 exception_error("catchup_callback", e);
32 }
e08443c1
AD
33 }
34}
f0601b87 35
6b4163cb
AD
36function headlines_callback() {
37 if (xmlhttp.readyState == 4) {
38 debug("headlines_callback");
39 var f = document.getElementById("headlines-frame");
44cc6f20
AD
40 try {
41 f.scrollTop = 0;
42 } catch (e) { };
3de0261a
AD
43
44 if (xmlhttp.responseXML) {
45 var headlines = xmlhttp.responseXML.getElementsByTagName("headlines")[0];
46 var counters = xmlhttp.responseXML.getElementsByTagName("counters")[0];
961f4c73 47 var articles = xmlhttp.responseXML.getElementsByTagName("article");
03c88bdd 48 var runtime_info = xmlhttp.responseXML.getElementsByTagName("runtime-info");
3de0261a 49
007a38d4
AD
50 if (headlines) {
51 f.innerHTML = headlines.firstChild.nodeValue;
52 } else {
53 debug("headlines_callback: returned no data");
54 f.innerHTML = "<div class='whiteBox'>" + __('Could not update headlines (missing XML data)') + "</div>";
55
56 }
3de0261a 57
961f4c73
AD
58 if (articles) {
59 for (var i = 0; i < articles.length; i++) {
60 var a_id = articles[i].getAttribute("id");
61 debug("found id: " + a_id);
62 cache_inject(a_id, articles[i].firstChild.nodeValue);
63 }
007a38d4
AD
64 } else {
65 debug("no cached articles received");
961f4c73
AD
66 }
67
3de0261a
AD
68 if (counters) {
69 debug("parsing piggybacked counters: " + counters);
70 parse_counters(counters, false);
addb5836
AD
71 } else {
72 debug("counters container not found in reply");
3de0261a 73 }
03c88bdd
AD
74
75 if (runtime_info) {
76 debug("parsing runtime info: " + runtime_info[0]);
77 parse_runtime_info(runtime_info[0]);
78 } else {
79 debug("counters container not found in reply");
80 }
81
3de0261a
AD
82 } else {
83 debug("headlines_callback: returned no XML object");
addb5836 84 f.innerHTML = "<div class='whiteBox'>" + __('Could not update headlines (missing XML object)') + "</div>";
3de0261a
AD
85 }
86
935f235d
AD
87 if (typeof correctPNG != 'undefined') {
88 correctPNG();
89 }
ba0978c8
AD
90
91 if (_cdm_wd_timeout) window.clearTimeout(_cdm_wd_timeout);
92
ac7bcd71
AD
93 if (!document.getElementById("headlinesList") &&
94 getInitParam("cdm_auto_catchup") == 1) {
ba0978c8
AD
95 debug("starting CDM watchdog");
96 _cdm_wd_timeout = window.setTimeout("cdmWatchdog()", 5000);
97 _cdm_wd_vishist = new Array();
ac7bcd71
AD
98 } else {
99 debug("not in CDM mode or watchdog disabled");
ba0978c8
AD
100 }
101
13f08f75
AD
102 if (_tag_cdm_scroll) {
103 try {
104 document.getElementById("headlinesInnerContainer").scrollTop = _tag_cdm_scroll;
105 _tag_cdm_scroll = false;
106 } catch (e) { }
107 }
108
33b8cab4 109 notify("");
6b4163cb
AD
110 }
111}
112
e097e8be
AD
113function render_article(article) {
114 try {
6b4163cb 115 var f = document.getElementById("content-frame");
44cc6f20
AD
116 try {
117 f.scrollTop = 0;
118 } catch (e) { };
e097e8be
AD
119
120 f.innerHTML = article;
121
122 } catch (e) {
123 exception_error("render_article", e);
124 }
125}
126
127function article_callback() {
128 if (xmlhttp.readyState == 4) {
129 debug("article_callback");
130
131 try {
132 if (xmlhttp.responseXML) {
133 var reply = xmlhttp.responseXML.firstChild.firstChild;
134
135 var articles = xmlhttp.responseXML.getElementsByTagName("article");
136
137 for (var i = 0; i < articles.length; i++) {
138 var a_id = articles[i].getAttribute("id");
139
140 debug("found id: " + a_id);
141
142 if (a_id == active_post_id) {
143 debug("active article, rendering...");
144 render_article(articles[i].firstChild.nodeValue);
145 }
146
147 cache_inject(a_id, articles[i].firstChild.nodeValue);
148 }
149
150 } else {
151 debug("article_callback: returned no XML object");
0d88fd97
AD
152 var f = document.getElementById("content-frame");
153 f.innerHTML = "<div class='whiteBox'>" + __('Could not display article (missing XML object)') + "</div>";
e097e8be
AD
154 }
155 } catch (e) {
156 exception_error("article_callback", e);
157 }
4b6206fa
AD
158
159 var date = new Date();
160 last_article_view = date.getTime() / 1000;
161
935f235d
AD
162 if (typeof correctPNG != 'undefined') {
163 correctPNG();
164 }
0b126ac2
AD
165
166 if (_reload_feedlist_after_view) {
167 setTimeout('updateFeedList(false, false)', 50);
168 _reload_feedlist_after_view = false;
169 } else {
5a94a953
AD
170 var counters = xmlhttp.responseXML.getElementsByTagName("counters")[0];
171
172 if (counters) {
173 debug("parsing piggybacked counters: " + counters);
174 parse_counters(counters, false);
175 } else {
addb5836 176 debug("counters container not found in reply");
5a94a953 177 }
0b126ac2 178 }
9ec58704
AD
179
180 notify("");
6b4163cb
AD
181 }
182}
183
1dc8dba0 184function view(id, feed_id, skip_history) {
ee1f45f4
AD
185
186 try {
ee1f45f4 187 debug("loading article: " + id + "/" + feed_id);
1dc8dba0 188
0b126ac2
AD
189 active_real_feed_id = feed_id;
190
e097e8be
AD
191 var cached_article = cache_find(id);
192
193 debug("cache check result: " + (cached_article != false));
ee1f45f4 194
ee1f45f4
AD
195 enableHotkeys();
196
1c2d7193 197 //setActiveFeedId(feed_id);
090e250b 198
6b4163cb
AD
199 var query = "backend.php?op=view&id=" + param_escape(id) +
200 "&feed=" + param_escape(feed_id);
201
4b6206fa
AD
202 var date = new Date();
203
204 if (!xmlhttp_ready(xmlhttp) && last_article_view < date.getTime() / 1000 - 15) {
205 debug("<b>xmlhttp seems to be stuck at view, aborting</b>");
206 xmlhttp.abort();
c5af7171 207 if (is_safari()) {
86227583
AD
208 debug("trying alternative reset method for Safari");
209 xmlhttp = Ajax.getTransport();
c5af7171 210 }
4b6206fa
AD
211 }
212
ac162cbe
AD
213 if (xmlhttp_ready(xmlhttp)) {
214
215 active_post_id = id;
4b6206fa
AD
216
217 cleanSelected("headlinesList");
218
219 var crow = document.getElementById("RROW-" + active_post_id);
e097e8be
AD
220
221 var article_is_unread = crow.className.match("Unread");
222 debug("article is unread: " + article_is_unread);
223
4b6206fa
AD
224 crow.className = crow.className.replace("Unread", "");
225
226 var upd_img_pic = document.getElementById("FUPDPIC-" + active_post_id);
227
228 if (upd_img_pic) {
229 upd_img_pic.src = "images/blank_icon.gif";
230 }
231
232 selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', false);
233 markHeadline(active_post_id);
234
e097e8be
AD
235 var neighbor_ids = getRelativePostIds(active_post_id);
236
237 /* only request uncached articles */
238
239 var cids_to_request = Array();
240
241 for (var i = 0; i < neighbor_ids.length; i++) {
242 if (!cache_check(neighbor_ids[i])) {
243 cids_to_request.push(neighbor_ids[i]);
244 }
245 }
246
247 debug("additional ids: " + cids_to_request.toString());
248
5a94a953
AD
249 /* additional info for piggyback counters */
250
251 if (tagsAreDisplayed()) {
252 query = query + "&omode=lt";
253 } else {
254 query = query + "&omode=flc";
255 }
256
86173d9a
AD
257 var date = new Date();
258 var timestamp = Math.round(date.getTime() / 1000);
9ec58704
AD
259 query = query + "&ts=" + timestamp;
260
e097e8be
AD
261 query = query + "&cids=" + cids_to_request.toString();
262
263 if (!cached_article) {
264
265 notify_progress("Loading, please wait...");
266
267 debug(query);
268
269 xmlhttp.open("GET", query, true);
270 xmlhttp.onreadystatechange=article_callback;
271 xmlhttp.send(null);
272 } else if (cached_article && article_is_unread) {
273
274 query = query + "&mode=prefetch";
275
276 debug(query);
277
278 xmlhttp.open("GET", query, true);
279 xmlhttp.onreadystatechange=article_callback;
280 xmlhttp.send(null);
281
282 render_article(cached_article);
283
284 } else if (cached_article) {
285
addb5836
AD
286 query = query + "&mode=prefetch_old";
287
288 debug(query);
289
290 xmlhttp.open("GET", query, true);
291 xmlhttp.onreadystatechange=article_callback;
292 xmlhttp.send(null);
293
e097e8be
AD
294 render_article(cached_article);
295
296 }
297
298 cache_expire();
86173d9a 299
6b4163cb
AD
300 } else {
301 debug("xmlhttp busy (@view)");
f88e0a5d 302 printLockingError();
6b4163cb
AD
303 }
304
ee1f45f4
AD
305 } catch (e) {
306 exception_error("view", e);
307 }
f0601b87
AD
308}
309
67343d9f
AD
310function tMark(id) {
311 return toggleMark(id);
312}
313
9932fb06 314function toggleMark(id) {
f0601b87
AD
315
316 if (!xmlhttp_ready(xmlhttp_rpc)) {
317 printLockingError();
318 return;
319 }
320
f0601b87
AD
321 var query = "backend.php?op=rpc&id=" + id + "&subop=mark";
322
67343d9f 323 var mark_img = document.getElementById("FMPIC-" + id);
0feab655 324 var vfeedu = document.getElementById("FEEDU--1");
7ba176d2 325 var crow = document.getElementById("RROW-" + id);
254e0e4b 326
9932fb06 327 if (mark_img.alt != "Reset mark") {
f0601b87
AD
328 mark_img.src = "images/mark_set.png";
329 mark_img.alt = "Reset mark";
f0601b87 330 query = query + "&mark=1";
254e0e4b 331
7ba176d2
AD
332 if (vfeedu && crow.className.match("Unread")) {
333 vfeedu.innerHTML = (+vfeedu.innerHTML) + 1;
334 }
335
f0601b87
AD
336 } else {
337 mark_img.src = "images/mark_unset.png";
338 mark_img.alt = "Set mark";
f0601b87 339 query = query + "&mark=0";
254e0e4b 340
7ba176d2
AD
341 if (vfeedu && crow.className.match("Unread")) {
342 vfeedu.innerHTML = (+vfeedu.innerHTML) - 1;
343 }
254e0e4b
AD
344
345 }
346
0feab655
AD
347 var vfeedctr = document.getElementById("FEEDCTR--1");
348 var vfeedr = document.getElementById("FEEDR--1");
254e0e4b
AD
349
350 if (vfeedu && vfeedctr) {
351 if ((+vfeedu.innerHTML) > 0) {
7ba176d2 352 if (crow.className.match("Unread") && !vfeedr.className.match("Unread")) {
8add756a 353 vfeedr.className = vfeedr.className + "Unread";
7ba176d2 354 vfeedctr.className = "odd";
8add756a 355 }
254e0e4b
AD
356 } else {
357 vfeedctr.className = "invisible";
8add756a 358 vfeedr.className = vfeedr.className.replace("Unread", "");
254e0e4b 359 }
f0601b87
AD
360 }
361
772bc83b
AD
362 debug("toggle starred for aid " + id);
363
364 new Ajax.Request(query);
f0601b87
AD
365
366}
367
ac162cbe
AD
368function correctHeadlinesOffset(id) {
369
370 try {
371
372 var hlist = document.getElementById("headlinesList");
373 var container = document.getElementById("headlinesInnerContainer");
374 var row = document.getElementById("RROW-" + id);
375
376 var viewport = container.offsetHeight;
377
378 var rel_offset_top = row.offsetTop - container.scrollTop;
379 var rel_offset_bottom = row.offsetTop + row.offsetHeight - container.scrollTop;
380
381 debug("Rtop: " + rel_offset_top + " Rbtm: " + rel_offset_bottom);
382 debug("Vport: " + viewport);
a5e46e0f 383
ac162cbe
AD
384 if (rel_offset_top <= 0 || rel_offset_top > viewport) {
385 container.scrollTop = row.offsetTop;
386 } else if (rel_offset_bottom > viewport) {
a5e46e0f
AD
387
388 /* doesn't properly work with Opera in some cases because
389 Opera fucks up element scrolling */
390
ac162cbe
AD
391 container.scrollTop = row.offsetTop + row.offsetHeight - viewport;
392 }
393
394 } catch (e) {
395 exception_error("correctHeadlinesOffset", e);
396 }
397
398}
399
bb7cface 400function moveToPost(mode) {
f0601b87 401
4e51dd2b
AD
402 // check for combined mode
403 if (!document.getElementById("headlinesList"))
404 return;
405
bb7cface
AD
406 var rows = getVisibleHeadlineIds();
407
ac162cbe
AD
408 var prev_id = false;
409 var next_id = false;
bb7cface 410
d4eec882
AD
411 if (!document.getElementById('RROW-' + active_post_id)) {
412 active_post_id = false;
413 }
414
bb7cface
AD
415 if (active_post_id == false) {
416 next_id = getFirstVisibleHeadlineId();
417 prev_id = getLastVisibleHeadlineId();
418 } else {
419 for (var i = 0; i < rows.length; i++) {
420 if (rows[i] == active_post_id) {
421 prev_id = rows[i-1];
422 next_id = rows[i+1];
423 }
424 }
425 }
426
427 if (mode == "next") {
ac162cbe
AD
428 if (next_id) {
429 correctHeadlinesOffset(next_id);
86741347 430 view(next_id, getActiveFeedId());
bb7cface
AD
431 }
432 }
433
434 if (mode == "prev") {
ac162cbe
AD
435 if (prev_id) {
436 correctHeadlinesOffset(prev_id);
86741347 437 view(prev_id, getActiveFeedId());
bb7cface
AD
438 }
439 }
440}
441
5f51022a
AD
442function toggleUnread(id, cmode) {
443 try {
444 if (!xmlhttp_ready(xmlhttp_rpc)) {
445 printLockingError();
446 return;
447 }
448
449 var row = document.getElementById("RROW-" + id);
450 if (row) {
451 var nc = row.className;
452 nc = nc.replace("Unread", "");
453 nc = nc.replace("Selected", "");
454
455 if (row.className.match("Unread")) {
456 row.className = nc;
457 } else {
458 row.className = nc + "Unread";
459 }
460
461 if (!cmode) cmode = 2;
462
463 var query = "backend.php?op=rpc&subop=catchupSelected&ids=" +
464 param_escape(id) + "&cmode=" + param_escape(cmode);
465
9ec58704
AD
466 notify_progress("Loading, please wait...");
467
5f51022a
AD
468 xmlhttp_rpc.open("GET", query, true);
469 xmlhttp_rpc.onreadystatechange=all_counters_callback;
470 xmlhttp_rpc.send(null);
471
472 }
473
474
475 } catch (e) {
476 exception_error("toggleUnread", e);
477 }
478}
479
2228d0e4 480function selectionToggleUnread(cdm_mode, set_state, callback_func, no_error) {
1572afe5
AD
481 try {
482 if (!xmlhttp_ready(xmlhttp_rpc)) {
483 printLockingError();
484 return;
485 }
486
386cbf27
AD
487 var rows;
488
489 if (cdm_mode) {
490 rows = cdmGetSelectedArticles();
491 } else {
492 rows = getSelectedTableRowIds("headlinesList", "RROW", "RCHK");
493 }
1572afe5 494
2228d0e4 495 if (rows.length == 0 && !no_error) {
9cc600d1
AD
496 alert(__("No articles are selected."));
497 return;
498 }
499
1572afe5 500 for (i = 0; i < rows.length; i++) {
f1f2db64
AD
501 var row = document.getElementById("RROW-" + rows[i]);
502 if (row) {
503 var nc = row.className;
504 nc = nc.replace("Unread", "");
505 nc = nc.replace("Selected", "");
506
507 if (row.className.match("Unread")) {
508 row.className = nc + "Selected";
509 } else {
510 row.className = nc + "UnreadSelected";
511 }
512 }
1572afe5
AD
513 }
514
515 if (rows.length > 0) {
516
b47b5af7
AD
517 var cmode = "";
518
519 if (set_state == undefined) {
520 cmode = "2";
521 } else if (set_state == true) {
522 cmode = "1";
523 } else if (set_state == false) {
524 cmode = "0";
525 }
526
1572afe5 527 var query = "backend.php?op=rpc&subop=catchupSelected&ids=" +
b47b5af7 528 param_escape(rows.toString()) + "&cmode=" + cmode;
1572afe5 529
e08443c1
AD
530 _catchup_callback_func = callback_func;
531
9ec58704
AD
532 notify_progress("Loading, please wait...");
533
1572afe5 534 xmlhttp_rpc.open("GET", query, true);
e08443c1 535 xmlhttp_rpc.onreadystatechange=catchup_callback;
1572afe5
AD
536 xmlhttp_rpc.send(null);
537
538 }
539
540 } catch (e) {
83f043bb 541 exception_error("selectionToggleUnread", e);
1572afe5
AD
542 }
543}
544
386cbf27 545function selectionToggleMarked(cdm_mode) {
1572afe5
AD
546 try {
547 if (!xmlhttp_ready(xmlhttp_rpc)) {
548 printLockingError();
549 return;
550 }
551
386cbf27
AD
552 var rows;
553
554 if (cdm_mode) {
555 rows = cdmGetSelectedArticles();
556 } else {
557 rows = getSelectedTableRowIds("headlinesList", "RROW", "RCHK");
558 }
1572afe5 559
9cc600d1
AD
560 if (rows.length == 0) {
561 alert(__("No articles are selected."));
562 return;
563 }
564
1572afe5
AD
565 for (i = 0; i < rows.length; i++) {
566 var row = document.getElementById("RROW-" + rows[i]);
567 var mark_img = document.getElementById("FMARKPIC-" + rows[i]);
568
569 if (row && mark_img) {
570
571 if (mark_img.alt == "Set mark") {
572 mark_img.src = "images/mark_set.png";
573 mark_img.alt = "Reset mark";
574 mark_img.setAttribute('onclick',
575 'javascript:toggleMark('+rows[i]+', false)');
576
577 } else {
578 mark_img.src = "images/mark_unset.png";
579 mark_img.alt = "Set mark";
580 mark_img.setAttribute('onclick',
581 'javascript:toggleMark('+rows[i]+', true)');
582 }
583 }
584 }
585
586 if (rows.length > 0) {
587
588 var query = "backend.php?op=rpc&subop=markSelected&ids=" +
589 param_escape(rows.toString()) + "&cmode=2";
590
591 xmlhttp_rpc.open("GET", query, true);
592 xmlhttp_rpc.onreadystatechange=all_counters_callback;
593 xmlhttp_rpc.send(null);
594
595 }
596
597 } catch (e) {
83f043bb 598 exception_error("selectionToggleMarked", e);
1572afe5
AD
599 }
600}
601
386cbf27
AD
602function cdmGetSelectedArticles() {
603 var sel_articles = new Array();
b2128f01 604 var container = document.getElementById("headlinesInnerContainer");
386cbf27
AD
605
606 for (i = 0; i < container.childNodes.length; i++) {
607 var child = container.childNodes[i];
608
609 if (child.id.match("RROW-") && child.className.match("Selected")) {
610 var c_id = child.id.replace("RROW-", "");
611 sel_articles.push(c_id);
612 }
613 }
614
615 return sel_articles;
616}
617
618// mode = all,none,unread
619function cdmSelectArticles(mode) {
b2128f01 620 var container = document.getElementById("headlinesInnerContainer");
386cbf27
AD
621
622 for (i = 0; i < container.childNodes.length; i++) {
623 var child = container.childNodes[i];
624
625 if (child.id.match("RROW-")) {
06d1a1c1
AD
626 var aid = child.id.replace("RROW-", "");
627
628 var cb = document.getElementById("RCHK-" + aid);
629
386cbf27
AD
630 if (mode == "all") {
631 if (!child.className.match("Selected")) {
632 child.className = child.className + "Selected";
06d1a1c1 633 cb.checked = true;
386cbf27
AD
634 }
635 } else if (mode == "unread") {
636 if (child.className.match("Unread") && !child.className.match("Selected")) {
637 child.className = child.className + "Selected";
06d1a1c1 638 cb.checked = true;
386cbf27
AD
639 }
640 } else {
641 child.className = child.className.replace("Selected", "");
06d1a1c1 642 cb.checked = false;
386cbf27
AD
643 }
644 }
645 }
646}
647
98bea1b1 648function catchupPage() {
b47b5af7 649
8a5b4579
AD
650 var fn = getFeedName(getActiveFeedId(), active_feed_is_cat);
651
652 var str = "Mark all visible articles in " + fn + " as read?";
653
654 if (getInitParam("confirm_feed_catchup") == 1 && !confirm(str)) {
655 return;
656 }
657
b47b5af7
AD
658 if (document.getElementById("headlinesList")) {
659 selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', true, 'Unread', true);
2228d0e4 660 selectionToggleUnread(false, false, 'viewCurrentFeed()', true);
b47b5af7
AD
661 selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', false);
662 } else {
663 cdmSelectArticles('all');
2228d0e4 664 selectionToggleUnread(true, false, 'viewCurrentFeed()', true)
b47b5af7
AD
665 cdmSelectArticles('none');
666 }
98bea1b1
AD
667}
668
88040f57
AD
669function labelFromSearch(search, search_mode, match_on, feed_id, is_cat) {
670
671 if (!xmlhttp_ready(xmlhttp_rpc)) {
672 printLockingError();
673 }
674
675 var title = prompt("Please enter label title:", "");
676
677 if (title) {
678
679 var query = "backend.php?op=labelFromSearch&search=" + param_escape(search) +
680 "&smode=" + param_escape(search_mode) + "&match=" + param_escape(match_on) +
681 "&feed=" + param_escape(feed_id) + "&is_cat=" + param_escape(is_cat) +
682 "&title=" + param_escape(title);
683
684 debug("LFS: " + query);
685
686 xmlhttp_rpc.open("GET", query, true);
0feab655 687 xmlhttp_rpc.onreadystatechange=dlg_frefresh_callback;
88040f57
AD
688 xmlhttp_rpc.send(null);
689 }
690
691}
692
13f08f75 693function editArticleTags(id, feed_id, cdm_enabled) {
0b126ac2
AD
694 _tag_active_post_id = id;
695 _tag_active_feed_id = feed_id;
13f08f75 696 _tag_active_cdm = cdm_enabled;
b07b61da
AD
697
698 cache_invalidate(id);
699
13f08f75
AD
700 try {
701 _tag_cdm_scroll = document.getElementById("headlinesInnerContainer").scrollTop;
702 } catch (e) { }
0b126ac2
AD
703 displayDlg('editArticleTags', id);
704}
705
706
707function tag_saved_callback() {
708 if (xmlhttp_rpc.readyState == 4) {
709 try {
710 debug("in tag_saved_callback");
711
712 closeInfoBox();
713 notify("");
714
715 if (tagsAreDisplayed()) {
716 _reload_feedlist_after_view = true;
717 }
718
13f08f75
AD
719 if (!_tag_active_cdm) {
720 if (active_post_id == _tag_active_post_id) {
721 debug("reloading current article");
722 view(_tag_active_post_id, _tag_active_feed_id);
723 }
724 } else {
725 debug("reloading current feed");
726 viewCurrentFeed();
727 }
0b126ac2
AD
728
729 } catch (e) {
730 exception_error("catchup_callback", e);
731 }
732 }
733}
734
735function editTagsSave() {
736
737 if (!xmlhttp_ready(xmlhttp_rpc)) {
738 printLockingError();
739 }
740
42c32916 741 notify_progress("Saving article tags...");
88040f57 742
0b126ac2
AD
743 var form = document.forms["tag_edit_form"];
744
745 var query = Form.serialize("tag_edit_form");
746
14b6c54b
AD
747 query = "backend.php?op=rpc&subop=setArticleTags&" + query;
748
749 debug(query);
750
751 xmlhttp_rpc.open("GET", query, true);
0b126ac2
AD
752 xmlhttp_rpc.onreadystatechange=tag_saved_callback;
753 xmlhttp_rpc.send(null);
754
755}
d62a3b63
AD
756
757function editTagsInsert() {
758 try {
759
760 var form = document.forms["tag_edit_form"];
761
762 var found_tags = form.found_tags;
763 var tags_str = form.tags_str;
764
765 var tag = found_tags[found_tags.selectedIndex].value;
766
767 if (tags_str.value.length > 0 &&
768 tags_str.value.lastIndexOf(", ") != tags_str.value.length - 2) {
769
770 tags_str.value = tags_str.value + ", ";
771 }
772
773 tags_str.value = tags_str.value + tag + ", ";
774
775 found_tags.selectedIndex = 0;
776
777 } catch (e) {
778 exception_error(e, "editTagsInsert");
779 }
780}
ba0978c8
AD
781
782function cdmWatchdog() {
783
784 try {
785
786 var ctr = document.getElementById("headlinesInnerContainer");
787
9acd22e8
AD
788 if (!ctr) return;
789
ba0978c8
AD
790 var ids = new Array();
791
792 var e = ctr.firstChild;
793
794 while (e) {
795 if (e.className && e.className == "cdmArticleUnread" && e.id &&
796 e.id.match("RROW-")) {
797
798 // article fits in viewport OR article is longer than viewport and
799 // its bottom is visible
800
801 if (ctr.scrollTop <= e.offsetTop && e.offsetTop + e.offsetHeight <=
802 ctr.scrollTop + ctr.offsetHeight) {
803
804// debug(e.id + " is visible " + e.offsetTop + "." +
805// (e.offsetTop + e.offsetHeight) + " vs " + ctr.scrollTop + "." +
806// (ctr.scrollTop + ctr.offsetHeight));
807
808 ids.push(e.id.replace("RROW-", ""));
809
810 } else if (e.offsetHeight > ctr.offsetHeight &&
811 e.offsetTop + e.offsetHeight >= ctr.scrollTop &&
812 e.offsetTop + e.offsetHeight <= ctr.scrollTop + ctr.offsetHeight) {
813
814 ids.push(e.id.replace("RROW-", ""));
815
816 }
817
c50e2b30
AD
818 // method 2: article bottom is visible and is in upper 1/2 of the viewport
819
820/* if (e.offsetTop + e.offsetHeight >= ctr.scrollTop &&
821 e.offsetTop + e.offsetHeight <= ctr.scrollTop + ctr.offsetHeight/2) {
822
823 ids.push(e.id.replace("RROW-", ""));
824
825 } */
826
ba0978c8
AD
827 }
828
829 e = e.nextSibling;
830 }
831
832 debug("cdmWatchdog, ids= " + ids.toString());
833
834 if (ids.length > 0 && xmlhttp_ready(xmlhttp_rpc)) {
835
836 for (var i = 0; i < ids.length; i++) {
837 var e = document.getElementById("RROW-" + ids[i]);
838 if (e) {
839 e.className = e.className.replace("Unread", "");
840 }
841 }
842
843 var query = "backend.php?op=rpc&subop=catchupSelected&ids=" +
844 param_escape(ids.toString()) + "&cmode=0";
845
f8e47112 846 xmlhttp_rpc.open("GET", query, true);
ba0978c8 847 xmlhttp_rpc.onreadystatechange=all_counters_callback;
c50e2b30 848 xmlhttp_rpc.send(null);
ba0978c8
AD
849
850 }
851
c50e2b30 852 _cdm_wd_timeout = window.setTimeout("cdmWatchdog()", 4000);
ba0978c8
AD
853
854 } catch (e) {
855 exception_error(e, "cdmWatchdog");
856 }
857
858}
e097e8be
AD
859
860
861function cache_inject(id, article) {
fed4387d 862 if (!cache_check(id)) {
e097e8be
AD
863 debug("cache_article: miss: " + id);
864
865 var cache_obj = new Array();
866
fed4387d 867 cache_obj["id"] = id;
e097e8be
AD
868 cache_obj["data"] = article;
869
fed4387d 870 article_cache.push(cache_obj);
e097e8be
AD
871
872 } else {
873 debug("cache_article: hit: " + id);
874 }
875}
876
877function cache_find(id) {
fed4387d
AD
878 for (var i = 0; i < article_cache.length; i++) {
879 if (article_cache[i]["id"] == id) {
fed4387d
AD
880 return article_cache[i]["data"];
881 }
e097e8be 882 }
fed4387d 883 return false;
e097e8be
AD
884}
885
886function cache_check(id) {
fed4387d
AD
887 for (var i = 0; i < article_cache.length; i++) {
888 if (article_cache[i]["id"] == id) {
889 return true;
890 }
891 }
892 return false;
e097e8be
AD
893}
894
895function cache_expire() {
7289eacf 896 while (article_cache.length > 20) {
fed4387d
AD
897 article_cache.shift();
898 }
e097e8be 899}
b07b61da
AD
900
901function cache_invalidate(id) {
902 var i = 0
c1b18749
AD
903
904 try {
905
906 while (i < article_cache.length) {
907 if (article_cache[i]["id"] == id) {
908 debug("cache_invalidate: removed id " + id);
909 article_cache.splice(i, 1);
910 return true;
911 }
912 i++;
b07b61da 913 }
c1b18749
AD
914 debug("cache_invalidate: id not found: " + id);
915 return false;
916 } catch (e) {
917 exception_error("cache_invalidate", e);
b07b61da 918 }
b07b61da 919}
298f3f78
AD
920
921function getActiveArticleId() {
922 return active_post_id;
923}
e4914b62
AD
924
925function cdmMouseIn(elem) {
926 try {
927 if (elem.id && elem.id.match("RROW-")) {
928 var id = elem.id.replace("RROW-", "");
929 active_post_id = id;
930 }
931 } catch (e) {
932 exception_error("cdmMouseIn", e);
933 }
934
935}
936
937function cdmMouseOut(elem) {
938 active_post_id = false;
939}