]>
git.wh0rd.org - tt-rss.git/blob - functions.js
7b7253d9f8529422d78ff96bc516b3583e051066
1 var hotkeys_enabled
= true;
2 var debug_mode_enabled
= false;
3 var xmlhttp_rpc
= Ajax
.getTransport();
5 /* add method to remove element from array */
7 Array
.prototype.remove = function(s
) {
8 for (var i
=0; i
< this.length
; i
++) {
9 if (s
== this[i
]) this.splice(i
, 1);
13 function browser_has_opacity() {
14 return navigator
.userAgent
.match("Gecko") != null ||
15 navigator
.userAgent
.match("Opera") != null;
19 return navigator
.userAgent
.match("MSIE");
23 return navigator
.userAgent
.match("Opera");
27 return navigator
.userAgent
.match("KHTML");
30 function is_safari() {
31 return navigator
.userAgent
.match("Safari");
34 function exception_error(location
, e
, silent
) {
38 var base_fname
= e
.fileName
.substring(e
.fileName
.lastIndexOf("/") + 1);
40 msg
= "Exception: " + e
.name
+ ", " + e
.message
+
41 "\nFunction: " + location
+ "()" +
42 "\nLocation: " + base_fname
+ ":" + e
.lineNumber
;
45 msg
= "Exception: " + e
+ "\nFunction: " + location
+ "()";
48 debug("<b>EXCEPTION: " + msg
+ "</b>");
55 function disableHotkeys() {
56 hotkeys_enabled
= false;
59 function enableHotkeys() {
60 hotkeys_enabled
= true;
63 function xmlhttp_ready(obj
) {
64 return obj
.readyState
== 4 || obj
.readyState
== 0 || !obj
.readyState
;
67 function logout_callback() {
68 var container
= document
.getElementById('notify');
69 if (xmlhttp
.readyState
== 4) {
71 var date
= new Date();
72 var timestamp
= Math
.round(date
.getTime() / 1000);
73 window
.location
.href
= "tt-rss.php";
75 exception_error("logout_callback", e
);
80 function notify_callback() {
81 var container
= document
.getElementById('notify');
82 if (xmlhttp
.readyState
== 4) {
83 container
.innerHTML
=xmlhttp
.responseText
;
87 function rpc_notify_callback() {
88 var container
= document
.getElementById('notify');
89 if (xmlhttp_rpc
.readyState
== 4) {
90 container
.innerHTML
=xmlhttp_rpc
.responseText
;
94 function param_escape(arg
) {
95 if (typeof encodeURIComponent
!= 'undefined')
96 return encodeURIComponent(arg
);
101 function param_unescape(arg
) {
102 if (typeof decodeURIComponent
!= 'undefined')
103 return decodeURIComponent(arg
);
105 return unescape(arg
);
108 function delay(gap
) {
110 then
=new Date().getTime();
112 while((now
-then
)<gap
) {
113 now
=new Date().getTime();
117 var notify_hide_timerid
= false;
119 function hide_notify() {
120 var n
= document
.getElementById("notify");
122 n
.style
.display
= "none";
126 function notify_real(msg
, no_hide
, n_type
) {
128 var n
= document
.getElementById("notify");
129 var nb
= document
.getElementById("notify_body");
131 if (!n
|| !nb
) return;
133 if (notify_hide_timerid
) {
134 window
.clearTimeout(notify_hide_timerid
);
138 if (n
.style
.display
== "block") {
139 notify_hide_timerid
= window
.setTimeout("hide_notify()", 0);
143 n
.style
.display
= "block";
155 if (typeof __
!= 'undefined') {
160 n
.className
= "notify";
161 } else if (n_type
== 2) {
162 n
.className
= "notifyProgress";
163 msg
= "<img src='images/indicator_white.gif'> " + msg
;
164 } else if (n_type
== 3) {
165 n
.className
= "notifyError";
166 msg
= "<img src='images/sign_excl.png'> " + msg
;
167 } else if (n_type
== 4) {
168 n
.className
= "notifyInfo";
169 msg
= "<img src='images/sign_info.png'> " + msg
;
172 // msg = "<img src='images/live_com_loading.gif'> " + msg;
177 notify_hide_timerid
= window
.setTimeout("hide_notify()", 3000);
181 function notify(msg
, no_hide
) {
182 notify_real(msg
, no_hide
, 1);
185 function notify_progress(msg
, no_hide
) {
186 notify_real(msg
, no_hide
, 2);
189 function notify_error(msg
, no_hide
) {
190 notify_real(msg
, no_hide
, 3);
194 function notify_info(msg
, no_hide
) {
195 notify_real(msg
, no_hide
, 4);
198 function printLockingError() {
199 notify_info("Please wait until operation finishes.");
202 function hotkey_handler(e
) {
207 var shift_key
= false;
210 shift_key
= e
.shiftKey
;
215 if (!hotkeys_enabled
) return;
218 keycode
= window
.event
.keyCode
;
223 if (keycode
== 82) { // r
224 return scheduleFeedUpdate(true);
227 if (keycode
== 83) { // s
228 return displayDlg("search", getActiveFeedId());
231 if (keycode
== 85) { // u
232 if (getActiveFeedId()) {
233 return viewfeed(getActiveFeedId(), "ForceUpdate");
237 if (keycode
== 65) { // a
238 return toggleDispRead();
241 var feedlist
= document
.getElementById('feedList');
243 if (keycode
== 74) { // j
244 var feed
= getActiveFeedId();
245 var new_feed
= getRelativeFeedId(feedlist
, feed
, 'prev');
246 if (new_feed
) viewfeed(new_feed
, '');
249 if (keycode
== 75) { // k
250 var feed
= getActiveFeedId();
251 var new_feed
= getRelativeFeedId(feedlist
, feed
, 'next');
252 if (new_feed
) viewfeed(new_feed
, '');
255 if (keycode
== 78 || keycode
== 40) { // n, down
256 if (typeof moveToPost
!= 'undefined') {
257 return moveToPost('next');
261 if (keycode
== 80 || keycode
== 38) { // p, up
262 if (typeof moveToPost
!= 'undefined') {
263 return moveToPost('prev');
267 if (keycode
== 68 && shift_key
) { // d
268 if (!debug_mode_enabled
) {
269 document
.getElementById('debug_output').style
.display
= 'block';
270 debug('debug mode activated');
272 document
.getElementById('debug_output').style
.display
= 'none';
275 debug_mode_enabled
= !debug_mode_enabled
;
278 if (keycode
== 190 && shift_key
) { // >
282 if (keycode
== 188 && shift_key
) { // <
286 if (keycode
== 191 && shift_key
) { // ?
290 if (keycode
== 69 && shift_key
) { // e
291 return editFeedDlg(getActiveFeedId());
294 if (keycode
== 70 && shift_key
) { // f
295 if (getActiveFeedId()) {
296 return catchupCurrentFeed();
300 if (keycode
== 80 && shift_key
) { // p
301 if (getActiveFeedId()) {
302 return catchupPage();
306 if (typeof localHotkeyHandler
!= 'undefined') {
308 return localHotkeyHandler(e
);
310 exception_error("hotkey_handler, local:", e
);
314 debug("KP=" + keycode
);
316 exception_error("hotkey_handler", e
);
320 function cleanSelectedList(element
) {
321 var content
= document
.getElementById(element
);
323 if (!document
.getElementById("feedCatHolder")) {
324 for (i
= 0; i
< content
.childNodes
.length
; i
++) {
325 var child
= content
.childNodes
[i
];
327 child
.className
= child
.className
.replace("Selected", "");
333 for (i
= 0; i
< content
.childNodes
.length
; i
++) {
334 var child
= content
.childNodes
[i
];
335 if (child
.id
== "feedCatHolder") {
337 var fcat
= child
.lastChild
;
338 for (j
= 0; j
< fcat
.childNodes
.length
; j
++) {
339 var feed
= fcat
.childNodes
[j
];
340 feed
.className
= feed
.className
.replace("Selected", "");
348 function cleanSelected(element
) {
349 var content
= document
.getElementById(element
);
351 for (i
= 0; i
< content
.rows
.length
; i
++) {
352 content
.rows
[i
].className
= content
.rows
[i
].className
.replace("Selected", "");
356 function getVisibleUnreadHeadlines() {
357 var content
= document
.getElementById("headlinesList");
359 var rows
= new Array();
361 for (i
= 0; i
< content
.rows
.length
; i
++) {
362 var row_id
= content
.rows
[i
].id
.replace("RROW-", "");
363 if (row_id
.length
> 0 && content
.rows
[i
].className
.match("Unread")) {
370 function getVisibleHeadlineIds() {
372 var content
= document
.getElementById("headlinesList");
374 var rows
= new Array();
376 for (i
= 0; i
< content
.rows
.length
; i
++) {
377 var row_id
= content
.rows
[i
].id
.replace("RROW-", "");
378 if (row_id
.length
> 0) {
385 function getFirstVisibleHeadlineId() {
386 var rows
= getVisibleHeadlineIds();
390 function getLastVisibleHeadlineId() {
391 var rows
= getVisibleHeadlineIds();
392 return rows
[rows
.length
-1];
395 function markHeadline(id
) {
396 var row
= document
.getElementById("RROW-" + id
);
398 var is_active
= false;
400 if (row
.className
.match("Active")) {
403 row
.className
= row
.className
.replace("Selected", "");
404 row
.className
= row
.className
.replace("Active", "");
405 row
.className
= row
.className
.replace("Insensitive", "");
408 row
.className
= row
.className
= "Active";
411 var check
= document
.getElementById("RCHK-" + id
);
414 check
.checked
= true;
417 row
.className
= row
.className
+ "Selected";
422 function getFeedIds() {
423 var content
= document
.getElementById("feedsList");
425 var rows
= new Array();
427 for (i
= 0; i
< content
.rows
.length
; i
++) {
428 var id
= content
.rows
[i
].id
.replace("FEEDR-", "");
437 function setCookie(name
, value
, lifetime
, path
, domain
, secure
) {
443 d
.setTime(d
.getTime() + (lifetime
* 1000));
446 debug("setCookie: " + name
+ " => " + value
+ ": " + d
);
448 int_setCookie(name
, value
, d
, path
, domain
, secure
);
452 function int_setCookie(name
, value
, expires
, path
, domain
, secure
) {
453 document
.cookie
= name
+ "=" + escape(value
) +
454 ((expires
) ? "; expires=" + expires
.toGMTString() : "") +
455 ((path
) ? "; path=" + path
: "") +
456 ((domain
) ? "; domain=" + domain
: "") +
457 ((secure
) ? "; secure" : "");
460 function delCookie(name
, path
, domain
) {
461 if (getCookie(name
)) {
462 document
.cookie
= name
+ "=" +
463 ((path
) ? ";path=" + path
: "") +
464 ((domain
) ? ";domain=" + domain
: "" ) +
465 ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
470 function getCookie(name
) {
472 var dc
= document
.cookie
;
473 var prefix
= name
+ "=";
474 var begin
= dc
.indexOf("; " + prefix
);
476 begin
= dc
.indexOf(prefix
);
477 if (begin
!= 0) return null;
482 var end
= document
.cookie
.indexOf(";", begin
);
486 return unescape(dc
.substring(begin
+ prefix
.length
, end
));
489 function disableContainerChildren(id
, disable
, doc
) {
491 if (!doc
) doc
= document
;
493 var container
= doc
.getElementById(id
);
496 //alert("disableContainerChildren: element " + id + " not found");
500 for (var i
= 0; i
< container
.childNodes
.length
; i
++) {
501 var child
= container
.childNodes
[i
];
504 child
.disabled
= disable
;
510 if (child
.className
&& child
.className
.match("button")) {
511 child
.className
= "disabledButton";
514 if (child
.className
&& child
.className
.match("disabledButton")) {
515 child
.className
= "button";
522 function gotoPreferences() {
523 document
.location
.href
= "prefs.php";
526 function gotoMain() {
527 document
.location
.href
= "tt-rss.php";
530 function gotoExportOpml() {
531 document
.location
.href
= "opml.php?op=Export";
534 function getActiveFeedId() {
535 // return getCookie("ttrss_vf_actfeed");
537 debug("gAFID: " + active_feed_id
);
538 return active_feed_id
;
540 exception_error("getActiveFeedId", e
);
544 function activeFeedIsCat() {
545 return active_feed_is_cat
;
548 function setActiveFeedId(id
) {
549 // return setCookie("ttrss_vf_actfeed", id);
551 debug("sAFID(" + id
+ ")");
554 exception_error("setActiveFeedId", e
);
558 function parse_counters(reply
, scheduled_call
) {
563 if (reply
.firstChild
&& reply
.firstChild
.firstChild
) {
564 debug("<b>wrong element passed to parse_counters, adjusting.</b>");
565 reply
= reply
.firstChild
;
568 for (var l
= 0; l
< reply
.childNodes
.length
; l
++) {
569 if (!reply
.childNodes
[l
] ||
570 typeof(reply
.childNodes
[l
].getAttribute
) == "undefined") {
571 // where did this come from?
575 var id
= reply
.childNodes
[l
].getAttribute("id");
576 var t
= reply
.childNodes
[l
].getAttribute("type");
577 var ctr
= reply
.childNodes
[l
].getAttribute("counter");
578 var error
= reply
.childNodes
[l
].getAttribute("error");
579 var has_img
= reply
.childNodes
[l
].getAttribute("hi");
580 var updated
= reply
.childNodes
[l
].getAttribute("updated");
582 if (id
== "global-unread") {
588 if (id
== "subscribed-feeds") {
593 if (t
== "category") {
594 var catctr
= document
.getElementById("FCATCTR-" + id
);
596 catctr
.innerHTML
= "(" + ctr
+ ")";
598 catctr
.className
= "catCtrHasUnread";
600 catctr
.className
= "catCtrNoUnread";
606 var feedctr
= document
.getElementById("FEEDCTR-" + id
);
607 var feedu
= document
.getElementById("FEEDU-" + id
);
608 var feedr
= document
.getElementById("FEEDR-" + id
);
609 var feed_img
= document
.getElementById("FIMG-" + id
);
610 var feedlink
= document
.getElementById("FEEDL-" + id
);
611 var feedupd
= document
.getElementById("FLUPD-" + id
);
613 if (updated
&& feedlink
) {
615 feedlink
.title
= "Error: " + error
+ " (" + updated
+ ")";
617 feedlink
.title
= "Updated: " + updated
;
621 if (updated
&& feedupd
) {
623 feedupd
.innerHTML
= updated
+ " (Error)";
625 feedupd
.innerHTML
= updated
;
629 if (feedctr
&& feedu
&& feedr
) {
631 if (feedu
.innerHTML
!= ctr
&& id
== getActiveFeedId() && scheduled_call
) {
635 feedu
.innerHTML
= ctr
;
638 feedr
.className
= feedr
.className
.replace("feed", "error");
640 feedr
.className
= feedr
.className
.replace("error", "feed");
644 feedctr
.className
= "odd";
645 if (!feedr
.className
.match("Unread")) {
646 var is_selected
= feedr
.className
.match("Selected");
648 feedr
.className
= feedr
.className
.replace("Selected", "");
649 feedr
.className
= feedr
.className
.replace("Unread", "");
651 feedr
.className
= feedr
.className
+ "Unread";
654 feedr
.className
= feedr
.className
+ "Selected";
659 feedctr
.className
= "invisible";
660 feedr
.className
= feedr
.className
.replace("Unread", "");
665 hideOrShowFeeds(document
, getInitParam("hide_read_feeds") == 1);
667 var feeds_stored
= number_of_feeds
;
669 debug("Feed counters, C: " + feeds_found
+ ", S:" + feeds_stored
);
671 if (feeds_stored
!= feeds_found
) {
672 number_of_feeds
= feeds_found
;
674 if (feeds_stored
!= 0) {
675 debug("Subscribed feed number changed, refreshing feedlist");
676 setTimeout('updateFeedList(false, false)', 50);
681 exception_error("parse_counters", e
);
685 function parse_counters_reply(xmlhttp
, scheduled_call
) {
687 if (!xmlhttp
.responseXML
) {
688 notify_error("Backend did not return valid XML", true);
692 var reply
= xmlhttp
.responseXML
.firstChild
;
695 notify_error("Backend did not return expected XML object", true);
700 var error_code
= false;
701 var error_msg
= false;
703 if (reply
.firstChild
) {
704 error_code
= reply
.firstChild
.getAttribute("error-code");
705 error_msg
= reply
.firstChild
.getAttribute("error-msg");
709 error_code
= reply
.getAttribute("error-code");
710 error_msg
= reply
.getAttribute("error-msg");
713 if (error_code
&& error_code
!= 0) {
714 debug("refetch_callback: got error code " + error_code
);
715 return fatalError(error_code
, error_msg
);
718 var counters
= reply
.firstChild
;
720 parse_counters(counters
, scheduled_call
);
722 var runtime_info
= counters
.nextSibling
;
724 parse_runtime_info(runtime_info
);
726 if (getInitParam("feeds_sort_by_unread") == 1) {
730 hideOrShowFeeds(document
, getInitParam("hide_read_feeds") == 1);
734 function all_counters_callback() {
735 if (xmlhttp_rpc
.readyState
== 4) {
737 /* if (!xmlhttp_rpc.responseXML || !xmlhttp_rpc.responseXML.firstChild) {
738 debug("[all_counters_callback] backend did not return valid XML");
742 debug("in all_counters_callback : " + xmlhttp_rpc.responseXML);
744 var reply = xmlhttp_rpc.responseXML.firstChild;
746 var counters = reply.firstChild;
748 parse_counters(counters);
750 var runtime = counters.nextSibling;
753 parse_runtime_info(runtime);
756 if (getInitParam("feeds_sort_by_unread") == 1) {
760 hideOrShowFeeds(document, getInitParam("hide_read_feeds") == 1); */
762 debug("in all_counters_callback");
764 parse_counters_reply(xmlhttp_rpc
);
767 exception_error("all_counters_callback", e
);
772 function get_feed_entry_unread(doc
, elem
) {
774 var id
= elem
.id
.replace("FEEDR-", "");
781 return parseInt(doc
.getElementById("FEEDU-" + id
).innerHTML
);
787 function resort_category(doc
, node
) {
788 debug("resort_category: " + node
);
790 if (node
.hasChildNodes() && node
.firstChild
.nextSibling
!= false) {
791 for (i
= 0; i
< node
.childNodes
.length
; i
++) {
792 if (node
.childNodes
[i
].nodeName
!= "LI") { continue; }
794 if (get_feed_entry_unread(doc
, node
.childNodes
[i
]) < 0) {
798 for (j
= i
+1; j
< node
.childNodes
.length
; j
++) {
799 if (node
.childNodes
[j
].nodeName
!= "LI") { continue; }
801 var tmp_val
= get_feed_entry_unread(doc
, node
.childNodes
[i
]);
802 var cur_val
= get_feed_entry_unread(doc
, node
.childNodes
[j
]);
804 if (cur_val
> tmp_val
) {
805 tempnode_i
= node
.childNodes
[i
].cloneNode(true);
806 tempnode_j
= node
.childNodes
[j
].cloneNode(true);
807 node
.replaceChild(tempnode_i
, node
.childNodes
[j
]);
808 node
.replaceChild(tempnode_j
, node
.childNodes
[i
]);
817 function resort_feedlist() {
818 debug("resort_feedlist");
822 if (fd
.getElementById("feedCatHolder")) {
824 var feeds
= fd
.getElementById("feedList");
825 var child
= feeds
.firstChild
;
829 if (child
.id
== "feedCatHolder") {
830 resort_category(fd
, child
.firstChild
);
833 child
= child
.nextSibling
;
837 resort_category(fd
, fd
.getElementById("feedList"));
841 function update_all_counters(feed
) {
842 if (xmlhttp_ready(xmlhttp_rpc
)) {
843 var query
= "backend.php?op=rpc&subop=getAllCounters";
846 query
= query
+ "&aid=" + feed
;
849 if (tagsAreDisplayed()) {
850 query
= query
+ "&omode=lt";
852 query
= query
+ "&omode=flc";
855 debug("update_all_counters QUERY: " + query
);
857 var date
= new Date();
858 var timestamp
= Math
.round(date
.getTime() / 1000);
859 query
= query
+ "&ts=" + timestamp
861 xmlhttp_rpc
.open("GET", query
, true);
862 xmlhttp_rpc
.onreadystatechange
=all_counters_callback
;
863 xmlhttp_rpc
.send(null);
867 function popupHelp(tid
) {
868 var w
= window
.open("backend.php?op=help&tid=" + tid
,
870 "menubar=no,location=no,resizable=yes,scrollbars=yes,status=no");
873 /** * @(#)isNumeric.js * * Copyright (c) 2000 by Sundar Dorai-Raj
874 * * @author Sundar Dorai-Raj
875 * * Email: sdoraira@vt.edu
876 * * This program is free software; you can redistribute it and/or
877 * * modify it under the terms of the GNU General Public License
878 * * as published by the Free Software Foundation; either version 2
879 * * of the License, or (at your option) any later version,
880 * * provided that any use properly credits the author.
881 * * This program is distributed in the hope that it will be useful,
882 * * but WITHOUT ANY WARRANTY; without even the implied warranty of
883 * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
884 * * GNU General Public License for more details at http://www.gnu.org * * */
886 var numbers
=".0123456789";
887 function isNumeric(x
) {
888 // is x a String or a character?
890 // remove negative sign
892 for(j
=0;j
<x
.length
;j
++) {
893 // call isNumeric recursively for each character
894 number
=isNumeric(x
.substring(j
,j
+1));
895 if(!number
) return number
;
900 // if x is number return true
901 if(numbers
.indexOf(x
)>=0) return true;
907 function hideOrShowFeeds(doc
, hide
) {
909 debug("hideOrShowFeeds: " + doc
+ ", " + hide
);
913 var list
= fd
.getElementById("feedList");
915 if (fd
.getElementById("feedCatHolder")) {
917 var feeds
= fd
.getElementById("feedList");
918 var child
= feeds
.firstChild
;
922 if (child
.id
== "feedCatHolder") {
923 hideOrShowFeedsCategory(fd
, child
.firstChild
, hide
, child
.previousSibling
);
926 child
= child
.nextSibling
;
930 hideOrShowFeedsCategory(fd
, fd
.getElementById("feedList"), hide
);
934 function hideOrShowFeedsCategory(doc
, node
, hide
, cat_node
) {
936 // debug("hideOrShowFeedsCategory: " + node + " (" + hide + ")");
941 debug("hideOrShowFeeds: passed node is null, aborting");
945 if (node
.hasChildNodes() && node
.firstChild
.nextSibling
!= false) {
946 for (i
= 0; i
< node
.childNodes
.length
; i
++) {
947 if (node
.childNodes
[i
].nodeName
!= "LI") { continue; }
949 if (node
.childNodes
[i
].style
!= undefined) {
951 var has_unread
= (node
.childNodes
[i
].className
!= "feed" &&
952 node
.childNodes
[i
].className
!= "tag");
954 // debug(node.childNodes[i].id + " --> " + has_unread);
956 if (hide
&& !has_unread
) {
957 node
.childNodes
[i
].style
.display
= "none";
961 node
.childNodes
[i
].style
.display
= "list-item";
965 node
.childNodes
[i
].style
.display
= "list-item";
972 if (cat_unread
== 0) {
973 if (cat_node
.style
== undefined) {
974 debug("ERROR: supplied cat_node " + cat_node
+
975 " has no styles. WTF?");
979 cat_node
.style
.display
= "none";
981 cat_node
.style
.display
= "list-item";
985 cat_node
.style
.display
= "list-item";
991 // debug("unread for category: " + cat_unread);
994 function selectTableRow(r
, do_select
) {
995 r
.className
= r
.className
.replace("Selected", "");
998 r
.className
= r
.className
+ "Selected";
1002 function selectTableRowById(elem_id
, check_id
, do_select
) {
1006 var row
= document
.getElementById(elem_id
);
1009 selectTableRow(row
, do_select
);
1012 var check
= document
.getElementById(check_id
);
1015 check
.checked
= do_select
;
1018 exception_error("selectTableRowById", e
);
1022 function selectTableRowsByIdPrefix(content_id
, prefix
, check_prefix
, do_select
,
1023 classcheck
, reset_others
) {
1025 var content
= document
.getElementById(content_id
);
1028 alert("[selectTableRows] Element " + content_id
+ " not found.");
1032 for (i
= 0; i
< content
.rows
.length
; i
++) {
1033 if (!classcheck
|| content
.rows
[i
].className
.match(classcheck
)) {
1035 if (content
.rows
[i
].id
.match(prefix
)) {
1036 selectTableRow(content
.rows
[i
], do_select
);
1038 var row_id
= content
.rows
[i
].id
.replace(prefix
, "");
1039 var check
= document
.getElementById(check_prefix
+ row_id
);
1042 check
.checked
= do_select
;
1044 } else if (reset_others
) {
1045 selectTableRow(content
.rows
[i
], false);
1047 var row_id
= content
.rows
[i
].id
.replace(prefix
, "");
1048 var check
= document
.getElementById(check_prefix
+ row_id
);
1051 check
.checked
= false;
1055 } else if (reset_others
) {
1056 selectTableRow(content
.rows
[i
], false);
1058 var row_id
= content
.rows
[i
].id
.replace(prefix
, "");
1059 var check
= document
.getElementById(check_prefix
+ row_id
);
1062 check
.checked
= false;
1069 function getSelectedTableRowIds(content_id
, prefix
) {
1071 var content
= document
.getElementById(content_id
);
1074 alert("[getSelectedTableRowIds] Element " + content_id
+ " not found.");
1078 var sel_rows
= new Array();
1080 for (i
= 0; i
< content
.rows
.length
; i
++) {
1081 if (content
.rows
[i
].id
.match(prefix
) &&
1082 content
.rows
[i
].className
.match("Selected")) {
1084 var row_id
= content
.rows
[i
].id
.replace(prefix
+ "-", "");
1085 sel_rows
.push(row_id
);
1093 function toggleSelectRowById(sender
, id
) {
1094 var row
= document
.getElementById(id
);
1096 if (sender
.checked
) {
1097 if (!row
.className
.match("Selected")) {
1098 row
.className
= row
.className
+ "Selected";
1101 if (row
.className
.match("Selected")) {
1102 row
.className
= row
.className
.replace("Selected", "");
1107 function toggleSelectListRow(sender
) {
1108 var parent_row
= sender
.parentNode
;
1110 if (sender
.checked
) {
1111 if (!parent_row
.className
.match("Selected")) {
1112 parent_row
.className
= parent_row
.className
+ "Selected";
1115 if (parent_row
.className
.match("Selected")) {
1116 parent_row
.className
= parent_row
.className
.replace("Selected", "");
1121 function tSR(sender
) {
1122 return toggleSelectRow(sender
);
1125 function toggleSelectRow(sender
) {
1126 var parent_row
= sender
.parentNode
.parentNode
;
1128 if (sender
.checked
) {
1129 if (!parent_row
.className
.match("Selected")) {
1130 parent_row
.className
= parent_row
.className
+ "Selected";
1133 if (parent_row
.className
.match("Selected")) {
1134 parent_row
.className
= parent_row
.className
.replace("Selected", "");
1139 function openExternalUrl(url
) {
1140 var w
= window
.open(url
);
1143 function getRelativeFeedId(list
, id
, direction
, unread_only
) {
1145 if (direction
== "next") {
1146 for (i
= 0; i
< list
.childNodes
.length
; i
++) {
1147 var child
= list
.childNodes
[i
];
1148 if (child
.id
&& child
.id
== "feedCatHolder") {
1149 if (child
.lastChild
) {
1150 var cr
= getRelativeFeedId(child
.firstChild
, id
, direction
, unread_only
);
1153 } else if (child
.id
&& child
.id
.match("FEEDR-")) {
1154 return child
.id
.replace('FEEDR-', '');
1159 // FIXME select last feed doesn't work when only unread feeds are visible
1161 if (direction
== "prev") {
1162 for (i
= list
.childNodes
.length
-1; i
>= 0; i
--) {
1163 var child
= list
.childNodes
[i
];
1164 if (child
.id
== "feedCatHolder" && child
.className
!= "invisible") {
1165 if (child
.firstChild
) {
1166 var cr
= getRelativeFeedId(child
.firstChild
, id
, direction
);
1169 } else if (child
.id
.match("FEEDR-")) {
1171 if (getInitParam("hide_read_feeds") == 1) {
1172 if (child
.className
!= "feed") {
1173 // alert(child.className);
1174 return child
.id
.replace('FEEDR-', '');
1177 return child
.id
.replace('FEEDR-', '');
1184 var feed
= list
.ownerDocument
.getElementById("FEEDR-" + id
);
1186 if (getInitParam("hide_read_feeds") == 1) {
1190 if (direction
== "next") {
1196 if (e
.nextSibling
) {
1200 } else if (e
.parentNode
.parentNode
.nextSibling
) {
1202 var this_cat
= e
.parentNode
.parentNode
;
1206 if (this_cat
&& this_cat
.nextSibling
) {
1207 while (!e
&& this_cat
.nextSibling
) {
1208 this_cat
= this_cat
.nextSibling
;
1209 if (this_cat
.id
== "feedCatHolder") {
1210 e
= this_cat
.firstChild
.firstChild
;
1220 if (!unread_only
|| (unread_only
&& e
.className
!= "feed" &&
1221 e
.className
.match("feed"))) {
1222 if (e
.parentNode
.parentNode
&& e
.parentNode
.parentNode
.className
1224 return e
.id
.replace("FEEDR-", "");
1230 } else if (direction
== "prev") {
1236 if (e
.previousSibling
) {
1238 e
= e
.previousSibling
;
1240 } else if (e
.parentNode
.parentNode
.previousSibling
) {
1242 var this_cat
= e
.parentNode
.parentNode
;
1246 if (this_cat
&& this_cat
.previousSibling
) {
1247 while (!e
&& this_cat
.previousSibling
) {
1248 this_cat
= this_cat
.previousSibling
;
1249 if (this_cat
.id
== "feedCatHolder") {
1250 e
= this_cat
.firstChild
.lastChild
;
1260 if (!unread_only
|| (unread_only
&& e
.className
!= "feed" &&
1261 e
.className
.match("feed"))) {
1262 if (e
.parentNode
.parentNode
&& e
.parentNode
.parentNode
.className
1264 return e
.id
.replace("FEEDR-", "");
1273 function showBlockElement(id
, h_id
) {
1274 var elem
= document
.getElementById(id
);
1277 elem
.style
.display
= "block";
1280 elem
= document
.getElementById(h_id
);
1282 elem
.style
.display
= "none";
1286 alert("[showBlockElement] can't find element with id " + id
);
1290 function hideParentElement(e
) {
1291 e
.parentNode
.style
.display
= "none";
1294 function dropboxSelect(e
, v
) {
1295 for (i
= 0; i
< e
.length
; i
++) {
1296 if (e
[i
].value
== v
) {
1297 e
.selectedIndex
= i
;
1303 // originally stolen from http://www.11tmr.com/11tmr.nsf/d6plinks/MWHE-695L9Z
1304 // bugfixed just a little bit :-)
1305 function getURLParam(strParamName
){
1307 var strHref
= window
.location
.href
;
1309 if (strHref
.indexOf("#") == strHref
.length
-1) {
1310 strHref
= strHref
.substring(0, strHref
.length
-1);
1313 if ( strHref
.indexOf("?") > -1 ){
1314 var strQueryString
= strHref
.substr(strHref
.indexOf("?"));
1315 var aQueryString
= strQueryString
.split("&");
1316 for ( var iParam
= 0; iParam
< aQueryString
.length
; iParam
++ ){
1317 if (aQueryString
[iParam
].indexOf(strParamName
+ "=") > -1 ){
1318 var aParam
= aQueryString
[iParam
].split("=");
1319 strReturn
= aParam
[1];
1327 function leading_zero(p
) {
1329 if (s
.length
== 1) s
= "0" + s
;
1333 function closeInfoBox(cleanup
) {
1335 if (!is_msie() && !getInitParam("infobox_disable_overlay")) {
1336 var overlay
= document
.getElementById("dialog_overlay");
1338 overlay
.style
.display
= "none";
1342 var box
= document
.getElementById('infoBox');
1343 var shadow
= document
.getElementById('infoBoxShadow');
1346 shadow
.style
.display
= "none";
1348 box
.style
.display
= "none";
1351 if (cleanup
) box
.innerHTML
= " ";
1359 function displayDlg(id
, param
) {
1361 if (!xmlhttp_ready(xmlhttp
)) {
1362 printLockingError();
1366 notify_progress("Loading, please wait...", true);
1368 xmlhttp
.open("GET", "backend.php?op=dlg&id=" +
1369 param_escape(id
) + "¶m=" + param_escape(param
), true);
1370 xmlhttp
.onreadystatechange
=infobox_callback
;
1378 function infobox_submit_callback() {
1379 if (xmlhttp
.readyState
== 4) {
1383 // called from prefs, reload tab
1385 selectTab(active_tab
, false);
1389 if (xmlhttp
.responseText
) {
1390 notify_info(xmlhttp
.responseText
);
1396 function infobox_callback() {
1397 if (xmlhttp
.readyState
== 4) {
1399 if (!is_msie() && !getInitParam("infobox_disable_overlay")) {
1400 var overlay
= document
.getElementById("dialog_overlay");
1402 overlay
.style
.display
= "block";
1406 var box
= document
.getElementById('infoBox');
1407 var shadow
= document
.getElementById('infoBoxShadow');
1409 box
.innerHTML
=xmlhttp
.responseText
;
1411 shadow
.style
.display
= "block";
1413 box
.style
.display
= "block";
1420 function helpbox_callback() {
1421 if (xmlhttp
.readyState
== 4) {
1422 var box
= document
.getElementById('helpBox');
1423 var shadow
= document
.getElementById('helpBoxShadow');
1425 box
.innerHTML
=xmlhttp
.responseText
;
1427 shadow
.style
.display
= "block";
1429 box
.style
.display
= "block";
1436 function addFilter() {
1438 if (!xmlhttp_ready(xmlhttp
)) {
1439 printLockingError();
1443 var form
= document
.forms
['filter_add_form'];
1444 var reg_exp
= form
.reg_exp
.value
;
1446 if (reg_exp
== "") {
1447 alert("Can't add filter: nothing to match on.");
1451 var query
= Form
.serialize("filter_add_form");
1453 xmlhttp
.open("GET", "backend.php?" + query
, true);
1454 xmlhttp
.onreadystatechange
=infobox_submit_callback
;
1460 function toggleSubmitNotEmpty(e
, submit_id
) {
1462 document
.getElementById(submit_id
).disabled
= (e
.value
== "")
1464 exception_error("toggleSubmitNotEmpty", e
);
1468 function isValidURL(s
) {
1469 return s
.match("http://") != null || s
.match("https://") != null || s
.match("feed://") != null;
1472 function qaddFeed() {
1474 if (!xmlhttp_ready(xmlhttp
)) {
1475 printLockingError();
1479 var form
= document
.forms
['feed_add_form'];
1480 var feed_url
= form
.feed_url
.value
;
1482 if (feed_url
== "") {
1483 alert("Can't subscribe: no feed URL given.");
1487 notify_progress(__("Subscribing to feed..."), true);
1491 var feeds_doc
= document
;
1493 // feeds_doc.location.href = "backend.php?op=error&msg=Loading,%20please wait...";
1495 var query
= Form
.serialize("feed_add_form");
1497 debug("subscribe q: " + query
);
1499 /* xmlhttp.open("GET", "backend.php?" + query, true);
1500 xmlhttp.onreadystatechange=dlg_frefresh_callback;
1501 xmlhttp.send(null); */
1503 xmlhttp
.open("POST", "backend.php", true);
1504 xmlhttp
.onreadystatechange
=dlg_frefresh_callback
;
1505 xmlhttp
.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
1506 xmlhttp
.send(query
);
1511 function filterCR(e
, f
)
1516 key
= window
.event
.keyCode
; //IE
1518 key
= e
.which
; //firefox
1521 if (typeof f
!= 'undefined') {
1532 function getMainContext() {
1536 function getFeedsContext() {
1540 function getContentContext() {
1544 function getHeadlinesContext() {
1548 var debug_last_class
= "even";
1550 function debug(msg
) {
1552 if (debug_last_class
== "even") {
1553 debug_last_class
= "odd";
1555 debug_last_class
= "even";
1558 var c
= document
.getElementById('debug_output');
1559 if (c
&& c
.style
.display
== "block") {
1560 while (c
.lastChild
!= 'undefined' && c
.childNodes
.length
> 100) {
1561 c
.removeChild(c
.lastChild
);
1565 var ts
= leading_zero(d
.getHours()) + ":" + leading_zero(d
.getMinutes()) +
1566 ":" + leading_zero(d
.getSeconds());
1567 c
.innerHTML
= "<li class=\"" + debug_last_class
+ "\"><span class=\"debugTS\">[" + ts
+ "]</span> " +
1568 msg
+ "</li>" + c
.innerHTML
;
1572 function getInitParam(key
) {
1573 return init_params
[key
];
1576 function storeInitParam(key
, value
) {
1577 debug("<b>storeInitParam is OBSOLETE: " + key
+ " => " + value
+ "</b>");
1578 init_params
[key
] = value
;
1581 function fatalError(code
, message
) {
1585 window
.location
.href
= "tt-rss.php";
1586 } else if (code
== 5) {
1587 window
.location
.href
= "update.php";
1589 var fe
= document
.getElementById("fatal_error");
1590 var fc
= document
.getElementById("fatal_error_msg");
1592 if (message
== "") message
= "Unknown error";
1594 fc
.innerHTML
= "<img src='images/sign_excl.png'> " + message
+ " (Code " + code
+ ")";
1596 fe
.style
.display
= "block";
1600 exception_error("fatalError", e
);
1604 function getFeedName(id
, is_cat
) {
1605 var d
= getFeedsContext().document
;
1610 e
= d
.getElementById("FCATN-" + id
);
1612 e
= d
.getElementById("FEEDN-" + id
);
1615 return e
.innerHTML
.stripTags();
1621 function viewContentUrl(url
) {
1622 getContentContext().location
= url
;
1625 function filterDlgCheckAction(sender
) {
1629 var action
= sender
[sender
.selectedIndex
].value
;
1631 var form
= document
.forms
["filter_add_form"];
1634 form
= document
.forms
["filter_edit_form"];
1638 debug("filterDlgCheckAction: can't find form!");
1642 var action_param
= form
.action_param
;
1644 if (!action_param
) {
1645 debug("filterDlgCheckAction: can't find action param!");
1649 // if selected action supports parameters, enable params field
1651 action_param
.disabled
= false;
1653 action_param
.disabled
= true;
1657 exception_error(e
, "filterDlgCheckAction");
1662 function explainError(code
) {
1663 return displayDlg("explainError", code
);
1666 function logoutUser() {
1668 if (xmlhttp_ready(xmlhttp_rpc
)) {
1670 notify_progress("Logging out, please wait...", true);
1672 xmlhttp_rpc
.open("GET", "backend.php?op=rpc&subop=logout", true);
1673 xmlhttp_rpc
.onreadystatechange
=logout_callback
;
1674 xmlhttp_rpc
.send(null);
1676 printLockingError();
1679 exception_error("logoutUser", e
);
1683 // this only searches loaded headlines list, not in CDM
1684 function getRelativePostIds(id
) {
1686 debug("getRelativePostIds: " + id
);
1688 var ids
= new Array();
1689 var container
= document
.getElementById("headlinesList");
1692 var rows
= container
.rows
;
1694 for (var i
= 0; i
< rows
.length
; i
++) {
1695 var r_id
= rows
[i
].id
.replace("RROW-", "");
1698 if (i
> 0) ids
.push(rows
[i
-1].id
.replace("RROW-", ""));
1699 if (i
> 1) ids
.push(rows
[i
-2].id
.replace("RROW-", ""));
1700 if (i
> 2) ids
.push(rows
[i
-3].id
.replace("RROW-", ""));
1702 if (i
< rows
.length
-1) ids
.push(rows
[i
+1].id
.replace("RROW-", ""));
1703 if (i
< rows
.length
-2) ids
.push(rows
[i
+2].id
.replace("RROW-", ""));
1704 if (i
< rows
.length
-3) ids
.push(rows
[i
+3].id
.replace("RROW-", ""));