Warning: Cannot modify header information - headers already sent by (output started at /home/catard/www/inc/config.php:38) in /home/catard/www/inc/clearbricks/common/lib.http.php on line 211

Warning: Cannot modify header information - headers already sent by (output started at /home/catard/www/inc/config.php:38) in /home/catard/www/inc/clearbricks/common/lib.http.php on line 213

Warning: Cannot modify header information - headers already sent by (output started at /home/catard/www/inc/config.php:38) in /home/catard/www/inc/load_plugin_file.php on line 83

Warning: Cannot modify header information - headers already sent by (output started at /home/catard/www/inc/config.php:38) in /home/catard/www/inc/load_plugin_file.php on line 84
/** * remy sharp / http://remysharp.com * http://remysharp.com/2007/05/18/add-twitter-to-your-blog-step-by-step/ * * @params * cssIdOfContainer: e.g. twitters * options: * { * id: {String} username, * count: {Int} 1-20, defaults to 1 - max limit 20 * prefix: {String} '%name% said', defaults to blank * clearContents: {Boolean} true, removes contents of element specified in cssIdOfContainer, defaults to true * ignoreReplies: {Boolean}, skips over tweets starting with '@', defaults to false * template: {String} HTML template to use for LI element (see URL above for examples), defaults to predefined template * enableLinks: {Boolean} linkifies text, defaults to true, * timeout: {Int} How long before triggering onTimeout, defaults to 10 seconds if onTimeout is set * onTimeoutCancel: {Boolean} Completely cancel twitter call if timedout, defaults to false * onTimeout: {Function} Function to run when the timeout occurs. Function is bound to element specified with * cssIdOfContainer (i.e. 'this' keyword) * * CURRENTLY DISABLED DUE TO CHANGE IN TWITTER API: * withFriends: {Boolean} includes friend's status * * } * * @license MIT (MIT-LICENSE.txt) * @version 1.11 - Added timeout functionality, and removed withFriends while Twitter works out API changes * @date $Date: 2008-05-31 14:26:49 +0100 (Sat, 31 May 2008) $ */ // to protect variables from resetting if included more than once if (typeof renderTwitters != 'function') (function () { /** Private variables */ var browser = (function() { var b = navigator.userAgent.toLowerCase(); // Figure out what browser is being used return { safari: /webkit/.test(b), opera: /opera/.test(b), msie: /msie/.test(b) && !(/opera/).test(b), mozilla: /mozilla/.test(b) && !(/(compatible|webkit)/).test(b) }; })(); var guid = 0; var readyList = []; var isReady = false; /** Global functions */ // to create a public function within our private scope, we attach the // the function to the window object window.renderTwitters = function (obj, options) { // private shortcuts function node(e) { return document.createElement(e); } function text(t) { return document.createTextNode(t); } var target = document.getElementById(options.twitterTarget); var data = null; var ul = node('ul'), li, statusSpan, timeSpan, i, max = obj.length > options.count ? options.count : obj.length; for (i = 0; i < max && obj[i]; i++) { data = getTwitterData(obj[i]); if (options.ignoreReplies && obj[i].text.substr(0, 1) == '@') { max++; continue; // skip } li = node('li'); if (options.template) { li.innerHTML = options.template.replace(/%([a-z_\-\.]*)%/ig, function (m, l) { var r = data[l] + "" || ""; if (l == 'text' && options.enableLinks) r = linkify(r); return r; }); } else { statusSpan = node('span'); statusSpan.className = 'twitterStatus'; timeSpan = node('span'); timeSpan.className = 'twitterTime'; statusSpan.innerHTML = obj[i].text; // forces the entities to be converted correctly if (options.enableLinks == true) { statusSpan.innerHTML = linkify(statusSpan.innerHTML); } timeSpan.innerHTML = relative_time(obj[i].created_at); if (options.prefix) { var s = node('span'); s.className = 'twitterPrefix'; s.innerHTML = options.prefix.replace(/%(.*?)%/g, function (m, l) { return obj[i].user[l]; }); li.appendChild(s); li.appendChild(text(' ')); // spacer :-( } li.appendChild(statusSpan); li.appendChild(text(' ')); li.appendChild(timeSpan); } ul.appendChild(li); } if (options.clearContents) { while (target.firstChild) { target.removeChild(target.firstChild); } } target.appendChild(ul); }; window.getTwitters = function (target, id, count, options) { guid++; if (typeof id == 'object') { options = id; id = options.id; count = options.count; } // defaulting options if (!count) count = 1; if (options) { options.count = count; } else { options = {}; } if (!options.timeout && typeof options.onTimeout == 'function') { options.timeout = 10; } if (typeof options.clearContents == 'undefined') { options.clearContents = true; } // Hack to disable withFriends, twitter changed their API so this requires auth // http://getsatisfaction.com/twitter/topics/friends_timeline_api_call_suddenly_requires_auth if (options.withFriends) options.withFriends = false; // need to make these global since we can't pass in to the twitter callback options['twitterTarget'] = target; // default enable links if (typeof options.enableLinks == 'undefined') options.enableLinks = true; // this looks scary, but it actually allows us to have more than one twitter // status on the page, which in the case of my example blog - I do! window['twitterCallback' + guid] = function (obj) { if (options.timeout) { clearTimeout(window['twitterTimeout' + guid]); } renderTwitters(obj, options); }; // check out the mad currying! ready((function(options, guid) { return function () { // if the element isn't on the DOM, don't bother if (!document.getElementById(options.twitterTarget)) { return; } var url = 'http://www.twitter.com/statuses/' + (options.withFriends ? 'friends_timeline' : 'user_timeline') + '/' + id + '.json?callback=twitterCallback' + guid + '&count=20'; if (options.timeout) { window['twitterTimeout' + guid] = setTimeout(function () { // cancel callback if (options.onTimeoutCancel) window['twitterCallback' + guid] = function () {}; options.onTimeout.call(document.getElementById(options.twitterTarget)); }, options.timeout); } var script = document.createElement('script'); script.setAttribute('src', url); document.getElementsByTagName('head')[0].appendChild(script); }; })(options, guid)); }; // GO! DOMReady(); /** Private functions */ function getTwitterData(orig) { var data = orig, i; for (i in orig.user) { data['user_' + i] = orig.user[i]; } data.time = relative_time(orig.created_at); return data; } function ready(callback) { if (!isReady) { readyList.push(callback); } else { callback.call(); } } function fireReady() { isReady = true; var fn; while (fn = readyList.shift()) { fn.call(); } } // ready and browser adapted from John Resig's jQuery library (http://jquery.com) function DOMReady() { if ( browser.mozilla || browser.opera ) { document.addEventListener( "DOMContentLoaded", fireReady, false ); } else if ( browser.msie ) { // If IE is used, use the excellent hack by Matthias Miller // http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited // Only works if you document.write() it document.write("<\/script>"); // Use the defer script hack var script = document.getElementById("__ie_init"); // script does not exist if jQuery is loaded dynamically if (script) { script.onreadystatechange = function() { if ( this.readyState != "complete" ) return; this.parentNode.removeChild( this ); fireReady.call(); }; } // Clear from memory script = null; // If Safari is used } else if ( browser.safari ) { // Continually check to see if the document.readyState is valid var safariTimer = setInterval(function () { // loaded and complete are both valid states if ( document.readyState == "loaded" || document.readyState == "complete" ) { // If either one are found, remove the timer clearInterval( safariTimer ); safariTimer = null; // and execute any waiting functions fireReady.call(); } }, 10); } } function relative_time(time_value) { var values = time_value.split(" "); time_value = values[1] + " " + values[2] + ", " + values[5] + " " + values[3]; var parsed_date = Date.parse(time_value); var relative_to = (arguments.length > 1) ? arguments[1] : new Date(); var delta = parseInt((relative_to.getTime() - parsed_date) / 1000); delta = delta + (relative_to.getTimezoneOffset() * 60); var r = ''; if (delta < 60) { r = 'less than a minute ago'; } else if(delta < 120) { r = 'about a minute ago'; } else if(delta < (45*60)) { r = (parseInt(delta / 60)).toString() + ' minutes ago'; } else if(delta < (2*90*60)) { // 2* because sometimes read 1 hours ago r = 'about an hour ago'; } else if(delta < (24*60*60)) { r = 'about ' + (parseInt(delta / 3600)).toString() + ' hours ago'; } else if(delta < (48*60*60)) { r = '1 day ago'; } else { r = (parseInt(delta / 86400)).toString() + ' days ago'; } return r; } function linkify(s) { return s.replace(/[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+/g, function(m) { return m.link(m); }).replace(/@[\S]+/g, function(m) { return '' + m + ''; }); } })();