var loading _progress = 0 ;
var sanity _check _done = false ;
var init _params = { } ;
var _label _base _index = - 1024 ;
var notify _hide _timerid = false ;
Ajax . Base . prototype . initialize = Ajax . Base . prototype . initialize . wrap (
function ( callOriginal , options ) {
if ( getInitParam ( "csrf_token" ) != undefined ) {
Object . extend ( options , options || { } ) ;
if ( Object . isString ( options . parameters ) )
options . parameters = options . parameters . toQueryParams ( ) ;
else if ( Object . isHash ( options . parameters ) )
options . parameters = options . parameters . toObject ( ) ;
options . parameters [ "csrf_token" ] = getInitParam ( "csrf_token" ) ;
}
return callOriginal ( options ) ;
}
) ;
/* 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 )
ext _info = JSON . stringify ( ext _info ) ;
try {
new Ajax . Request ( "backend.php" , {
parameters : { op : "rpc" , method : "log" , logmsg : msg } ,
onComplete : function ( transport ) {
console . log ( transport . responseText ) ;
} } ) ;
} catch ( eii ) {
console . log ( "Exception while trying to log the error." ) ;
console . log ( eii ) ;
}
msg += "<p>" + _ _ ( "The error will be reported to the configured log destination." ) +
"</p>" ;
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 information about your web browser and tt-rss configuration. Your IP will be saved in the database." ) ) ) {
document . forms [ 'exceptionForm' ] . params . value = $H ( {
browserName : navigator . appName ,
browserVersion : navigator . appVersion ,
browserPlatform : navigator . platform ,
browserCookies : navigator . cookieEnabled ,
ttrssVersion : _ _ttrss _version ,
initParams : JSON . stringify ( init _params ) ,
} ) . toQueryString ( ) ;
document . forms [ 'exceptionForm' ] . submit ( ) ;
}
} ,
content : content } ) ;
dialog . show ( ) ;
} catch ( ei ) {
console . log ( "Exception while trying to report an exception. Oh boy." ) ;
console . log ( ei ) ;
console . log ( "Original exception:" ) ;
console . log ( e ) ;
msg += "\n\nAdditional exception caught while trying to show the error dialog.\n\n" + format _exception _error ( 'exception_error' , ei ) ;
try {
new Ajax . Request ( "backend.php" , {
parameters : { op : "rpc" , method : "log" , logmsg : msg } ,
onComplete : function ( transport ) {
console . log ( transport . responseText ) ;
} } ) ;
} catch ( eii ) {
console . log ( "Third exception while trying to log the error! Seriously?" ) ;
console . log ( eii ) ;
}
msg += "\n\nThe error will be reported to the configured log destination." ;
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 ) ;
}
function notify _real ( msg , no _hide , n _type ) {
var n = $ ( "notify" ) ;
if ( ! n ) return ;
if ( notify _hide _timerid ) {
window . clearTimeout ( notify _hide _timerid ) ;
}
if ( msg == "" ) {
if ( n . hasClassName ( "visible" ) ) {
notify _hide _timerid = window . setTimeout ( function ( ) {
n . removeClassName ( "visible" ) } , 0 ) ;
}
return ;
}
/ * t y p e s :
1 - generic
2 - progress
3 - error
4 - info
* /
msg = "<span class=\"msg\"> " + _ _ ( msg ) + "</span>" ;
if ( n _type == 2 ) {
msg = "<span><img src='images/indicator_white.gif'></span>" + msg ;
no _hide = true ;
} else if ( n _type == 3 ) {
msg = "<span><img src='images/alert.png'></span>" + msg ;
} else if ( n _type == 4 ) {
msg = "<span><img src='images/information.png'></span>" + msg ;
}
msg += " <span><img src=\"images/cross.png\" class=\"close\" title=\"" +
_ _ ( "Click to close" ) + "\" onclick=\"notify('')\"></span>" ;
n . innerHTML = msg ;
window . setTimeout ( function ( ) {
// goddamnit firefox
if ( n _type == 2 ) {
n . className = "notify notify_progress visible" ;
} else if ( n _type == 3 ) {
n . className = "notify notify_error visible" ;
msg = "<span><img src='images/alert.png'></span>" + msg ;
} else if ( n _type == 4 ) {
n . className = "notify notify_info visible" ;
} else {
n . className = "notify visible" ;
}
if ( ! no _hide ) {
notify _hide _timerid = window . setTimeout ( function ( ) {
n . removeClassName ( "visible" ) } , 5 * 1000 ) ;
}
} , 10 ) ;
}
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 gotoLogout ( ) {
document . location . href = "backend.php?op=logout" ;
}
function gotoMain ( ) {
document . location . href = "index.php" ;
}
/ * * * @ ( # ) 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 ( var 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 ) ;
}
/* this is for dijit Checkbox */
function toggleSelectRow2 ( sender , row , is _cdm ) {
if ( ! row )
if ( ! is _cdm )
row = sender . domNode . parentNode . parentNode ;
else
row = sender . domNode . parentNode . parentNode . parentNode ; // oh ffs
if ( sender . checked && ! row . hasClassName ( 'Selected' ) )
row . addClassName ( 'Selected' ) ;
else
row . removeClassName ( 'Selected' ) ;
if ( typeof updateSelectedPrompt != undefined )
updateSelectedPrompt ( ) ;
}
function toggleSelectRow ( sender , row ) {
if ( ! row ) row = sender . parentNode . parentNode ;
if ( sender . checked && ! row . hasClassName ( 'Selected' ) )
row . addClassName ( 'Selected' ) ;
else
row . removeClassName ( 'Selected' ) ;
if ( typeof updateSelectedPrompt != undefined )
updateSelectedPrompt ( ) ;
}
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 ( var 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 closeInfoBox ( cleanup ) {
try {
dialog = dijit . byId ( "infoBox" ) ;
if ( dialog ) dialog . hide ( ) ;
} catch ( e ) {
//exception_error("closeInfoBox", e);
}
return false ;
}
function displayDlg ( title , id , param , callback ) {
notify _progress ( "Loading, please wait..." , true ) ;
var query = "?op=dlg&method=" +
param _escape ( id ) + "¶m=" + param _escape ( param ) ;
new Ajax . Request ( "backend.php" , {
parameters : query ,
onComplete : function ( transport ) {
infobox _callback2 ( transport , title ) ;
if ( callback ) callback ( transport ) ;
} } ) ;
return false ;
}
function infobox _callback2 ( transport , title ) {
try {
var dialog = false ;
if ( dijit . byId ( "infoBox" ) ) {
dialog = dijit . byId ( "infoBox" ) ;
}
//console.log("infobox_callback2");
notify ( '' ) ;
var content = transport . responseText ;
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 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 = "index.php" ;
} else if ( code == 5 ) {
window . location . href = "public.php?op=dbupdate" ;
} 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 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 || action == 9 ) {
new Effect . Appear ( action _param , { duration : 0.5 } ) ;
Element . hide ( dijit . byId ( "filterDlg_actionParam" ) . domNode ) ;
Element . hide ( dijit . byId ( "filterDlg_actionParamLabel" ) . domNode ) ;
Element . hide ( dijit . byId ( "filterDlg_actionParamPlugin" ) . domNode ) ;
if ( action == 7 ) {
Element . show ( dijit . byId ( "filterDlg_actionParamLabel" ) . domNode ) ;
} else if ( action == 9 ) {
Element . show ( dijit . byId ( "filterDlg_actionParamPlugin" ) . domNode ) ;
} else {
Element . show ( dijit . byId ( "filterDlg_actionParam" ) . domNode ) ;
}
} else {
Element . hide ( action _param ) ;
}
} catch ( e ) {
exception _error ( "filterDlgCheckAction" , e ) ;
}
}
function explainError ( code ) {
return displayDlg ( _ _ ( "Error explained" ) , "explainError" , code ) ;
}
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 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&method=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 ( "removeFeedIcon" , 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&method=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=feeds&method=quickAddFeed" ;
// overlapping widgets
if ( dijit . byId ( "batchSubDlg" ) ) dijit . byId ( "batchSubDlg" ) . destroyRecursive ( ) ;
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 ;
Element . show ( "feed_add_spinner" ) ;
new Ajax . Request ( "backend.php" , {
parameters : dojo . objectToQuery ( this . attr ( 'value' ) ) ,
onComplete : function ( transport ) {
try {
try {
var reply = JSON . parse ( transport . responseText ) ;
} catch ( e ) {
Element . hide ( "feed_add_spinner" ) ;
alert ( _ _ ( "Failed to parse output. This can indicate server timeout and/or network issues. Backend output was logged to browser console." ) ) ;
console . log ( 'quickAddFeed, backend returned:' + transport . responseText ) ;
return ;
}
var rc = reply [ 'result' ] ;
notify ( '' ) ;
Element . hide ( "feed_add_spinner" ) ;
console . log ( rc ) ;
switch ( parseInt ( rc [ 'code' ] ) ) {
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 :
feeds = rc [ 'feeds' ] ;
Element . show ( "fadd_multiple_notify" ) ;
var select = dijit . byId ( "feedDlg_feedContainerSelect" ) ;
while ( select . getOptions ( ) . length > 0 )
select . removeOption ( 0 ) ;
select . addOption ( { value : '' , label : _ _ ( "Expand to select feed" ) } ) ;
var count = 0 ;
for ( var feedUrl in feeds ) {
select . addOption ( { value : feedUrl , label : feeds [ feedUrl ] } ) ;
count ++ ;
}
Effect . Appear ( 'feedDlg_feedsContainer' , { duration : 0.5 } ) ;
break ;
case 5 :
alert ( _ _ ( "Couldn't download the specified URL: %s" ) .
replace ( "%s" , rc [ 'message' ] ) ) ;
break ;
case 6 :
alert ( _ _ ( "XML validation failed: %s" ) .
replace ( "%s" , rc [ 'message' ] ) ) ;
break ;
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 createNewRuleElement ( parentNode , replaceNode ) {
try {
var form = document . forms [ "filter_new_rule_form" ] ;
form . reg _exp . value = form . reg _exp . value . replace ( /(<([^>]+)>)/ig , "" ) ;
var query = "backend.php?op=pref-filters&method=printrulename&rule=" +
param _escape ( dojo . formToJson ( form ) ) ;
console . log ( query ) ;
new Ajax . Request ( "backend.php" , {
parameters : query ,
onComplete : function ( transport ) {
try {
var li = dojo . create ( "li" ) ;
var cb = dojo . create ( "input" , { type : "checkbox" } , li ) ;
new dijit . form . CheckBox ( {
onChange : function ( ) {
toggleSelectListRow2 ( this ) } ,
} , cb ) ;
dojo . create ( "input" , { type : "hidden" ,
name : "rule[]" ,
value : dojo . formToJson ( form ) } , li ) ;
dojo . create ( "span" , {
onclick : function ( ) {
dijit . byId ( 'filterEditDlg' ) . editRule ( this ) ;
} ,
innerHTML : transport . responseText } , li ) ;
if ( replaceNode ) {
parentNode . replaceChild ( li , replaceNode ) ;
} else {
parentNode . appendChild ( li ) ;
}
} catch ( e ) {
exception _error ( "createNewRuleElement" , e ) ;
}
} } ) ;
} catch ( e ) {
exception _error ( "createNewRuleElement" , e ) ;
}
}
function createNewActionElement ( parentNode , replaceNode ) {
try {
var form = document . forms [ "filter_new_action_form" ] ;
if ( form . action _id . value == 7 ) {
form . action _param . value = form . action _param _label . value ;
} else if ( form . action _id . value == 9 ) {
form . action _param . value = form . action _param _plugin . value ;
}
var query = "backend.php?op=pref-filters&method=printactionname&action=" +
param _escape ( dojo . formToJson ( form ) ) ;
console . log ( query ) ;
new Ajax . Request ( "backend.php" , {
parameters : query ,
onComplete : function ( transport ) {
try {
var li = dojo . create ( "li" ) ;
var cb = dojo . create ( "input" , { type : "checkbox" } , li ) ;
new dijit . form . CheckBox ( {
onChange : function ( ) {
toggleSelectListRow2 ( this ) } ,
} , cb ) ;
dojo . create ( "input" , { type : "hidden" ,
name : "action[]" ,
value : dojo . formToJson ( form ) } , li ) ;
dojo . create ( "span" , {
onclick : function ( ) {
dijit . byId ( 'filterEditDlg' ) . editAction ( this ) ;
} ,
innerHTML : transport . responseText } , li ) ;
if ( replaceNode ) {
parentNode . replaceChild ( li , replaceNode ) ;
} else {
parentNode . appendChild ( li ) ;
}
} catch ( e ) {
exception _error ( "createNewActionElement" , e ) ;
}
} } ) ;
} catch ( e ) {
exception _error ( "createNewActionElement" , e ) ;
}
}
function addFilterRule ( replaceNode , ruleStr ) {
try {
if ( dijit . byId ( "filterNewRuleDlg" ) )
dijit . byId ( "filterNewRuleDlg" ) . destroyRecursive ( ) ;
var query = "backend.php?op=pref-filters&method=newrule&rule=" +
param _escape ( ruleStr ) ;
var rule _dlg = new dijit . Dialog ( {
id : "filterNewRuleDlg" ,
title : ruleStr ? _ _ ( "Edit rule" ) : _ _ ( "Add rule" ) ,
style : "width: 600px" ,
execute : function ( ) {
if ( this . validate ( ) ) {
createNewRuleElement ( $ ( "filterDlg_Matches" ) , replaceNode ) ;
this . hide ( ) ;
}
} ,
href : query } ) ;
rule _dlg . show ( ) ;
} catch ( e ) {
exception _error ( "addFilterRule" , e ) ;
}
}
function addFilterAction ( replaceNode , actionStr ) {
try {
if ( dijit . byId ( "filterNewActionDlg" ) )
dijit . byId ( "filterNewActionDlg" ) . destroyRecursive ( ) ;
var query = "backend.php?op=pref-filters&method=newaction&action=" +
param _escape ( actionStr ) ;
var rule _dlg = new dijit . Dialog ( {
id : "filterNewActionDlg" ,
title : actionStr ? _ _ ( "Edit action" ) : _ _ ( "Add action" ) ,
style : "width: 600px" ,
execute : function ( ) {
if ( this . validate ( ) ) {
createNewActionElement ( $ ( "filterDlg_Actions" ) , replaceNode ) ;
this . hide ( ) ;
}
} ,
href : query } ) ;
rule _dlg . show ( ) ;
} catch ( e ) {
exception _error ( "addFilterAction" , e ) ;
}
}
function editFilterTest ( query ) {
try {
if ( dijit . byId ( "filterTestDlg" ) )
dijit . byId ( "filterTestDlg" ) . destroyRecursive ( ) ;
var test _dlg = new dijit . Dialog ( {
id : "filterTestDlg" ,
title : "Test Filter" ,
style : "width: 600px" ,
results : 0 ,
limit : 100 ,
max _offset : 10000 ,
getTestResults : function ( query , offset ) {
var updquery = query + "&offset=" + offset + "&limit=" + test _dlg . limit ;
console . log ( "getTestResults:" + offset ) ;
new Ajax . Request ( "backend.php" , {
parameters : updquery ,
onComplete : function ( transport ) {
try {
var result = JSON . parse ( transport . responseText ) ;
if ( result && dijit . byId ( "filterTestDlg" ) && dijit . byId ( "filterTestDlg" ) . open ) {
test _dlg . results += result . size ( ) ;
console . log ( "got results:" + result . size ( ) ) ;
$ ( "prefFilterProgressMsg" ) . innerHTML = _ _ ( "Looking for articles (%d processed, %f found)..." )
. replace ( "%f" , test _dlg . results )
. replace ( "%d" , offset ) ;
console . log ( offset + " " + test _dlg . max _offset ) ;
for ( var i = 0 ; i < result . size ( ) ; i ++ ) {
var tmp = new Element ( "table" ) ;
tmp . innerHTML = result [ i ] ;
dojo . parser . parse ( tmp ) ;
$ ( "prefFilterTestResultList" ) . innerHTML += tmp . innerHTML ;
}
if ( test _dlg . results < 30 && offset < test _dlg . max _offset ) {
// get the next batch
window . setTimeout ( function ( ) {
test _dlg . getTestResults ( query , offset + test _dlg . limit ) ;
} , 0 ) ;
} else {
// all done
Element . hide ( "prefFilterLoadingIndicator" ) ;
if ( test _dlg . results == 0 ) {
$ ( "prefFilterTestResultList" ) . innerHTML = "<tr><td align='center'>No recent articles matching this filter have been found.</td></tr>" ;
$ ( "prefFilterProgressMsg" ) . innerHTML = "Articles matching this filter:" ;
} else {
$ ( "prefFilterProgressMsg" ) . innerHTML = _ _ ( "Found %d articles matching this filter:" )
. replace ( "%d" , test _dlg . results ) ;
}
}
} else if ( ! result ) {
console . log ( "getTestResults: can't parse results object" ) ;
Element . hide ( "prefFilterLoadingIndicator" ) ;
notify _error ( "Error while trying to get filter test results." ) ;
} else {
console . log ( "getTestResults: dialog closed, bailing out." ) ;
}
} catch ( e ) {
exception _error ( "editFilterTest/inner" , e ) ;
}
} } ) ;
} ,
href : query } ) ;
dojo . connect ( test _dlg , "onLoad" , null , function ( e ) {
test _dlg . getTestResults ( query , 0 ) ;
} ) ;
test _dlg . show ( ) ;
} catch ( e ) {
exception _error ( "editFilterTest" , e ) ;
}
}
function quickAddFilter ( ) {
try {
var query = "" ;
if ( ! inPreferences ( ) ) {
query = "backend.php?op=pref-filters&method=newfilter&feed=" +
param _escape ( getActiveFeedId ( ) ) + "&is_cat=" +
param _escape ( activeFeedIsCat ( ) ) ;
} else {
query = "backend.php?op=pref-filters&method=newfilter" ;
}
console . log ( query ) ;
if ( dijit . byId ( "feedEditDlg" ) )
dijit . byId ( "feedEditDlg" ) . destroyRecursive ( ) ;
if ( dijit . byId ( "filterEditDlg" ) )
dijit . byId ( "filterEditDlg" ) . destroyRecursive ( ) ;
dialog = new dijit . Dialog ( {
id : "filterEditDlg" ,
title : _ _ ( "Create Filter" ) ,
style : "width: 600px" ,
test : function ( ) {
var query = "backend.php?" + dojo . formToQuery ( "filter_new_form" ) + "&savemode=test" ;
editFilterTest ( query ) ;
} ,
selectRules : function ( select ) {
$$ ( "#filterDlg_Matches input[type=checkbox]" ) . each ( function ( e ) {
e . checked = select ;
if ( select )
e . parentNode . addClassName ( "Selected" ) ;
else
e . parentNode . removeClassName ( "Selected" ) ;
} ) ;
} ,
selectActions : function ( select ) {
$$ ( "#filterDlg_Actions input[type=checkbox]" ) . each ( function ( e ) {
e . checked = select ;
if ( select )
e . parentNode . addClassName ( "Selected" ) ;
else
e . parentNode . removeClassName ( "Selected" ) ;
} ) ;
} ,
editRule : function ( e ) {
var li = e . parentNode ;
var rule = li . getElementsByTagName ( "INPUT" ) [ 1 ] . value ;
addFilterRule ( li , rule ) ;
} ,
editAction : function ( e ) {
var li = e . parentNode ;
var action = li . getElementsByTagName ( "INPUT" ) [ 1 ] . value ;
addFilterAction ( li , action ) ;
} ,
addAction : function ( ) { addFilterAction ( ) ; } ,
addRule : function ( ) { addFilterRule ( ) ; } ,
deleteAction : function ( ) {
$$ ( "#filterDlg_Actions li.[class*=Selected]" ) . each ( function ( e ) { e . parentNode . removeChild ( e ) } ) ;
} ,
deleteRule : function ( ) {
$$ ( "#filterDlg_Matches li.[class*=Selected]" ) . each ( function ( e ) { e . parentNode . removeChild ( e ) } ) ;
} ,
execute : function ( ) {
if ( this . validate ( ) ) {
var query = dojo . formToQuery ( "filter_new_form" ) ;
console . log ( query ) ;
new Ajax . Request ( "backend.php" , {
parameters : query ,
onComplete : function ( transport ) {
if ( inPreferences ( ) ) {
updateFilterList ( ) ;
}
dialog . hide ( ) ;
} } ) ;
}
} ,
href : query } ) ;
if ( ! inPreferences ( ) ) {
var selectedText = getSelectionText ( ) ;
var lh = dojo . connect ( dialog , "onLoad" , function ( ) {
dojo . disconnect ( lh ) ;
if ( selectedText != "" ) {
var feed _id = activeFeedIsCat ( ) ? 'CAT:' + parseInt ( getActiveFeedId ( ) ) :
getActiveFeedId ( ) ;
var rule = { reg _exp : selectedText , feed _id : feed _id , filter _type : 1 } ;
addFilterRule ( null , dojo . toJson ( rule ) ) ;
} else {
var query = "op=rpc&method=getlinktitlebyid&id=" + getActiveArticleId ( ) ;
new Ajax . Request ( "backend.php" , {
parameters : query ,
onComplete : function ( transport ) {
var reply = JSON . parse ( transport . responseText ) ;
var title = false ;
if ( reply && reply ) title = reply . title ;
if ( title || getActiveFeedId ( ) || activeFeedIsCat ( ) ) {
console . log ( title + " " + getActiveFeedId ( ) ) ;
var feed _id = activeFeedIsCat ( ) ? 'CAT:' + parseInt ( getActiveFeedId ( ) ) :
getActiveFeedId ( ) ;
var rule = { reg _exp : title , feed _id : feed _id , filter _type : 1 } ;
addFilterRule ( null , dojo . toJson ( rule ) ) ;
}
} } ) ;
}
} ) ;
}
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&method=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&method=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({feed:-5})" , 100 ) ;
if ( feed _id < 0 ) updateFeedList ( ) ;
}
} } ) ;
}
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...' ) ;
for ( k in params ) {
console . log ( "IP: " + k + " => " + JSON . stringify ( params [ k ] ) ) ;
if ( k == "label_base_index" ) _label _base _index = parseInt ( params [ k ] ) ;
}
init _params = params ;
// PluginHost might not be available on non-index pages
window . PluginHost && PluginHost . run ( PluginHost . HOOK _PARAMS _LOADED , init _params ) ;
}
sanity _check _done = true ;
init _second _stage ( ) ;
} catch ( e ) {
exception _error ( "backend_sanity_check_callback" , e , transport ) ;
}
}
/ * f u n c t i o n h a s _ l o c a l _ s t o r a g e ( ) {
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&method=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=pref-feeds&method=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 ;
var dcb = 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 ;
dcb = dijit . getEnclosingWidget ( cb ) ;
break ;
}
}
if ( cb || dcb ) {
var issel = row . hasClassName ( "Selected" ) ;
if ( mode == "all" && ! issel ) {
row . addClassName ( "Selected" ) ;
cb . checked = true ;
if ( dcb ) dcb . set ( "checked" , true ) ;
} else if ( mode == "none" && issel ) {
row . removeClassName ( "Selected" ) ;
cb . checked = false ;
if ( dcb ) dcb . set ( "checked" , false ) ;
} else if ( mode == "invert" ) {
if ( issel ) {
row . removeClassName ( "Selected" ) ;
cb . checked = false ;
if ( dcb ) dcb . set ( "checked" , false ) ;
} else {
row . addClassName ( "Selected" ) ;
cb . checked = true ;
if ( dcb ) dcb . set ( "checked" , true ) ;
}
}
}
}
}
} catch ( e ) {
exception _error ( "selectTableRows" , e ) ;
}
}
function getSelectedTableRowIds ( id ) {
var rows = [ ] ;
try {
var elem _rows = $ ( id ) . rows ;
for ( var 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&method=editfeed&id=" +
param _escape ( feed ) ;
console . log ( query ) ;
if ( dijit . byId ( "filterEditDlg" ) )
dijit . byId ( "filterEditDlg" ) . destroyRecursive ( ) ;
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=feeds&method=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&method=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 . getSelectedFeedIds ( ) ;
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&method=remarchive&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=pref-feeds&method=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&method=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 ) ;
}
}
/* new support functions for SelectByTag */
function get _all _tags ( selObj ) {
try {
if ( ! selObj ) return "" ;
var result = "" ;
var len = selObj . options . length ;
for ( var i = 0 ; i < len ; i ++ ) {
if ( selObj . options [ i ] . selected ) {
result += selObj [ i ] . value + "%2C" ; // is really a comma
}
}
if ( result . length > 0 ) {
result = result . substr ( 0 , result . length - 3 ) ; // remove trailing %2C
}
return ( result ) ;
} catch ( e ) {
exception _error ( "get_all_tags" , e ) ;
}
}
function get _radio _checked ( radioObj ) {
try {
if ( ! radioObj ) return "" ;
var len = radioObj . length ;
if ( len == undefined ) {
if ( radioObj . checked ) {
return ( radioObj . value ) ;
} else {
return ( "" ) ;
}
}
for ( var i = 0 ; i < len ; i ++ ) {
if ( radioObj [ i ] . checked ) {
return ( radioObj [ i ] . value ) ;
}
}
} catch ( e ) {
exception _error ( "get_radio_checked" , e ) ;
}
return ( "" ) ;
}
function get _timestamp ( ) {
var date = new Date ( ) ;
return Math . round ( date . getTime ( ) / 1000 ) ;
}
function helpDialog ( topic ) {
try {
var query = "backend.php?op=backend&method=help&topic=" + param _escape ( topic ) ;
if ( dijit . byId ( "helpDlg" ) )
dijit . byId ( "helpDlg" ) . destroyRecursive ( ) ;
dialog = new dijit . Dialog ( {
id : "helpDlg" ,
title : _ _ ( "Help" ) ,
style : "width: 600px" ,
href : query ,
} ) ;
dialog . show ( ) ;
} catch ( e ) {
exception _error ( "helpDialog" , e ) ;
}
}
function htmlspecialchars _decode ( string , quote _style ) {
// http://kevin.vanzonneveld.net
// + original by: Mirek Slugen
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + bugfixed by: Mateusz "loonquawl" Zalega
// + input by: ReverseSyntax
// + input by: Slawomir Kaniecki
// + input by: Scott Cariss
// + input by: Francois
// + bugfixed by: Onno Marsman
// + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + bugfixed by: Brett Zamir (http://brett-zamir.me)
// + input by: Ratheous
// + input by: Mailfaker (http://www.weedem.fr/)
// + reimplemented by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Brett Zamir (http://brett-zamir.me)
// * example 1: htmlspecialchars_decode("<p>this -> "</p>", 'ENT_NOQUOTES');
// * returns 1: '<p>this -> "</p>'
// * example 2: htmlspecialchars_decode("&quot;");
// * returns 2: '"'
var optTemp = 0 ,
i = 0 ,
noquotes = false ;
if ( typeof quote _style === 'undefined' ) {
quote _style = 2 ;
}
string = string . toString ( ) . replace ( /</g , '<' ) . replace ( />/g , '>' ) ;
var OPTS = {
'ENT_NOQUOTES' : 0 ,
'ENT_HTML_QUOTE_SINGLE' : 1 ,
'ENT_HTML_QUOTE_DOUBLE' : 2 ,
'ENT_COMPAT' : 2 ,
'ENT_QUOTES' : 3 ,
'ENT_IGNORE' : 4
} ;
if ( quote _style === 0 ) {
noquotes = true ;
}
if ( typeof quote _style !== 'number' ) { // Allow for a single string or an array of string flags
quote _style = [ ] . concat ( quote _style ) ;
for ( i = 0 ; i < quote _style . length ; i ++ ) {
// Resolve string input to bitwise e.g. 'PATHINFO_EXTENSION' becomes 4
if ( OPTS [ quote _style [ i ] ] === 0 ) {
noquotes = true ;
} else if ( OPTS [ quote _style [ i ] ] ) {
optTemp = optTemp | OPTS [ quote _style [ i ] ] ;
}
}
quote _style = optTemp ;
}
if ( quote _style & OPTS . ENT _HTML _QUOTE _SINGLE ) {
string = string . replace ( /�*39;/g , "'" ) ; // PHP doesn't currently escape if more than one 0, but it should
// string = string.replace(/'|�*27;/g, "'"); // This would also be useful here, but not a part of PHP
}
if ( ! noquotes ) {
string = string . replace ( /"/g , '"' ) ;
}
// Put this in last place to avoid escape being double-decoded
string = string . replace ( /&/g , '&' ) ;
return string ;
}
function label _to _feed _id ( label ) {
return _label _base _index - 1 - Math . abs ( label ) ;
}
function feed _to _label _id ( feed ) {
return _label _base _index - 1 + Math . abs ( feed ) ;
}
// http://stackoverflow.com/questions/6251937/how-to-get-selecteduser-highlighted-text-in-contenteditable-element-and-replac
function getSelectionText ( ) {
var text = "" ;
if ( typeof window . getSelection != "undefined" ) {
var sel = window . getSelection ( ) ;
if ( sel . rangeCount ) {
var container = document . createElement ( "div" ) ;
for ( var i = 0 , len = sel . rangeCount ; i < len ; ++ i ) {
container . appendChild ( sel . getRangeAt ( i ) . cloneContents ( ) ) ;
}
text = container . innerHTML ;
}
} else if ( typeof document . selection != "undefined" ) {
if ( document . selection . type == "Text" ) {
text = document . selection . createRange ( ) . textText ;
}
}
return text . stripTags ( ) ;
}
function openArticlePopup ( id ) {
window . open ( "backend.php?op=article&method=view&mode=raw&html=1&zoom=1&id=" + id +
"&csrf_token=" + getInitParam ( "csrf_token" ) ,
"ttrss_article_popup" ,
"height=900,width=900,resizable=yes,status=no,location=no,menubar=no,directories=no,scrollbars=yes,toolbar=no" ) ;
}