Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
tree: 738187d079
Fetching contributors…

Cannot retrieve contributors at this time

263 lines (259 sloc) 9.781 kB
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width">
<title>twicli</title>
<style>
body {background-color: transparent; margin: 1px; min-height: 500px;}
#tw, #tw_p { font-size: small; }
#tw div div, #tw_p div div { padding: 2px; }
img { border: 0; }
.status { text-decoration: none; color: black; cursor: pointer; }
.date { color: #999; font-size: x-small; }
.fromme { background-color: #cfc; }
.tome { background-color: #ccf; }
#loading {opacity: 0.5; position: absolute; left: 50px; top: 2px; width: 220px; height: 19; }
#fst { position: absolute; left: 56px; top: 0px; width: 208px; }
#rst { position: absolute; left: 264px; top: 6px; text-decoration: none; }
.inreply { text-decoration: none; }
#rep { display: none; background-color: #fee; position: absolute; width: 90%; left: 4%; top: 200px; border: #666 4px solid; }
hr { margin: 0; padding: 0; }
form { margin: 5px; }
</style>
<script>
var myname = null;
function twAuth(a) {
if (a.error) return alert(a.error);
myname = a.screen_name;
}
</script>
<script src="http://twitter.com/account/verify_credentials.json?callback=twAuth"></script>
</head>
<body onLoad="init()">
<iframe style="display:none;" name="tx"></iframe>
<a href="http://twitter.com/home" target="twitter"><b><small>Twitter</small></b></a>
<!--発言フォーム-->
<form name="frm" action="http://twitter.com/statuses/update.xml" method="POST" onSubmit="return twSend();" target="tx">
<small><input id="fst" type="text" name="status"><input type="hidden" name="source" value="twicli">
<a id="rst" href="javascript:void(resetFrm())"><img src="clr.png"></a>
</small><img id="loading" src="loading.gif"></form>
<!--favフォーム-->
<form name="favf" action="" method="POST" target="tx"></form>
<div id="tw"><hr></div>
<div id="rep"><a href="javascript:closeRep()" style="color: red;">[x]</a><p id="reps"><p></div>
<script>
var nr_limit = 50; // 表示する更新回数の上限
var seq = (new Date).getTime();
var since_id = false;
var in_reply_to_user = false;
var myname = false;
var update_ele = false;
var reply_ele = false;
var rep_top = 0;
var failover_timeout = false;
// クロスドメインなJavaScriptを呼び出し
function loadXDomainScript(url, ele) {
if (ele)
ele.parentNode.removeChild(ele);
ele = document.createElement("script");
ele.src = url;
document.body.appendChild(ele);
return ele;
}
// 要素の位置を取得
function cumulativeOffset(ele) {
var top = 0, left = 0;
do {
top += ele.offsetTop || 0;
left += ele.offsetLeft || 0;
ele = ele.offsetParent;
} while (ele);
return [left, top];
}
// ローディング表示ON、twit更新
function reload(to) {
document.getElementById("loading").style.display = "block";
setTimeout("update()", to);
}
// 発言
function twSend() {
if (document.frm.status.value == '') { // 空欄であればTimeline更新のみ
reload(0);
return false;
}
if (!document.frm.status.value.match("@"+in_reply_to_user)) // @ユーザが含まれているときのみ返信先を指定
setReplyId(false);
in_reply_to_user = "";
document.frm.status.select();
setTimeout(resetFrm, 10); // twit送信後にフォームをクリア
reload(3000); // 送信3秒後にTimelineを更新
}
// フォームの初期化
function resetFrm() {
document.frm.reset();
setReplyId(false);
}
// reply先の設定/解除
function setReplyId(id) {
var repid = document.getElementById('in_reply_to_status_id');
if (repid)
repid.parentNode.removeChild(repid);
if (id) {
repid = document.createElement('input');
repid.type = 'hidden';
repid.id = repid.name = 'in_reply_to_status_id';
repid.value = id;
document.frm.appendChild(repid)
}
}
// reply
function replyTo(user, id) {
if (window.getSelection().toString() == '') {
in_reply_to_user = user;
document.frm.status.value += "@" + user + " ";
setReplyId(id);
document.frm.status.focus();
}
}
// reply先を表示
function dispReply(id,ele) {
var d = document.getElementById(id);
if (!d) {
rep_top = cumulativeOffset(ele)[1] + 20;
reply_ele = loadXDomainScript('http://twitter.com/statuses/show/'+id+'.json?seq='+(seq++)+'&callback=dispReply2', reply_ele);
return;
}
closeRep();
var top = cumulativeOffset(d)[1];
var h = d.offsetHeight;
var sc_top = window.pageYOffset || document.body.scrollTop;
var win_h = window.innerHeight;
if (top < sc_top) scrollTo(0, top);
if (sc_top+win_h < top+h) scrollTo(0, top+h-win_h);
var old = d.style.backgroundColor;
d.style.backgroundColor = '#fcc';
setTimeout(function(){d.style.backgroundColor = old}, 2000);
}
// reply先をoverlay表示 (Timelineに無い場合)
function dispReply2(tw) {
document.getElementById('reps').innerHTML = makeHTML(tw);
document.getElementById('rep').style.display = "block";
document.getElementById('rep').style.top = rep_top;
}
// replyのoverlay表示を閉じる
function closeRep() {
document.getElementById('rep').style.display='none';
}
// 最新twitを取得
function update() {
update_ele = loadXDomainScript('http://twitter.com/statuses/friends_timeline.json?seq=' + (seq++) +
'&callback=twShow&count=200' + (since_id ? '&since_id='+since_id : ''), update_ele);
}
// twitのHTML表現を生成
function makeHTML(tw) {
function d2(dig) { return (dig>9?"":"0") + dig }
var d = new Date(tw.created_at);
d = d.getDate() + "" + d.getHours() + ":" + d2(d.getMinutes()) + ":" + d2(d.getSeconds());
//ユーザアイコン
return (tw.user.url ? '<a target="twitter" href="'+tw.user.url+'">' : '') +
'<img border="0" align="left" width="24" height="24" alt="' + tw.user.name +
'" src="' + tw.user.profile_image_url + '">' + (tw.user.url ? '</a>' : '') +
//fav
'<img align="right" src="http://assets3.twitter.com/images/icon_star_'+(tw.favorited?'full':'empty')+'.gif" ' +
'onClick="fav(this,' + tw.id + ')">' +
//名前(Twitter本家のリンク)
'<a target="twitter" href="http://twitter.com/' + tw.user.screen_name + '">' + tw.user.screen_name +
/*プロフィールの名前*/ (tw.user.name!=tw.user.screen_name ? '('+tw.user.name+')' : '') + '</a>' +
/* protected? */ (tw.user.protected ? '<img src="http://assets0.twitter.com/images/icon_red_lock.gif">' : '') +
//本文クリックで@追加
" <span onClick=\"replyTo('" + tw.user.screen_name + "'," + tw.id + ")\" class=\"status\">" +
//本文 (https〜をリンクに置換 + @をtwitter本家へのリンクに置換)
tw.text.replace(/(https?:\/\/[^ ]*)/g, " <a onClick=\"event.stopPropagation();\" target=\"_blank\" href=\"$1\">$1</a>")
.replace(/@([0-9A-Za-z_\-]+)/g, "<a onClick=\"event.stopPropagation();\" target=\"twitter\" " +
"href=\"http://twitter.com/$1\">@$1</a>") + '</span>' +
//日付
'<span class="date">' + d + '</span>' +
//返信元へのリンク
(tw.in_reply_to_status_id ? ' <a class="inreply" href="#" onClick="dispReply('+tw.in_reply_to_status_id+',this);return false;">☞</a>' : '') +
'<br clear="left">';
}
// favoriteの追加(f=true)/削除(f=false)
function fav(img, id) {
var f = img.src.match('empty');
document.favf.action = 'http://twitter.com/favourings/' + (f ? 'create' : 'destroy') + '/' + id + '.xml';
document.favf.submit();
img.src = 'http://assets3.twitter.com/images/icon_star_' + (f ? 'full' : 'empty') + '.gif';
}
// 受信twitを表示
function twShow(tw) {
document.getElementById('loading').style.display='none';
if (failover_timeout) clearTimeout(failover_timeout);
failover_timeout = false;
var len = tw.length;
if (len == 0) return;
var twNode = document.getElementById('tw');
var pNode = document.createElement('div');
var dummy = pNode.appendChild(document.createElement('div'));
for (i = len-1; i >= 0; i--) {
if (since_id && since_id >= tw[i].id)
continue;
if (tw[i].user.profile_image_url) {
var s = document.createElement('div');
s.id = tw[i].id;
s.innerHTML = makeHTML(tw[i]);
if (tw[i].text.match('@'+myname+' '))
s.className = "tome";
if (tw[i].user.screen_name == myname)
s.className = "fromme";
pNode.insertBefore(s, pNode.childNodes[0]);
pNode.insertBefore(document.createElement('hr'), s);
}
}
pNode.removeChild(dummy);
twNode.insertBefore(pNode, twNode.childNodes[0]);
var maxH = pNode.clientHeight;
pNode.style.overflow = "hidden";
if ((window.pageYOffset || document.body.scrollTop) > 10)
scrollBy(0, maxH);
else
animate(pNode, maxH, (new Date).getTime());
while (twNode.childNodes.length > nr_limit)
twNode.removeChild(twNode.childNodes[nr_limit]);
since_id = tw[0].id;
}
// 新規twitの出現アニメーション処理
function animate(elem, max, start) {
var t = (new Date).getTime();
if (start+1000 <= t)
return elem.style.maxHeight = 'none';
elem.style.maxHeight = Math.ceil(max*(1-Math.cos((t-start)/1000*Math.PI))/2);
setTimeout(function(){ animate(elem, max, start) }, 50);
}
function init() {
setTimeout(scrollTo, 0, 0, 1);
// 初回アップデート
setTimeout(update, 0);
setInterval(update, 60*1000);
}
// ホイールの回転でスクロール (スクロール不可のウィンドウ・フレーム内で有効)
function wheel(event) {
var delta = 0;
if (!event) event = window.event;
if (event.wheelDelta) {
delta = event.wheelDelta/10;
} else if (event.detail)
delta = -event.detail;
if (navigator.userAgent.indexOf("Firefox") != -1)
delta *= 10;
if (delta)
scrollBy(0, -delta);
if (event.preventDefault)
event.preventDefault();
event.returnValue = false;
}
if (window.addEventListener) window.addEventListener('DOMMouseScroll', wheel, false);
window.onmousewheel = document.onmousewheel = wheel;
</script>
</body>
</html>
Jump to Line
Something went wrong with that request. Please try again.