/**
* remy sharp / http://remysharp.com
* Twitter / @rem
* 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,
* newwindow {Boolean} opens links in new window, defaults to false
* 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)
* callback: {Function} Callback function once the render is complete, doesn't fire on timeout
*
* CURRENTLY DISABLED DUE TO CHANGE IN TWITTER API:
* withFriends: {Boolean} includes friend's status
*
* }
*
* @license MIT (MIT-LICENSE.txt)
* @version 1.13.3 - ify now supports lists
* @date $Date: 2010-11-10 15:05:04 $
*/
// to protect variables from resetting if included more than once
if (typeof renderTwitters != 'function') (function () {
/** Private variables */
// only used for the DOM ready, since IE & Safari require special conditions
var browser = (function() {
var b = navigator.userAgent.toLowerCase();
// Figure out what browser is being used
return {
webkit: /(webkit|khtml)/.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;
var monthDict = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
/** Global functions */
// based on Dustin Diaz's ify, but with my fixes :-)
window.ify = function() {
var entities = {
'"' : '"',
'&' : '&',
'<' : '<',
'>' : '>'
};
//tweetURL = "http://www.gsn.com"; //default can break CSS if there is no URL in tweet coming in
twitter_tag_img = "";
return {
"tweeturl": function(t) {
return t.replace(/[a-z]+:\/\/[a-z0-9-_]+\.[a-z0-9-_:~%&\?#\/.=]+[^:\.,\)\s*$]/ig, function(m) {
return '' + ((m.length > 25) ? m.substr(0, 24) + '...' : m) + '';
//tweetURL = m;
return '';
});
},
// "urllink": function(t) {
// return '' + t + '';
// },
//"at": function(t) {
// return t.replace(/(^|[^\w]+)\@([a-zA-Z0-9_]{1,15}(\/[a-zA-Z0-9-_]+)*)/g, function(m, m1, m2) {
// return m1 + '@' + m2 + '';
// });
//},
"hashes": function(t) {
return t.replace(/(^|[^&\w'"]+)\#([a-zA-Z0-9_]+)/g, function(m, m1, m2) {
//return m1 + '#' + m2 + '';
return m1 + '#' + m2 + '';
});
},
"hash_fb": function(t) {
return t.replace(/(^|[^&\w'"]+)\#fb/g, function(m, m1, m2) {
return '';
});
},
"hash_imgcheck": function(t) {
var matchOne = /#Prize/;
var matchTwo = /#Sweeps/;
var matchThree = /#Buyitnow/;
var matchFour = /#Playtowin/;
var matchFive = /#Auctions/;
if ( matchOne.test(t) ) { twitter_tag_img = "update"; }
else if ( matchTwo.test(t) ) { twitter_tag_img = "sweeps"; }
else if ( matchThree.test(t) ) { twitter_tag_img = "buyitnow"; }
else if ( matchFour.test(t) ) { twitter_tag_img = "playtowin"; }
else if ( matchFive.test(t) ) { twitter_tag_img = "auctions"; }
return t;
},
"imgswap": function(t) {
if ( twitter_tag_img != "" ) {
var img_tag = twitter_tag_img;
twitter_tag_img = "";
//alert(t);
return '' + t;
} else {
return t;
}
},
//"hash_oodles": function(t) {
// return t.replace(/(^|[^&\w'"]+)\#oodles/g, function(m, m1, m2) { return ''; });
//},
"clean": function(tweet) {
return this.imgswap( this.hash_imgcheck( this.tweeturl( this.hashes( this.hash_fb( tweet ) ) ) ) ) ;
}
};
}();
// 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;
var classincrement = 0;
for (i = 0; i < max && obj[i]; i++) {
data = getTwitterData(obj[i]);
if (options.ignoreReplies && obj[i].text.substr(0, 1) == '@')
{
max++;
continue; // skip
}
matchOne = /#Prize/;
matchTwo = /#Sweeps/;
matchThree = /#Buyitnow/;
matchFour = /#Playtowin/;
matchFive = /#Auctions/;
if ( matchOne.test(obj[i].text) ||
matchTwo.test(obj[i].text) ||
matchThree.test(obj[i].text) ||
matchFour.test(obj[i].text) ||
matchFive.test(obj[i].text)
)
{
classincrement ++
} else {
max++;
continue; // skip anything NOT prizes
}
li = node('li');
li.className = 'tweet' + classincrement; //'tweet' + i;
if (options.template) {
li.innerHTML = options.template.replace(/%([a-z_\-\.]*)%/ig, function (m, l) {
var r = data[l] + "" || "";
if (l == 'text' && options.enableLinks) r = ify.clean(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 = ify.clean(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);
}
if (options.newwindow) {
li.innerHTML = li.innerHTML.replace(/<\/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;
} else if ( browser.webkit ) {
// 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(" "),
parsed_date = Date.parse(values[1] + " " + values[2] + ", " + values[5] + " " + values[3]),
date = new Date(parsed_date),
relative_to = (arguments.length > 1) ? arguments[1] : new Date(),
delta = parseInt((relative_to.getTime() - parsed_date) / 1000),
r = '';
function formatTime(date) {
var hour = date.getHours(),
min = date.getMinutes() + "",
ampm = 'AM';
if (hour == 0) {
hour = 12;
} else if (hour == 12) {
ampm = 'PM';
} else if (hour > 12) {
hour -= 12;
ampm = 'PM';
}
if (min.length == 1) {
min = '0' + min;
}
return hour + ':' + min + ' ' + ampm;
}
function formatDate(date) {
var ds = date.toDateString().split(/ /),
mon = monthDict[date.getMonth()],
day = date.getDate()+'',
dayi = parseInt(day),
year = date.getFullYear(),
thisyear = (new Date()).getFullYear(),
th = 'th';
// anti-'th' - but don't do the 11th, 12th or 13th
if ((dayi % 10) == 1 && day.substr(0, 1) != '1') {
th = 'st';
} else if ((dayi % 10) == 2 && day.substr(0, 1) != '1') {
th = 'nd';
} else if ((dayi % 10) == 3 && day.substr(0, 1) != '1') {
th = 'rd';
}
if (day.substr(0, 1) == '0') {
day = day.substr(1);
}
return mon + ' ' + day + th + (thisyear != year ? ', ' + year : '');
}
delta = delta + (relative_to.getTimezoneOffset() * 60);
if (delta < 5) {
r = 'less than 5 seconds ago';
} else if (delta < 30) {
r = 'half a minute ago';
} else if (delta < 60) {
r = 'less than a minute ago';
} else if (delta < 120) {
r = '1 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 1 hour ago';
} else if (delta < (24*60*60)) {
r = 'about ' + (parseInt(delta / 3600)).toString() + ' hours ago';
} else {
if (delta < (48*60*60)) {
r = formatTime(date) + ' yesterday';
} else {
r = formatTime(date) + ' ' + formatDate(date);
// r = (parseInt(delta / 86400)).toString() + ' days ago';
}
}
return r;
}
})();