Skip to content

Instantly share code, notes, and snippets.

@Constellation
Created June 7, 2009 09:10
Show Gist options
  • Save Constellation/125251 to your computer and use it in GitHub Desktop.
Save Constellation/125251 to your computer and use it in GitHub Desktop.
// Chat upload
// format sample
// http://utatane.tumblr.com/post/118386131/private-chat-format-test
(function(){
Tombloo.Service.extractors.register([
{ // Chat extractor
name : 'Chat',
ICON : models.Twitter.ICON,
TARGET_BACKGROUND : '#888',
TEMPLATE : (<><![CDATA[
<dt class="account {even_or_odd}">{image point}
<strong class="name"><a href="{account_url}">{account}</a></strong>
</dt>
<dd class="description {even_or_odd}">{body}<span class="source"><a href="{source}">{date}</a></span></dd>
]]></>).toString(),
IMAGE_TEMPLATE : '\n <span class="image"><a href="{account_url}"><img alt="{image_alt}" src="{image}" /></a></span>',
extract : function(ctx, xpath){
return this.select(xpath);
},
select : function(xpath, doc){
var self = this;
var deferred = new Deferred();
doc = doc || currentDocument();
var list = [];
var now_target = null;
function getChatElement(e){
return $x(xpath, e.target);
}
function onMouseOver(e){
var target = null;
if((target = getChatElement(e)) && !target.captureSelected){
now_target = target;
target.originalBackground = target.style.background;
target.style.background = self.TARGET_BACKGROUND;
}
}
function onMouseOut(e){
var target = null;
if((target = getChatElement(e)) && !target.captureSelected){
now_target = null;
unpoint(target);
}
}
function onClick(e){
cancel(e);
var target = null;
if(target = getChatElement(e)){
if(target.captureSelected = !target.captureSelected){
list.push(target);
} else {
var index = list.indexOf(target);
if(!(index === -1)){
list.splice(index, 1);
}
}
}
}
function onKeyDown(e){
cancel(e);
switch(keyString(e)){
case 'ESCAPE':
finalize();
deferred.cancel();
return;
case 'RETURN':
finalize();
if(list.length){
deferred.callback(list);
} else {
deferred.cancel();
}
return;
}
}
function unpoint(elm){
if(elm.originalBackground!=null){
elm.style.background = elm.originalBackground;
elm.originalBackground = null;
}
}
function finalize(){
doc.removeEventListener('mouseover', onMouseOver, true);
doc.removeEventListener('mouseout', onMouseOut, true);
doc.removeEventListener('click', onClick, true);
doc.removeEventListener('keydown', onKeyDown, true);
list.forEach(function(elm){
elm.captureSelected = null;
unpoint(elm);
});
if(now_target){
now_target.captureSelected = null;
unpoint(now_target);
}
}
doc.addEventListener('mouseover', onMouseOver, true);
doc.addEventListener('mouseout', onMouseOut, true);
doc.addEventListener('click', onClick, true);
doc.addEventListener('keydown', onKeyDown, true);
return deferred;
},
createChat : function(list){
chat = list.map(function(item, index){
var text = this.TEMPLATE
.replace(/{account}/g, this.escapeHTML(item.account))
.replace(/{account_url}/g, item.account_url)
.replace(/{source}/g, item.source)
.replace(/{body}/g, this.escapeHTML(item.body))
.replace(/{date}/g, (item.date)? this.escapeHTML(item.date) : 'src')
.replace(/{even_or_odd}/g, ((index % 2)? 'even' : 'odd'));
if(item.image){
return text
.replace(/{image point}/g, this.IMAGE_TEMPLATE
.replace(/{image}/g, item.image)
.replace(/{image_alt}/g, item.image_alt)
.replace(/{account_url}/g, item.account_url)
.replace(/{account}/g, this.escapeHTML(item.account))
);
} else {
return text
.replace(/{image point}/g, (item.alt || ""));
}
}, this);
chat.unshift('<dl class="dialog">');
chat.push('</dl>');
return chat.join('\n');
},
escapeHTML : function(text){
return text.replace(/&/g, '&amp;').replace(/\"/g, '&quot;').replace(/>/g, '&gt;').replace(/</g, '&lt;');
}
},
{
// STOT like twitter extractor
name : 'Chat - Twitter',
ICON : models.Twitter.ICON,
li_xpath : 'ancestor-or-self::li[contains(concat(" ",@class," ")," hentry ")]',
a_xpath : 'descendant::a[contains(concat(" ",@rel," ")," bookmark ")]',
check : function(ctx){
return ctx.href.match('https?://twitter.com/');
},
extract : function(ctx){
var self = this;
var Chat = Tombloo.Service.extractors.Chat;
return Chat.extract(ctx, this.li_xpath).addCallback(function(list){
return new DeferredList(list.map(function(li){
var url = $x(self.a_xpath, li).href;
return request(url).addCallback(function(res){
var doc = convertToHTMLDocument(res.responseText);
var account = url.match('http://twitter\\.com/([^/]+)')[1];
var image = $x('descendant::div[@class="thumb"]/descendant::img//@src', doc);
var text = $x('descendant::span[contains(concat(" ",normalize-space(@class)," ")," entry-content ")]//text()', doc, true).join("");
return {
account_url : 'http://twitter.com/' + account,
account : account,
source : url,
image : image,
image_alt: (/s/i.test(account.substr(-1, 1)))? (account + "' icon") : (account + "'s icon"),
date : url,
body : text,
}
});
}));
}).addCallback(function(resses){
resses.forEach(function(res, index){
if(!res[0]) throw "Chat - Twitter Request Error"
resses[index] = res[1];
});
return {
type : 'regular',
item : ctx.title,
description : Chat.createChat(resses)
};
});
},
}
]);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment