Created
September 19, 2012 14:20
-
-
Save tanamako/3749928 to your computer and use it in GitHub Desktop.
forked: simple twitter search
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
html{ | |
background:#fff; | |
} | |
html,body,ul,li,p,form{ | |
margin:0; | |
padding:0; | |
} | |
html,body{ | |
} | |
.highlight-word{ | |
background-color:#ffff80; | |
} | |
a img{ | |
border:none; | |
} | |
a{ | |
text-decoration:none; | |
} | |
a:hover{ | |
text-decoration:underline; | |
} | |
.twsrrlt{ | |
overflow:auto; | |
width:90%; | |
padding:0 5px; | |
position:fixed;/* for Opera*/ | |
} | |
* html .twsrrlt{ | |
position:relative; | |
} | |
.twsrrlt ul.twl{ | |
list-style-type:none; | |
} | |
.twsrrlt .twl li{ | |
margin:6px 0; | |
padding:6px; | |
position:relative; | |
background-image:none; | |
-moz-border-radius:6px; | |
border-radius:6px; | |
color:#222; | |
border:2px solid #fff; | |
} | |
.twsrrlt .twl li.new{ | |
border-color:#ffff80; | |
} | |
.twsrrlt .twl li.odd{ | |
background-color: #eee; | |
} | |
.twsrrlt .twl li.even{ | |
background-color: #ddd; | |
} | |
.twsrrlt .twl li a.usr{ | |
width:50px; | |
position:absolute; | |
top:5px; | |
} | |
* html .twsrrlt .twl li a.usr{ | |
width:50px; | |
} | |
.twsrrlt .twl li a.usr{ | |
height:50px; | |
overflow:hidden; | |
} | |
.twsrrlt .twl li a.usr:hover{ | |
height:auto; | |
overflow:visible; | |
width:auto; | |
min-width:50px; | |
} | |
.twsrrlt .twl li a.usr:hover span{ | |
padding:2px 6px; | |
background:#fff; | |
-moz-border-radius:4px; | |
border-radius:4px; | |
word-break: keep-all; | |
word-wrap: normal; | |
} | |
.twsrrlt .twl li p{ | |
margin:0; | |
display:inline-block; | |
} | |
* html .twsrrlt .twl li p{ | |
display:block; | |
} | |
.twsrrlt .twl li p.entry{ | |
min-height:55px; | |
margin-left:52px; | |
} | |
* html .twsrrlt .twl li p.entry{ | |
height:55px; | |
} | |
.twsrrlt .twl li div.time{ | |
display:block; | |
text-align:right; | |
background:#fafafa; | |
-moz-border-radius:4px; | |
border-radius:4px; | |
padding:2px; | |
margin:6px 0 0; | |
} | |
.twsrrlt .twl li div.time a{ | |
padding:0 2px; | |
} | |
#timer{ | |
position:absolute; | |
display:inline; | |
display:inline-block; | |
top:0px; | |
right:0px; | |
font-size:150%; | |
color:#444; | |
background:#ccc; | |
-moz-border-radius:4px; | |
border-radius:4px; | |
padding:4px; | |
} | |
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
<form id="searchform"> | |
<input type="search" id="searchvalue" value="JavaScript"> | |
<select id="searchlang"> | |
<option value="all">all</option> | |
<option value="ja">ja</option> | |
</select> | |
<input type="submit" value="検索"> | |
</form> | |
<div id="search-result" class="twsrrlt"></div> | |
<div id="timer"></div> | |
<ul id="search-tmpl" style="display:none;"> | |
<li> | |
<a class="usr"> | |
<img width="48" height="48"><br> | |
<span></span> | |
</a> | |
<p class="entry"></p> | |
<div class="time"> | |
<a class="source"></a> | |
<a class="username"></a> | |
<a class="timelink"></a> | |
</div> | |
</li> | |
</ul> |
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
// forked from os0x's "simple twitter search" http://jsdo.it/os0x/search.twitter | |
/* | |
* シンプルなTwitter検索 | |
*/ | |
if (!window.XMLHttpRequest){ | |
XMLHttpRequest = function () { | |
try { | |
return new ActiveXObject("Msxml2.XMLHTTP.6.0"); | |
} catch (e) {} | |
try { | |
return new ActiveXObject("Msxml2.XMLHTTP.3.0"); | |
} catch (e) {} | |
try { | |
return new ActiveXObject("Msxml2.XMLHTTP"); | |
} catch (e) {} | |
throw new Error("This browser does not support XMLHttpRequest."); | |
}; | |
} | |
var tmpl = document.getElementById('search-tmpl').getElementsByTagName('li')[0]; | |
var timeline = document.getElementById('search-result'); | |
var tree; | |
var prev_result; | |
function TwitterCallback(data){ | |
if (prev_result){ | |
write_timeline(data); | |
} else { | |
clear(); | |
write_timeline(data); | |
start_timer(); | |
} | |
prev_result = data; | |
} | |
function clear(){ | |
if(tree){ | |
timeline.removeChild(tree); | |
tree = null; | |
} | |
} | |
document.body.onclick = function(e){ | |
var evt = e || window.event; | |
var target = evt.target || evt.srcElement; | |
if (target.href && target.innerHTML.indexOf('#') === 0) { | |
searchvalue.value = target.innerHTML; | |
searchform.onsubmit(); | |
return false; | |
} | |
}; | |
function write_timeline(data){ | |
var keyword = searchvalue.value; | |
var results = data.results; | |
if (!tree) { | |
tree = document.createElement('ul'); | |
tree.className = 'twl'; | |
} | |
var items = tree.childNodes.length; | |
results.reverse(); | |
if(prev_result){ | |
for (var i = 0, len = prev_result.results.length;i < len; i++){ | |
var _li = tree.childNodes[i]; | |
_li.className = _li.className.replace(/(\s)+new(\s*|$)/,''); | |
} | |
} | |
for (i = 0, len = results.length;i < len; i++){ | |
var usr = results[i]; | |
var user = usr.from_user; | |
/* 要素を作る */ | |
var li = tmpl.cloneNode(true); | |
var link = li.getElementsByTagName('a')[0]; | |
var icon = link.getElementsByTagName('img')[0]; | |
var name = link.getElementsByTagName('span')[0]; | |
var entry = li.getElementsByTagName('p')[0]; | |
var time = li.getElementsByTagName('div')[0]; | |
var source = time.getElementsByTagName('a')[0]; | |
var username = time.getElementsByTagName('a')[1]; | |
var timelink = time.getElementsByTagName('a')[2]; | |
/* CSS用にclassを設定 */ | |
li.className = (((i+1+items)%2) ? 'odd' : 'even') + ' new'; | |
/* リンクや画像などの属性を設定 */ | |
username.href = link.href = 'http://twitter.com/' + user; | |
var src = usr.profile_image_url; | |
if (src.indexOf('http') === 0) { | |
icon.src = src; | |
} | |
icon.width = 48; | |
icon.height = 48; | |
timelink.href = 'http://twitter.com/' + | |
user +'/status/' + usr.id; | |
var d = new Date(usr.created_at); | |
var date = d.getFullYear() + '/' + (d.getMonth()+1) + | |
'/' + d.getDate() + ' ' + d.getHours() + ':' + | |
('0'+d.getMinutes()).slice(-2); | |
/* テキストノードの挿入 */ | |
var node = document.createTextNode(usr.text.replace(/&(lt|gt|quot|amp);/g,function(_$,_1){ | |
return {lt:'<', gt:'>', quot:'"', amp:'&'}[_1]; | |
})); | |
entry.appendChild(node); | |
linkfy(entry, '@(\\w+)', '[^\\w@]|$', 'http://twitter.com/'); | |
linkfy(entry, '#(\\w+)', '[^\\w#]|$', 'http://search.twitter.com/search?q=%23'); | |
linkfy(entry, '(https?://.*)', '[ \\)\\]\'\"\n]|$', ''); | |
expandUrl(entry); | |
highlight(entry, keyword); | |
if (usr.source){ | |
var match = usr.source.match(/"(http.*?)"/); | |
if(match){ | |
source.href = match[1]; | |
source.appendChild(document.createTextNode('from '+usr.source.match(/>(.*?)</)[1])); | |
} | |
} | |
username.appendChild(document.createTextNode('@' + user)); | |
timelink.appendChild(document.createTextNode(date)); | |
name.appendChild(document.createTextNode(user)); | |
/* 要素の組み立て */ | |
tree.insertBefore(li, tree.firstChild); | |
} | |
/* 画面に反映 */ | |
if (!tree.parentNode || !tree.parentNode.parentNode){ | |
timeline.appendChild(tree); | |
} | |
} | |
function highlight(element, keyword){ | |
for (var i =0,l = element.childNodes.length;i < l;i++){ | |
var node = element.childNodes[i]; | |
if(node.nodeType !== 3){ | |
continue; | |
} | |
var keywordExp = new RegExp(keyword,'i'); | |
var keywordLength = keyword.length; | |
if (node.nodeValue.search(keywordExp) >= 0) { | |
var text = node.nodeValue, index; | |
var parent = node.parentNode; | |
while (text && (index=text.search(keywordExp)) >= 0 ){ | |
// テキストを分割し、後ろ側のノードを取得 | |
var _txt = node.splitText(index); | |
// キーワードの終わりで再度分割 | |
var __txt = _txt.splitText(keywordLength); | |
var s = document.createElement('span'); | |
s.className ='highlight-word'; | |
s.appendChild(_txt); | |
if (!__txt.nodeValue || !__txt.parentNode){ | |
parent.appendChild(__txt); | |
} else { | |
parent.insertBefore(s, __txt); | |
} | |
// ループ用に初期化 | |
text = __txt.nodeValue; | |
node = __txt; | |
} | |
} | |
} | |
} | |
function linkfy(element, start, end, prefix){ | |
for (var i =0,l = element.childNodes.length;i < l;i++){ | |
var node = element.childNodes[i]; | |
if(node.nodeType !== 3){ | |
continue; | |
} | |
if (node.nodeValue.search(start) >= 0) { | |
var text = node.nodeValue, index; | |
var parent = node.parentNode; | |
while (text && (index=text.search(start)) >= 0 ){ | |
// テキストを分割し、後ろ側のノードを取得 | |
var _txt = node.splitText(index); | |
// キーワードの終わりで再度分割 | |
var _end = _txt.nodeValue.search(end); | |
var __txt = _txt.splitText(_end); | |
var a = document.createElement('a'); | |
a.href = prefix + _txt.nodeValue.match(start)[1]; | |
a.target = '_blank'; | |
a.appendChild(_txt); | |
if (!__txt.nodeValue || !__txt.parentNode){ | |
parent.appendChild(a); | |
} else { | |
parent.insertBefore(a, __txt); | |
} | |
// ループ用に初期化 | |
text = __txt.nodeValue; | |
node = __txt; | |
} | |
} | |
} | |
} | |
function expandUrl(element){ | |
var links = element.getElementsByTagName('a'); | |
for (var i =0,l = links.length;i < l;i++){ | |
var a = links[i]; | |
if (a.href.length < 30 && a.host !== 'twitter.com'){ | |
getCrossSiteXhrOrJsonP(a); | |
} | |
} | |
} | |
function getCrossSiteXhrOrJsonP(a){ | |
var same_origin = location.hostname === 'ss-o.net' && (location.port==='' || location.port==='80') && location.protocol === 'http:'; | |
var xhr; | |
var onload = function(){ | |
var data = JSON.parse(xhr.responseText); | |
if (data.url && data.url !== a.href){ | |
a.textContent = data.url; | |
a.href = data.url; | |
} | |
}; | |
if (same_origin) { | |
xhr = new XMLHttpRequest(); | |
} else if(window.XDomainRequest){ | |
xhr = new XDomainRequest(); | |
} else if(window.XMLHttpRequest) { | |
xhr = new XMLHttpRequest(); | |
if (!('withCredentials' in xhr)){ | |
xhr = { | |
open:function(method, url){ | |
var s = xhr.__script = document.createElement('script'); | |
var callback = ('JSONP_' + new Date().getTime() + Math.random()).replace(/\W/,''); | |
s.src = url + '&callback=' + callback; | |
window[callback] = function(data){ | |
xhr.responseText = JSON.stringify(data); | |
onload(); | |
document.body.removeChild(s); | |
delete window[callback]; | |
}; | |
}, | |
send:function(){ | |
document.body.appendChild(xhr.__script); | |
} | |
}; | |
} | |
} | |
xhr.open('GET', 'http://ss-o.net/api/reurl.json?url=' + encodeURIComponent(a.href), true); | |
if (!('onload' in xhr)){ | |
xhr.onreadystatechange = function(){ | |
if(xhr.readyState === 4 && xhr.status === 200){ | |
onload(); | |
} | |
}; | |
} else { | |
xhr.onload = onload; | |
}; | |
xhr.send(null); | |
} | |
var searchform = document.getElementById('searchform'); | |
var searchvalue= document.getElementById('searchvalue'); | |
var searchlang = document.getElementById('searchlang'); | |
var timer = document.getElementById('timer'); | |
var lang = ''; | |
function getJSONP(query){ | |
var script = document.createElement('script'); | |
script.src = 'http://search.twitter.com/search.json' + query; | |
document.body.appendChild(script); | |
} | |
searchform.onsubmit=function(){ | |
prev_result = null; | |
clearInterval(timerID); | |
lang = searchlang.value; | |
getJSONP('?callback=TwitterCallback&lang='+lang+'&q=' + encodeURIComponent(searchvalue.value)); | |
// submitをキャンセル(ページ遷移させない) | |
return false; | |
}; | |
/* | |
var addEvent = (document.addEventListener) ? | |
function(node,type,handler){ | |
node.addEventListener(type,handler,false); | |
} | |
: function(node,type,handler){ | |
node.attachEvent('on' + type, function(evt){ | |
handler.call(node, evt); | |
}); | |
}; | |
addEvent(searchform, 'submit', function(evt){ | |
prev_result = null; | |
clearInterval(timerID); | |
lang = searchlang.value; | |
getJSONP('?callback=TwitterCallback&lang='+lang+'&q=' + | |
encodeURIComponent(searchvalue.value)); | |
// submitをキャンセル(ページ遷移させない) | |
if (evt.preventDefault) { | |
evt.preventDefault(); | |
} else { | |
evt.returnValue = false; | |
} | |
}); | |
*/ | |
var TIME = 60, timerID; | |
function start_timer(){ | |
var time = TIME; | |
timerID = setInterval(function(){ | |
time--; | |
timer.innerHTML = time; | |
if(time === 0){ | |
time = TIME; | |
if (prev_result){ | |
getJSONP(prev_result.refresh_url+'&callback=TwitterCallback&lang='+lang); | |
} | |
} | |
}, 1000); | |
} | |
window.onresize = function(){ | |
timeline.style.height = (document.documentElement.clientHeight - searchform.offsetHeight) + 'px'; | |
}; | |
window.onresize(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment