/* ------------------------------------------ RSS Replay v 1.6.3 build 070 Coded by Ronald Northrip Jan-Mar 2009 All code here is Copyright Protected. Use or distribution without permission is strictly prohibited. Copyright 2006. All Rights Reserved. Ronald Northrip Software Incorporated http://www.rnsoft.com/ ------------------------------------------ */ // Global Settings -------------------------- // rssReplayFeed ---------------------------- // the function creates new feeds ----------- function rssReplayFeed(){ // params - id, dSM, dP, dH, dHC, dS, dSC, dSx, sources, [xC, xCTTL, suprs, sorter] // 0 1 2 3 4 5 6 7 8 9 10 11 12 var i=0 var args=rssReplayFeed.arguments var feed=new rssReplay() //if (args.length<9) { document.write(feed.localStringReplayFeedParamError); return; } if ((args.length<9) && (args[0]!="") && (document.getElementById(args[0]))) { document.getElementById(args[0]).innerHTML=feed.localStringReplayFeedParamError; return; } //proxy feed.proxyHref="" var loc=document.location.href loc=loc.toLowerCase() if ((document) && (document.getElementsByTagName) && (loc.substring(0,5)!="file:")) { var links=document.getElementsByTagName("link") if ((links) && (links.length>0)) { var exp="^(rssReplayProxy|.*/rssReplayProxy)\\.....?(?:\\?format=js)?$" var re=new RegExp(exp) for (i=0; i9) { feed.proxyCache=args[9] } if (args.length>10) { feed.proxyCacheTTL=args[10] } if (args.length>11) { feed.supressErrors=args[11] } //sorter + default if (args.length>12) { feed.sorter=args[12] } //identity feed.id=args[0] //settings feed.displayStoriesMax=args[1] feed.displayPrefix=args[2] feed.displayHeadline=args[3] feed.displayHeadlineClass=args[4] feed.displayStory=args[5] feed.displayStoryClass=args[6] feed.displaySuffix=args[7] //sources if (typeof(args[8])=="string") { feed.addSource(args[8]) } else { var list=args[8] for (i=0; i]+)/ exp="<\\/?([^\\s='\"<>]+)" rexJustTag=new RegExp(exp) //rexJustAttributes=/(?:\s+|(?:([^\s='"<>]+)\s*=\s*([^\s='"<>]+))|(?:([^\s='"<>]+)\s*=\s*"([^"]*)")|(?:([^\s='"<>]+)\s*=\s*'([^']*)')|(?:[^\s='"<>]+))/ exp="(?:\\s+|(?:([^\\s='\"<>]+)\\s*=\\s*([^\\s'\"<>]+))|(?:([^\\s='\"<>]+)\\s*=\\s*\"([^\"]*)\")|(?:([^\\s='\"<>]+)\\s*=\\s*'([^']*)')|(?:[^\\s='\"<>]+))" rexJustAttributes=new RegExp(exp) //rexJustSpaces=/^\s+$/ exp="^\\s+$" rexJustSpaces=new RegExp(exp) //rexProtocol=/^\w+:\/\// exp="^\\w+:\\/\\/" rexProtocol=new RegExp(exp) //rexCommentSimpleG=//g exp="" rexCommentSimpleG=new RegExp(exp,"g") //rexCommentLongG=//g exp="" rexCommentLongG=new RegExp(exp,"g") //rexXMLCommandG=/<\?[\s\S]*?>/g exp="<\\?[\\s\\S]*?>" rexXMLCommandG=new RegExp(exp,"g") //rexXMLDocTypeSBG=//gi exp="" rexXMLDocTypeSBG=new RegExp(exp,"gi") //rexXMLDocTypeG=//gi exp="" rexXMLDocTypeG=new RegExp(exp,"gi") //rexTagG=/<[^\s='"<>!]+(?:\s+|(?:[^\s='"<>]+\s*=\s*[^\s='"<>]+)|(?:[^\s='"<>]+\s*=\s*"[^"]*")|(?:[^\s='"<>]+\s*=\s*'[^']*')|(?:[^\s='"<>]+))*?>/g exp="<[^\\s='\"<>!]+(?:\\s+|(?:[^\\s='\"<>]+\\s*=\\s*[^\\s'\"<>]+)|(?:[^\\s='\"<>]+\\s*=\\s*\"[^\"]*\")|(?:[^\\s='\"<>]+\\s*=\\s*'[^']*')|(?:[^\\s='\"<>]+))*?>" rexTagG=new RegExp(exp,"g") //rexScriptTagContentsG=/]+\s*=\s*[^\s='"<>]+)|(?:[^\s='"<>]+\s*=\s*"[^"]*")|(?:[^\s='"<>]+\s*=\s*'[^']*')|(?:[^\s='"<>]+))*?>[\s\S]*?<\/script>/gi exp="]+\\s*=\\s*[^\\s'\"<>]+)|(?:[^\\s='\"<>]+\\s*=\\s*\"[^\"]*\")|(?:[^\\s='\"<>]+\\s*=\\s*'[^']*')|(?:[^\\s='\"<>]+))*?>[\\s\\S]*?<\\/script>" rexScriptTagContentsG=new RegExp(exp,"gi") //rexStyleTagContentsG=/]+\s*=\s*[^\s='"<>]+)|(?:[^\s='"<>]+\s*=\s*"[^"]*")|(?:[^\s='"<>]+\s*=\s*'[^']*')|(?:[^\s='"<>]+))*?>[\s\S]*?<\/script>/gi exp="]+\\s*=\\s*[^\\s'\"<>]+)|(?:[^\\s='\"<>]+\\s*=\\s*\"[^\"]*\")|(?:[^\\s='\"<>]+\\s*=\\s*'[^']*')|(?:[^\\s='\"<>]+))*?>[\\s\\S]*?<\\/script>" rexStyleTagContentsG=new RegExp(exp,"gi") //rexCDataOrTag=/|<[^\s='"<>!]+(?:\s+|(?:[^\s='"<>]+\s*=\s*[^\s='"<>]+)|(?:[^\s='"<>]+\s*=\s*"[^"]*")|(?:[^\s='"<>]+\s*=\s*'[^']*')|(?:[^\s='"<>]+))*?>/ exp="|<[^\\s='\"<>!]+(?:\\s+|(?:[^\\s='\"<>]+\\s*=\\s*[^\\s'\"<>]+)|(?:[^\\s='\"<>]+\\s*=\\s*\"[^\"]*\")|(?:[^\\s='\"<>]+\\s*=\\s*'[^']*')|(?:[^\\s='\"<>]+))*?>" rexCDataOrTag=new RegExp(exp) return true } //strip tags function function rrpStripTags(text) { var out=text out=out.replace(rexXMLCommandG,"") out=out.replace(rexXMLDocTypeSBG,"") out=out.replace(rexXMLDocTypeG,"") out=out.replace(rexScriptTagContentsG,"") out=out.replace(rexStyleTagContentsG,"") out=out.replace(rexCommentSimpleG,"") out=out.replace(rexCommentLongG,"") out=out.replace(rexTagG,"") out=out.replace(/(\s)+/g,"$1") return out } // html entities function rrpReverseCharCodes(text) { var out=text var p=out.indexOf('&#'); while (p>-1) { var ps=out.indexOf(';',p+1); if (ps==-1) { return out; } else { var x=out.substring(p+2,p+3) //xml ꪪ if (x=="x") { var code=out.substring(p+3,ps) code=parseInt(code,16) } else { var code=out.substring(p+2,ps) } var newchar=String.fromCharCode(code) var out=out.substring(0,p)+newchar+out.substring(ps+1,out.length) } p=out.indexOf('&#',p+1); } return out; } function rrpHtmlEntities(text) { var out=text //var enc=getDreamweaverTextEncoding() out=out.replace(/&/g,"&"+"amp;") out=out.replace(//g,"&"+"gt;") out=out.replace(/"/g,"&"+"quot;") out=out.replace(/'/g,"&"+"apos;") var comp=out out="" for (var i = 0; i < comp.length; i++ ) { var ch = comp.charAt(i); var charCode = ch.charCodeAt(0); //if ((charCode > 255) && (htmlEntitiesUseLargeNums)) { // out+="&#"+charCode+";" //} else if (charCode > 255) { // out+=ch //} else if (charCode > 255) { out+=ch } else if (charCode > 127) { out+="&#"+charCode+";" } else { out+=ch } } return out } function rrpHtmlDecode(text) { var out=text out=rrpReverseCharCodes(out) out=out.replace(/</g,"<") out=out.replace(/>/g,">") out=out.replace(/"/g,'"') out=out.replace(/'/g,"'") out=out.replace(/&/g,"&") return out } // RSSReplay Object Creation -------------------------- function rssReplay() { //localizable string this.localStringLoading="RSS feeds are loading" this.localStringNoDisplaySettings="RSS Replay has No Display Settings" this.localStringLoadError="An error occured when getting feed" this.localString404FileError="The file is not on the server" this.localString404ProxyError="The proxy is not on the server" this.localStringBrowserError="RSS Replay does not work in this web browser" this.localStringNoStoriesError="There are no stories to display" this.localStringEmptyFeedError="The feed was empty" this.localStringUnrecognizedFormatError="Unrecognized format for feed" this.localStringNotParsedError="The feed could not be not parsed as XML" this.localStringReplayFeedParamError="Parameters Error in rssReplayFeed" this.localStringMadeWithReplay="Made with RSS Replay" this.localStringProxyErrorPrefix="RSS Replay Proxy Error:" //initial properties and method assignment this.isIE = false this.supressErrors=false this.id="rssReplayDefaultID" this.errorFlag="RRPERROR:" this.proxyHref="" this.sorter="d-date" //can also be set in the PHP/ASP file this.proxyCache=true this.proxyCacheTTL=-1 this.sources=Array() this.sourcePages=Array() this.sourceXMLs=Array() this.sourcesLoading=Array() this.sourceRequests=Array() this.displayPrefix="" this.displayHeadline="" this.displayHeadlineClass="" this.displayStory="" this.displayStoryClass="" this.displaySuffix="" this.displayStoriesMax=0 this.loadingString=rssReplay_loadingString this.display=rssReplay_display this.displayDate=rssReplay_displayDate this.displayStripTags=rssReplay_displayStripTags this.displayTrimText=rssReplay_displayTrimText this.displayClassDotCheck=rssReplay_displayClassDotCheck this.sortByDate=rssReplay_sortByDate this.sortReverseByDate=rssReplay_sortReverseByDate this.displayParse=rssReplay_displayParse this.displayPrefixSuffixParse=rssReplay_displayPrefixSuffixParse this.displayPostLoad=rssReplay_displayPostLoad this.countSourcesLoading=rssReplay_countSourcesLoading this.addSource=rssReplay_addSource this.loadXMLDoc=rssReplay_loadXMLDoc this.processReqChange=rssReplay_processReqChange this.stories=Array() this.parse=rssReplay_parse this.parserGetDate=rssReplay_parserGetDate this.parserPrepText=rssReplay_parserPrepText this.startupRegExpError=!rrpSetupRegExp() } // Object Methods --------------------------- function rssReplay_loadingString() { //localize this return this.localStringLoading+" ("+this.countSourcesLoading()+")" } function rssReplay_displayDate(theFormat, theDate) { var daylist=Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday") var monthlist=Array("January","February","March","April","May","June","July","August","September","October","November","December") var intext=theFormat var out="" //c = ISO-8601 format = 2004-02-12T15:19:21+00:00 intext=intext.replace(/c/,"Y-m-dTH:i:sP") //r = RFC-2822 format = Thu, 21 Dec 2006 16:01:07 +0200 intext=intext.replace(/r/,"D, j M Y H:i:s O") var re=/[dDjlNSwFmMnYyaAgGhHisOPZU]/ if (!re.test(intext)) { return intext } var ro=re.exec(intext) while (ro) { var temp="" var temp2="" out+=intext.substring(0,ro.index) //control formatting switch(ro[0]) { //day formatting case "d": //day of month, 2 digits with leading 0 - 01 to 31 temp="00"+theDate.getDate() out+=temp.substring(temp.length-2, temp.length) break case "D": //short textual representation of day, 3 letters temp=daylist[theDate.getDay()] out+=temp.substring(0,3) break case "j": //day of month, no leading 0 - 1 to 31 out+=theDate.getDate() break case "l": //full textual representation of day out+=daylist[theDate.getDay()] break case "N": //ISO-8601 num rep of day of week - 1(Mon) to 7(Sun) temp=theDate.getDay() if (temp==0) {temp=7} out+=temp break case "S": //ordinal suffix for day of month 2 chars - 1(st),2(nd),3(rd),4(th) temp="00"+theDate.getDate() temp=temp.substring(temp.length-1,temp.length) if ((theDate.getDate()>=11) && (theDate.getDate()<=13)) {temp="th"} //11th 12th 13th switch(temp) { case "1": temp="st" break case "2": temp="nd" break case "3": temp="rd" break default: temp="th" } out+=temp break case "w": //num rep of day of week - 0(Sun) to 6(Sat) out+=theDate.getDay() break //month formatting case "F": //full textual representation of month out+=monthlist[theDate.getMonth()] break case "m": //numeric representation of month, leading 0 temp="00"+(1+theDate.getMonth()) out+=temp.substring(temp.length-2, temp.length) break case "M": //short textual representation of month, 3 letters temp=monthlist[theDate.getMonth()] out+=temp.substring(0,3) break case "n": //numeric representation of month, no leading 0 out+=(1+theDate.getMonth()) break //year formatting case "Y": //4 digit representation of year out+=theDate.getFullYear() break case "y": //2 digit representation of year temp="00"+theDate.getFullYear() out+=temp.substring(4,6) break //time formatting case "a": //am or pm temp=theDate.getHours() if (temp>=12) {temp="pm"} else {temp="am"} out+=temp break case "A": //AM or PM temp=theDate.getHours() if (temp>=12) {temp="PM"} else {temp="AM"} out+=temp break case "g": //12 hour format of hour no leading 0 - 1 to 12 temp=theDate.getHours() if (temp>12) {temp=temp-12} if (temp==0) {temp="12"} out+=temp break case "G": //24 hour format of hour with no leading 0 - 0 to 23 out+=theDate.getHours() break case "h": //12 hour format of hour with leading 0 - 01 to 12 temp=theDate.getHours() if (temp>12) {temp=temp-12} if (temp==0) {temp="12"} temp="00"+temp out+=temp.substring(temp.length-2, temp.length) break case "H": //24 hour format of hour with leading 0 - 00 to 23 temp=theDate.getHours() temp="00"+temp out+=temp.substring(temp.length-2, temp.length) break case "i": //minutes leading 0 - 00 to 59 temp=theDate.getMinutes() temp="00"+temp out+=temp.substring(temp.length-2, temp.length) break case "s": //seconds leading 0 - 00 to 59 temp=theDate.getSeconds() temp="00"+temp out+=temp.substring(temp.length-2, temp.length) break case "U": //seconds since epoch temp=Date.UTC(theDate.getUTCFullYear(),theDate.getUTCMonth(),theDate.getUTCDate(),theDate.getUTCHours(),theDate.getUTCMinutes(),theDate.getUTCSeconds(),theDate.getUTCMilliseconds()) //careful - this is milliseconds - convert to seconds temp=Math.floor(temp/1000) out+=temp break //timezone formatting case "O": //GMT time zone offset presented as +0200 temp=theDate.getTimezoneOffset() if (temp<0) {out+="-";temp=temp*-1;} else {out+="+"} temp2="00"+Math.floor(temp/60) out+=temp2.substring(temp2.length-2,temp2.length) temp2="00"+(temp%60) out+=temp2.substring(temp2.length-2,temp2.length) break case "P": //GMT time zone offset presented as +02:00 temp=theDate.getTimezoneOffset() if (temp<0) {out+="-";temp=temp*-1;} else {out+="+"} temp2="00"+Math.floor(temp/60) out+=temp2.substring(temp2.length-2,temp2.length) out+=":" temp2="00"+(temp%60) out+=temp2.substring(temp2.length-2,temp2.length) break case "Z": //GMT time zone offset in seconds (mintues+00) temp=theDate.getTimezoneOffset()+"00" out+=temp break } intext=intext.substring(ro.index+ro[0].length,intext.length) ro=re.exec(intext) if ((!ro) && (intext!="")) { out+=intext } } return out } function rssReplay_displayStripTags(text) { //commented out the things that shouldn't be in the content //rexXMLCommandG=/<\?[\s\S]*?>/g //rexXMLDocTypeSBG=//gi //rexXMLDocTypeG=//gi //var rexScriptTagContentsG=/]+\s*=\s*[^\s='"<>]+)|(?:[^\s='"<>]+\s*=\s*"[^"]*")|(?:[^\s='"<>]+\s*=\s*'[^']*')|(?:[^\s='"<>]+))*?>[\s\S]*?<\/script>/gi //var rexCommentSimpleG=//g //var rexCommentLongG=//g //var rexTagG=/<[^\s='"<>]+(?:\s+|(?:[^\s='"<>]+\s*=\s*[^\s='"<>]+)|(?:[^\s='"<>]+\s*=\s*"[^"]*")|(?:[^\s='"<>]+\s*=\s*'[^']*')|(?:[^\s='"<>]+))*?>/g var out=text out=out.replace(rexXMLCommandG,"") out=out.replace(rexXMLDocTypeSBG,"") out=out.replace(rexXMLDocTypeG,"") out=out.replace(rexScriptTagContentsG,"") out=out.replace(rexStyleTagContentsG,"") out=out.replace(rexCommentSimpleG,"") out=out.replace(rexCommentLongG,"") out=out.replace(rexTagG,"") out=out.replace(/(\s)+/g,"$1") return out } function rssReplay_displayTrimText(type, count, text) { var out=text out=this.displayStripTags(out) //type: w(ords) or c(haracters) if (type=="w") { out=out.replace(/\s+/g," ") var outstack=out.split(" ") if (outstack.length>count) { outstack=outstack.slice(0,count) out=outstack.join(" ")+"..." } } else if (type=="c") { if (out.length>count) { out=out.substring(0,count)+"..." } } return out } function rssReplay_displayClassDotCheck(text) { var out=text if (out=="") { return out; } if (out.substring(0,1)==".") { out=out.substring(1,out.length) } return out } function rssReplay_displayPrefixSuffixParse(text) { var intext=text if (intext=="") { return intext } var out="" var exp="<<([^>]*?)>>" try {var re=new RegExp(exp) } catch(err) { return intext } if (!re.test(intext)) { return intext } //now do the job with <> var ro=re.exec(intext) while (ro) { out+=intext.substring(0,ro.index) if (ro[1].substring(0,5)=="date_") { out+=this.displayDate(ro[1].substring(5,ro[1].length),new Date()) } else if (ro[1]=="madewithrssreplay") { out+=this.localStringMadeWithReplay } else { out+=ro[0] } intext=intext.substring(ro.index+ro[0].length,intext.length) //intext="" ro=re.exec(intext) if ((!ro) && (intext!="")) { out+=intext } } return out } function rssReplay_displayParse(text,story) { var intext=text if (intext=="") { return intext } var out="" var exp="<<([^>]*?)>>" try {var re=new RegExp(exp) } catch(err) { return intext } if (!re.test(intext)) { return intext } //replace <>:<> and <<story>>:<<description>> exp="<<headline>>" var r2=new RegExp(exp,"g") intext=intext.replace(r2,"<<title>>") exp="<<story>>" var r2=new RegExp(exp,"g") intext=intext.replace(r2,"<<description>>") exp="<<([^>]*?)_headline>>" var r2=new RegExp(exp,"g") intext=intext.replace(r2,"<<$1_title>>") exp="<<([^>]*?)_story>>" var r2=new RegExp(exp,"g") intext=intext.replace(r2,"<<$1_description>>") //now do the job with <<XXX>> var ro=re.exec(intext) while (ro) { out+=intext.substring(0,ro.index) if (ro[1].substring(0,5)=="date_") { out+=this.displayDate(ro[1].substring(5,ro[1].length),story.date) } else if (ro[1].substring(0,5)=="trim_") { var i=ro[1].indexOf("_",5) if (i>-1) { var n=ro[1].substring(5,i-1) var t=ro[1].substring(i-1,i) var l=ro[1].substring(i+1,ro[1].length) if (story[l]) { out+=this.displayTrimText(t,n,story[l]) } } } else if (ro[1].substring(0,6)=="strip_") { var l=ro[1].substring(6,ro[1].length) if (story[l]) { out+=this.displayStripTags(story[l])} } else if (ro[1]=="headlineclass") { if (this.displayHeadlineClass!="") { out+='class="'+this.displayClassDotCheck(this.displayHeadlineClass)+'"' } } else if (ro[1]=="storyclass") { if (this.displayStoryClass!="") { out+='class="'+this.displayClassDotCheck(this.displayStoryClass)+'"' } } else if (ro[1]=="enclosureorlink") { if (story.enclosure!="") { out+=story.enclosure } else if (story.link!="") { out+=story.link } } else if (ro[1]=="thumbnailorfirstimage") { if (story.thumbnail!="") { out+=story.thumbnail } else if (story.firstimage!="") { out+=story.firstimage } } else if (story[ro[1]]!=null) { out+=story[ro[1]] } else { out+=ro[0] } intext=intext.substring(ro.index+ro[0].length,intext.length) //intext="" ro=re.exec(intext) if ((!ro) && (intext!="")) { out+=intext } } return out } function rssReplay_sortByDate(a,b) { //a and b are story objects with .date properties //.date can be converted to milliseconds UTC and substracted if ((a.date) && (b.date) && (a.date!=null) && (b.date!=null)) { var atemp=Date.UTC(a.date.getUTCFullYear(),a.date.getUTCMonth(),a.date.getUTCDate(),a.date.getUTCHours(),a.date.getUTCMinutes(),a.date.getUTCSeconds(),a.date.getUTCMilliseconds()) var btemp=Date.UTC(b.date.getUTCFullYear(),b.date.getUTCMonth(),b.date.getUTCDate(),b.date.getUTCHours(),b.date.getUTCMinutes(),b.date.getUTCSeconds(),b.date.getUTCMilliseconds()) return (atemp-btemp) } return 0 } function rssReplay_sortReverseByDate(a,b) { //a and b are story objects with .date properties //.date can be converted to milliseconds UTC and substracted if ((a.date) && (b.date) && (a.date!=null) && (b.date!=null)) { var atemp=Date.UTC(a.date.getUTCFullYear(),a.date.getUTCMonth(),a.date.getUTCDate(),a.date.getUTCHours(),a.date.getUTCMinutes(),a.date.getUTCSeconds(),a.date.getUTCMilliseconds()) var btemp=Date.UTC(b.date.getUTCFullYear(),b.date.getUTCMonth(),b.date.getUTCDate(),b.date.getUTCHours(),b.date.getUTCMinutes(),b.date.getUTCSeconds(),b.date.getUTCMilliseconds()) //if they are the same leave them in original order if (btemp-atemp==0) { return (a.origIndex-b.origIndex) } return (btemp-atemp) } return 0 } function rssReplay_displayPostLoad(num) { //check if I have already loaded this one - it might be a product of onload and onreadystatechange being called together if (this.sourcesLoading[num]==0) { return; } this.sourcesLoading[num]=0 var l=this.countSourcesLoading() if (l>0) { //still loading if (document.getElementById) { document.getElementById(this.id).innerHTML=this.loadingString() } } else { //done loading - format and place in layout if (document.getElementById) { var out="" //create stories and capture errors at the top of the space var i=0 var j=this.sources.length var p="" if (j>0) { for (i=0; i<j; i++) { if (this.sourcePages[i].substring(0,this.errorFlag.length)==this.errorFlag) { if (!this.supressErrors) { out+="<p style='color: red; font-weight: bold;'>"+ this.sourcePages[i].substring(this.errorFlag.length,this.sourcePages[i].length)+"</p>" } } else { p=this.parse(i) if ((p) && (!this.supressErrors)) { out+="<p style='color: red; font-weight: bold;'>"+p+"</p>" } } } } //loop through the stories, sort by date, and then format them var i=0 var j=this.stories.length out+=this.displayPrefixSuffixParse(this.displayPrefix) if (j>0) { //sort the array using the new function if (this.sorter=="a-date") { //ascending date sort - exception not default this.stories.sort(this.sortByDate) } else { //descending date sort - default this.stories.sort(this.sortReverseByDate) } for (i=0; i<j; i++) { //out+=this.stories[i].title+"<br />" if ((this.displayStoriesMax==0) || (i<this.displayStoriesMax)) { if (this.displayHeadline!="") { out+=this.displayParse(this.displayHeadline,this.stories[i]) } if (this.displayStory!="") { out+=this.displayParse(this.displayStory,this.stories[i]) } } } } else { out+=this.localStringNoStoriesError } out+=this.displayPrefixSuffixParse(this.displaySuffix) if (document.getElementById(this.id)) { //using dom node replacement with innerHTML= method as backup //because of IE problem with not parsing the string into a dom block var myelem=document.getElementById(this.id) var myparent=myelem.parentNode var replaced=false var tempdiv=null if (myelem.cloneNode) { tempdiv=myelem.cloneNode(false) tempdiv.innerHTML=out } if ((tempdiv) && (myparent.replaceChild)) { myparent.replaceChild(tempdiv,myelem) replaced=true } if (replaced==false) { document.getElementById(this.id).innerHTML=out } } } } } function rssReplay_display() { if (this.startupRegExpError) { //B57 //document.write("<div id='"+this.id+"'>"+this.localStringBrowserError+"</div>") if (document.getElementById(this.id)) { document.getElementById(this.id).innerHTML=this.localStringBrowserError } } else { //B57 //document.write("<div id='"+this.id+"'>"+this.loadingString()+"</div>") if (document.getElementById(this.id)) { document.getElementById(this.id).innerHTML=this.loadingString() } var i=0 var j=this.sources.length for (i=0; i<j; i++) { if (this.sources[i]!="") { this.loadXMLDoc(i) } } } } function rssReplay_countSourcesLoading() { var out=0 var i=0 var j=this.sourcesLoading.length if (j>0) { for (i=0; i<j; i++) { out+=this.sourcesLoading[i] } } return out } function rssReplay_addSource(src) { var href=src var href2=href var sid="" if (href.indexOf("|")>-1) { sid=href.substring(0,href.indexOf("|")) href=href.substring(href.indexOf("|")+1,href.length) href2=href } var proto=href.toLowerCase() var num=this.sources.length if ((proto.substring(0,7)=="http://") || (proto.substring(0,8)=="https://")){ if (this.proxyHref!="") { href=this.proxyHref+"?" if (this.proxyCache) { href=href+"cache=true&" } if ((this.proxyCache) && (this.proxyCacheTTL>-1)) { href=href+"cachettl="+this.proxyCacheTTL+"&" } if (sid!="") { href=href+"source="+sid } else { href=href+"request=" href=href+escape(href2) } } } this.sources[num]=href this.sourcePages[num]="" this.sourceXMLs[num]="" this.sourcesLoading[num]=1 } // retrieve XML document (reusable generic function); // parameter is URL string (relative or complete) to // an .xml file whose Content-Type is a valid XML // type, such as text/xml; XML source must be from // same domain as HTML file function rssReplay_loadXMLDoc(num) { var url=this.sources[num] var iam=this // branch for native XMLHttpRequest object if (window.XMLHttpRequest) { this.sourceRequests[num] = new XMLHttpRequest(); this.sourceRequests[num].onreadystatechange = function() {rssReplay_processReqChange(iam,num)}; //NS6 uses onload in multiple request situations - but so do others so there may be overlap this.sourceRequests[num].onload = function() {rssReplay_processReqChange(iam,num)}; this.sourceRequests[num].open("GET", url, true); this.sourceRequests[num].send(null); // branch for IE/Windows ActiveX version } else if (window.ActiveXObject) { isIE = true; //use try because it might not work with older IE/Mac IE try {this.sourceRequests[num] = new ActiveXObject("Microsoft.XMLHTTP")} catch(err) {this.sourceRequests[num] = null} if (this.sourceRequests[num]) { this.sourceRequests[num].onreadystatechange = function() {rssReplay_processReqChange(iam,num)}; this.sourceRequests[num].open("GET", url, true); this.sourceRequests[num].send(); } else { //error message - no HTTP object this.sourcePages[num]=this.errorFlag + this.localStringBrowserError this.displayPostLoad(num) } } else { //error message - no HTTP object this.sourcePages[num]=this.errorFlag + this.localStringBrowserError this.displayPostLoad(num) } } // handle onreadystatechange event of req object function rssReplay_processReqChange(obj,num) { // only if req shows "loaded" // N6 has no readyState property var docHref=document.location.href docHref=docHref.substring(0,5) var url=obj.sources[num] url=url.substring(0,5) if (obj.sourceRequests[num].readyState) { if (obj.sourceRequests[num].readyState == 4) { // only if "OK" if (obj.sourceRequests[num].status == 200) { obj.sourcePages[num]=obj.sourceRequests[num].responseText obj.sourceXMLs[num]=obj.sourceRequests[num].responseXML obj.displayPostLoad(num) } else if ((docHref.toLowerCase()=="file:") && (url.toLowerCase()!="http:")) { //local load so don't worry about status obj.sourcePages[num]=obj.sourceRequests[num].responseText obj.sourceXMLs[num]=obj.sourceRequests[num].responseXML obj.displayPostLoad(num) } else if (obj.sourceRequests[num].status == 404) { //localize error message - proxy/file is missing obj.sourcePages[num]=obj.errorFlag + obj.localStringLoadError+" "+num+":\n"+ obj.sources[num]+ ":\n" + obj.sourceRequests[num].status+" " if (obj.sources[num].indexOf("rssReplayProxy")==-1) { obj.sourcePages[num]+=obj.localString404FileError } else { obj.sourcePages[num]+=obj.localString404ProxyError } obj.displayPostLoad(num) } else { //localize error message obj.sourcePages[num]=obj.errorFlag + obj.localStringLoadError+" "+num+":\n"+ obj.sources[num]+ ":\n" + obj.sourceRequests[num].status+" "+obj.sourceRequests[num].statusText obj.displayPostLoad(num) } } } else if (obj.sourceRequests[num].status) { //works with N6 and onload if (obj.sourceRequests[num].status == 200) { obj.sourcePages[num]=obj.sourceRequests[num].responseText obj.sourceXMLs[num]=obj.sourceRequests[num].responseXML obj.displayPostLoad(num) } else { //localize error message obj.sourcePages[num]=obj.errorFlag + obj.localStringLoadError+" "+num+":\n"+ obj.sources[num]+ ":\n" + obj.sourceRequests[num].status+" "+obj.sourceRequests[num].statusText obj.displayPostLoad(num) } } else { obj.sourcePages[num]=obj.errorFlag + obj.localStringBrowserError } } // Story Object Creation -------------------------- function rssReplayStory() { //elements this.title="" this.link="" this.description="" this.enclosure="" this.thumbnail="" this.firstimage="" this.origIndex=0 this.date=rssReplayCurrentDate //this.date=new Date() } // Parse Methods ---------------------------------- function rssReplay_parserPrepText(po) { var attr=po.getAttribute("type") if (attr!=null) { //a03:text/plain:text/html:application/xhtml+xml //a10:text/html/xhtml if ((attr=="text") || (attr=="text/plain")) { return po.innerXMLContent() } else { //assume its html escaped mode return rrpHtmlDecode(po.innerXMLContent()) } } return rrpHtmlDecode(po.innerXMLContent()) } function rssReplay_parserGetDate(text) { //convert date string to a date //var re=/(\d+)-(\d+)-(\d+)[T\s](\d+):(\d+):(\d+)([\+\-\Z]*)(\d*):?(\d*)/ var re=/(\d+)-(\d+)-(\d+)[T\s](\d+):(\d+):(\d+)\s*([\+\-Z]*)(\d*):?(\d*)/ var re2=/(\d+)-(\d+)-(\d+)/ var out=new Date(text) //check to see if text failed to parse into a date object if (isNaN(out.getFullYear())) { if (re.test(text)) { var ro=re.exec(text) out=new Date("9/1/2003") out.setFullYear(ro[1]) out.setMonth(ro[2]-1) out.setDate(ro[3]) out.setHours(ro[4]) out.setMinutes(ro[5]) out.setSeconds(ro[6]) //note: getTime and setTime are in milliseconds //note: getTimesonzeOffset is in minutes: m*60s*1000m if (ro[7]=="Z") { //adjust for GMT out.setTime(out.getTime()-(out.getTimezoneOffset()*60000)) } else if (ro[7]=="+") { if (ro[9]=="") { var tms=((60*ro[8].substring(0,2))+ro[8].substring(2,4))*600 } else { var tms=((60*ro[8])+ro[9])*600 } //adjust for positive offest out.setTime(out.getTime()-tms-(out.getTimezoneOffset()*60000)) } else if (ro[7]=="-") { if (ro[9]=="") { var tms=((60*ro[8].substring(0,2))+ro[8].substring(2,4))*600 } else { var tms=((60*ro[8])+ro[9])*600 } //adjust for negative offset out.setTime(out.getTime()+tms-(out.getTimezoneOffset()*60000)) } } else if (re2.test(text)) { var ro=re2.exec(text) out=new Date("9/1/2003") out.setFullYear(ro[1]) out.setMonth(ro[2]-1) out.setDate(ro[3]) } else { //doesn't work - so just use today out=new Date() } } return out } function rssReplay_parse(num) { //parser returns error strings //return this.localStringEmptyFeedError //this.localStringUnrecognizedFormatError //this.localStringEmptyFeedError var sourcetext=this.sourcePages[num] //var sourcexml=this.sourceXMLs[num] if (sourcetext=="") { return this.localStringEmptyFeedError+":\n"+this.sources[num] } //proxy error check if (sourcetext.substring(0,this.localStringProxyErrorPrefix.length)==this.localStringProxyErrorPrefix) { return sourcetext } //root options: rss|rdf:rdf|feed var rexRoot=/\<(rss|rdf:rdf|feed)\W/i if (!rexRoot.test(sourcetext)) { return this.localStringUnrecognizedFormatError+":\n"+this.sources[num] } var ro=rexRoot.exec(sourcetext) var rootTag=(ro[1]).toLowerCase() //remove the content before the tag (should be all the <?xml & <!DOCTYPE garbagio sourcetext=sourcetext.substring(ro.index,sourcetext.length) //now parse the dang thing var sourceParsed=new ParsedPage(sourcetext) var itemsTag="item" if (rootTag=="feed") { itemsTag="entry" } var items=sourceParsed.getElementsByTagName(itemsTag) if ((items==null) || (items.length==0)) { return this.localStringEmptyFeedError+":\n"+this.sources[num] } //now look for the content that I want var i=0 var j=items.length //iterate across all items for (i=0; i<j; i++) { var theStory=new rssReplayStory() theStory.origIndex=i var itemParsed=new ParsedPage(items[i].innerHTML()) //get the pieces var t=itemParsed.getElementsByTagName("title") if ((t!=null) && (t.length>0)) { theStory.title=this.parserPrepText(t[0]) } var t=itemParsed.getElementsByTagName("summary") if ((t!=null) && (t.length>0)) { theStory.description=this.parserPrepText(t[0]) } var t=itemParsed.getElementsByTagName("description") if ((t!=null) && (t.length>0)) { theStory.description=this.parserPrepText(t[0]) } var t=itemParsed.getElementsByTagName("content") if ((t!=null) && (t.length>0)) { theStory.description=this.parserPrepText(t[0]) } var t=itemParsed.getElementsByTagName("content:encoded") if ((t!=null) && (t.length>0)) { theStory.description=this.parserPrepText(t[0]) } var t=itemParsed.getElementsByTagName("pubdate") if ((t!=null) && (t.length>0)) { theStory.date=this.parserGetDate(t[0].innerXMLContentDecoded()) } var t=itemParsed.getElementsByTagName("updated") if ((t!=null) && (t.length>0)) { theStory.date=this.parserGetDate(t[0].innerXMLContentDecoded()) } var t=itemParsed.getElementsByTagName("published") if ((t!=null) && (t.length>0)) { theStory.date=this.parserGetDate(t[0].innerXMLContentDecoded()) } var t=itemParsed.getElementsByTagName("dc:date") if ((t!=null) && (t.length>0)) { theStory.date=this.parserGetDate(t[0].innerXMLContentDecoded()) } var t=itemParsed.getElementsByTagName("modified") if ((t!=null) && (t.length>0)) { theStory.date=this.parserGetDate(t[0].innerXMLContentDecoded()) } var t=itemParsed.getElementsByTagName("issued") if ((t!=null) && (t.length>0)) { theStory.date=this.parserGetDate(t[0].innerXMLContentDecoded()) } var t=itemParsed.getElementsByTagName("link") if ((t!=null) && (t.length>0)) { var k=0 for (k=0; k<t.length; k++) { if (theStory.link=="") { theStory.link=t[k].innerXMLContent() if ((rootTag=="feed") && (t[k].getAttribute("href")!=null ) && ((t[k].getAttribute("rel")==null) || (t[k].getAttribute("rel")=="alternate")) ) { theStory.link=t[k].getCasedAttribute("href") } } if (theStory.enclosure=="") { if ((rootTag=="feed") && (t[k].getAttribute("rel")!=null) && (t[k].getAttribute("rel")=="enclosure")) { theStory.enclosure=t[k].getCasedAttribute("href") } } } } var t=itemParsed.getElementsByTagName("guid") if ((t!=null) && (t.length>0)) { if ((t[0].getAttribute("isPermaLink")!="false") && (theStory.link=="")) { theStory.link=t[0].innerXMLContent() } } //break out enclosure as its own thing var t=itemParsed.getElementsByTagName("enclosure") if ((t!=null) && (t.length>0)) { if (t[0].getAttribute("url")!=null) { theStory.enclosure=t[0].getCasedAttribute("url") } } //specials - like a thumbnail var t=itemParsed.getElementsByTagName("apple-wallpapers:thumbnail") if ((t!=null) && (t.length>0)) { theStory.thumbnail=t[0].innerXMLContent() } //specials - firstimage var descrParse=new ParsedPage(theStory.description) var t=descrParse.getElementsByTagName("img") if ((t!=null) && (t.length>0)) { theStory.firstimage=t[0].getCasedAttribute("src") } else if (theStory.link!="") { var imgext=theStory.link.toLowerCase() imgext=imgext.substring(imgext.lastIndexOf(".")+1,imgext.length) if ((imgext=="gif") || (imgext=="png") || (imgext=="jpeg") || (imgext=="jpg") || (imgext=="bmp") || (imgext=="pdf") || (imgext=="swf") || (imgext=="mov") || (imgext=="wmv")) { theStory.thumbnail=theStory.link } } //if the story is not empty add it to the end of the stories array if (theStory.title!="") { this.stories[this.stories.length]=theStory } } } // ParsedPage & ParseElement Object Creation -------------------------- // XML/HTML parser based on regular expressions // Includes objects for ParsedPage and ParseElement (a tag/content parser) // Version 1.5 - trimmed to core elements for Replay // Coded by Ron Northrip // Jul 2006 //methods for parsing object function ParseElement_isContent() { if (this.type==0) return true return false } function ParseElement_isTag() { if (this.type==1) return true return false } function ParseElement_isCloseTag() { if (this.type==-1) return true return false } function ParseElement_isCData() { if (this.type==-2) return true return false } function ParseElement_sourceCData() { var out=this.source if (this.type==-2) { out=out.substring(9,out.length-3) out=rrpHtmlEntities(out) } return out } function ParseElement_getTag() { var re=this.source.match(rexJustTag) if (re!=null) this.tag=re[1].toLowerCase() } function ParseElement_getCloseTag() { var re=this.source.match(rexJustTag) if (re!=null) this.tag=re[1].toLowerCase() } function ParseElement_getAttributes() { var text=this.source this.attributes=new Array this.casedAttributes=new Array if (text.substring(0,1)=="<") { //trim off < > & the tag text=text.substring(1,text.length-1) if (this.tag==null) { this.tag="" //alert(getLocalizedText("A serious error occured when parsing JavaScript in your HTML pages")) } if (this.tag!="") text=text.substring(this.tag.length,text.length) //now get the attributes var p=0 var re=text.match(rexJustAttributes) while (re!=null) { //check for just spaces - not included in attributes list if (! re[0].match(rexJustSpaces)) { if ((re[1]) && (re[1]!="")) { this.attributes[re[1].toLowerCase()]=re[2].toLowerCase() this.casedAttributes[re[1].toLowerCase()]=re[2] } else if ((re[3]) && (re[3]!="")) { this.attributes[re[3].toLowerCase()]=re[4].toLowerCase() this.casedAttributes[re[3].toLowerCase()]=re[4] } else if ((re[5]) && (re[5]!="")) { this.attributes[re[5].toLowerCase()]=re[6].toLowerCase() this.casedAttributes[re[5].toLowerCase()]=re[6] } else { this.attributes[re[0].toLowerCase()]="" this.casedAttributes[re[0].toLowerCase()]="" } } //skip position and rematch p=re.index+re[0].length text=text.substring(p,text.length) re=text.match(rexJustAttributes) } } } function ParseElement_getAttribute(attr) { if (this.isTag()) { if (this.attributes[attr]!=null) { return this.attributes[attr] } } return null } function ParseElement_getCasedAttribute(attr) { if (this.isTag()) { if (this.casedAttributes[attr]!=null) { return this.casedAttributes[attr] } } return null } function ParseElement_setAttribute(attr,val) { if (this.isTag()) { //set in list var attrlower=attr.toLowerCase() this.attributes[attrlower]=val //change the source var text=this.source var op=0 var mp=-1 var ml=-1 //now find the attribute to change var p=0 var re=text.match(rexJustAttributes) while (re!=null) { //check for just spaces - not included in attributes list if (! re[0].match(rexJustSpaces)) { if ((re[1]) && (re[1]!="")) { //no quotes if (re[1].toLowerCase()==attr.toLowerCase()) { mp=op+re.index; ml=re[0].length } } else if ((re[3]) && (re[3]!="")) { //dble quotes if (re[3].toLowerCase()==attr.toLowerCase()) { mp=op+re.index; ml=re[0].length } } else if ((re[5]) && (re[5]!="")) { //single quotes if (re[5].toLowerCase()==attr.toLowerCase()) { mp=op+re.index; ml=re[0].length } } else { //just the word if (re[0].toLowerCase()==attr.toLowerCase()) { mp=op+re.index; ml=re[0].length } } } //skip position and rematch p=re.index+re[0].length op=op+p text=text.substring(p,text.length) if (mp==-1) { re=text.match(rexJustAttributes) } else { re=null } } //if there's no attribute then add it to the end of the source //otherwise change the source at the mp, with ml length text=this.source if (mp==-1) { p=text.lastIndexOf(">") if (p.substring(p-1,p)=="/") p=p-1 p=p-1 var start=text.substring(0,p) var end=text.substring(p,text.length) if (val=="") { //no content this.source=start+" "+attr+" "+end } else if (val.indexOf('"')==-1) { //no double this.source=start+" "+attr+'="'+val+'" '+end } else { //use singles this.source=start+" "+attr+"='"+val+"' "+end } } else { var start=text.substring(0,mp) var end=text.substring(mp+ml,text.length) if (val=="") { //no content this.source=start+attr+end } else if (val.indexOf('"')==-1) { //no double this.source=start+attr+'="'+val+'"'+end } else { //use singles this.source=start+attr+"='"+val+"'"+end } } } } function ParseElement_innerHTML() { if (this.isTag()) { if (this.page!=null) { var parseStack=this.page.parseStack if (parseStack.length>0) { var out="" var i=0 var j=parseStack.length if (parseStack[this.index]!=this) { while ((parseStack[i]!=this) && (i<j)) {i++} this.index=i } i=this.index+1 var opens=1 while ((opens>0) && (i<j)) { if (parseStack[i].tag==this.tag) { if (parseStack[i].isCloseTag()) {opens--} else if (parseStack[i].isTag()) {opens++} } if (opens>0) {out+=parseStack[i].source} if (opens==0) {this.closeIndex=i} i++ } if (opens>0) { //unmatched close out=this.source } return out } } } else { return this.source } } function ParseElement_innerXMLContent() { if (this.isTag()) { if (this.page!=null) { var parseStack=this.page.parseStack if (parseStack.length>0) { var out="" var i=0 var j=parseStack.length if (parseStack[this.index]!=this) { while ((parseStack[i]!=this) && (i<j)) {i++} this.index=i } i=this.index+1 var opens=1 while ((opens>0) && (i<j)) { if (parseStack[i].tag==this.tag) { if (parseStack[i].isCloseTag()) {opens--} else if (parseStack[i].isTag()) {opens++} } if (opens>0) { if (parseStack[i].isCData()) { out+=parseStack[i].sourceCData() } else { out+=parseStack[i].source } } if (opens==0) {this.closeIndex=i} i++ } if (opens>0) { //unmatched close out="" } return out } } } else { return "" } } function ParseElement_innerXMLContentDecoded() { return rrpHtmlDecode(this.innerXMLContent()); } function ParseElement_outerHTML() { if (this.isTag()) { if (this.page!=null) { var parseStack=this.page.parseStack if (parseStack.length>0) { var out=this.source var i=0 var j=parseStack.length if (parseStack[this.index]!=this) { while ((parseStack[i]!=this) && (i<j)) {i++} this.index=i } i=this.index+1 var opens=1 while ((opens>0) && (i<j)) { if (parseStack[i].tag==this.tag) { if (parseStack[i].isCloseTag()) {opens--} else if (parseStack[i].isTag()) {opens++} } out+=parseStack[i].source i++ } this.closeIndex=i return out } } } else { return this.source } } //object for parsing the source function ParseElement(text) { this.source=text this.index=0 this.closeIndex=-1 this.page=null this.type=0 //0-content: 1/-1 tag/close //-2 cdata this.tag=null this.attributes=null this.casedAttributes=null this.isContent=ParseElement_isContent this.isTag=ParseElement_isTag this.isCloseTag=ParseElement_isCloseTag this.isCData=ParseElement_isCData this.sourceCData=ParseElement_sourceCData this.getTag=ParseElement_getTag this.getCloseTag=ParseElement_getCloseTag this.getAttributes=ParseElement_getAttributes this.getAttribute=ParseElement_getAttribute this.getCasedAttribute=ParseElement_getCasedAttribute this.setAttribute=ParseElement_setAttribute this.innerHTML=ParseElement_innerHTML this.outerHTML=ParseElement_outerHTML this.innerXMLContent=ParseElement_innerXMLContent this.innerXMLContentDecoded=ParseElement_innerXMLContentDecoded //doin the work if (this.source.substring(0,1)=="<") { //if ((this.source.substring(0,1)=="<") && (this.source.substring(this.source.length-1,this.source.length)==">")) { //its a tag if (this.source.substring(1,2)=="/") { //close tag this.type=-1 this.getCloseTag() } else if (this.source.substring(1,9)=="![CDATA[") { //cdata this.type=-2 } else { //regular tag - parse the attributes this.type=1 this.getTag() this.getAttributes() } } } //methods for parsedpage object function ParsedPage_getElementsByTagName(text) { var comptext=text.toLowerCase() var out=new Array() if (this.parseStack!=null) { var i=0 var j=this.parseStack.length if (j>0) { for (i=0; i<j; i++) { if (this.parseStack[i].isTag()) { if (this.parseStack[i].tag==comptext) { out[out.length]=this.parseStack[i] } } } } } return out } function ParsedPage_getSource() { var out="" if (this.parseStack!=null) { var i=0 var j=this.parseStack.length if (j>0) { for (i=0; i<j; i++) { out+=this.parseStack[i].source } } } return out } function ParsedPage_subSource(a,b) { var out="" if (this.parseStack!=null) { var i=a for (i=a; i<b; i++) { out+=this.parseStack[i].source } } return out } //parse page object function ParsedPage(text) { this.source=text var data=this.source this.parseStack=new Array() this.getElementsByTagName=ParsedPage_getElementsByTagName this.getSource=ParsedPage_getSource this.subSource=ParsedPage_subSource //clean out tags/content that I don't want //data=data.replace(rexPHPCodeG,"") //data=data.replace(rexASPJSPCodeG,"") data=data.replace(rexXMLCommandG,"") data=data.replace(rexXMLDocTypeSBG,"") data=data.replace(rexXMLDocTypeG,"") data=data.replace(rexScriptTagContentsG,"") data=data.replace(rexStyleTagContentsG,"") data=data.replace(rexCommentSimpleG,"") data=data.replace(rexCommentLongG,"") //doin the loop work var p=0 var pdata="" var pelem=null var re=data.match(rexCDataOrTag) while (re!=null) { //check to see if we are not leading with a match //grab intermediate content - put on end of parse stack if (re.index!=0) { pdata=data.substring(0,re.index) pelem=new ParseElement(pdata) pelem.index=this.parseStack.length pelem.page=this this.parseStack[this.parseStack.length]=pelem } //add my match to the end of the parseStack pelem=new ParseElement(re[0]) pelem.index=this.parseStack.length pelem.page=this this.parseStack[this.parseStack.length]=pelem //skip position and rematch p=re.index+re[0].length data=data.substring(p,data.length) re=data.match(rexCDataOrTag) } }