Created
January 16, 2011 02:41
-
-
Save tkawa/781494 to your computer and use it in GitHub Desktop.
リプライをTL上に自動的に展開表示する twicli プラグイン
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
var embedReply, tweetCache = {}; | |
(function () { | |
// APIが足りない時用proxy(気休め) | |
var proxies = [ | |
{ | |
url: twitterAPI + 'statuses/show/{id}.json?suppress_response_codes=true', | |
filter: function (d) { return d } | |
}, | |
{ | |
url: 'https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20twitter.status%20where%20id%3D{id}%3B&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys', | |
filter: function (d) { | |
var tw = d.query.results.status; | |
if (!tw) return tw; // TODO: エラー処理 | |
for (k in tw) { | |
if (tw[k] == 'false') tw[k] = false; | |
} | |
for (k in tw.user) { | |
if (tw.user[k] == 'false') tw.user[k] = false; | |
} | |
return tw; | |
} | |
} | |
]; | |
// トリガーになるボタンをつくる | |
function makeEmbedButton(element, tw) { | |
//console.log(['makeEmbedButton', element, tw]); | |
tw = tw.retweeted_status || tw; | |
if (tw.in_reply_to_status_id_str) { | |
// getElementsByClassName使ってるのでIEでは動かない? | |
var reply = element.getElementsByClassName('reply'); | |
if (reply.length > 0) { | |
reply = reply[0]; | |
var embrep = document.createElement('a'); | |
embrep.className = 'button embrep'; | |
embrep.setAttribute('href', '#'); | |
/* | |
embrep.onclick = function () { | |
embedReply(tw.in_reply_to_screen_name, tw.in_reply_to_status_id_str, this); | |
} | |
*/ | |
embrep.setAttribute('onclick', | |
"embedReply('" | |
+ tw.in_reply_to_screen_name | |
+ "','" | |
+ tw.in_reply_to_status_id_str | |
+ "',this);return false;" | |
); | |
embrep.innerHTML = '@'; | |
reply.parentNode.insertBefore(embrep, reply); | |
} else { | |
console.log(['reply button not found', element]); | |
} | |
} | |
} | |
// 上でつくった埋め込みボタンを自動的に押す | |
function autoEmbed(tw, tw_node, nr_show) { | |
//console.log(['autoEmbed', tw, tw_node, nr_show]); | |
if (nr_show > 0) { | |
links = tw_node.getElementsByClassName('embrep'); | |
//console.log(['search embrep', links]); | |
for (var i = 0; i < links.length; i++) { | |
//console.log(['click function', links[i].onclick, links[i]]); | |
if (getTweetDiv(links[i]).id.indexOf('emb-') == -1) { // 今のところ、2つ以上は自動で開かない | |
links[i].onclick(); // click()ではなぜか動かなかった(Chrome) | |
} | |
} | |
} | |
} | |
// ボタンから呼ばれる | |
embedReply = function (user, id, elem) { | |
//console.log(arguments); | |
$('loading').style.display = 'block'; | |
fetchTweet(id, function (tw) { | |
//console.log(tw); | |
$('loading').style.display = 'none'; | |
var el = document.createElement('div'); | |
el.id = 'emb-'+id; | |
el.className = 'emb'; | |
el.style.paddingLeft = '32px'; //とりあえずのスタイル | |
el.innerHTML = makeHTML(tw, false, 'emb'); | |
el.tw = tw; | |
callPlugins("newMessageElement", el, tw, 'emb'); | |
var p_elem = getTweetDiv(elem); | |
if (p_elem.parentNode) { | |
p_elem.parentNode.insertBefore(el, p_elem.nextSibling); | |
// twShowToNode の duplication の処理のところで呼ばれる removeChild を差し替え | |
// addEventListener('DOMNodeRemoved', ... ) のほうがいいんじゃないかと思いつつ | |
p_elem.parentNode.removeChild = removeChildAndEmbedded; | |
} | |
elem.parentNode.removeChild(elem); | |
}); | |
}; | |
// リプライもまとめて削除する差し替え用関数 | |
function removeChildAndEmbedded (removedNode) { | |
var removeChild_original = $('re').removeChild; // Element.prototype.removeChild のつもり | |
var emb = removedNode.nextSibling; | |
while (emb && emb.id.indexOf('emb-') != -1) { | |
var emb_next = emb.nextSibling; | |
removeChild_original.call(this, emb); | |
emb = emb_next; | |
} | |
return removeChild_original.call(this, removedNode); | |
}; | |
// API消費が激しい可能性があるのでできるだけキャッシュしておく | |
function fetchTweet(id, callback) { | |
if (tweetCache[id]) { | |
callback(tweetCache[id]); | |
return; | |
} | |
var d = $('tw-' + id) || $('re-' + id) || $('tw2c-' + id) || $('emb-' + id); | |
if (d && d.tw) { | |
tweetCache[id] = d.tw; | |
callback(d.tw); | |
} else { | |
var proxy = proxies[0]; // 0はproxyなし | |
var url = proxy.url.replace(/\{id\}/, id); | |
xds.load(url, function (tw) { | |
tw = proxy.filter(tw); | |
tweetCache[id] = tw; | |
callback(tw); | |
}); | |
} | |
} | |
// 任意のElementから親をたどっていって、含まれるツイートのdivを得る | |
function getTweetDiv(elem) { | |
var t = elem; | |
while (t && !(t.tagName.toLowerCase() == 'div' && /^[a-z0-9]+-\d{10,}$/.test(t.id))) t = t.parentNode; | |
return t; | |
} | |
// twShowToNode関数に独自のフックポイントを追加 | |
var twShowToNode_original = twShowToNode; | |
twShowToNode = function (tw, tw_node) { | |
var nr_show = twShowToNode_original.apply(window, arguments); | |
callPlugins("afterTwShowToNode", tw, tw_node, nr_show, arguments); | |
return nr_show; | |
}; | |
registerPlugin({ | |
newMessageElement: makeEmbedButton, | |
afterTwShowToNode: autoEmbed | |
}); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment