var notify _silent = false ;
var loading _progress = 0 ;
var sanity _check _done = false ;
/* add method to remove element from array */
Array . prototype . remove = function ( s ) {
for ( var i = 0 ; i < this . length ; i ++ ) {
if ( s == this [ i ] ) this . splice ( i , 1 ) ;
}
}
/* create console.log if it doesn't exist */
if ( ! window . console ) console = { } ;
console . log = console . log || function ( msg ) { } ;
console . warn = console . warn || function ( msg ) { } ;
console . error = console . error || function ( msg ) { } ;
function exception _error ( location , e , ext _info ) {
var msg = format _exception _error ( location , e ) ;
if ( ! ext _info ) ext _info = false ;
try {
if ( ext _info ) {
if ( ext _info . responseText ) {
ext _info = ext _info . responseText ;
}
}
var content = "<div class=\"fatalError\">" +
"<pre>" + msg + "</pre>" ;
content += "<form name=\"exceptionForm\" id=\"exceptionForm\" target=\"_blank\" " +
"action=\"http://tt-rss.org/report.php\" method=\"POST\">" ;
content += "<textarea style=\"display : none\" name=\"message\">" + msg + "</textarea>" ;
content += "<textarea style=\"display : none\" name=\"params\">N/A</textarea>" ;
if ( ext _info ) {
content += "<div><b>Additional information:</b></div>" +
"<textarea name=\"xinfo\" readonly=\"1\">" + ext _info + "</textarea>" ;
}
content += "<div><b>Stack trace:</b></div>" +
"<textarea name=\"stack\" readonly=\"1\">" + e . stack + "</textarea>" ;
content += "</form>" ;
content += "</div>" ;
content += "<div class='dlgButtons'>" ;
content += "<button dojoType=\"dijit.form.Button\"" +
"onclick=\"dijit.byId('exceptionDlg').report()\">" +
_ _ ( 'Report to tt-rss.org' ) + "</button> " ;
content += "<button dojoType=\"dijit.form.Button\" " +
"onclick=\"dijit.byId('exceptionDlg').hide()\">" +
_ _ ( 'Close' ) + "</button>" ;
content += "</div>" ;
if ( dijit . byId ( "exceptionDlg" ) )
dijit . byId ( "exceptionDlg" ) . destroyRecursive ( ) ;
var dialog = new dijit . Dialog ( {
id : "exceptionDlg" ,
title : "Unhandled exception" ,
style : "width: 600px" ,
report : function ( ) {
if ( confirm ( _ _ ( "Are you sure to report this exception to tt-rss.org? The report will include your browser information. Your IP would be saved in the database." ) ) ) {
document . forms [ 'exceptionForm' ] . params . value = $H ( {
browserName : navigator . appName ,
browserVersion : navigator . appVersion ,
browserPlatform : navigator . platform ,
browserCookies : navigator . cookieEnabled ,
} ) . toQueryString ( ) ;
document . forms [ 'exceptionForm' ] . submit ( ) ;
}
} ,
content : content } ) ;
dialog . show ( ) ;
} catch ( e ) {
alert ( msg ) ;
}
}
function format _exception _error ( location , e ) {
var msg ;
if ( e . fileName ) {
var base _fname = e . fileName . substring ( e . fileName . lastIndexOf ( "/" ) + 1 ) ;
msg = "Exception: " + e . name + ", " + e . message +
"\nFunction: " + location + "()" +
"\nLocation: " + base _fname + ":" + e . lineNumber ;
} else if ( e . description ) {
msg = "Exception: " + e . description + "\nFunction: " + location + "()" ;
} else {
msg = "Exception: " + e + "\nFunction: " + location + "()" ;
}
console . error ( "EXCEPTION: " + msg ) ;
return msg ;
}
function param _escape ( arg ) {
if ( typeof encodeURIComponent != 'undefined' )
return encodeURIComponent ( arg ) ;
else
return escape ( arg ) ;
}
function param _unescape ( arg ) {
if ( typeof decodeURIComponent != 'undefined' )
return decodeURIComponent ( arg ) ;
else
return unescape ( arg ) ;
}
var notify _hide _timerid = false ;
function hide _notify ( ) {
var n = $ ( "notify" ) ;
if ( n ) {
n . style . display = "none" ;
}
}
function notify _silent _next ( ) {
notify _silent = true ;
}
function notify _real ( msg , no _hide , n _type ) {
if ( notify _silent ) {
notify _silent = false ;
return ;
}
var n = $ ( "notify" ) ;
var nb = $ ( "notify_body" ) ;
if ( ! n || ! nb ) return ;
if ( notify _hide _timerid ) {
window . clearTimeout ( notify _hide _timerid ) ;
}
if ( msg == "" ) {
if ( n . style . display == "block" ) {
notify _hide _timerid = window . setTimeout ( "hide_notify()" , 0 ) ;
}
return ;
} else {
n . style . display = "block" ;
}
/ * t y p e s :
1 - generic
2 - progress
3 - error
4 - info
* /
if ( typeof _ _ != 'undefined' ) {
msg = _ _ ( msg ) ;
}
if ( n _type == 1 ) {
n . className = "notify" ;
} else if ( n _type == 2 ) {
n . className = "notifyProgress" ;
msg = "<img src='" + getInitParam ( "sign_progress" ) + "'> " + msg ;
} else if ( n _type == 3 ) {
n . className = "notifyError" ;
msg = "<img src='" + getInitParam ( "sign_excl" ) + "'> " + msg ;
} else if ( n _type == 4 ) {
n . className = "notifyInfo" ;
msg = "<img src='" + getInitParam ( "sign_info" ) + "'> " + msg ;
}
// msg = "<img src='images/live_com_loading.gif'> " + msg;
nb . innerHTML = msg ;
if ( ! no _hide ) {
notify _hide _timerid = window . setTimeout ( "hide_notify()" , 3000 ) ;
}
}
function notify ( msg , no _hide ) {
notify _real ( msg , no _hide , 1 ) ;
}
function notify _progress ( msg , no _hide ) {
notify _real ( msg , no _hide , 2 ) ;
}
function notify _error ( msg , no _hide ) {
notify _real ( msg , no _hide , 3 ) ;
}
function notify _info ( msg , no _hide ) {
notify _real ( msg , no _hide , 4 ) ;
}
function setCookie ( name , value , lifetime , path , domain , secure ) {
var d = false ;
if ( lifetime ) {
d = new Date ( ) ;
d . setTime ( d . getTime ( ) + ( lifetime * 1000 ) ) ;
}
console . log ( "setCookie: " + name + " => " + value + ": " + d ) ;
int _setCookie ( name , value , d , path , domain , secure ) ;
}
function int _setCookie ( name , value , expires , path , domain , secure ) {
document . cookie = name + "=" + escape ( value ) +
( ( expires ) ? "; expires=" + expires . toGMTString ( ) : "" ) +
( ( path ) ? "; path=" + path : "" ) +
( ( domain ) ? "; domain=" + domain : "" ) +
( ( secure ) ? "; secure" : "" ) ;
}
function delCookie ( name , path , domain ) {
if ( getCookie ( name ) ) {
document . cookie = name + "=" +
( ( path ) ? ";path=" + path : "" ) +
( ( domain ) ? ";domain=" + domain : "" ) +
";expires=Thu, 01-Jan-1970 00:00:01 GMT" ;
}
}
function getCookie ( name ) {
var dc = document . cookie ;
var prefix = name + "=" ;
var begin = dc . indexOf ( "; " + prefix ) ;
if ( begin == - 1 ) {
begin = dc . indexOf ( prefix ) ;
if ( begin != 0 ) return null ;
}
else {
begin += 2 ;
}
var end = document . cookie . indexOf ( ";" , begin ) ;
if ( end == - 1 ) {
end = dc . length ;
}
return unescape ( dc . substring ( begin + prefix . length , end ) ) ;
}
function gotoPreferences ( ) {
document . location . href = "prefs.php" ;
}
function gotoMain ( ) {
document . location . href = "tt-rss.php" ;
}
function gotoExportOpml ( filename , settings ) {
tmp = settings ? 1 : 0 ;
document . location . href = "opml.php?op=Export&filename=" + filename + "&settings=" + tmp ;
}
/ * * * @ ( # ) i s N u m e r i c . j s * * C o p y r i g h t ( c ) 2 0 0 0 b y S u n d a r D o r a i - R a j
* * @ author Sundar Dorai - Raj
* * Email : sdoraira @ vt . edu
* * This program is free software ; you can redistribute it and / or
* * modify it under the terms of the GNU General Public License
* * as published by the Free Software Foundation ; either version 2
* * of the License , or ( at your option ) any later version ,
* * provided that any use properly credits the author .
* * This program is distributed in the hope that it will be useful ,
* * but WITHOUT ANY WARRANTY ; without even the implied warranty of
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* * GNU General Public License for more details at http : //www.gnu.org * * */
var numbers = ".0123456789" ;
function isNumeric ( x ) {
// is x a String or a character?
if ( x . length > 1 ) {
// remove negative sign
x = Math . abs ( x ) + "" ;
for ( j = 0 ; j < x . length ; j ++ ) {
// call isNumeric recursively for each character
number = isNumeric ( x . substring ( j , j + 1 ) ) ;
if ( ! number ) return number ;
}
return number ;
}
else {
// if x is number return true
if ( numbers . indexOf ( x ) >= 0 ) return true ;
return false ;
}
}
function toggleSelectRowById ( sender , id ) {
var row = $ ( id ) ;
return toggleSelectRow ( sender , row ) ;
}
function toggleSelectListRow ( sender ) {
var row = sender . parentNode ;
return toggleSelectRow ( sender , row ) ;
}
/* this is for dijit Checkbox */
function toggleSelectListRow2 ( sender ) {
var row = sender . domNode . parentNode ;
return toggleSelectRow ( sender , row ) ;
}
function tSR ( sender , row ) {
return toggleSelectRow ( sender , row ) ;
}
/* this is for dijit Checkbox */
function toggleSelectRow2 ( sender , row ) {
if ( ! row ) row = sender . domNode . parentNode . parentNode ;
if ( sender . checked && ! row . hasClassName ( 'Selected' ) )
row . addClassName ( 'Selected' ) ;
else
row . removeClassName ( 'Selected' ) ;
}
function toggleSelectRow ( sender , row ) {
if ( ! row ) row = sender . parentNode . parentNode ;
if ( sender . checked && ! row . hasClassName ( 'Selected' ) )
row . addClassName ( 'Selected' ) ;
else
row . removeClassName ( 'Selected' ) ;
}
function checkboxToggleElement ( elem , id ) {
if ( elem . checked ) {
Effect . Appear ( id , { duration : 0.5 } ) ;
} else {
Effect . Fade ( id , { duration : 0.5 } ) ;
}
}
function dropboxSelect ( e , v ) {
for ( i = 0 ; i < e . length ; i ++ ) {
if ( e [ i ] . value == v ) {
e . selectedIndex = i ;
break ;
}
}
}
function getURLParam ( param ) {
return String ( window . location . href ) . parseQuery ( ) [ param ] ;
}
function leading _zero ( p ) {
var s = String ( p ) ;
if ( s . length == 1 ) s = "0" + s ;
return s ;
}
function make _timestamp ( ) {
var d = new Date ( ) ;
return leading _zero ( d . getHours ( ) ) + ":" + leading _zero ( d . getMinutes ( ) ) +
":" + leading _zero ( d . getSeconds ( ) ) ;
}
function closeErrorBox ( ) {
if ( Element . visible ( "errorBoxShadow" ) ) {
Element . hide ( "dialog_overlay" ) ;
Element . hide ( "errorBoxShadow" ) ;
}
return false ;
}
function closeInfoBox ( cleanup ) {
try {
dialog = dijit . byId ( "infoBox" ) ;
if ( dialog ) dialog . hide ( ) ;
} catch ( e ) {
//exception_error("closeInfoBox", e);
}
return false ;
}
function displayDlg ( id , param , callback ) {
notify _progress ( "Loading, please wait..." , true ) ;
var query = "?op=dlg&id=" +
param _escape ( id ) + "¶m=" + param _escape ( param ) ;
new Ajax . Request ( "backend.php" , {
parameters : query ,
onComplete : function ( transport ) {
infobox _callback2 ( transport ) ;
if ( callback ) callback ( transport ) ;
} } ) ;
return false ;
}
function infobox _callback2 ( transport ) {
try {
var dialog = false ;
if ( dijit . byId ( "infoBox" ) ) {
dialog = dijit . byId ( "infoBox" ) ;
}
//console.log("infobox_callback2");
notify ( '' ) ;
var content ;
var dtitle = "Dialog" ;
var dlg = transport . responseXML . getElementsByTagName ( "dlg" ) [ 0 ] ;
var title = transport . responseXML . getElementsByTagName ( "title" ) [ 0 ] ;
if ( title )
title = title . firstChild . nodeValue ;
var content = transport . responseXML . getElementsByTagName ( "content" ) [ 0 ] ;
content = content . firstChild . nodeValue ;
if ( ! dialog ) {
dialog = new dijit . Dialog ( {
title : title ,
id : 'infoBox' ,
style : "width: 600px" ,
onCancel : function ( ) {
return true ;
} ,
onExecute : function ( ) {
return true ;
} ,
onClose : function ( ) {
return true ;
} ,
content : content } ) ;
} else {
dialog . attr ( 'title' , title ) ;
dialog . attr ( 'content' , content ) ;
}
dialog . show ( ) ;
notify ( "" ) ;
} catch ( e ) {
exception _error ( "infobox_callback2" , e ) ;
}
}
function filterCR ( e , f )
{
var key ;
if ( window . event )
key = window . event . keyCode ; //IE
else
key = e . which ; //firefox
if ( key == 13 ) {
if ( typeof f != 'undefined' ) {
f ( ) ;
return false ;
} else {
return false ;
}
} else {
return true ;
}
}
function getInitParam ( key ) {
return init _params [ key ] ;
}
function setInitParam ( key , value ) {
init _params [ key ] = value ;
}
function fatalError ( code , msg , ext _info ) {
try {
if ( code == 6 ) {
window . location . href = "tt-rss.php" ;
} else if ( code == 5 ) {
window . location . href = "db-updater.php" ;
} else {
if ( msg == "" ) msg = "Unknown error" ;
if ( ext _info ) {
if ( ext _info . responseText ) {
ext _info = ext _info . responseText ;
}
}
if ( ERRORS && ERRORS [ code ] && ! msg ) {
msg = ERRORS [ code ] ;
}
var content = "<div><b>Error code:</b> " + code + "</div>" +
"<p>" + msg + "</p>" ;
if ( ext _info ) {
content = content + "<div><b>Additional information:</b></div>" +
"<textarea style='width: 100%' readonly=\"1\">" +
ext _info + "</textarea>" ;
}
var dialog = new dijit . Dialog ( {
title : "Fatal error" ,
style : "width: 600px" ,
content : content } ) ;
dialog . show ( ) ;
}
return false ;
} catch ( e ) {
exception _error ( "fatalError" , e ) ;
}
}
function filterDlgCheckType ( sender ) {
try {
var ftype = sender . value ;
// if selected filter type is 5 (Date) enable the modifier dropbox
if ( ftype == 5 ) {
Element . show ( "filterDlg_dateModBox" ) ;
Element . show ( "filterDlg_dateChkBox" ) ;
} else {
Element . hide ( "filterDlg_dateModBox" ) ;
Element . hide ( "filterDlg_dateChkBox" ) ;
}
} catch ( e ) {
exception _error ( "filterDlgCheckType" , e ) ;
}
}
function filterDlgCheckAction ( sender ) {
try {
var action = sender . value ;
var action _param = $ ( "filterDlg_paramBox" ) ;
if ( ! action _param ) {
console . log ( "filterDlgCheckAction: can't find action param box!" ) ;
return ;
}
// if selected action supports parameters, enable params field
if ( action == 4 || action == 6 || action == 7 ) {
new Effect . Appear ( action _param , { duration : 0.5 } ) ;
if ( action != 7 ) {
Element . show ( dijit . byId ( "filterDlg_actionParam" ) . domNode ) ;
Element . hide ( dijit . byId ( "filterDlg_actionParamLabel" ) . domNode ) ;
} else {
Element . show ( dijit . byId ( "filterDlg_actionParamLabel" ) . domNode ) ;
Element . hide ( dijit . byId ( "filterDlg_actionParam" ) . domNode ) ;
}
} else {
Element . hide ( action _param ) ;
}
} catch ( e ) {
exception _error ( "filterDlgCheckAction" , e ) ;
}
}
function filterDlgCheckDate ( ) {
try {
var dialog = dijit . byId ( "filterEditDlg" ) ;
var reg _exp = dialog . attr ( 'value' ) . reg _exp ;
var query = "?op=rpc&subop=checkDate&date=" + reg _exp ;
new Ajax . Request ( "backend.php" , {
parameters : query ,
onComplete : function ( transport ) {
var reply = JSON . parse ( transport . responseText ) ;
if ( reply [ 'result' ] == true ) {
alert ( _ _ ( "Date syntax appears to be correct:" ) + " " + reply [ 'date' ] ) ;
return ;
} else {
alert ( _ _ ( "Date syntax is incorrect." ) ) ;
}
} } ) ;
} catch ( e ) {
exception _error ( "filterDlgCheckDate" , e ) ;
}
}
function explainError ( code ) {
return displayDlg ( "explainError" , code ) ;
}
function displayHelpInfobox ( topic _id ) {
var url = "backend.php?op=help&tid=" + param _escape ( topic _id ) ;
var w = window . open ( url , "ttrss_help" ,
"status=0,toolbar=0,location=0,width=450,height=500,scrollbars=1,menubar=0" ) ;
}
function loading _set _progress ( p ) {
try {
loading _progress += p ;
if ( dijit . byId ( "loading_bar" ) )
dijit . byId ( "loading_bar" ) . update ( { progress : loading _progress } ) ;
if ( loading _progress >= 90 )
remove _splash ( ) ;
} catch ( e ) {
exception _error ( "loading_set_progress" , e ) ;
}
}
function remove _splash ( ) {
if ( Element . visible ( "overlay" ) ) {
console . log ( "about to remove splash, OMG!" ) ;
Element . hide ( "overlay" ) ;
console . log ( "removed splash!" ) ;
}
}
function transport _error _check ( transport ) {
try {
if ( transport . responseXML ) {
var error = transport . responseXML . getElementsByTagName ( "error" ) [ 0 ] ;
if ( error ) {
var code = error . getAttribute ( "error-code" ) ;
var msg = error . getAttribute ( "error-msg" ) ;
if ( code != 0 ) {
fatalError ( code , msg ) ;
return false ;
}
}
}
} catch ( e ) {
exception _error ( "check_for_error_xml" , e ) ;
}
return true ;
}
function strip _tags ( s ) {
return s . replace ( /<\/?[^>]+(>|$)/g , "" ) ;
}
function truncate _string ( s , length ) {
if ( ! length ) length = 30 ;
var tmp = s . substring ( 0 , length ) ;
if ( s . length > length ) tmp += "…" ;
return tmp ;
}
function hotkey _prefix _timeout ( ) {
try {
var date = new Date ( ) ;
var ts = Math . round ( date . getTime ( ) / 1000 ) ;
if ( hotkey _prefix _pressed && ts - hotkey _prefix _pressed >= 5 ) {
console . log ( "hotkey_prefix seems to be stuck, aborting" ) ;
hotkey _prefix _pressed = false ;
hotkey _prefix = false ;
Element . hide ( 'cmdline' ) ;
}
setTimeout ( "hotkey_prefix_timeout()" , 1000 ) ;
} catch ( e ) {
exception _error ( "hotkey_prefix_timeout" , e ) ;
}
}
function hideAuxDlg ( ) {
try {
Element . hide ( 'auxDlg' ) ;
} catch ( e ) {
exception _error ( "hideAuxDlg" , e ) ;
}
}
function uploadIconHandler ( rc ) {
try {
switch ( rc ) {
case 0 :
notify _info ( "Upload complete." ) ;
if ( inPreferences ( ) ) {
updateFeedList ( ) ;
} else {
setTimeout ( 'updateFeedList(false, false)' , 50 ) ;
}
break ;
case 1 :
notify _error ( "Upload failed: icon is too big." ) ;
break ;
case 2 :
notify _error ( "Upload failed." ) ;
break ;
}
} catch ( e ) {
exception _error ( "uploadIconHandler" , e ) ;
}
}
function removeFeedIcon ( id ) {
try {
if ( confirm ( _ _ ( "Remove stored feed icon?" ) ) ) {
var query = "backend.php?op=pref-feeds&subop=removeicon&feed_id=" + param _escape ( id ) ;
console . log ( query ) ;
notify _progress ( "Removing feed icon..." , true ) ;
new Ajax . Request ( "backend.php" , {
parameters : query ,
onComplete : function ( transport ) {
notify _info ( "Feed icon removed." ) ;
if ( inPreferences ( ) ) {
updateFeedList ( ) ;
} else {
setTimeout ( 'updateFeedList(false, false)' , 50 ) ;
}
} } ) ;
}
return false ;
} catch ( e ) {
exception _error ( "uploadFeedIcon" , e ) ;
}
}
function uploadFeedIcon ( ) {
try {
var file = $ ( "icon_file" ) ;
if ( file . value . length == 0 ) {
alert ( _ _ ( "Please select an image file to upload." ) ) ;
} else {
if ( confirm ( _ _ ( "Upload new icon for this feed?" ) ) ) {
notify _progress ( "Uploading, please wait..." , true ) ;
return true ;
}
}
return false ;
} catch ( e ) {
exception _error ( "uploadFeedIcon" , e ) ;
}
}
function addLabel ( select , callback ) {
try {
var caption = prompt ( _ _ ( "Please enter label caption:" ) , "" ) ;
if ( caption != undefined ) {
if ( caption == "" ) {
alert ( _ _ ( "Can't create label: missing caption." ) ) ;
return false ;
}
var query = "?op=pref-labels&subop=add&caption=" +
param _escape ( caption ) ;
if ( select )
query += "&output=select" ;
notify _progress ( "Loading, please wait..." , true ) ;
if ( inPreferences ( ) && ! select ) active _tab = "labelConfig" ;
new Ajax . Request ( "backend.php" , {
parameters : query ,
onComplete : function ( transport ) {
if ( callback ) {
callback ( transport ) ;
} else if ( inPreferences ( ) ) {
updateLabelList ( ) ;
} else {
updateFeedList ( ) ;
}
} } ) ;
}
} catch ( e ) {
exception _error ( "addLabel" , e ) ;
}
}
function quickAddFeed ( ) {
try {
var query = "backend.php?op=dlg&id=quickAddFeed" ;
if ( dijit . byId ( "feedAddDlg" ) )
dijit . byId ( "feedAddDlg" ) . destroyRecursive ( ) ;
var dialog = new dijit . Dialog ( {
id : "feedAddDlg" ,
title : _ _ ( "Subscribe to Feed" ) ,
style : "width: 600px" ,
execute : function ( ) {
if ( this . validate ( ) ) {
console . log ( dojo . objectToQuery ( this . attr ( 'value' ) ) ) ;
var feed _url = this . attr ( 'value' ) . feed ;
notify _progress ( _ _ ( "Subscribing to feed..." ) , true ) ;
new Ajax . Request ( "backend.php" , {
parameters : dojo . objectToQuery ( this . attr ( 'value' ) ) ,
onComplete : function ( transport ) {
try {
var reply = JSON . parse ( transport . responseText ) ;
var rc = parseInt ( reply [ 'result' ] ) ;
notify ( '' ) ;
console . log ( "GOT RC: " + rc ) ;
switch ( rc ) {
case 1 :
dialog . hide ( ) ;
notify _info ( _ _ ( "Subscribed to %s" ) . replace ( "%s" , feed _url ) ) ;
updateFeedList ( ) ;
break ;
case 2 :
alert ( _ _ ( "Specified URL seems to be invalid." ) ) ;
break ;
case 3 :
alert ( _ _ ( "Specified URL doesn't seem to contain any feeds." ) ) ;
break ;
case 4 :
notify _progress ( "Searching for feed urls..." , true ) ;
new Ajax . Request ( "backend.php" , {
parameters : 'op=rpc&subop=extractfeedurls&url=' + param _escape ( feed _url ) ,
onComplete : function ( transport , dialog , feed _url ) {
notify ( '' ) ;
var reply = JSON . parse ( transport . responseText ) ;
var feeds = reply [ 'urls' ] ;
console . log ( transport . responseText ) ;
var select = dijit . byId ( "feedDlg_feedContainerSelect" ) ;
while ( select . getOptions ( ) . length > 0 )
select . removeOption ( 0 ) ;
var count = 0 ;
for ( var feedUrl in feeds ) {
select . addOption ( { value : feedUrl , label : feeds [ feedUrl ] } ) ;
count ++ ;
}
// if (count > 5) count = 5;
// select.size = count;
Effect . Appear ( 'feedDlg_feedsContainer' , { duration : 0.5 } ) ;
}
} ) ;
break ;
case 5 :
alert ( _ _ ( "Couldn't download the specified URL." ) ) ;
break ;
case 0 :
alert ( _ _ ( "You are already subscribed to this feed." ) ) ;
break ;
}
} catch ( e ) {
exception _error ( "subscribeToFeed" , e , transport ) ;
}
} } ) ;
}
} ,
href : query } ) ;
dialog . show ( ) ;
} catch ( e ) {
exception _error ( "quickAddFeed" , e ) ;
}
}
function quickAddFilter ( ) {
try {
var query = "backend.php?op=dlg&id=quickAddFilter" ;
if ( dijit . byId ( "filterEditDlg" ) )
dijit . byId ( "filterEditDlg" ) . destroyRecursive ( ) ;
dialog = new dijit . Dialog ( {
id : "filterEditDlg" ,
title : _ _ ( "Create Filter" ) ,
style : "width: 600px" ,
test : function ( ) {
if ( this . validate ( ) ) {
if ( dijit . byId ( "filterTestDlg" ) )
dijit . byId ( "filterTestDlg" ) . destroyRecursive ( ) ;
tdialog = new dijit . Dialog ( {
id : "filterTestDlg" ,
title : _ _ ( "Filter Test Results" ) ,
style : "width: 600px" ,
href : "backend.php?savemode=test&" +
dojo . objectToQuery ( dialog . attr ( 'value' ) ) ,
} ) ;
tdialog . show ( ) ;
}
} ,
execute : function ( ) {
if ( this . validate ( ) ) {
var query = "?op=rpc&subop=verifyRegexp®_exp=" +
param _escape ( dialog . attr ( 'value' ) . reg _exp ) ;
notify _progress ( "Verifying regular expression..." ) ;
new Ajax . Request ( "backend.php" , {
parameters : query ,
onComplete : function ( transport ) {
var reply = JSON . parse ( transport . responseText ) ;
if ( reply ) {
notify ( '' ) ;
if ( ! reply [ 'status' ] ) {
alert ( "Match regular expression seems to be invalid." ) ;
return ;
} else {
notify _progress ( "Saving data..." , true ) ;
console . log ( dojo . objectToQuery ( dialog . attr ( 'value' ) ) ) ;
new Ajax . Request ( "backend.php" , {
parameters : dojo . objectToQuery ( dialog . attr ( 'value' ) ) ,
onComplete : function ( transport ) {
dialog . hide ( ) ;
notify _info ( transport . responseText ) ;
if ( inPreferences ( ) ) {
updateFilterList ( ) ;
}
} } )
}
}
} } ) ;
}
} ,
href : query } ) ;
dialog . show ( ) ;
} catch ( e ) {
exception _error ( "quickAddFilter" , e ) ;
}
}
function resetPubSub ( feed _id , title ) {
var msg = _ _ ( "Reset subscription? Tiny Tiny RSS will try to subscribe to the notification hub again on next feed update." ) . replace ( "%s" , title ) ;
if ( title == undefined || confirm ( msg ) ) {
notify _progress ( "Loading, please wait..." ) ;
var query = "?op=pref-feeds&quiet=1&subop=resetPubSub&ids=" + feed _id ;
new Ajax . Request ( "backend.php" , {
parameters : query ,
onComplete : function ( transport ) {
dijit . byId ( "pubsubReset_Btn" ) . attr ( 'disabled' , true ) ;
notify _info ( "Subscription reset." ) ;
} } ) ;
}
return false ;
}
function unsubscribeFeed ( feed _id , title ) {
var msg = _ _ ( "Unsubscribe from %s?" ) . replace ( "%s" , title ) ;
if ( title == undefined || confirm ( msg ) ) {
notify _progress ( "Removing feed..." ) ;
var query = "?op=pref-feeds&quiet=1&subop=remove&ids=" + feed _id ;
new Ajax . Request ( "backend.php" , {
parameters : query ,
onComplete : function ( transport ) {
if ( dijit . byId ( "feedEditDlg" ) ) dijit . byId ( "feedEditDlg" ) . hide ( ) ;
if ( inPreferences ( ) ) {
updateFeedList ( ) ;
} else {
if ( feed _id == getActiveFeedId ( ) )
setTimeout ( "viewfeed(-5)" , 100 ) ;
}
} } ) ;
}
return false ;
}
function backend _sanity _check _callback ( transport ) {
try {
if ( sanity _check _done ) {
fatalError ( 11 , "Sanity check request received twice. This can indicate " +
"presence of Firebug or some other disrupting extension. " +
"Please disable it and try again." ) ;
return ;
}
var reply = JSON . parse ( transport . responseText ) ;
if ( ! reply ) {
fatalError ( 3 , "Sanity check: invalid RPC reply" , transport . responseText ) ;
return ;
}
var error _code = reply [ 'error' ] [ 'code' ] ;
if ( error _code && error _code != 0 ) {
return fatalError ( error _code , reply [ 'error' ] [ 'message' ] ) ;
}
console . log ( "sanity check ok" ) ;
var params = reply [ 'init-params' ] ;
if ( params ) {
console . log ( 'reading init-params...' ) ;
if ( params ) {
for ( k in params ) {
var v = params [ k ] ;
console . log ( "IP: " + k + " => " + v ) ;
}
}
init _params = params ;
}
sanity _check _done = true ;
init _second _stage ( ) ;
} catch ( e ) {
exception _error ( "backend_sanity_check_callback" , e , transport ) ;
}
}
function has _local _storage ( ) {
try {
return 'sessionStorage' in window && window [ 'sessionStorage' ] != null ;
} catch ( e ) {
return false ;
}
}
function catSelectOnChange ( elem ) {
try {
/ * v a r v a l u e = e l e m [ e l e m . s e l e c t e d I n d e x ] . v a l u e ;
var def = elem . getAttribute ( 'default' ) ;
if ( value == "ADD_CAT" ) {
if ( def )
dropboxSelect ( elem , def ) ;
else
elem . selectedIndex = 0 ;
quickAddCat ( elem ) ;
} * /
} catch ( e ) {
exception _error ( "catSelectOnChange" , e ) ;
}
}
function quickAddCat ( elem ) {
try {
var cat = prompt ( _ _ ( "Please enter category title:" ) ) ;
if ( cat ) {
var query = "?op=rpc&subop=quickAddCat&cat=" + param _escape ( cat ) ;
notify _progress ( "Loading, please wait..." , true ) ;
new Ajax . Request ( "backend.php" , {
parameters : query ,
onComplete : function ( transport ) {
var response = transport . responseXML ;
var select = response . getElementsByTagName ( "select" ) [ 0 ] ;
var options = select . getElementsByTagName ( "option" ) ;
dropbox _replace _options ( elem , options ) ;
notify ( '' ) ;
} } ) ;
}
} catch ( e ) {
exception _error ( "quickAddCat" , e ) ;
}
}
function genUrlChangeKey ( feed , is _cat ) {
try {
var ok = confirm ( _ _ ( "Generate new syndication address for this feed?" ) ) ;
if ( ok ) {
notify _progress ( "Trying to change address..." , true ) ;
var query = "?op=rpc&subop=regenFeedKey&id=" + param _escape ( feed ) +
"&is_cat=" + param _escape ( is _cat ) ;
new Ajax . Request ( "backend.php" , {
parameters : query ,
onComplete : function ( transport ) {
var reply = JSON . parse ( transport . responseText ) ;
var new _link = reply . link ;
var e = $ ( 'gen_feed_url' ) ;
if ( new _link ) {
e . innerHTML = e . innerHTML . replace ( /\&key=.*$/ ,
"&key=" + new _link ) ;
e . href = e . href . replace ( /\&key=.*$/ ,
"&key=" + new _link ) ;
new Effect . Highlight ( e ) ;
notify ( '' ) ;
} else {
notify _error ( "Could not change feed URL." ) ;
}
} } ) ;
}
} catch ( e ) {
exception _error ( "genUrlChangeKey" , e ) ;
}
return false ;
}
function labelSelectOnChange ( elem ) {
try {
/ * v a r v a l u e = e l e m [ e l e m . s e l e c t e d I n d e x ] . v a l u e ;
var def = elem . getAttribute ( 'default' ) ;
if ( value == "ADD_LABEL" ) {
if ( def )
dropboxSelect ( elem , def ) ;
else
elem . selectedIndex = 0 ;
addLabel ( elem , function ( transport ) {
try {
var response = transport . responseXML ;
var select = response . getElementsByTagName ( "select" ) [ 0 ] ;
var options = select . getElementsByTagName ( "option" ) ;
dropbox _replace _options ( elem , options ) ;
notify ( '' ) ;
} catch ( e ) {
exception _error ( "addLabel" , e ) ;
}
} ) ;
} * /
} catch ( e ) {
exception _error ( "labelSelectOnChange" , e ) ;
}
}
function dropbox _replace _options ( elem , options ) {
try {
while ( elem . hasChildNodes ( ) )
elem . removeChild ( elem . firstChild ) ;
var sel _idx = - 1 ;
for ( var i = 0 ; i < options . length ; i ++ ) {
var text = options [ i ] . firstChild . nodeValue ;
var value = options [ i ] . getAttribute ( "value" ) ;
if ( value == undefined ) value = text ;
var issel = options [ i ] . getAttribute ( "selected" ) == "1" ;
var option = new Option ( text , value , issel ) ;
if ( options [ i ] . getAttribute ( "disabled" ) )
option . setAttribute ( "disabled" , true ) ;
elem . insert ( option ) ;
if ( issel ) sel _idx = i ;
}
// Chrome doesn't seem to just select stuff when you pass new Option(x, y, true)
if ( sel _idx >= 0 ) elem . selectedIndex = sel _idx ;
} catch ( e ) {
exception _error ( "dropbox_replace_options" , e ) ;
}
}
// mode = all, none, invert
function selectTableRows ( id , mode ) {
try {
var rows = $ ( id ) . rows ;
for ( var i = 0 ; i < rows . length ; i ++ ) {
var row = rows [ i ] ;
var cb = false ;
if ( row . id && row . className ) {
var bare _id = row . id . replace ( /^[A-Z]*?-/ , "" ) ;
var inputs = rows [ i ] . getElementsByTagName ( "input" ) ;
for ( var j = 0 ; j < inputs . length ; j ++ ) {
var input = inputs [ j ] ;
if ( input . getAttribute ( "type" ) == "checkbox" &&
input . id . match ( bare _id ) ) {
cb = input ;
break ;
}
}
if ( cb ) {
var issel = row . hasClassName ( "Selected" ) ;
if ( mode == "all" && ! issel ) {
row . addClassName ( "Selected" ) ;
cb . checked = true ;
} else if ( mode == "none" && issel ) {
row . removeClassName ( "Selected" ) ;
cb . checked = false ;
} else if ( mode == "invert" ) {
if ( issel ) {
row . removeClassName ( "Selected" ) ;
cb . checked = false ;
} else {
row . addClassName ( "Selected" ) ;
cb . checked = true ;
}
}
}
}
}
} catch ( e ) {
exception _error ( "selectTableRows" , e ) ;
}
}
function getSelectedTableRowIds ( id ) {
var rows = [ ] ;
try {
var elem _rows = $ ( id ) . rows ;
for ( i = 0 ; i < elem _rows . length ; i ++ ) {
if ( elem _rows [ i ] . hasClassName ( "Selected" ) ) {
var bare _id = elem _rows [ i ] . id . replace ( /^[A-Z]*?-/ , "" ) ;
rows . push ( bare _id ) ;
}
}
} catch ( e ) {
exception _error ( "getSelectedTableRowIds" , e ) ;
}
return rows ;
}
function editFeed ( feed , event ) {
try {
if ( feed <= 0 )
return alert ( _ _ ( "You can't edit this kind of feed." ) ) ;
var query = "backend.php?op=pref-feeds&subop=editfeed&id=" +
param _escape ( feed ) ;
console . log ( query ) ;
if ( dijit . byId ( "feedEditDlg" ) )
dijit . byId ( "feedEditDlg" ) . destroyRecursive ( ) ;
dialog = new dijit . Dialog ( {
id : "feedEditDlg" ,
title : _ _ ( "Edit Feed" ) ,
style : "width: 600px" ,
execute : function ( ) {
if ( this . validate ( ) ) {
// console.log(dojo.objectToQuery(this.attr('value')));
notify _progress ( "Saving data..." , true ) ;
new Ajax . Request ( "backend.php" , {
parameters : dojo . objectToQuery ( dialog . attr ( 'value' ) ) ,
onComplete : function ( transport ) {
dialog . hide ( ) ;
notify ( '' ) ;
updateFeedList ( ) ;
} } )
}
} ,
href : query } ) ;
dialog . show ( ) ;
} catch ( e ) {
exception _error ( "editFeed" , e ) ;
}
}
function feedBrowser ( ) {
try {
var query = "backend.php?op=dlg&id=feedBrowser" ;
if ( dijit . byId ( "feedAddDlg" ) )
dijit . byId ( "feedAddDlg" ) . hide ( ) ;
if ( dijit . byId ( "feedBrowserDlg" ) )
dijit . byId ( "feedBrowserDlg" ) . destroyRecursive ( ) ;
var dialog = new dijit . Dialog ( {
id : "feedBrowserDlg" ,
title : _ _ ( "More Feeds" ) ,
style : "width: 600px" ,
getSelectedFeedIds : function ( ) {
var list = $$ ( "#browseFeedList li[id*=FBROW]" ) ;
var selected = new Array ( ) ;
list . each ( function ( child ) {
var id = child . id . replace ( "FBROW-" , "" ) ;
if ( child . hasClassName ( 'Selected' ) ) {
selected . push ( id ) ;
}
} ) ;
return selected ;
} ,
getSelectedFeeds : function ( ) {
var list = $$ ( "#browseFeedList li.Selected" ) ;
var selected = new Array ( ) ;
list . each ( function ( child ) {
var title = child . getElementsBySelector ( "span.fb_feedTitle" ) [ 0 ] . innerHTML ;
var url = child . getElementsBySelector ( "a.fb_feedUrl" ) [ 0 ] . href ;
selected . push ( [ title , url ] ) ;
} ) ;
return selected ;
} ,
subscribe : function ( ) {
var mode = this . attr ( 'value' ) . mode ;
var selected = [ ] ;
if ( mode == "1" )
selected = this . getSelectedFeeds ( ) ;
else
selected = this . getSelectedFeedIds ( ) ;
if ( selected . length > 0 ) {
dijit . byId ( "feedBrowserDlg" ) . hide ( ) ;
notify _progress ( "Loading, please wait..." , true ) ;
// we use dojo.toJson instead of JSON.stringify because
// it somehow escapes everything TWICE, at least in Chrome 9
var query = "?op=rpc&subop=massSubscribe&payload=" +
param _escape ( dojo . toJson ( selected ) ) + "&mode=" + param _escape ( mode ) ;
console . log ( query ) ;
new Ajax . Request ( "backend.php" , {
parameters : query ,
onComplete : function ( transport ) {
notify ( '' ) ;
updateFeedList ( ) ;
} } ) ;
} else {
alert ( _ _ ( "No feeds are selected." ) ) ;
}
} ,
update : function ( ) {
var query = dojo . objectToQuery ( dialog . attr ( 'value' ) ) ;
Element . show ( 'feed_browser_spinner' ) ;
new Ajax . Request ( "backend.php" , {
parameters : query ,
onComplete : function ( transport ) {
notify ( '' ) ;
Element . hide ( 'feed_browser_spinner' ) ;
var c = $ ( "browseFeedList" ) ;
var reply = JSON . parse ( transport . responseText ) ;
var r = reply [ 'content' ] ;
var mode = reply [ 'mode' ] ;
if ( c && r ) {
c . innerHTML = r ;
}
dojo . parser . parse ( "browseFeedList" ) ;
if ( mode == 2 ) {
Element . show ( dijit . byId ( 'feed_archive_remove' ) . domNode ) ;
} else {
Element . hide ( dijit . byId ( 'feed_archive_remove' ) . domNode ) ;
}
} } ) ;
} ,
removeFromArchive : function ( ) {
var selected = this . getSelectedFeeds ( ) ;
if ( selected . length > 0 ) {
var pr = _ _ ( "Remove selected feeds from the archive? Feeds with stored articles will not be removed." ) ;
if ( confirm ( pr ) ) {
Element . show ( 'feed_browser_spinner' ) ;
var query = "?op=rpc&subop=remarchived&ids=" +
param _escape ( selected . toString ( ) ) ; ;
new Ajax . Request ( "backend.php" , {
parameters : query ,
onComplete : function ( transport ) {
dialog . update ( ) ;
} } ) ;
}
}
} ,
execute : function ( ) {
if ( this . validate ( ) ) {
this . subscribe ( ) ;
}
} ,
href : query } ) ;
dialog . show ( ) ;
} catch ( e ) {
exception _error ( "editFeed" , e ) ;
}
}
function showFeedsWithErrors ( ) {
try {
var query = "backend.php?op=dlg&id=feedsWithErrors" ;
if ( dijit . byId ( "errorFeedsDlg" ) )
dijit . byId ( "errorFeedsDlg" ) . destroyRecursive ( ) ;
dialog = new dijit . Dialog ( {
id : "errorFeedsDlg" ,
title : _ _ ( "Feeds with update errors" ) ,
style : "width: 600px" ,
getSelectedFeeds : function ( ) {
return getSelectedTableRowIds ( "prefErrorFeedList" ) ;
} ,
removeSelected : function ( ) {
var sel _rows = this . getSelectedFeeds ( ) ;
console . log ( sel _rows ) ;
if ( sel _rows . length > 0 ) {
var ok = confirm ( _ _ ( "Remove selected feeds?" ) ) ;
if ( ok ) {
notify _progress ( "Removing selected feeds..." , true ) ;
var query = "?op=pref-feeds&subop=remove&ids=" +
param _escape ( sel _rows . toString ( ) ) ;
new Ajax . Request ( "backend.php" , {
parameters : query ,
onComplete : function ( transport ) {
notify ( '' ) ;
dialog . hide ( ) ;
updateFeedList ( ) ;
} } ) ;
}
} else {
alert ( _ _ ( "No feeds are selected." ) ) ;
}
} ,
execute : function ( ) {
if ( this . validate ( ) ) {
}
} ,
href : query } ) ;
dialog . show ( ) ;
} catch ( e ) {
exception _error ( "showFeedsWithErrors" , e ) ;
}
}