Created
March 14, 2010 16:12
-
-
Save kentbrew/332055 to your computer and use it in GitHub Desktop.
Twitter Search Widget
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1: copy index.html and sxsw.js to your local hard drive. | |
(For best results, click the RAW link next to each one.) | |
2: drag index.html into your browser. | |
3: have fun, and hit me up on Twitter at @kentbrew if you're having trouble. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<title>Twitter Search Widget</title> | |
</head> | |
<body> | |
<script src="twitter_search.js"></script> | |
</body> | |
</html> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// bare-bones Twitter search widget | |
// Kent Brewster | |
// TODO: unfuck goBack. It's presently broken; sorry about that! | |
(function (d, w) { | |
var $, k; | |
k = 'kb_' + new Date().getTime(); | |
var $ = w[k] = {}; | |
$.k = k; | |
$.d = d; | |
$.w = w; | |
$.f = (function () { | |
return { | |
init : function (findMe) { | |
var i, s; | |
s = $.d.getElementsByTagName('SCRIPT'); | |
for (i = 0; i < s.length; i = i + 1) { | |
if (s[i].src.match(findMe)) { | |
$.s = $.d.createElement('DIV'); | |
var settings = s[i].getAttribute('settings'); | |
s[i].parentNode.insertBefore($.s, s[i]); | |
s[i].parentNode.removeChild(s[i]); | |
$.f.houseKeep(); | |
break; | |
} | |
} | |
}, | |
houseKeep : function() { | |
$.a = { | |
"count": "10", | |
"w": 300, | |
"p": 2 | |
} | |
$.v = {}; | |
$.p = []; | |
$.v.goBack = []; | |
$.d.h = $.d.getElementsByTagName('HEAD')[0]; | |
$.d.b = $.d.getElementsByTagName('BODY')[0]; | |
$.f.presentation(); | |
$.f.structure(); | |
$.f.behavior(); | |
}, | |
structure : function () { | |
$.s.id = $.k; | |
$.s.k = $.d.createElement('DIV'); | |
$.s.k.id = $.k + '_inner'; | |
$.s.q = $.d.createElement('INPUT'); | |
$.s.k.appendChild($.s.q); | |
$.s.ul = $.d.createElement('UL'); | |
$.s.k.appendChild($.s.ul); | |
$.s.appendChild($.s.k); | |
}, | |
presentation : function () { | |
var inner, outer, styles, rules, css; | |
outer = '#' + $.k; | |
// atri: the open area at the heart of the house | |
inner = outer + ' #' + $.k + '_inner'; | |
// high level of CSS specificity should protect most interior content from outside styles | |
styles = [ | |
outer + ' { background:#000; border:1px solid #000; -moz-border-radius:3px; -webkit-border-radius:3px; margin:0; outline:0; position:absolute; width:' + $.a.w + 'px; }', | |
inner + ' * { border:0; color:inherit; font:normal normal normal 12px/16px arial; list-style:none; margin:0; outline:0; padding:0; text-align:inherit; text-indent:0; zoom:1; }', | |
inner + ' { background:#fff;color:#000;margin:' + $.a.p + 'px;overflow:none;text-align:left;}', | |
inner + ' input { background:#fff url(http://twitter.com/favicon.ico) no-repeat scroll 2px 50%; padding:3px 3px 3px 20px; width:' + ($.a.w - 30) + 'px;}', | |
inner + ' ul { list-style:none; }', | |
inner + ' li { margin-top:3px;padding:3px 6px; border-top:1px dashed #aaa;}', | |
inner + ' li.footer { text-align:right;}', | |
inner + ' li cite { font-weight:bold; padding-right:3px; }', | |
inner + ' li a { color:#f00; text-decoration:none; cursor:pointer;}', | |
inner + ' li img { height:48px; width:48px; float:left; margin:3px 6px 5px 0; }', | |
inner + ' li date { display:block; font-size: 90%; text-align:right; }', | |
inner + ' li:after { content:"."; display:block; height:0; clear:both; visibility:hidden; }', | |
inner + ' .hide { display:none!important; }' | |
]; | |
rules = styles.join("\n"); | |
css = $.d.createElement('STYLE'); | |
css.type = 'text/css'; | |
if (css.styleSheet) { | |
css.styleSheet.cssText = rules; | |
} else { | |
css.appendChild($.d.createTextNode(rules)); | |
} | |
$.d.h.appendChild(css); | |
}, | |
behavior : function () { | |
setInterval($.f.run, 1000); | |
}, | |
run : function () { | |
var i, id, n, s, url, q; | |
if ($.s.q.value) { | |
if ($.s.q.value !== $.v.lastQuery) { | |
for (i = 0; i < $.v.goBack.length; i++) { | |
if ($.v.goBack[i] === $.v.lastQuery) { | |
$.v.goBack.splice(i, 1); | |
} | |
} | |
$.v.goBack.push($.v.lastQuery); | |
$.v.lastQuery = $.s.q.value; | |
var n = $.p.length; | |
var id = $.k + '.p[' + n + ']'; | |
$.p[n] = function(r) { | |
delete($.p[n]); | |
$.f.removeScript($.k + '.p[' + n + ']'); | |
$.f.render(r); | |
}; | |
// ick, not sure how to escape a double quote | |
var q = $.s.q.value.replace(/\"/g, ''); | |
var url = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20twitter.search%20where%20rpp=50%20and%20q%3D%22" + encodeURIComponent(q) + "%22&format=json&diagnostics=false&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=" + id; | |
$.f.runScript(url, $.k + '.p[' + n + ']'); | |
} | |
} else { | |
if ($.v.lastQuery) { | |
$.v.lastQuery = ''; | |
$.s.ul.innerHTML = ''; | |
} | |
} | |
}, | |
render : function (z) { | |
var i, r, li, a, created_at, from_user, span, img; | |
$.s.ul.innerHTML = ''; | |
if (z.query && z.query.results && z.query.results.results && z.query.results.results.length) { | |
r = z.query.results.results; | |
for (i = 0; i < r.length; i++) { | |
li = $.d.createElement('LI'); | |
img = $.d.createElement('IMG'); | |
img.src = r[i].profile_image_url; | |
li.appendChild(img); | |
from_user = $.d.createElement('CITE'); | |
from_user.onclick = function() { | |
$.s.q.value = 'from:' + this.innerHTML; | |
} | |
from_user.textContent = r[i].from_user; | |
li.appendChild(from_user); | |
span = $.d.createElement('SPAN'); | |
var raw = r[i].text; | |
cooked = raw.replace(/"/g, '"'); | |
var cooked = raw.replace(/\/u([^ ]+)/gi, "&#$1;"); | |
cooked = cooked.replace(/http:\/\/([^ ]+)/g, "<a href=\"http://$1\" target=\"_blank\">http://$1</a>"); | |
var woo = '@<a onclick="' + $.k + '.f.stuffQuery(this.innerHTML, \'from:\');">$1</a>'; | |
cooked = cooked.replace(/@([\w*]+)/g, woo); | |
var yay = '#<a onclick="' + $.k + '.f.stuffQuery(this.innerHTML, \'\');">$1</a>'; | |
cooked = cooked.replace(/#([\w*]+)/g, yay) | |
span.innerHTML = cooked; | |
li.appendChild(span); | |
created_at = $.d.createElement('DATE'); | |
created_at.textContent = r[i].created_at.split(',')[1].split('+')[0]; | |
li.appendChild(created_at); | |
$.s.ul.appendChild(li); | |
} | |
} | |
if ($.v.goBack.length) { | |
li = $.d.createElement('LI'); | |
li.className = 'footer'; | |
li.appendChild($.d.createTextNode('go back to: ')); | |
a = $.d.createElement('A'); | |
a.innerHTML = $.v.goBack[$.v.goBack.length - 1]; | |
a.onclick = function() { | |
$.s.q.value = this.innerHTML; | |
$.v.goBack.pop(); | |
} | |
li.appendChild(a); | |
$.s.ul.appendChild(li); | |
} | |
}, | |
stuffQuery : function(v, p) { | |
$.s.q.value = p + v; | |
}, | |
runScript : function(url, id) { | |
var s = $.d.createElement('script'); | |
s.id = id; | |
s.type ='text/javascript'; | |
s.src = url; | |
$.d.b.appendChild(s); | |
}, | |
removeScript : function(id) { | |
if ($.d.getElementById(id)) { | |
var s = $.d.getElementById(id); | |
s.parentNode.removeChild(s); | |
} | |
} | |
}; | |
}()); | |
$.f.init(/twitter_search\.js$/); | |
}(document, window)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment