2 // @name FriendFeed comments
3 // @description Add FriendFeed 'likes' and comments to any page
4 // @namespace http://oblomov.myopenid.com
6 // @exclude http://friendfeed.com/*
7 // @exclude http://*.friendfeed.com/*
8 // @exclude http://friendfeed-api.com/*
9 // @author Giuseppe "Oblomov" Bilotta
13 if (typeof(unsafeWindow) == 'undefined') unsafeWindow = window;
17 var ff_preload = new Image();
18 ff_preload.src = 'http://friendfeed.com/favicon.ico';
19 ff_preload.src = 'http://friendfeed.com/static/images/logo-small.png';
21 unsafeWindow.ujs_ff_load = function(url) {
22 var e = unsafeWindow.document.createElement('script');
23 e.type = 'text/javascript';
25 unsafeWindow.document.getElementsByTagName('head')[0].appendChild(e);
28 unsafeWindow.ujs_ff_load_entries = function(str) {
29 if (str.entries && str.entries.length > 0) {
30 var doc = unsafeWindow.document;
32 var pdiv = doc.getElementById('ujs_friendfeed');
37 pdiv = doc.createElement('div');
38 pdiv.setAttribute('id', 'ujs_friendfeed');
39 pdiv.setAttribute('title', 'FriendFeed comments on this page');
40 pdiv.style.position = 'absolute';
43 pdiv.style.zIndex = 100000;
44 pdiv.style.maxWidth = '30%';
45 pdiv.style.height='auto';
46 pdiv.style.border='3px outset lightblue';
47 pdiv.style.margin = 0;
48 pdiv.style.padding = 0;
49 pdiv.style.textAlign = 'center';
50 pdiv.style.fontSize = '0px';
51 pdiv.style.lineHeight = 1;
52 // pdiv.style.opacity = 0.7;
53 pdiv.style.backgroundColor = 'white';
55 doc.body.appendChild(pdiv);
57 var logo = doc.createElement('img');
58 logo.src = 'http://friendfeed.com/favicon.ico';
59 logo.setAttribute('alt', 'FriendFeed logo');
60 logo.setAttribute('title', 'FriendFeed logo');
61 logo.style.margin='0 auto 0 auto';
63 pdiv.appendChild(logo);
65 div = doc.createElement('div');
66 div.style.fontSize = 'small';
67 div.style.display = 'none';
68 pdiv.appendChild(div);
70 function displayToggle() {
71 // don't toggle if we were dragging
76 var d = pdiv.lastChild;
77 if (d.style.display == 'none') {
78 d.style.display = 'block';
79 logo.src = 'http://friendfeed.com/static/images/logo-small.png';
80 logo.style.padding = '5px';
82 d.style.display = 'none';
83 logo.src = 'http://friendfeed.com/favicon.ico';
84 logo.style.padding = 0;
88 logo.addEventListener('click', displayToggle, false);
94 var dx = ev.pageX - dragging.x;
95 var dy = ev.pageY - dragging.y;
96 pdiv.style.left = (parseInt(pdiv.style.left) + dx) + 'px';
97 pdiv.style.top = (parseInt(pdiv.style.top) + dy) + 'px';
98 dragging.x = ev.pageX;
99 dragging.y = ev.pageY;
101 ev.stopPropagation();
106 logo.addEventListener('mousedown',
108 dragging=new Object();
109 dragging.x = ev.pageX;
110 dragging.y = ev.pageY;
112 ev.stopPropagation();
114 logo.addEventListener('mouseup',
118 ev.stopPropagation();
120 // handle on the whole document because otherwise fast
121 // movements will make the mouse get out of the logo, thus
122 // 'dropping' the drag
123 doc.addEventListener('mousemove', drag, false);
127 var ecount = str.entries.length;
128 for (var i=0; i < ecount; ++i) {
129 var entry = str.entries[i];
131 var p_entry_id = 'ujs_ff_entry/' + entry.id;
133 // skip this entry if we already added it from a different source
134 if (doc.getElementById(p_entry_id))
137 var date2link = function(d, l) {
138 var day = d.substring(0, 10);
139 var tm = d.substring(11, 19);
141 return '<a href="' + l + '">' + day + ' at ' + tm + '</a>';
143 return day + ' at ' + tm;
146 var from2link = function(from) {
147 return '<a href="http://friendfeed.com/' + from.id + '">' + from.name + '</a>';
150 var from2linkimg = function(from) {
151 return '<a style="margin: 0 1ex .5ex 0;float:left;" href="http://friendfeed.com/' + from.id + '"><img src="http://friendfeed-api.com/v2/picture/' + from.id + '?size=small" /></a>';
155 var fed = '<p id="' + p_entry_id + '">Fed by ' + from2link(entry.from);
156 fed += ' on ' + date2link(entry.date, entry.url);
157 var ediv = doc.createElement('div');
159 ediv.style.padding='.5ex';
160 ediv.style.borderTop='.25ex dashed lightblue';
161 ediv.style.textAlign = 'justify';
162 ediv.style.display = 'block';
164 div.appendChild(ediv);
166 var likes = entry.likes || [];
167 var jcount = likes.length;
169 var liked = '<p style="margin:0 2ex;text-indent:-2ex">Liked by ';
170 for (var j=0; j < jcount; ++j) {
173 liked += (j > 0 ? ', ' : '') + from2link(like.from);
175 liked += ' and ' + like.body;
178 var ldiv = doc.createElement('div');
179 ldiv.innerHTML = liked;
180 ediv.appendChild(ldiv);
183 var comments = entry.comments || [];
184 jcount = comments.length;
186 for (var j=0 ; j < jcount; ++j) {
187 var comment = comments[j];
188 var cdiv = doc.createElement('div');
189 cdiv.style.borderTop = '.1ex dotted blue';
190 cdiv.style.padding = '1ex .5ex';
191 ediv.appendChild(cdiv);
194 cdiv.innerHTML = from2linkimg(comment.from) +
195 '<p style="margin:0;font-size:smaller">' + date2link(comment.date) + ' by ' + from2link(comment.from) +
196 '<p style="margin:0">' + comment.body;
198 cdiv.innerHTML += comment.body;
207 // escape() does not escape +, but we want it escaped too
208 var encoded_loc = escape(unsafeWindow.location.toString()).replace('+','%2b');
209 var ff_url = 'http://friendfeed-api.com/v2/url?url=' + encoded_loc + '&callback=ujs_ff_load_entries&cache=' + Math.floor(Math.random()*1024*1024);
211 unsafeWindow.ujs_ff_load(ff_url);
213 ff_url = 'http://friendfeed-api.com/v2/search?q=' + encoded_loc + '&callback=ujs_ff_load_entries&cache=' + Math.floor(Math.random()*1024*1024);
215 unsafeWindow.ujs_ff_load(ff_url);