]>
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 /* 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");
953 // debug(node.childNodes[i].id + " --> " + has_unread);
955 if (hide
&& !has_unread
) {
956 node
.childNodes
[i
].style
.display
= "none";
960 node
.childNodes
[i
].style
.display
= "list-item";
964 node
.childNodes
[i
].style
.display
= "list-item";
971 if (cat_unread
== 0) {
972 if (cat_node
.style
== undefined) {
973 debug("ERROR: supplied cat_node " + cat_node
+
974 " has no styles. WTF?");
978 cat_node
.style
.display
= "none";
980 cat_node
.style
.display
= "list-item";
984 cat_node
.style
.display
= "list-item";
990 // debug("unread for category: " + cat_unread);
993 function selectTableRow(r
, do_select
) {
994 r
.className
= r
.className
.replace("Selected", "");
997 r
.className
= r
.className
+ "Selected";
1001 function selectTableRowById(elem_id
, check_id
, do_select
) {
1005 var row
= document
.getElementById(elem_id
);
1008 selectTableRow(row
, do_select
);
1011 var check
= document
.getElementById(check_id
);
1014 check
.checked
= do_select
;
1017 exception_error("selectTableRowById", e
);
1021 function selectTableRowsByIdPrefix(content_id
, prefix
, check_prefix
, do_select
,
1022 classcheck
, reset_others
) {
1024 var content
= document
.getElementById(content_id
);
1027 alert("[selectTableRows] Element " + content_id
+ " not found.");
1031 for (i
= 0; i
< content
.rows
.length
; i
++) {
1032 if (!classcheck
|| content
.rows
[i
].className
.match(classcheck
)) {
1034 if (content
.rows
[i
].id
.match(prefix
)) {
1035 selectTableRow(content
.rows
[i
], do_select
);
1037 var row_id
= content
.rows
[i
].id
.replace(prefix
, "");
1038 var check
= document
.getElementById(check_prefix
+ row_id
);
1041 check
.checked
= do_select
;
1043 } else if (reset_others
) {
1044 selectTableRow(content
.rows
[i
], false);
1046 var row_id
= content
.rows
[i
].id
.replace(prefix
, "");
1047 var check
= document
.getElementById(check_prefix
+ row_id
);
1050 check
.checked
= false;
1054 } else if (reset_others
) {
1055 selectTableRow(content
.rows
[i
], false);
1057 var row_id
= content
.rows
[i
].id
.replace(prefix
, "");
1058 var check
= document
.getElementById(check_prefix
+ row_id
);
1061 check
.checked
= false;
1068 function getSelectedTableRowIds(content_id
, prefix
) {
1070 var content
= document
.getElementById(content_id
);
1073 alert("[getSelectedTableRowIds] Element " + content_id
+ " not found.");
1077 var sel_rows
= new Array();
1079 for (i
= 0; i
< content
.rows
.length
; i
++) {
1080 if (content
.rows
[i
].id
.match(prefix
) &&
1081 content
.rows
[i
].className
.match("Selected")) {
1083 var row_id
= content
.rows
[i
].id
.replace(prefix
+ "-", "");
1084 sel_rows
.push(row_id
);
1092 function toggleSelectRowById(sender
, id
) {
1093 var row
= document
.getElementById(id
);
1095 if (sender
.checked
) {
1096 if (!row
.className
.match("Selected")) {
1097 row
.className
= row
.className
+ "Selected";
1100 if (row
.className
.match("Selected")) {
1101 row
.className
= row
.className
.replace("Selected", "");
1106 function toggleSelectListRow(sender
) {
1107 var parent_row
= sender
.parentNode
;
1109 if (sender
.checked
) {
1110 if (!parent_row
.className
.match("Selected")) {
1111 parent_row
.className
= parent_row
.className
+ "Selected";
1114 if (parent_row
.className
.match("Selected")) {
1115 parent_row
.className
= parent_row
.className
.replace("Selected", "");
1120 function tSR(sender
) {
1121 return toggleSelectRow(sender
);
1124 function toggleSelectRow(sender
) {
1125 var parent_row
= sender
.parentNode
.parentNode
;
1127 if (sender
.checked
) {
1128 if (!parent_row
.className
.match("Selected")) {
1129 parent_row
.className
= parent_row
.className
+ "Selected";
1132 if (parent_row
.className
.match("Selected")) {
1133 parent_row
.className
= parent_row
.className
.replace("Selected", "");
1138 function openExternalUrl(url
) {
1139 var w
= window
.open(url
);
1142 function getRelativeFeedId(list
, id
, direction
, unread_only
) {
1144 if (direction
== "next") {
1145 for (i
= 0; i
< list
.childNodes
.length
; i
++) {
1146 var child
= list
.childNodes
[i
];
1147 if (child
.id
&& child
.id
== "feedCatHolder") {
1148 if (child
.lastChild
) {
1149 var cr
= getRelativeFeedId(child
.firstChild
, id
, direction
, unread_only
);
1152 } else if (child
.id
&& child
.id
.match("FEEDR-")) {
1153 return child
.id
.replace('FEEDR-', '');
1158 // FIXME select last feed doesn't work when only unread feeds are visible
1160 if (direction
== "prev") {
1161 for (i
= list
.childNodes
.length
-1; i
>= 0; i
--) {
1162 var child
= list
.childNodes
[i
];
1163 if (child
.id
== "feedCatHolder" && child
.className
!= "invisible") {
1164 if (child
.firstChild
) {
1165 var cr
= getRelativeFeedId(child
.firstChild
, id
, direction
);
1168 } else if (child
.id
.match("FEEDR-")) {
1170 if (getInitParam("hide_read_feeds") == 1) {
1171 if (child
.className
!= "feed") {
1172 // alert(child.className);
1173 return child
.id
.replace('FEEDR-', '');
1176 return child
.id
.replace('FEEDR-', '');
1183 var feed
= list
.ownerDocument
.getElementById("FEEDR-" + id
);
1185 if (getInitParam("hide_read_feeds") == 1) {
1189 if (direction
== "next") {
1195 if (e
.nextSibling
) {
1199 } else if (e
.parentNode
.parentNode
.nextSibling
) {
1201 var this_cat
= e
.parentNode
.parentNode
;
1205 if (this_cat
&& this_cat
.nextSibling
) {
1206 while (!e
&& this_cat
.nextSibling
) {
1207 this_cat
= this_cat
.nextSibling
;
1208 if (this_cat
.id
== "feedCatHolder") {
1209 e
= this_cat
.firstChild
.firstChild
;
1219 if (!unread_only
|| (unread_only
&& e
.className
!= "feed" &&
1220 e
.className
.match("feed"))) {
1221 if (e
.parentNode
.parentNode
&& e
.parentNode
.parentNode
.className
1223 return e
.id
.replace("FEEDR-", "");
1229 } else if (direction
== "prev") {
1235 if (e
.previousSibling
) {
1237 e
= e
.previousSibling
;
1239 } else if (e
.parentNode
.parentNode
.previousSibling
) {
1241 var this_cat
= e
.parentNode
.parentNode
;
1245 if (this_cat
&& this_cat
.previousSibling
) {
1246 while (!e
&& this_cat
.previousSibling
) {
1247 this_cat
= this_cat
.previousSibling
;
1248 if (this_cat
.id
== "feedCatHolder") {
1249 e
= this_cat
.firstChild
.lastChild
;
1259 if (!unread_only
|| (unread_only
&& e
.className
!= "feed" &&
1260 e
.className
.match("feed"))) {
1261 if (e
.parentNode
.parentNode
&& e
.parentNode
.parentNode
.className
1263 return e
.id
.replace("FEEDR-", "");
1272 function showBlockElement(id
, h_id
) {
1273 var elem
= document
.getElementById(id
);
1276 elem
.style
.display
= "block";
1279 elem
= document
.getElementById(h_id
);
1281 elem
.style
.display
= "none";
1285 alert("[showBlockElement] can't find element with id " + id
);
1289 function hideParentElement(e
) {
1290 e
.parentNode
.style
.display
= "none";
1293 function dropboxSelect(e
, v
) {
1294 for (i
= 0; i
< e
.length
; i
++) {
1295 if (e
[i
].value
== v
) {
1296 e
.selectedIndex
= i
;
1302 // originally stolen from http://www.11tmr.com/11tmr.nsf/d6plinks/MWHE-695L9Z
1303 // bugfixed just a little bit :-)
1304 function getURLParam(strParamName
){
1306 var strHref
= window
.location
.href
;
1308 if (strHref
.indexOf("#") == strHref
.length
-1) {
1309 strHref
= strHref
.substring(0, strHref
.length
-1);
1312 if ( strHref
.indexOf("?") > -1 ){
1313 var strQueryString
= strHref
.substr(strHref
.indexOf("?"));
1314 var aQueryString
= strQueryString
.split("&");
1315 for ( var iParam
= 0; iParam
< aQueryString
.length
; iParam
++ ){
1316 if (aQueryString
[iParam
].indexOf(strParamName
+ "=") > -1 ){
1317 var aParam
= aQueryString
[iParam
].split("=");
1318 strReturn
= aParam
[1];
1326 function leading_zero(p
) {
1328 if (s
.length
== 1) s
= "0" + s
;
1332 function closeInfoBox(cleanup
) {
1334 if (!is_msie() && !getInitParam("infobox_disable_overlay")) {
1335 var overlay
= document
.getElementById("dialog_overlay");
1337 overlay
.style
.display
= "none";
1341 var box
= document
.getElementById('infoBox');
1342 var shadow
= document
.getElementById('infoBoxShadow');
1345 shadow
.style
.display
= "none";
1347 box
.style
.display
= "none";
1350 if (cleanup
) box
.innerHTML
= " ";
1358 function displayDlg(id
, param
) {
1360 if (!xmlhttp_ready(xmlhttp
)) {
1361 printLockingError();
1365 notify_progress("Loading, please wait...");
1367 xmlhttp
.open("GET", "backend.php?op=dlg&id=" +
1368 param_escape(id
) + "¶m=" + param_escape(param
), true);
1369 xmlhttp
.onreadystatechange
=infobox_callback
;
1377 function infobox_submit_callback() {
1378 if (xmlhttp
.readyState
== 4) {
1382 // called from prefs, reload tab
1384 selectTab(active_tab
, false);
1388 if (xmlhttp
.responseText
) {
1389 notify_info(xmlhttp
.responseText
);
1395 function infobox_callback() {
1396 if (xmlhttp
.readyState
== 4) {
1398 if (!is_msie() && !getInitParam("infobox_disable_overlay")) {
1399 var overlay
= document
.getElementById("dialog_overlay");
1401 overlay
.style
.display
= "block";
1405 var box
= document
.getElementById('infoBox');
1406 var shadow
= document
.getElementById('infoBoxShadow');
1408 box
.innerHTML
=xmlhttp
.responseText
;
1410 shadow
.style
.display
= "block";
1412 box
.style
.display
= "block";
1419 function helpbox_callback() {
1420 if (xmlhttp
.readyState
== 4) {
1421 var box
= document
.getElementById('helpBox');
1422 var shadow
= document
.getElementById('helpBoxShadow');
1424 box
.innerHTML
=xmlhttp
.responseText
;
1426 shadow
.style
.display
= "block";
1428 box
.style
.display
= "block";
1435 function addFilter() {
1437 if (!xmlhttp_ready(xmlhttp
)) {
1438 printLockingError();
1442 var form
= document
.forms
['filter_add_form'];
1443 var reg_exp
= form
.reg_exp
.value
;
1445 if (reg_exp
== "") {
1446 alert("Can't add filter: nothing to match on.");
1450 var query
= Form
.serialize("filter_add_form");
1452 xmlhttp
.open("GET", "backend.php?" + query
, true);
1453 xmlhttp
.onreadystatechange
=infobox_submit_callback
;
1459 function toggleSubmitNotEmpty(e
, submit_id
) {
1461 document
.getElementById(submit_id
).disabled
= (e
.value
== "")
1463 exception_error("toggleSubmitNotEmpty", e
);
1467 function isValidURL(s
) {
1468 return s
.match("http://") != null || s
.match("https://") != null || s
.match("feed://") != null;
1471 function qaddFeed() {
1473 if (!xmlhttp_ready(xmlhttp
)) {
1474 printLockingError();
1478 var form
= document
.forms
['feed_add_form'];
1479 var feed_url
= form
.feed_url
.value
;
1481 if (feed_url
== "") {
1482 alert("Can't subscribe: no feed URL given.");
1486 notify_progress(__("Subscribing to feed..."), true);
1490 var feeds_doc
= document
;
1492 // feeds_doc.location.href = "backend.php?op=error&msg=Loading,%20please wait...";
1494 var query
= Form
.serialize("feed_add_form");
1496 debug("subscribe q: " + query
);
1498 /* xmlhttp.open("GET", "backend.php?" + query, true);
1499 xmlhttp.onreadystatechange=dlg_frefresh_callback;
1500 xmlhttp.send(null); */
1502 xmlhttp
.open("POST", "backend.php", true);
1503 xmlhttp
.onreadystatechange
=dlg_frefresh_callback
;
1504 xmlhttp
.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
1505 xmlhttp
.send(query
);
1510 function filterCR(e
, f
)
1515 key
= window
.event
.keyCode
; //IE
1517 key
= e
.which
; //firefox
1520 if (typeof f
!= 'undefined') {
1531 function getMainContext() {
1535 function getFeedsContext() {
1539 function getContentContext() {
1543 function getHeadlinesContext() {
1547 var debug_last_class
= "even";
1549 function debug(msg
) {
1551 if (debug_last_class
== "even") {
1552 debug_last_class
= "odd";
1554 debug_last_class
= "even";
1557 var c
= document
.getElementById('debug_output');
1558 if (c
&& c
.style
.display
== "block") {
1559 while (c
.lastChild
!= 'undefined' && c
.childNodes
.length
> 100) {
1560 c
.removeChild(c
.lastChild
);
1564 var ts
= leading_zero(d
.getHours()) + ":" + leading_zero(d
.getMinutes()) +
1565 ":" + leading_zero(d
.getSeconds());
1566 c
.innerHTML
= "<li class=\"" + debug_last_class
+ "\"><span class=\"debugTS\">[" + ts
+ "]</span> " +
1567 msg
+ "</li>" + c
.innerHTML
;
1571 function getInitParam(key
) {
1572 return init_params
[key
];
1575 function storeInitParam(key
, value
) {
1576 debug("<b>storeInitParam is OBSOLETE: " + key
+ " => " + value
+ "</b>");
1577 init_params
[key
] = value
;
1580 function fatalError(code
, message
) {
1584 window
.location
.href
= "tt-rss.php";
1585 } else if (code
== 5) {
1586 window
.location
.href
= "update.php";
1588 var fe
= document
.getElementById("fatal_error");
1589 var fc
= document
.getElementById("fatal_error_msg");
1591 if (message
== "") message
= "Unknown error";
1593 fc
.innerHTML
= "<img src='images/sign_excl.png'> " + message
+ " (Code " + code
+ ")";
1595 fe
.style
.display
= "block";
1599 exception_error("fatalError", e
);
1603 function getFeedName(id
, is_cat
) {
1604 var d
= getFeedsContext().document
;
1609 e
= d
.getElementById("FCATN-" + id
);
1611 e
= d
.getElementById("FEEDN-" + id
);
1614 return e
.innerHTML
.stripTags();
1620 function viewContentUrl(url
) {
1621 getContentContext().location
= url
;
1624 function filterDlgCheckAction(sender
) {
1628 var action
= sender
[sender
.selectedIndex
].value
;
1630 var form
= document
.forms
["filter_add_form"];
1633 form
= document
.forms
["filter_edit_form"];
1637 debug("filterDlgCheckAction: can't find form!");
1641 var action_param
= form
.action_param
;
1643 if (!action_param
) {
1644 debug("filterDlgCheckAction: can't find action param!");
1648 // if selected action supports parameters, enable params field
1650 action_param
.disabled
= false;
1652 action_param
.disabled
= true;
1656 exception_error(e
, "filterDlgCheckAction");
1661 function explainError(code
) {
1662 return displayDlg("explainError", code
);
1665 function logoutUser() {
1667 if (xmlhttp_ready(xmlhttp_rpc
)) {
1669 notify_progress("Logging out, please wait...", true);
1671 xmlhttp_rpc
.open("GET", "backend.php?op=rpc&subop=logout", true);
1672 xmlhttp_rpc
.onreadystatechange
=logout_callback
;
1673 xmlhttp_rpc
.send(null);
1675 printLockingError();
1678 exception_error("logoutUser", e
);
1682 // this only searches loaded headlines list, not in CDM
1683 function getRelativePostIds(id
) {
1685 debug("getRelativePostIds: " + id
);
1687 var ids
= new Array();
1688 var container
= document
.getElementById("headlinesList");
1691 var rows
= container
.rows
;
1693 for (var i
= 0; i
< rows
.length
; i
++) {
1694 var r_id
= rows
[i
].id
.replace("RROW-", "");
1697 if (i
> 0) ids
.push(rows
[i
-1].id
.replace("RROW-", ""));
1698 if (i
> 1) ids
.push(rows
[i
-2].id
.replace("RROW-", ""));
1699 if (i
> 2) ids
.push(rows
[i
-3].id
.replace("RROW-", ""));
1701 if (i
< rows
.length
-1) ids
.push(rows
[i
+1].id
.replace("RROW-", ""));
1702 if (i
< rows
.length
-2) ids
.push(rows
[i
+2].id
.replace("RROW-", ""));
1703 if (i
< rows
.length
-3) ids
.push(rows
[i
+3].id
.replace("RROW-", ""));