]>
git.wh0rd.org - tt-rss.git/blob - functions.js
1 var hotkeys_enabled
= true;
2 var debug_mode_enabled
= false;
3 var xmlhttp_rpc
= Ajax
.getTransport();
5 function browser_has_opacity() {
6 return navigator
.userAgent
.match("Gecko") != null ||
7 navigator
.userAgent
.match("Opera") != null;
11 return navigator
.userAgent
.match("MSIE");
15 return navigator
.userAgent
.match("Opera");
19 return navigator
.userAgent
.match("KHTML");
22 function is_safari() {
23 return navigator
.userAgent
.match("Safari");
26 function exception_error(location
, e
, silent
) {
30 var base_fname
= e
.fileName
.substring(e
.fileName
.lastIndexOf("/") + 1);
32 msg
= "Exception: " + e
.name
+ ", " + e
.message
+
33 "\nFunction: " + location
+ "()" +
34 "\nLocation: " + base_fname
+ ":" + e
.lineNumber
;
37 msg
= "Exception: " + e
+ "\nFunction: " + location
+ "()";
40 debug("<b>EXCEPTION: " + msg
+ "</b>");
47 function disableHotkeys() {
48 hotkeys_enabled
= false;
51 function enableHotkeys() {
52 hotkeys_enabled
= true;
55 function xmlhttp_ready(obj
) {
56 return obj
.readyState
== 4 || obj
.readyState
== 0 || !obj
.readyState
;
59 function logout_callback() {
60 var container
= document
.getElementById('notify');
61 if (xmlhttp
.readyState
== 4) {
63 var date
= new Date();
64 var timestamp
= Math
.round(date
.getTime() / 1000);
65 window
.location
.href
= "tt-rss.php";
67 exception_error("logout_callback", e
);
72 function notify_callback() {
73 var container
= document
.getElementById('notify');
74 if (xmlhttp
.readyState
== 4) {
75 container
.innerHTML
=xmlhttp
.responseText
;
79 function rpc_notify_callback() {
80 var container
= document
.getElementById('notify');
81 if (xmlhttp_rpc
.readyState
== 4) {
82 container
.innerHTML
=xmlhttp_rpc
.responseText
;
86 function param_escape(arg
) {
87 if (typeof encodeURIComponent
!= 'undefined')
88 return encodeURIComponent(arg
);
93 function param_unescape(arg
) {
94 if (typeof decodeURIComponent
!= 'undefined')
95 return decodeURIComponent(arg
);
100 function delay(gap
) {
102 then
=new Date().getTime();
104 while((now
-then
)<gap
) {
105 now
=new Date().getTime();
109 var notify_hide_timerid
= false;
111 function hide_notify() {
112 var n
= document
.getElementById("notify");
114 n
.style
.display
= "none";
118 function notify_real(msg
, no_hide
, n_type
) {
120 var n
= document
.getElementById("notify");
121 var nb
= document
.getElementById("notify_body");
123 if (!n
|| !nb
) return;
125 if (notify_hide_timerid
) {
126 window
.clearTimeout(notify_hide_timerid
);
130 if (n
.style
.display
== "block") {
131 notify_hide_timerid
= window
.setTimeout("hide_notify()", 0);
135 n
.style
.display
= "block";
147 if (typeof __
!= 'undefined') {
152 n
.className
= "notify";
153 } else if (n_type
== 2) {
154 n
.className
= "notifyProgress";
155 msg
= "<img src='images/indicator_white.gif'> " + msg
;
156 } else if (n_type
== 3) {
157 n
.className
= "notifyError";
158 msg
= "<img src='images/sign_excl.png'> " + msg
;
159 } else if (n_type
== 4) {
160 n
.className
= "notifyInfo";
161 msg
= "<img src='images/sign_info.png'> " + msg
;
164 // msg = "<img src='images/live_com_loading.gif'> " + msg;
169 notify_hide_timerid
= window
.setTimeout("hide_notify()", 3000);
173 function notify(msg
, no_hide
) {
174 notify_real(msg
, no_hide
, 1);
177 function notify_progress(msg
, no_hide
) {
178 notify_real(msg
, no_hide
, 2);
181 function notify_error(msg
, no_hide
) {
182 notify_real(msg
, no_hide
, 3);
186 function notify_info(msg
, no_hide
) {
187 notify_real(msg
, no_hide
, 4);
190 function printLockingError() {
191 notify_info("Please wait until operation finishes.");
194 function hotkey_handler(e
) {
199 var shift_key
= false;
202 shift_key
= e
.shiftKey
;
207 if (!hotkeys_enabled
) return;
210 keycode
= window
.event
.keyCode
;
215 if (keycode
== 82) { // r
216 return scheduleFeedUpdate(true);
219 if (keycode
== 83) { // s
220 return displayDlg("search", getActiveFeedId());
223 if (keycode
== 85) { // u
224 if (getActiveFeedId()) {
225 return viewfeed(getActiveFeedId(), "ForceUpdate");
229 if (keycode
== 65) { // a
230 return toggleDispRead();
233 var feedlist
= document
.getElementById('feedList');
235 if (keycode
== 74) { // j
236 var feed
= getActiveFeedId();
237 var new_feed
= getRelativeFeedId(feedlist
, feed
, 'prev');
238 if (new_feed
) viewfeed(new_feed
, '');
241 if (keycode
== 75) { // k
242 var feed
= getActiveFeedId();
243 var new_feed
= getRelativeFeedId(feedlist
, feed
, 'next');
244 if (new_feed
) viewfeed(new_feed
, '');
247 if (!is_safari() && (keycode
== 78 || keycode
== 40)) { // n, down
248 if (typeof moveToPost
!= 'undefined') {
249 return moveToPost('next');
253 if (!is_safari() && (keycode
== 80 || keycode
== 38)) { // p, up
254 if (typeof moveToPost
!= 'undefined') {
255 return moveToPost('prev');
259 if (keycode
== 68 && shift_key
) { // d
260 if (!debug_mode_enabled
) {
261 document
.getElementById('debug_output').style
.display
= 'block';
262 debug('debug mode activated');
264 document
.getElementById('debug_output').style
.display
= 'none';
267 debug_mode_enabled
= !debug_mode_enabled
;
270 if (keycode
== 190 && shift_key
) { // >
274 if (keycode
== 188 && shift_key
) { // <
278 if (keycode
== 191 && shift_key
) { // ?
282 if (keycode
== 69 && shift_key
) { // e
283 return editFeedDlg(getActiveFeedId());
286 if (keycode
== 70 && shift_key
) { // f
287 if (getActiveFeedId()) {
288 return catchupCurrentFeed();
292 if (keycode
== 80 && shift_key
) { // p
293 if (getActiveFeedId()) {
294 return catchupPage();
298 if (typeof localHotkeyHandler
!= 'undefined') {
300 return localHotkeyHandler(e
);
302 exception_error("hotkey_handler, local:", e
);
306 debug("KP=" + keycode
);
308 exception_error("hotkey_handler", e
);
312 function cleanSelectedList(element
) {
313 var content
= document
.getElementById(element
);
315 if (!document
.getElementById("feedCatHolder")) {
316 for (i
= 0; i
< content
.childNodes
.length
; i
++) {
317 var child
= content
.childNodes
[i
];
319 child
.className
= child
.className
.replace("Selected", "");
325 for (i
= 0; i
< content
.childNodes
.length
; i
++) {
326 var child
= content
.childNodes
[i
];
327 if (child
.id
== "feedCatHolder") {
329 var fcat
= child
.lastChild
;
330 for (j
= 0; j
< fcat
.childNodes
.length
; j
++) {
331 var feed
= fcat
.childNodes
[j
];
332 feed
.className
= feed
.className
.replace("Selected", "");
340 function cleanSelected(element
) {
341 var content
= document
.getElementById(element
);
343 for (i
= 0; i
< content
.rows
.length
; i
++) {
344 content
.rows
[i
].className
= content
.rows
[i
].className
.replace("Selected", "");
348 function getVisibleUnreadHeadlines() {
349 var content
= document
.getElementById("headlinesList");
351 var rows
= new Array();
353 for (i
= 0; i
< content
.rows
.length
; i
++) {
354 var row_id
= content
.rows
[i
].id
.replace("RROW-", "");
355 if (row_id
.length
> 0 && content
.rows
[i
].className
.match("Unread")) {
362 function getVisibleHeadlineIds() {
364 var content
= document
.getElementById("headlinesList");
366 var rows
= new Array();
368 for (i
= 0; i
< content
.rows
.length
; i
++) {
369 var row_id
= content
.rows
[i
].id
.replace("RROW-", "");
370 if (row_id
.length
> 0) {
377 function getFirstVisibleHeadlineId() {
378 var rows
= getVisibleHeadlineIds();
382 function getLastVisibleHeadlineId() {
383 var rows
= getVisibleHeadlineIds();
384 return rows
[rows
.length
-1];
387 function markHeadline(id
) {
388 var row
= document
.getElementById("RROW-" + id
);
390 var is_active
= false;
392 if (row
.className
.match("Active")) {
395 row
.className
= row
.className
.replace("Selected", "");
396 row
.className
= row
.className
.replace("Active", "");
397 row
.className
= row
.className
.replace("Insensitive", "");
400 row
.className
= row
.className
= "Active";
403 var check
= document
.getElementById("RCHK-" + id
);
406 check
.checked
= true;
409 row
.className
= row
.className
+ "Selected";
414 function getFeedIds() {
415 var content
= document
.getElementById("feedsList");
417 var rows
= new Array();
419 for (i
= 0; i
< content
.rows
.length
; i
++) {
420 var id
= content
.rows
[i
].id
.replace("FEEDR-", "");
429 function setCookie(name
, value
, lifetime
, path
, domain
, secure
) {
435 d
.setTime(d
.getTime() + (lifetime
* 1000));
438 debug("setCookie: " + name
+ " => " + value
+ ": " + d
);
440 int_setCookie(name
, value
, d
, path
, domain
, secure
);
444 function int_setCookie(name
, value
, expires
, path
, domain
, secure
) {
445 document
.cookie
= name
+ "=" + escape(value
) +
446 ((expires
) ? "; expires=" + expires
.toGMTString() : "") +
447 ((path
) ? "; path=" + path
: "") +
448 ((domain
) ? "; domain=" + domain
: "") +
449 ((secure
) ? "; secure" : "");
452 function delCookie(name
, path
, domain
) {
453 if (getCookie(name
)) {
454 document
.cookie
= name
+ "=" +
455 ((path
) ? ";path=" + path
: "") +
456 ((domain
) ? ";domain=" + domain
: "" ) +
457 ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
462 function getCookie(name
) {
464 var dc
= document
.cookie
;
465 var prefix
= name
+ "=";
466 var begin
= dc
.indexOf("; " + prefix
);
468 begin
= dc
.indexOf(prefix
);
469 if (begin
!= 0) return null;
474 var end
= document
.cookie
.indexOf(";", begin
);
478 return unescape(dc
.substring(begin
+ prefix
.length
, end
));
481 function disableContainerChildren(id
, disable
, doc
) {
483 if (!doc
) doc
= document
;
485 var container
= doc
.getElementById(id
);
488 //alert("disableContainerChildren: element " + id + " not found");
492 for (var i
= 0; i
< container
.childNodes
.length
; i
++) {
493 var child
= container
.childNodes
[i
];
496 child
.disabled
= disable
;
502 if (child
.className
&& child
.className
.match("button")) {
503 child
.className
= "disabledButton";
506 if (child
.className
&& child
.className
.match("disabledButton")) {
507 child
.className
= "button";
514 function gotoPreferences() {
515 document
.location
.href
= "prefs.php";
518 function gotoMain() {
519 document
.location
.href
= "tt-rss.php";
522 function gotoExportOpml() {
523 document
.location
.href
= "opml.php?op=Export";
526 function getActiveFeedId() {
527 // return getCookie("ttrss_vf_actfeed");
529 debug("gAFID: " + active_feed_id
);
530 return active_feed_id
;
532 exception_error("getActiveFeedId", e
);
536 function activeFeedIsCat() {
537 return active_feed_is_cat
;
540 function setActiveFeedId(id
) {
541 // return setCookie("ttrss_vf_actfeed", id);
543 debug("sAFID(" + id
+ ")");
546 exception_error("setActiveFeedId", e
);
550 function parse_counters(reply
, scheduled_call
) {
555 if (reply
.firstChild
&& reply
.firstChild
.firstChild
) {
556 debug("<b>wrong element passed to parse_counters, adjusting.</b>");
557 reply
= reply
.firstChild
;
560 for (var l
= 0; l
< reply
.childNodes
.length
; l
++) {
561 if (!reply
.childNodes
[l
] ||
562 typeof(reply
.childNodes
[l
].getAttribute
) == "undefined") {
563 // where did this come from?
567 var id
= reply
.childNodes
[l
].getAttribute("id");
568 var t
= reply
.childNodes
[l
].getAttribute("type");
569 var ctr
= reply
.childNodes
[l
].getAttribute("counter");
570 var error
= reply
.childNodes
[l
].getAttribute("error");
571 var has_img
= reply
.childNodes
[l
].getAttribute("hi");
572 var updated
= reply
.childNodes
[l
].getAttribute("updated");
574 if (id
== "global-unread") {
580 if (id
== "subscribed-feeds") {
585 if (t
== "category") {
586 var catctr
= document
.getElementById("FCATCTR-" + id
);
588 catctr
.innerHTML
= "(" + ctr
+ ")";
590 catctr
.className
= "catCtrHasUnread";
592 catctr
.className
= "catCtrNoUnread";
598 var feedctr
= document
.getElementById("FEEDCTR-" + id
);
599 var feedu
= document
.getElementById("FEEDU-" + id
);
600 var feedr
= document
.getElementById("FEEDR-" + id
);
601 var feed_img
= document
.getElementById("FIMG-" + id
);
602 var feedlink
= document
.getElementById("FEEDL-" + id
);
603 var feedupd
= document
.getElementById("FLUPD-" + id
);
605 if (updated
&& feedlink
) {
607 feedlink
.title
= "Error: " + error
+ " (" + updated
+ ")";
609 feedlink
.title
= "Updated: " + updated
;
613 if (updated
&& feedupd
) {
615 feedupd
.innerHTML
= updated
+ " (Error)";
617 feedupd
.innerHTML
= updated
;
621 if (feedctr
&& feedu
&& feedr
) {
623 if (feedu
.innerHTML
!= ctr
&& id
== getActiveFeedId() && scheduled_call
) {
627 feedu
.innerHTML
= ctr
;
630 feedr
.className
= feedr
.className
.replace("feed", "error");
632 feedr
.className
= feedr
.className
.replace("error", "feed");
636 feedctr
.className
= "odd";
637 if (!feedr
.className
.match("Unread")) {
638 var is_selected
= feedr
.className
.match("Selected");
640 feedr
.className
= feedr
.className
.replace("Selected", "");
641 feedr
.className
= feedr
.className
.replace("Unread", "");
643 feedr
.className
= feedr
.className
+ "Unread";
646 feedr
.className
= feedr
.className
+ "Selected";
651 feedctr
.className
= "invisible";
652 feedr
.className
= feedr
.className
.replace("Unread", "");
657 hideOrShowFeeds(document
, getInitParam("hide_read_feeds") == 1);
659 var feeds_stored
= number_of_feeds
;
661 debug("Feed counters, C: " + feeds_found
+ ", S:" + feeds_stored
);
663 if (feeds_stored
!= feeds_found
) {
664 number_of_feeds
= feeds_found
;
666 if (feeds_stored
!= 0) {
667 debug("Subscribed feed number changed, refreshing feedlist");
668 setTimeout('updateFeedList(false, false)', 50);
673 exception_error("parse_counters", e
);
677 function parse_counters_reply(xmlhttp
, scheduled_call
) {
679 if (!xmlhttp
.responseXML
) {
680 notify_error("Backend did not return valid XML", true);
684 var reply
= xmlhttp
.responseXML
.firstChild
;
687 notify_error("Backend did not return expected XML object", true);
692 var error_code
= false;
693 var error_msg
= false;
695 if (reply
.firstChild
) {
696 error_code
= reply
.firstChild
.getAttribute("error-code");
697 error_msg
= reply
.firstChild
.getAttribute("error-msg");
701 error_code
= reply
.getAttribute("error-code");
702 error_msg
= reply
.getAttribute("error-msg");
705 if (error_code
&& error_code
!= 0) {
706 debug("refetch_callback: got error code " + error_code
);
707 return fatalError(error_code
, error_msg
);
710 var counters
= reply
.firstChild
;
712 parse_counters(counters
, scheduled_call
);
714 var runtime_info
= counters
.nextSibling
;
716 parse_runtime_info(runtime_info
);
718 if (getInitParam("feeds_sort_by_unread") == 1) {
722 hideOrShowFeeds(document
, getInitParam("hide_read_feeds") == 1);
726 function all_counters_callback() {
727 if (xmlhttp_rpc
.readyState
== 4) {
729 /* if (!xmlhttp_rpc.responseXML || !xmlhttp_rpc.responseXML.firstChild) {
730 debug("[all_counters_callback] backend did not return valid XML");
734 debug("in all_counters_callback : " + xmlhttp_rpc.responseXML);
736 var reply = xmlhttp_rpc.responseXML.firstChild;
738 var counters = reply.firstChild;
740 parse_counters(counters);
742 var runtime = counters.nextSibling;
745 parse_runtime_info(runtime);
748 if (getInitParam("feeds_sort_by_unread") == 1) {
752 hideOrShowFeeds(document, getInitParam("hide_read_feeds") == 1); */
754 debug("in all_counters_callback");
756 parse_counters_reply(xmlhttp_rpc
);
759 exception_error("all_counters_callback", e
);
764 function get_feed_entry_unread(doc
, elem
) {
766 var id
= elem
.id
.replace("FEEDR-", "");
773 return parseInt(doc
.getElementById("FEEDU-" + id
).innerHTML
);
779 function resort_category(doc
, node
) {
780 debug("resort_category: " + node
);
782 if (node
.hasChildNodes() && node
.firstChild
.nextSibling
!= false) {
783 for (i
= 0; i
< node
.childNodes
.length
; i
++) {
784 if (node
.childNodes
[i
].nodeName
!= "LI") { continue; }
786 if (get_feed_entry_unread(doc
, node
.childNodes
[i
]) < 0) {
790 for (j
= i
+1; j
< node
.childNodes
.length
; j
++) {
791 if (node
.childNodes
[j
].nodeName
!= "LI") { continue; }
793 var tmp_val
= get_feed_entry_unread(doc
, node
.childNodes
[i
]);
794 var cur_val
= get_feed_entry_unread(doc
, node
.childNodes
[j
]);
796 if (cur_val
> tmp_val
) {
797 tempnode_i
= node
.childNodes
[i
].cloneNode(true);
798 tempnode_j
= node
.childNodes
[j
].cloneNode(true);
799 node
.replaceChild(tempnode_i
, node
.childNodes
[j
]);
800 node
.replaceChild(tempnode_j
, node
.childNodes
[i
]);
809 function resort_feedlist() {
810 debug("resort_feedlist");
814 if (fd
.getElementById("feedCatHolder")) {
816 var feeds
= fd
.getElementById("feedList");
817 var child
= feeds
.firstChild
;
821 if (child
.id
== "feedCatHolder") {
822 resort_category(fd
, child
.firstChild
);
825 child
= child
.nextSibling
;
829 resort_category(fd
, fd
.getElementById("feedList"));
833 function update_all_counters(feed
) {
834 if (xmlhttp_ready(xmlhttp_rpc
)) {
835 var query
= "backend.php?op=rpc&subop=getAllCounters";
838 query
= query
+ "&aid=" + feed
;
841 if (tagsAreDisplayed()) {
842 query
= query
+ "&omode=lt";
844 query
= query
+ "&omode=flc";
847 debug("update_all_counters QUERY: " + query
);
849 var date
= new Date();
850 var timestamp
= Math
.round(date
.getTime() / 1000);
851 query
= query
+ "&ts=" + timestamp
853 xmlhttp_rpc
.open("GET", query
, true);
854 xmlhttp_rpc
.onreadystatechange
=all_counters_callback
;
855 xmlhttp_rpc
.send(null);
859 function popupHelp(tid
) {
860 var w
= window
.open("backend.php?op=help&tid=" + tid
,
862 "menubar=no,location=no,resizable=yes,scrollbars=yes,status=no");
865 /** * @(#)isNumeric.js * * Copyright (c) 2000 by Sundar Dorai-Raj
866 * * @author Sundar Dorai-Raj
867 * * Email: sdoraira@vt.edu
868 * * This program is free software; you can redistribute it and/or
869 * * modify it under the terms of the GNU General Public License
870 * * as published by the Free Software Foundation; either version 2
871 * * of the License, or (at your option) any later version,
872 * * provided that any use properly credits the author.
873 * * This program is distributed in the hope that it will be useful,
874 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
875 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
876 * * GNU General Public License for more details at http://www.gnu.org * * */
878 var numbers
=".0123456789";
879 function isNumeric(x
) {
880 // is x a String or a character?
882 // remove negative sign
884 for(j
=0;j
<x
.length
;j
++) {
885 // call isNumeric recursively for each character
886 number
=isNumeric(x
.substring(j
,j
+1));
887 if(!number
) return number
;
892 // if x is number return true
893 if(numbers
.indexOf(x
)>=0) return true;
899 function hideOrShowFeeds(doc
, hide
) {
901 debug("hideOrShowFeeds: " + doc
+ ", " + hide
);
905 var list
= fd
.getElementById("feedList");
907 if (fd
.getElementById("feedCatHolder")) {
909 var feeds
= fd
.getElementById("feedList");
910 var child
= feeds
.firstChild
;
914 if (child
.id
== "feedCatHolder") {
915 hideOrShowFeedsCategory(fd
, child
.firstChild
, hide
, child
.previousSibling
);
918 child
= child
.nextSibling
;
922 hideOrShowFeedsCategory(fd
, fd
.getElementById("feedList"), hide
);
926 function hideOrShowFeedsCategory(doc
, node
, hide
, cat_node
) {
928 // debug("hideOrShowFeedsCategory: " + node + " (" + hide + ")");
933 debug("hideOrShowFeeds: passed node is null, aborting");
937 if (node
.hasChildNodes() && node
.firstChild
.nextSibling
!= false) {
938 for (i
= 0; i
< node
.childNodes
.length
; i
++) {
939 if (node
.childNodes
[i
].nodeName
!= "LI") { continue; }
941 if (node
.childNodes
[i
].style
!= undefined) {
943 var has_unread
= (node
.childNodes
[i
].className
!= "feed");
945 // debug(node.childNodes[i].id + " --> " + has_unread);
947 if (hide
&& !has_unread
) {
948 node
.childNodes
[i
].style
.display
= "none";
952 node
.childNodes
[i
].style
.display
= "list-item";
956 node
.childNodes
[i
].style
.display
= "list-item";
963 if (cat_unread
== 0) {
964 if (cat_node
.style
== undefined) {
965 debug("ERROR: supplied cat_node " + cat_node
+
966 " has no styles. WTF?");
970 cat_node
.style
.display
= "none";
972 cat_node
.style
.display
= "list-item";
976 cat_node
.style
.display
= "list-item";
982 // debug("unread for category: " + cat_unread);
985 function selectTableRow(r
, do_select
) {
986 r
.className
= r
.className
.replace("Selected", "");
989 r
.className
= r
.className
+ "Selected";
993 function selectTableRowById(elem_id
, check_id
, do_select
) {
997 var row
= document
.getElementById(elem_id
);
1000 selectTableRow(row
, do_select
);
1003 var check
= document
.getElementById(check_id
);
1006 check
.checked
= do_select
;
1009 exception_error("selectTableRowById", e
);
1013 function selectTableRowsByIdPrefix(content_id
, prefix
, check_prefix
, do_select
,
1014 classcheck
, reset_others
) {
1016 var content
= document
.getElementById(content_id
);
1019 alert("[selectTableRows] Element " + content_id
+ " not found.");
1023 for (i
= 0; i
< content
.rows
.length
; i
++) {
1024 if (!classcheck
|| content
.rows
[i
].className
.match(classcheck
)) {
1026 if (content
.rows
[i
].id
.match(prefix
)) {
1027 selectTableRow(content
.rows
[i
], do_select
);
1029 var row_id
= content
.rows
[i
].id
.replace(prefix
, "");
1030 var check
= document
.getElementById(check_prefix
+ row_id
);
1033 check
.checked
= do_select
;
1035 } else if (reset_others
) {
1036 selectTableRow(content
.rows
[i
], false);
1038 var row_id
= content
.rows
[i
].id
.replace(prefix
, "");
1039 var check
= document
.getElementById(check_prefix
+ row_id
);
1042 check
.checked
= false;
1046 } else if (reset_others
) {
1047 selectTableRow(content
.rows
[i
], false);
1049 var row_id
= content
.rows
[i
].id
.replace(prefix
, "");
1050 var check
= document
.getElementById(check_prefix
+ row_id
);
1053 check
.checked
= false;
1060 function getSelectedTableRowIds(content_id
, prefix
) {
1062 var content
= document
.getElementById(content_id
);
1065 alert("[getSelectedTableRowIds] Element " + content_id
+ " not found.");
1069 var sel_rows
= new Array();
1071 for (i
= 0; i
< content
.rows
.length
; i
++) {
1072 if (content
.rows
[i
].id
.match(prefix
) &&
1073 content
.rows
[i
].className
.match("Selected")) {
1075 var row_id
= content
.rows
[i
].id
.replace(prefix
+ "-", "");
1076 sel_rows
.push(row_id
);
1084 function toggleSelectRowById(sender
, id
) {
1085 var row
= document
.getElementById(id
);
1087 if (sender
.checked
) {
1088 if (!row
.className
.match("Selected")) {
1089 row
.className
= row
.className
+ "Selected";
1092 if (row
.className
.match("Selected")) {
1093 row
.className
= row
.className
.replace("Selected", "");
1098 function toggleSelectListRow(sender
) {
1099 var parent_row
= sender
.parentNode
;
1101 if (sender
.checked
) {
1102 if (!parent_row
.className
.match("Selected")) {
1103 parent_row
.className
= parent_row
.className
+ "Selected";
1106 if (parent_row
.className
.match("Selected")) {
1107 parent_row
.className
= parent_row
.className
.replace("Selected", "");
1113 function toggleSelectRow(sender
) {
1114 var parent_row
= sender
.parentNode
.parentNode
;
1116 if (sender
.checked
) {
1117 if (!parent_row
.className
.match("Selected")) {
1118 parent_row
.className
= parent_row
.className
+ "Selected";
1121 if (parent_row
.className
.match("Selected")) {
1122 parent_row
.className
= parent_row
.className
.replace("Selected", "");
1127 function openExternalUrl(url
) {
1128 var w
= window
.open(url
);
1131 function getRelativeFeedId(list
, id
, direction
, unread_only
) {
1133 if (direction
== "next") {
1134 for (i
= 0; i
< list
.childNodes
.length
; i
++) {
1135 var child
= list
.childNodes
[i
];
1136 if (child
.id
&& child
.id
== "feedCatHolder") {
1137 if (child
.lastChild
) {
1138 var cr
= getRelativeFeedId(child
.firstChild
, id
, direction
, unread_only
);
1141 } else if (child
.id
&& child
.id
.match("FEEDR-")) {
1142 return child
.id
.replace('FEEDR-', '');
1147 // FIXME select last feed doesn't work when only unread feeds are visible
1149 if (direction
== "prev") {
1150 for (i
= list
.childNodes
.length
-1; i
>= 0; i
--) {
1151 var child
= list
.childNodes
[i
];
1152 if (child
.id
== "feedCatHolder") {
1153 if (child
.firstChild
) {
1154 var cr
= getRelativeFeedId(child
.firstChild
, id
, direction
);
1157 } else if (child
.id
.match("FEEDR-")) {
1159 if (getInitParam("hide_read_feeds") == 1) {
1160 if (child
.className
!= "feed") {
1161 alert(child
.className
);
1162 return child
.id
.replace('FEEDR-', '');
1165 return child
.id
.replace('FEEDR-', '');
1172 var feed
= list
.ownerDocument
.getElementById("FEEDR-" + id
);
1174 if (getInitParam("hide_read_feeds") == 1) {
1178 if (direction
== "next") {
1184 if (e
.nextSibling
) {
1188 } else if (e
.parentNode
.parentNode
.nextSibling
) {
1190 var this_cat
= e
.parentNode
.parentNode
;
1194 if (this_cat
&& this_cat
.nextSibling
) {
1195 while (!e
&& this_cat
.nextSibling
) {
1196 this_cat
= this_cat
.nextSibling
;
1197 if (this_cat
.id
== "feedCatHolder") {
1198 e
= this_cat
.firstChild
.firstChild
;
1208 if (!unread_only
|| (unread_only
&& e
.className
!= "feed" &&
1209 e
.className
.match("feed"))) {
1210 return e
.id
.replace("FEEDR-", "");
1215 } else if (direction
== "prev") {
1221 if (e
.previousSibling
) {
1223 e
= e
.previousSibling
;
1225 } else if (e
.parentNode
.parentNode
.previousSibling
) {
1227 var this_cat
= e
.parentNode
.parentNode
;
1231 if (this_cat
&& this_cat
.previousSibling
) {
1232 while (!e
&& this_cat
.previousSibling
) {
1233 this_cat
= this_cat
.previousSibling
;
1234 if (this_cat
.id
== "feedCatHolder") {
1235 e
= this_cat
.firstChild
.lastChild
;
1245 if (!unread_only
|| (unread_only
&& e
.className
!= "feed" &&
1246 e
.className
.match("feed"))) {
1247 return e
.id
.replace("FEEDR-", "");
1255 function showBlockElement(id
, h_id
) {
1256 var elem
= document
.getElementById(id
);
1259 elem
.style
.display
= "block";
1262 elem
= document
.getElementById(h_id
);
1264 elem
.style
.display
= "none";
1268 alert("[showBlockElement] can't find element with id " + id
);
1272 function hideParentElement(e
) {
1273 e
.parentNode
.style
.display
= "none";
1276 function dropboxSelect(e
, v
) {
1277 for (i
= 0; i
< e
.length
; i
++) {
1278 if (e
[i
].value
== v
) {
1279 e
.selectedIndex
= i
;
1285 // originally stolen from http://www.11tmr.com/11tmr.nsf/d6plinks/MWHE-695L9Z
1286 // bugfixed just a little bit :-)
1287 function getURLParam(strParamName
){
1289 var strHref
= window
.location
.href
;
1291 if (strHref
.indexOf("#") == strHref
.length
-1) {
1292 strHref
= strHref
.substring(0, strHref
.length
-1);
1295 if ( strHref
.indexOf("?") > -1 ){
1296 var strQueryString
= strHref
.substr(strHref
.indexOf("?"));
1297 var aQueryString
= strQueryString
.split("&");
1298 for ( var iParam
= 0; iParam
< aQueryString
.length
; iParam
++ ){
1299 if (aQueryString
[iParam
].indexOf(strParamName
+ "=") > -1 ){
1300 var aParam
= aQueryString
[iParam
].split("=");
1301 strReturn
= aParam
[1];
1309 function leading_zero(p
) {
1311 if (s
.length
== 1) s
= "0" + s
;
1315 function closeInfoBox(cleanup
) {
1316 var box
= document
.getElementById('infoBox');
1317 var shadow
= document
.getElementById('infoBoxShadow');
1320 shadow
.style
.display
= "none";
1322 box
.style
.display
= "none";
1325 if (cleanup
) box
.innerHTML
= " ";
1333 function displayDlg(id
, param
) {
1335 if (!xmlhttp_ready(xmlhttp
)) {
1336 printLockingError();
1340 notify_progress("Loading, please wait...");
1342 xmlhttp
.open("GET", "backend.php?op=dlg&id=" +
1343 param_escape(id
) + "¶m=" + param_escape(param
), true);
1344 xmlhttp
.onreadystatechange
=infobox_callback
;
1352 function infobox_submit_callback() {
1353 if (xmlhttp
.readyState
== 4) {
1357 // called from prefs, reload tab
1359 selectTab(active_tab
, false);
1363 if (xmlhttp
.responseText
) {
1364 notify_info(xmlhttp
.responseText
);
1370 function infobox_callback() {
1371 if (xmlhttp
.readyState
== 4) {
1372 var box
= document
.getElementById('infoBox');
1373 var shadow
= document
.getElementById('infoBoxShadow');
1375 box
.innerHTML
=xmlhttp
.responseText
;
1377 shadow
.style
.display
= "block";
1379 box
.style
.display
= "block";
1386 function addFilter() {
1388 if (!xmlhttp_ready(xmlhttp
)) {
1389 printLockingError();
1393 var form
= document
.forms
['filter_add_form'];
1394 var reg_exp
= form
.reg_exp
.value
;
1396 if (reg_exp
== "") {
1397 alert("Can't add filter: nothing to match on.");
1401 var query
= Form
.serialize("filter_add_form");
1403 xmlhttp
.open("GET", "backend.php?" + query
, true);
1404 xmlhttp
.onreadystatechange
=infobox_submit_callback
;
1410 function toggleSubmitNotEmpty(e
, submit_id
) {
1412 document
.getElementById(submit_id
).disabled
= (e
.value
== "")
1414 exception_error("toggleSubmitNotEmpty", e
);
1418 function isValidURL(s
) {
1419 return s
.match("http://") != null || s
.match("https://") != null || s
.match("feed://") != null;
1422 function qaddFeed() {
1424 if (!xmlhttp_ready(xmlhttp
)) {
1425 printLockingError();
1429 var form
= document
.forms
['feed_add_form'];
1430 var feed_url
= form
.feed_url
.value
;
1432 if (feed_url
== "") {
1433 alert("Can't subscribe: no feed URL given.");
1437 notify_progress("Adding feed...");
1441 var feeds_doc
= document
;
1443 // feeds_doc.location.href = "backend.php?op=error&msg=Loading,%20please wait...";
1445 var query
= Form
.serialize("feed_add_form");
1447 debug("subscribe q: " + query
);
1449 /* xmlhttp.open("GET", "backend.php?" + query, true);
1450 xmlhttp.onreadystatechange=dlg_frefresh_callback;
1451 xmlhttp.send(null); */
1453 xmlhttp
.open("POST", "backend.php", true);
1454 xmlhttp
.onreadystatechange
=dlg_frefresh_callback
;
1455 xmlhttp
.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
1456 xmlhttp
.send(query
);
1461 function filterCR(e
, f
)
1466 key
= window
.event
.keyCode
; //IE
1468 key
= e
.which
; //firefox
1471 if (typeof f
!= 'undefined') {
1482 function getMainContext() {
1486 function getFeedsContext() {
1490 function getContentContext() {
1494 function getHeadlinesContext() {
1498 var debug_last_class
= "even";
1500 function debug(msg
) {
1502 if (debug_last_class
== "even") {
1503 debug_last_class
= "odd";
1505 debug_last_class
= "even";
1508 var c
= document
.getElementById('debug_output');
1509 if (c
&& c
.style
.display
== "block") {
1510 while (c
.lastChild
!= 'undefined' && c
.childNodes
.length
> 100) {
1511 c
.removeChild(c
.lastChild
);
1515 var ts
= leading_zero(d
.getHours()) + ":" + leading_zero(d
.getMinutes()) +
1516 ":" + leading_zero(d
.getSeconds());
1517 c
.innerHTML
= "<li class=\"" + debug_last_class
+ "\"><span class=\"debugTS\">[" + ts
+ "]</span> " +
1518 msg
+ "</li>" + c
.innerHTML
;
1522 function getInitParam(key
) {
1523 return init_params
[key
];
1526 function storeInitParam(key
, value
) {
1527 debug("<b>storeInitParam is OBSOLETE: " + key
+ " => " + value
+ "</b>");
1528 init_params
[key
] = value
;
1531 function fatalError(code
, message
) {
1535 window
.location
.href
= "tt-rss.php";
1536 } else if (code
== 5) {
1537 window
.location
.href
= "update.php";
1539 var fe
= document
.getElementById("fatal_error");
1540 var fc
= document
.getElementById("fatal_error_msg");
1542 if (message
== "") message
= "Unknown error";
1544 fc
.innerHTML
= "<img src='images/sign_excl.png'> " + message
+ " (Code " + code
+ ")";
1546 fe
.style
.display
= "block";
1550 exception_error("fatalError", e
);
1554 function getFeedName(id
, is_cat
) {
1555 var d
= getFeedsContext().document
;
1560 e
= d
.getElementById("FCATN-" + id
);
1562 e
= d
.getElementById("FEEDN-" + id
);
1565 return e
.innerHTML
.stripTags();
1571 function viewContentUrl(url
) {
1572 getContentContext().location
= url
;
1575 function filterDlgCheckAction(sender
) {
1579 var action
= sender
[sender
.selectedIndex
].value
;
1581 var form
= document
.forms
["filter_add_form"];
1584 form
= document
.forms
["filter_edit_form"];
1588 debug("filterDlgCheckAction: can't find form!");
1592 var action_param
= form
.action_param
;
1594 if (!action_param
) {
1595 debug("filterDlgCheckAction: can't find action param!");
1599 // if selected action supports parameters, enable params field
1601 action_param
.disabled
= false;
1603 action_param
.disabled
= true;
1607 exception_error(e
, "filterDlgCheckAction");
1612 function explainError(code
) {
1613 return displayDlg("explainError", code
);
1616 function logoutUser() {
1618 if (xmlhttp_ready(xmlhttp_rpc
)) {
1620 notify_progress("Logging out, please wait...", true);
1622 xmlhttp_rpc
.open("GET", "backend.php?op=rpc&subop=logout", true);
1623 xmlhttp_rpc
.onreadystatechange
=logout_callback
;
1624 xmlhttp_rpc
.send(null);
1626 printLockingError();
1629 exception_error("logoutUser", e
);