TwitterのAPIでは<や&などがエスケープされた状態
個々の発言の作成#1
/* エスケープされた文字を戻す */
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);
さて,
テキストのリンク化
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;
}
}
}
}
最後は短縮URLの展開処理です。こちらも第11回のJSONPの活用例で短縮URLを展開するAPIを紹介していますが,
短縮URLの展開
function expandUrl(element){
var links = element.getElementsByTagName('a');
for (var i =0,l = links.length;i < l;i++){
var a = links[i];
// 長いURLやtwitter.comの内部リンクは対象外
if (a.href.length < 30 && a.host !== 'twitter.com'){
getCrossSiteXhrOrJsonP(a);
}
}
}
function getCrossSiteXhrOrJsonP(a){
// 現在のURLとAPIのURLが同一オリジンかチェック
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 = document.createElement('script');
xhr.__script = s;
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);
}
まず,
続いて,
オリジンが異なる場合はXMLHttpRequest level 2かXDomainRequestを使用しますが,
XMLHttpRequestのインターフェースを持ったJSONPオブジェクト
xhr = {
open:function(method, url){
var s = document.createElement('script');
xhr.__script = s;
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);
}
};
このようにXMLHttpRequestのインタフェースを実装したオブジェクトで,
- simple twitter search - ss-o.
net (URL展開APIと同一オリジン版) - simple twitter search - jsdo.
it (jsdo. it版)
まとめ
今回はここまでの復習として12回で取り上げた内容を使って簡単なアプリケーションを作成してみました。もし忘れているところなどがあったら是非復習してみてください。次回からはJavaScriptの基礎に再び戻って,