// http://code.google.com/apis/gdata/reference.html // http://lvchen.blogspot.com/feeds/comments/default?start-index=1&max-results=7 // http://lvchen.blogspot.com/feeds/posts/summary?published-min=2007-04-00&published-max=2007-04-31&max-results=90 // 1. 快取文章標題 (Done) // 2. 如何加快顯示的速度?(Done) // 3 沒有留言時,footer 的顯示資訊 (Not necessary) // 4. Google 取消了 max-results 99 的限制,現在可以取超過99的文章與回應,在安裝程式中取消限制。 // 5. 增加是否可顯示日期設定 (可以在樣式設定中更改,只要拿掉 %timestamp% 就可以了,原來的樣式設定對於隱藏內文的判斷會有問題,已修正) (Done) // 6. 文章被刪除後,留言還在的問題。(Done) // 7. 文章的總數,應扣掉被刪除的留言,這樣就不需要顯示看不到留言的訊息???可能做到嗎??? (好像不行耶) // 8. 嘗試作出可相容 neo 的換文章方式 (???) // 9. 確定相容最新版 jquery (Done) // 10. 取消迴圈設定,增加快取大小設定 cachesize (Done) // 11. 修正沒有留言時的錯誤 (Done) // 12. 修正查無文章的錯誤 (Done) // 13. 查無文章但設定為顯示留言的話,要記得把連結拿掉 // 14. 增加直接到留言頁面的圖示,利用 blogID and postID 。 // 15. 修正 content 出現 <> 會造成顯示錯誤。 // 16. 全部展開,按下一頁後,開關圖示會不正常。 // 17. 相容其他使用 jQuery 的外掛。 // 跳頁測試,先按下一頁,再按上一頁,跳到最後一頁(使用跳頁按鈕),按上一頁,再按下一頁,跳到第二頁(使用跳頁按鈕,index=4),按上一頁,完成。 //----------- Define Global Variables, can be modified--------------- //var rcPreSetting = {}; var rcPreSetting = { g_szBlogDomain:'lvchen.blogspot.com', g_iShowCount: 10, noContent: ['原文已被刪除','

沒有留言可以顯示

'], cachesize: 40, showJumpButton:true, showRCnoPost:false, rcFoldImage:[ 'http://lvchen.hostse.com/rc20/rc_0609_f.gif','留了言', 'http://lvchen.hostse.com/rc20/rc_0609_uf.gif','留言說:', ' 載入中...', '全部展開','全部隱藏'], otherText:['跳至留言','我跳','上一頁','下一頁','您正在看留言 %range%,共有 %totalNum% 則留言'], reply:['http://lvchen.hostse.com/rc20/external.png','直接去留言'], rcAuthorLinkFormat:'%author%', rcTitleLinkFormat: '%g_szTitle%', createDisplayFormat:'%rcAuthorLinkFormat% 於 %rcTitleLinkFormat%%replyImg% %rcSay% 「%content%」  - %timestamp%', today:'今天', authorLink:true, rcDateFormat: 1 }; // add %replyURL% and %replyImg% //----------- Define Global Variables, should NOT be modified--------------- jQuery.noConflict(); var rcSetting = { g_szComments:[], maxPostsNum:0, // Max posts number commentStartIndex : 1, // find comment from commentTotalNum : 0, // Total comments number showAllFlag : false, // Check if the showAll button clicke outDate:0, titleArr:[], linkArr:[], replyArr:[] }; var rcFunction = {}; // The only Globa function...maybe // ----------- Add header buttons--------------- rcFunction.addHeaderButton = function () { var headerButton = '
'+rcPreSetting.rcFoldImage[5]+''; if (rcPreSetting.showJumpButton) headerButton += '
'+rcPreSetting.otherText[0]+'   
'; else headerButton += ''; jQuery('#divrc').before(headerButton); }; //----------- Fetch comment JSON feed, several variables that is comments related are determine here --------------- rcFunction.commentJSONfeed = function (json) { if (json.feed.entry!=undefined) { rcSetting.g_szComments = json.feed.entry; if (rcSetting.commentTotalNum == 0) rcSetting.commentTotalNum = json.feed.openSearch$totalResults.$t*1; // Retrive total number of comments if (rcPreSetting.g_iShowCount > rcSetting.commentTotalNum) rcPreSetting.g_iShowCount = rcSetting.commentTotalNum; rcFunction.fetchPostsTitle(1,''); } else { jQuery('#divrc').html(rcPreSetting.noContent[1]); } }; rcFunction.fetchComments = function(Index,increment) { jQuery ('#jumpButton').attr('disabled','disabled'); var y_script = document.createElement('script'); var callbacksrc = 'http://' + rcPreSetting.g_szBlogDomain + '/feeds/comments/default?alt=json-in-script&callback=rcFunction.commentJSONfeed&max-results=' + increment + '&start-index='+ Index; y_script.setAttribute('src',callbacksrc); y_script.setAttribute('id', 'jsonCommnets'); y_script.setAttribute('type', 'text/javascript'); document.documentElement.firstChild.appendChild(y_script); }; rcFunction.fetchPostsTitle = function(Index,source) { if (rcSetting.linkArr.length > 0 & source == '') { rcFunction.titleJSONfeed(''); } else { var y_script = document.createElement('script'); if (source !='') callbacksrc = source + '?&alt=json-in-script&callback=rcFunction.findLossTitles'; else callbacksrc = 'http://' + rcPreSetting.g_szBlogDomain + '/feeds/posts/summary?max-results='+ rcPreSetting.cachesize + '&start-index=' + Index + '&alt=json-in-script&callback=rcFunction.titleJSONfeed'; y_script.setAttribute('src',callbacksrc); y_script.setAttribute('id', 'jsonPosts'); y_script.setAttribute('type', 'text/javascript'); document.documentElement.firstChild.appendChild(y_script); } }; rcFunction.findTitle = function(orgLink) { var loop = rcPreSetting.cachesize; // set up looping time, default is 30, which means we check only 30 title every time. for (var j = 0 ; j < loop ; j++) // This is main loop to chekc if the title of the link exists. { if (rcSetting.linkArr[j] == orgLink) { break; } } if (j != loop) return j; else { //return ' '; // If title can not be found within a cycle, prepare to check again. return -1; } }; //----------- An inner funciton that converts Month--------------- rcFunction.monthConvert = function(monthIndex) { var monthName=['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']; return monthName[(parseInt(monthIndex,10)-1)]; }; //----------- An inner function that check dates Get Today's Date--------------- rcFunction.checkTodayDate = function(dateString) { var timeStr = new Date(); var rcDateStr = new Date(parseInt(dateString.substr(0,4),10),parseInt(dateString.substr(5,2),10)-1,parseInt(dateString.substr(8,2),10)); //alert, I am not sure this method is working, Better test before try. 04/04/2008 //rcDateStr.setFullYear(parseInt(dateString.substr(0,4),10),parseInt(dateString.substr(5,2),10)-1,parseInt(dateString.substr(8,2),10)); if (rcDateStr.getYear() == timeStr.getYear()) { if (rcDateStr.getMonth() == timeStr.getMonth()) { if (rcDateStr.getDate() == timeStr.getDate()) return true; else return false; } else return false; } else return false; }; //----------- Fetch posts JSON feed, several variables that is comments related are determine here --------------- //----------- Look for matched titles and show comments --------------- rcFunction.titleJSONfeed = function (posts) { // initial variables var temp = ''; jQuery('#divrc').html(temp); // Some necessary operations to match custom format //jQuery(document).ready(function() //{ if (jQuery('#divrc li .comcontent').html() != null) {// folding feature is used when full content exists. jQuery('#divrc li').css({listStyle:'none',background:'none'}); if (!rcSetting.showAllFlag) jQuery('#divrc li .rcfold').css('background','url('+rcPreSetting.rcFoldImage[0]+') center no-repeat'); else jQuery('#divrc li .rcfold').css('background','url('+rcPreSetting.rcFoldImage[2]+') center no-repeat'); } else {// if full content does not exist, remove folding feature jQuery('#divrc li').find('.rcfold').remove(); jQuery('#showAllButton').remove(); } //}); rcFunction.RunAfterDomReady(); if (rcPreSetting.showRCnoPost) jQuery('#divrc li:has(.postDeleted)').find('.rcPostTitle').replaceWith(rcPreSetting.noContent[0]).end().each(function(){ jQuery(this).find('.rcAuthor').html(jQuery(this).find('.rcAuthor').text()); }); else jQuery('#divrc li:has(.postDeleted)').remove(); // If a post has been deleted, remove that comment. rcSetting.outDate = jQuery('#divrc li:has(.noTitleMessage)').length; if (rcSetting.outDate == 0) { if (jQuery('#divrc li').length == 0) jQuery('#divrc').html(rcPreSetting.noContent[1]); rcFunction.addFooterButton(); } else rcFunction.titleReCheck(); // go to titleCheck to check if any title misses. }; rcFunction.addFooterButton = function () //This function is only used in titleCheck(), so I make it an inner function for easy management { var text = rcPreSetting.otherText; var commentInfo ='

'+text[4]; var index = rcSetting.commentStartIndex; var tnum = rcSetting.commentTotalNum; var g_show = rcPreSetting.g_iShowCount; if (index + g_show > tnum) g_show = tnum - index + 1; commentInfo = commentInfo.replace(/%range%/,index +'~'+ (index+g_show-1)); commentInfo = commentInfo.replace(/%totalNum%/,tnum); var footerButton; jQuery('#loading').remove(); jQuery('#jumpButton').removeAttr('disabled'); if (index == 1) { if (tnum == g_show) footerButton = '

'; else footerButton = '
'+text[3]+'

'; } else if (g_show + index > tnum) { footerButton = '
'+text[2]+'

'; } else { footerButton = '
'+text[2]+'      '+text[3]+'

'; } jQuery('#divrc').after(commentInfo + footerButton); //rcFunction.RunAfterDomReady(); }; rcFunction.titleReCheck = function() { var source = jQuery('#divrc li .noTitleMessage').eq(0).text(); jQuery('#jsonPosts').remove(); rcFunction.fetchPostsTitle(1,source); }; // How do we find the title of a post that we miss at first check? // We look again and then use jQuery to replace noTitleMessage' // This function is called by titleCheck ONLY. rcFunction.findLossTitles = function (posts) { var title = posts.entry.title.$t; var link = posts.entry.link; for (var i = 0 ; i < link.length ; i++) { if (link[i].rel == 'alternate') var titleLink = link[i].href; else if (link[i].rel == 'replies' && link[i].type == 'text/html') var replyLink = link[i].href; else if (link[i].rel == 'self') var sourceLink = link[i].href; } jQuery('#divrc li:has(.noTitleMessage)').each(function(i){ if (jQuery('.noTitleMessage',this).text() == sourceLink) { jQuery(this).find('.replyImg a').attr('href',replyLink).end().find('.noTitleMessage').replaceWith(title); rcSetting.outDate--; } }); if (rcSetting.outDate != 0) rcFunction.titleReCheck(); else rcFunction.addFooterButton(); }; //----------- Some actions run after list of comments are created. ---------------//on mouseover?? instead of hover rcFunction.RunAfterDomReady = function () { if (!rcSetting.showAllFlag) jQuery('#divrc li').find('.comcontent').hide(); jQuery('#divrc li').find('.rcfold').hover( function(){jQuery(this).css({cursor:'pointer'});}, function(){jQuery(this).css({cursor:'default'});}).click( function() { var comment = jQuery(this).parent().find('.comcontent'); if (comment.is(':visible')) { jQuery(this).css('background','url(' + rcPreSetting.rcFoldImage[0] + ') center no-repeat'); jQuery(this).parent().find('.rcsay').html(rcPreSetting.rcFoldImage[1]); comment.hide(); } else { jQuery(this).css('background','url(' + rcPreSetting.rcFoldImage[2] +') center no-repeat'); jQuery(this).parent().find('.rcsay').html(rcPreSetting.rcFoldImage[3]); comment.show(); } }); //if (rcSetting.showAllFlag) {rcSetting.showAllFlag= false; rcFunction.showOrHideAll();} }; // ----------- Handler for showing or hiding all comment ----------- // ----------- Dynamic onclick does not work, so I merge two function into one. it seems working and running better ! 10/17 ----------- rcFunction.showOrHideAll = function() { if (rcSetting.showAllFlag) { jQuery('.comcontent').hide(); jQuery('.rcfold').css('background','url('+ rcPreSetting.rcFoldImage[0] +') center no-repeat'); jQuery('#headerButton a:eq(0)').html(rcPreSetting.rcFoldImage[5]); jQuery('#divrc .rcsay').html(rcPreSetting.rcFoldImage[1]); rcSetting.showAllFlag = false; } else { jQuery('.comcontent').show(); jQuery('.rcfold').css('background','url('+ rcPreSetting.rcFoldImage[2] +') center no-repeat'); jQuery('#headerButton a:eq(0)').html(rcPreSetting.rcFoldImage[6]); jQuery('#divrc .rcsay').html(rcPreSetting.rcFoldImage[3]); rcSetting.showAllFlag = true; } }; /*----------- ChangePage, backward, forward, or jump --------------- //----------- Direction = -1, backward --------------- //----------- Direction = 0, jump by index --------------- //----------- Direction = 1, forward --------------- //----------- Direction = 2, jump by date --------------- //----------- indexIwant is index I want --------------*/ rcFunction.changePage = function(direction,indexIwant) { var jump = true; if (direction == 1) // Next page rcSetting.commentStartIndex += rcPreSetting.g_iShowCount; else if (direction == -1) // previsous page rcSetting.commentStartIndex -= rcPreSetting.g_iShowCount; else {//rcFunction.gotoIndexIwant = function (indexIwant) if (indexIwant > rcSetting.commentTotalNum) indexIwant = rcSetting.commentTotalNum; else if (indexIwant < 1) indexIwant = 1; var pageNumber = Math.ceil(indexIwant/rcPreSetting.g_iShowCount); if (pageNumber == Math.ceil(rcSetting.commentStartIndex/rcPreSetting.g_iShowCount)) jump = false; else rcSetting.commentStartIndex = (pageNumber-1)*rcPreSetting.g_iShowCount + 1; } if (jump)// 同一頁不跳, 不同頁我跳 { jQuery('#jsonCommnets').remove(); jQuery('#jsonPosts').remove(); jQuery('#divrc').next().remove().end().after('
'+rcPreSetting.rcFoldImage[4]+'
'); if (rcSetting.commentStartIndex + rcPreSetting.g_iShowCount > rcSetting.commentTotalNum) rcFunction.fetchComments(rcSetting.commentStartIndex, rcSetting.commentTotalNum - rcSetting.commentStartIndex + 1); else rcFunction.fetchComments(rcSetting.commentStartIndex, rcPreSetting.g_iShowCount); } }; // ----------- Run after DOM ready ----------- jQuery(document).ready(function() { //----------- Create basic structure--------------- var rcStart = jQuery('div.widget-content').filter(':contains(###recentComment###)').slice(0,1); // Choise only the first tag we found. 9/23 if(rcStart.length > 0) { rcStart.find('script').remove(); //fix script confict while two script in the same widget. 08/24/2007 rcStart.html(rcStart.html().replace(/###recentComment###/i,'
')); jQuery('#divrc').html(rcPreSetting.rcFoldImage[4]); rcFunction.addHeaderButton(); // Why not add footer here? Because the info in footer is mainly depending on the comment body rcFunction.fetchComments(rcSetting.commentStartIndex, rcPreSetting.g_iShowCount); } });