2 // @name Flickr Buddy Interesting
3 // @namespace http://6v8.gamboni.org/
4 // @description Quick access to user's interesting photos from the Buddy Icon Menu
6 // @identifier http://6v8.gamboni.org/IMG/js/flickrbuddyinteresting.user.js
8 // @creator Pierre Andrews (mortimer.pa@free.fr)
9 // @contributor Stephen Fernandez ( http://steeev.freehostia.com )
10 // @include http://*flickr.com*
13 // --------------------------------------------------------------------
15 // This is a Greasemonkey user script.
17 // To install, you need Greasemonkey: http://greasemonkey.mozdev.org/
18 // Then restart Firefox and revisit this script.
19 // Under Tools, there will be a new menu item to "Install User Script".
20 // Accept the default configuration and install.
22 // --------------------------------------------------------------------
23 // Copyright (C) 2006 Pierre Andrews
25 // This program is free software; you can redistribute it and/or
26 // modify it under the terms of the GNU General Public License
27 // as published by the Free Software Foundation; either version 2
28 // of the License, or (at your option) any later version.
30 // This program is distributed in the hope that it will be useful,
31 // but WITHOUT ANY WARRANTY; without even the implied warranty of
32 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 // GNU General Public License for more details.
35 // The GNU General Public License is available by visiting
36 // http://www.gnu.org/copyleft/gpl.html
38 // Free Software Foundation, Inc.
39 // 51 Franklin Street, Fifth Floor
40 // Boston, MA 02110-1301
48 name: "Flickr Buddy Interesting",
49 namespace: "http://6v8.gamboni.org/",
50 description: "Quick access to user's interesting photos from the Buddy Icon Menu",
51 identifier: "http://6v8.gamboni.org/IMG/js/flickrbuddyinteresting.user.js",
52 version: "0.3", // version
53 date: (new Date("2007-06-26")) // update date
59 return document.evaluate(
63 XPathResult.FIRST_ORDERED_NODE_TYPE, null
68 /***********************************************************************
70 **********************************************************************/
72 var FlickrLocaliser = function(locals) {
75 FlickrLocaliser.prototype = {
76 selectedLang: undefined,
77 localisations: undefined,
78 getLanguage: function() {
79 if(!this.selectedLang) {
80 var langA = $x1("//p[@class='LanguageSelector']//a[contains(@class,'selected')]");
82 var matches = /\/change_language.gne\?lang=([^&]+)&.*/.exec(langA.href);
83 if(matches && matches[1]) {
84 this.selectedLang = matches[1];
85 return this.selectedLang;
89 } else return this.selectedLang;
92 init: function(locals) {
93 this.localisations = locals;
96 localise: function(string, params) {
97 if(this.localisations && this.getLanguage()) {
98 var currentLang = this.localisations[this.selectedLang];
99 if(!currentLang) currentLang = this.localisations[this.localisations.defaultLang];
100 var local = currentLang[string];
102 local = this.localisations[this.localisations.defaultLang][string];
104 if(!local) return string;
106 var rep = new RegExp('@'+arg+'@','g');
107 local = local.replace(rep,params[arg]);
109 local =local.replace(/@[^@]+@/g,'');
111 } else return undefined;
116 /*****************************Flickr Localisation**********************/
119 var localiser = new FlickrLocaliser({
121 'pool_interesting' : 'Pool Interestingness',
122 'quick_interesting' : 'Quick Interestingness',
126 'pool_interesting' : 'Interestingness du Groupe',
127 'quick_interesting' : 'Interestingness Rapide',
131 'pool_interesting' : 'Interestingness del Gruppo',
132 'quick_interesting' : 'Interestingness Rapida',
139 if(unsafeWindow.console)
140 unsafeWindow.console.log(arguments);
146 Xpath trickery, from:
147 http://ecmanaut.blogspot.com/2006/07/expressive-user-scripts-with-xpath-and.html
149 function $x( xpath, root )
151 var doc = root ? root.evaluate?root:root.ownerDocument : document;
152 var got = doc.evaluate( xpath, root||doc, null, 0, null ), next;
154 while( next = got.iterateNext() )
160 function foreach( xpath, cb, root )
162 var nodes = $x( xpath, root ), e = 0;
163 for( var i=0; i<nodes.length; i++ )
164 e += cb( nodes[i], i ) || 0;
170 function getObjectMethodClosure(object, method) {
171 return function(arg) {
172 return object[method](arg);
177 LightWeightBox - Thom Shannon
183 var LightWeightBoxOn=false;
184 var LightWeightBox = function(ele){
186 this.backgroundColor = '#CCC';
189 with (LightWeightBox){
190 prototype.Render = function(){
191 if (!LightWeightBoxOn){
192 bgDiv = document.createElement('div');
194 bgDiv.style.backgroundColor = this.backgroundColor;
195 bgDiv.style.position='fixed';
196 bgDiv.style.height='100%';
197 bgDiv.style.width='100%';
199 bgDiv.style.left='0';
200 bgDiv.style.opacity=this.opacity;
201 this.ele.style.position='fixed';
203 document.body.appendChild(this.bgDiv);
204 document.body.appendChild(this.ele);
206 LightWeightBoxOn = true;
208 this.sizeCheck = setInterval(function(){oSelf.CheckSize();},20);
211 prototype.CheckSize = function(){
212 if (this.ele.offsetHeight!=this.currentHeight) {
213 this.offsetTop = (self.innerHeight/2)-(this.ele.offsetHeight/2);
214 this.ele.style.top = this.offsetTop+'px';
215 this.currentHeight=this.ele.offsetHeight;
217 if (this.ele.offsetWidth!=this.currentWidth) {
218 this.offsetLeft = (self.innerWidth/2)-(this.ele.offsetWidth/2);
219 this.ele.style.left = this.offsetLeft+'px';
220 this.currentWidth=this.ele.offsetWidth;
224 prototype.Close=function(oSelf){
225 document.body.removeChild(oSelf.bgDiv);
226 document.body.removeChild(oSelf.ele);
227 LightWeightBoxOn = false;
233 var flickrbuddyinteresting = function() {this.init();}
235 flickrbuddyinteresting.prototype = {
237 var menu = document.getElementById('personmenu_contacts_link');
239 var link =document.createElement('a');
240 link.setAttribute('class','block');
241 link.setAttribute('id','tag_person_link');
242 link.setAttribute('href','javascript:;');
243 link.addEventListener('click',getObjectMethodClosure(this,'showInteresting'),true);
244 link.textContent=localiser.localise('quick_interesting');
246 menu.parentNode.insertBefore(link,menu.nextSibling);
249 if(document.location.href.match(/\/groups\//) && unsafeWindow.document.getElementById('SubNav')) {
250 psi=$x1('//p[@class="Links"]');
251 psi.innerHTML+=' <img src="/images/subnavi_dots.gif" alt="" height="11" width="1"> ';
252 var link =document.createElement('a');
253 link.setAttribute('class','block');;
254 link.setAttribute('href','javascript:;');
255 link.addEventListener('click',getObjectMethodClosure(this,'showInteresting'),true);
256 link.textContent=localiser.localise('pool_interesting');
257 psi.appendChild(link);
263 showInteresting: function(ev) {
264 // create a block element of some kind
265 var boxEle = document.createElement('div');
266 var ul = boxEle.appendChild(document.createElement('ul'));
267 // style it up with a class or inline
268 boxEle.className = 'popup';
269 // create something to act as a close button
270 btnClose = document.createElement('a');
271 btnClose.href='javascript:;';
272 btnClose.innerHTML=localiser.localise('close');
273 // add close button to block element
274 boxEle.appendChild(btnClose);
275 // create box with block element
276 var lwBox = new LightWeightBox(boxEle);
277 // optional bg color and opacity
278 boxEle.style.paddingTop= '20px';
279 boxEle.style.width= (75*5+20)+'px';
280 boxEle.style.height= (75*5+40)+'px';
281 boxEle.style.backgroundColor = '#333';
282 // attach close event and add your own code
283 btnClose.addEventListener('click',function(){
284 // you have to pass box object into event
285 // because of the js event scoping
287 // false to cancel link
290 btnClose.setAttribute('style','background-color:#CCC;');
292 ul.setAttribute('style','margin:0;padding:0;list-style-type:none;');
295 flickr_photos_search_onLoad: function(success, responseXML, responseText, params){
297 var rsp = responseText.replace(/jsonFlickrApi\(/,'');
299 if(rsp.stat == 'ok') {
302 for(i=0;i<rsp.photos.photo.length;i++) {
303 var photo = rsp.photos.photo[i];
304 html += '<li style="margin:0;padding:0;display:inline;"><a href="http://www.flickr.com/photos/'+photo.owner+'/'+photo.id+'/"><img title=""' + photo.title + '" by ' + photo.ownername + '" src="http://farm'+photo.farm+'.static.flickr.com/'+photo.server+'/'+photo.id+'_'+photo.secret+'_s.jpg" width="75" height="75"/></a></li>';
310 M8_log("Error2 "+responseText);
312 M8_log("Error1 "+responseText);
318 var block = ev.target.parentNode;
319 var matches = /messages_write\.gne\?to=([^"]*)"/.exec(block.innerHTML);
321 unsafeWindow.F.API.callMethod('flickr.photos.search', {
322 user_id: matches[1], sort: 'interestingness-desc', page:1, per_page: 25,
323 format: 'json', extras: 'owner_name'
326 if(ev.target.textContent==localiser.localise('pool_interesting')) {
327 thegroupid=unsafeWindow.document.getElementById('SubNav').innerHTML.split('\/buddyicons\/')[1].split('\.jpg')[0];
328 unsafeWindow.F.API.callMethod('flickr.photos.search', {
329 group_id: thegroupid , sort: 'interestingness-desc', page:1, per_page: 25,
330 format: 'json', extras: 'owner_name'
335 //======================================================================
338 window.addEventListener("load", function () {
341 // update automatically (http://userscripts.org/scripts/show/2296)
342 win.UserScriptUpdates.requestAutomaticUpdates(SCRIPT);
345 var flickrgp = new flickrbuddyinteresting();