update version number and date
[FlickrHacks.git] / _greasemonkey_ / flickreasyphotopost.user.js
blob7f540bcb421d4f1a45966a67dd5210b325e48eec
1 // ==UserScript==
2 // @name         Flickr Easy Photo Post
3 // @namespace   http://6v8.gamboni.org/
4 // @description Remembers the photo you just visited on flickr and offers you an easy way to post them in a comment.
5 // @version        0.5
6 // @identifier  http://6v8.gamboni.org/IMG/js/flickreasyphotopost.user.js
7 // @date           2007-06-26
8 // @creator        Pierre Andrews (mortimer.pa@free.fr)
9 // @include http://*flickr.com/photos/*/*
10 // @include http://*flickr.com/photos/*//*
11 // @include http://*flickr.com/groups/*/discuss*
12 // @include http://*flickr.com/groups_newtopic.gne*
13 // @exclude *flickr.com/photos/*/alltags*
14 // @exclude *flickr.com/photos/organize*
15 // 
16 // ==/UserScript==
18 // --------------------------------------------------------------------
20 // This is a Greasemonkey user script.
22 // To install, you need Greasemonkey: http://greasemonkey.mozdev.org/
23 // Then restart Firefox and revisit this script.
24 // Under Tools, there will be a new menu item to "Install User Script".
25 // Accept the default configuration and install.
27 // --------------------------------------------------------------------
28 // Copyright (C) 2006 Pierre Andrews
29 // 
30 // This program is free software; you can redistribute it and/or
31 // modify it under the terms of the GNU General Public License
32 // as published by the Free Software Foundation; either version 2
33 // of the License, or (at your option) any later version.
34 // 
35 // This program is distributed in the hope that it will be useful,
36 // but WITHOUT ANY WARRANTY; without even the implied warranty of
37 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38 // GNU General Public License for more details.
39 // 
40 // The GNU General Public License is available by visiting
41 //   http://www.gnu.org/copyleft/gpl.html
42 // or by writing to
43 //   Free Software Foundation, Inc.
44 //   51 Franklin Street, Fifth Floor
45 //   Boston, MA  02110-1301
46 //   USA
48 var MEMORY = 15;
50 (function () {
52         //update information
53         var SCRIPT = {
54                 name: " Flickr Easy Photo Post",
55                 namespace: "http://6v8.gamboni.org/",
56                 description: "Remembers the photo you just visited on flickr and offers you an easy way to post them in a comment.",
57                 identifier: "http://6v8.gamboni.org/IMG/js/flickreasyphotopost.user.js",
58                 version: "0.5",                                                         // version
59                 date: (new Date("2007-06-26"))          // update date
60                 .valueOf()
61         };
62         
63         
64         function M8_log() {
65                 if(unsafeWindow.console)
66                         unsafeWindow.console.log(arguments);
67                 else
68                         GM_log(arguments);
69         }
71         /*
72           Xpath trickery, from:
73           http://ecmanaut.blogspot.com/2006/07/expressive-user-scripts-with-xpath-and.html
74          */
75         function $x( xpath, root )
76                 {
77                         var doc = root ? root.evaluate?root:root.ownerDocument : document;
78                         var got = doc.evaluate( xpath, root||doc, null, 0, null ), next;
79                         var result = [];
80                         while( next = got.iterateNext() )
81                                 result.push( next );
82                         return result;
83                 }
86         function $x1(xpath) {
87                 return document.evaluate(
88                                                                  xpath,
89                                                                  document,
90                                                                  null,
91                                                                  XPathResult.FIRST_ORDERED_NODE_TYPE, null
92                                                                  ).singleNodeValue;
93         }
95         function foreach( xpath, cb, root )
96         {
97                 var nodes = $x( xpath, root ), e = 0;
98                 for( var i=0; i<nodes.length; i++ )
99                         e += cb( nodes[i], i ) || 0;
100                 return e;
101         }
103         
104         /***********************************************************************
105          * Flickr Localisation
106          **********************************************************************/
108         var FlickrLocaliser = function(locals) {
109                 this.init(locals);
110         }
111         FlickrLocaliser.prototype = {
112                 selectedLang: undefined,
113                 localisations: undefined,
114                 getLanguage: function() {
115                         if(!this.selectedLang) {
116                                 var langA = $x1("//p[@class='LanguageSelector']//a[contains(@class,'selected')]");
117                                 if(langA) {
118                                         var matches = /\/change_language.gne\?lang=([^&]+)&.*/.exec(langA.href);
119                                         if(matches && matches[1]) {
120                                                 this.selectedLang = matches[1];
121                                                 return this.selectedLang;
122                                         }
123                                 }
124                                 return false;
125                         } else return this.selectedLang;
126                 },
128                 init: function(locals) {
129                         this.localisations = locals;
130                 },
132                 localise: function(string, params) {
133                         if(this.localisations && this.getLanguage()) {
134                                 var currentLang = this.localisations[this.selectedLang];
135                                 if(!currentLang) currentLang = this.localisations[this.localisations.defaultLang];
136                                 var local = currentLang[string];
137                                 if(!local) {
138                                         local = this.localisations[this.localisations.defaultLang][string];
139                                 } 
140                                 if(!local)
141                                         return string;
142                                 for(arg in params) {
143                                         var rep = new RegExp('@'+arg+'@','g');
144                                         local = local.replace(rep,params[arg]);
145                                 }
146                                 local =local.replace(/@[^@]+@/g,'');
147                                 return local;
148                         } else return undefined;
149                 }
151         }
153         /*****************************Flickr Localisation**********************/
156         function getObjectMethodClosure(object, method) {
157                 return function(arg) {
158                         return object[method](arg); 
159                 }
160         }
162         var localiser = new FlickrLocaliser({
163                                 'en-us' : {
164                                         'post' : 'Post a photo ...',
165                                         'medium' : 'Medium',
166                                         'small' : 'Small',
167                                         'thumbnail' : 'Thumbnail',
168                                         'square' : 'Square',
169                                         'hide' : 'Hide thumbnails',
170                                         'clear' :  "Clear EasyPhotoPost History"
171                                 },
172                                 'fr-fr' : {
173                                         'post' : 'Ajouter une photo ...',
174                                         'medium' : 'Moyen',
175                                         'small' : 'Petite',
176                                         'thumbnail' : 'Miniature',
177                                         'square' : 'Carr&eacute;',
178                                         'hide' : 'Cach&eacute; les miniatures',
179                                         'clear' :  "Vider l'historique d'EasyPhotoPost"
180                                 },
181                                 'de-de': {
182                                         // M
183                                         'medium' : 'Mittel',
184                                         // S
185                                         'small' : 'Klein',
186                                         'square' : 'Quadrat',
187                                         // T
188                                         'thumbnail' : 'Thumbnail'
189                                 },
190                                 'es-us': {
191                                         // M
192                                         'medium' : 'Mediano',
193                                         // S
194                                         'small' : 'Peque&ntilde;o',
195                                         'square' : 'Cuadrato',
196                                         // T
197                                         'thumbnail' : 'Miniatura'
198                                 },
199                                 'it-it': {
200                                         // M
201                                         'medium' : 'Medie',
202                                         // S
203                                         'small' : 'Picolle',
204                                         'square' : 'Quadrate',
205                                         // T
206                                         'thumbnail' : 'Miniature'
207                                 },
208                                 'ko-kr': {
209                                         // M
210                                         'medium' : '&#20013;&#31561;',
211                                         // S
212                                         'small' : '&#23567;&#22294;',
213                                         'square' : '&#27491;&#26041;&#24418;',
214                                         // T
215                                         'thumbnail' : '&#32302;&#22294;'
216                                 },
217                                 'pt-br': {
218                                         // M
219                                         'medium' : 'M&eacute;dio',
220                                         // S
221                                         'small' : 'Pequeno',
222                                         'square' : 'Quadrado',
223                                         // T
224                                         'thumbnail' : 'Miniatura'
225                                 },
226                                 'zh-hk': {
227                                         // M
228                                         'medium' : '&#20013;&#31561;',
229                                         // S
230                                         'small' : '&#23567;&#22294;',
231                                         'square' : '&#27491;&#26041;&#24418;',
232                                         // T
233                                         'thumbnail' : '&#32302;&#22294;'
234                                 },
235                                 defaultLang: 'en-us'
236                 });
237         
238         var flickreasyphotopost = function() {this.init();}
240         flickreasyphotopost.prototype = {       
242                 createCommenter: function() {
243                         var outerdiv = document.createElement('div');
244                         var show = outerdiv.appendChild(document.createElement('a'));
245                         show.href="javascript:;";
246                         var div = outerdiv.appendChild(document.createElement('div'));
247                         div.style.display = 'none';
249                         show.innerHTML = localiser.localise('post');
250                         show.addEventListener('click',function(evt) {
251                                 show.style.display = 'none';
252                                 div.style.display = '';
253                         },true);
254                         
255                         var choice = div.appendChild(document.createElement('div'));
256                         choice.setAttribute("style","margin-bottom:1em;text-align:center;");
257                         var form = choice.appendChild(document.createElement('form'));
258                         form.innerHTML = '<input type="radio" name="size" value="-" id="imgpost_medium"/><label for="imgpost_medium">'+localiser.localise('medium')+'</label>';
259                         form.innerHTML += '<input type="radio" name="size" value="m" id="imgpost_small" checked="true"/><label for="imgpost_small">'+localiser.localise('small')+'</label>';
260                         form.innerHTML += '<input type="radio" name="size" value="t" id="imgpost_thumb"/><label for="imgpost_thumb">'+localiser.localise('thumbnail')+'</label>';
261                         form.innerHTML += '<input type="radio" name="size" value="s" id="imgpost_square"/><label for="imgpost_square">'+localiser.localise('square')+'</label>';
262                         form.id= "imgpost_form";
263                         var ul = div.appendChild(document.createElement('ul'));
264                         ul.setAttribute("style","margin:0;list-style-type:none;");
265                         var i=0;
266                         var cnt = 0;
267                         for(i=0;i<MEMORY;i++) {
268                                 var id = GM_getValue(i+".id");
269                                 if(id != undefined && id != '') {
270                                         cnt++;
271                                         var li = ul.appendChild(document.createElement('li'));
272                                         li.setAttribute("style","display:inline;margin:.5em;");
273                                         var a = li.appendChild(document.createElement('a'));
274                                         var img = a.appendChild(document.createElement('img'));
275                                         img.src ='http://static.flickr.com/'+GM_getValue(i+".server")+'/'+id+'_'+
276                                                 GM_getValue(i+".secret")+'_s.jpg';
277                                         img.alt=GM_getValue(i+".title");
278                                         img.width="75";
279                                         img.height="75";
280                                         img.id="imgpost_"+i;
281                                         a.href="javascript:;";
282                                         a.addEventListener('click',function(evt) {
283                                                                                    allTextAreas = $x('//textarea[@name="message"]',     document);
284                                                                                    
285                                                                                    var index = evt.target.id.replace('imgpost_','');
286                                                                                    var size = '';
287                                                                                    //                                                                              var form = document.getElementById("imgpost_form");
288                                                                                    for(var j = 0; j < form.elements.length; j++) {
289                                                                                            if(form.elements[j].checked) {
290                                                                                                    if(form.elements[j].value == '-') size = '';
291                                                                                                    else size = '_'+form.elements[j].value;
292                                                                                                    break;
293                                                                                            }
294                                                                                    }
295                                                                                    var name = GM_getValue(index+".ownername");
296                                                                                    if(!name) {
297                                                                                            name = GM_getValue(index+".ownerurl").replace('photos','').replace(/\//g,'');
298                                                                                    }
300                                                                                    var mesg = "&quot;"+GM_getValue(index+".title")+"&quot; by "+name+' <a href="http://6v8.gamboni.org/Flickr-Easy-Photo-Post.html">[?]</a>'+
301 "\n"+'<a href="http://www.flickr.com'+GM_getValue(index+".ownerurl")+GM_getValue(index+".id")+'/" title="Go to the photo page"><img src="http://static.flickr.com/'+GM_getValue(index+".server")+'/'+GM_getValue(index+".id")+'_'+GM_getValue(index+".secret")+size+'.jpg" alt="'+GM_getValue(index+".title")+'" alt="'+GM_getValue(index+".title")+' by '+name.replace(/<\/?b>/g,'')+'"/></a>';
302                                                                                    for (var i = 0; i < allTextAreas.length; i++) {
303                                                                                            thisTextArea = allTextAreas[i];
304                                                                                            try{
305                                                                                                    thisTextArea.value = thisTextArea.value.substr(0,thisTextArea.selectionStart) 
306                                                                                                    + mesg
307                                                                                                    + thisTextArea.value.substr(thisTextArea.selectionStart);
308                                                                                            } catch(e) {
309                                                                                                    /*  var iframe = $x1('//form//iframe',unsafeWindow.document);
310                                                                                                            M8_log(iframe.contentDocument.getSelection().focusOffset);*/
311                                                                                                    thisTextArea.value +=  mesg;
312                                                                                            }
313                                                                                            
314                                                                                    }
315                                                                                    
316                                                                            },true);
317                                 }
318                         }
319                         var hide = div.appendChild(document.createElement('a'));
320                         hide.innerHTML = localiser.localise('hide');
321                         hide.addEventListener('click',function(evt) {
322                                 show.style.display = '';
323                                 div.style.display = 'none';
324                         },true);
325                         hide.href="javascript:;";
327                         if(cnt > 0)
328                         return outerdiv;
329                         else
330                         return null;
331                 },
333                 getOwnerName: function() {
334                         var uploadedBy = $x1("/html/body/div[@id='Main']/table[@id='Photo']/tbody/tr/td[2]/div[1]/a[1]/img[1]",
335                                                                  document.body);
336                         if(uploadedBy)
337                         return uploadedBy.parentNode.parentNode.getElementsByTagName('a').item(2).innerHTML;
338                         return '';
339                 },
341                 init: function() {
342                         if(unsafeWindow.page_photo_id) {
343                                 var current_index = GM_getValue("current_index");
344                                 if(!current_index) current_index = 0;
345                                 var photo = unsafeWindow.global_photos[unsafeWindow.page_photo_id];
346                                 var i = 0;
347                                 var exist = false;
348                                 for(i=0;i<MEMORY;i++) {
349                                         if(GM_getValue(i+".id") == unsafeWindow.page_photo_id) {exist = true; break;}
350                                 }
351                                 if(!exist) {
352                                         GM_setValue("current_index",(current_index+1)%MEMORY);
353                                         GM_setValue(current_index+".id",unsafeWindow.page_photo_id);
354                                         GM_setValue(current_index+".ownerurl",photo.ownersUrl);
355                                         GM_setValue(current_index+".ownername",this.getOwnerName());
356                                         GM_setValue(current_index+".server",photo.server);
357                                         GM_setValue(current_index+".secret",photo.secret);
358                                         GM_setValue(current_index+".title",photo.title);
359                                 }
361                                 //insert the commenter stuff.
362                                 var arse = this.createCommenter();
363                                 if(arse != null) {
364                                         var allLinks, thisLink;
365                                         allLinks = $x('//div[@id="DiscussPhoto"]/h3',
366                                                                   document);
367                                         for (var i = 0; i < allLinks.length; i++) {
368                                                 thisLink = allLinks[i];
369                                                 thisLink.parentNode.insertBefore(arse, thisLink.nextSibling);
370                                         }
371                                 }
372                         } else if(document.location.pathname.indexOf('editcomment') >= 0) {
373                                 var arse = this.createCommenter();
374                                 if(arse != null) {
375                                         thisLink = $x1('//td[@id=\'GoodStuff\']/h3',
376                                                                    document);   
378                                         if(thisLink)
379                                                 thisLink.parentNode.insertBefore(arse, thisLink.nextSibling);
380                                 }                       
381                         } else if(document.location.pathname.indexOf('discuss/') >= 0) {
382                                 var arse = this.createCommenter();              
383                                 if(arse != null) {
384                                         if(document.location.pathname.indexOf('edit') >= 0) {
385                                                 thisLink = $x1('//td[@id=\'GoodStuff\']/form/p[1]/textarea',
386                                                                            document);
387                                                 if(thisLink)
388                                                         thisLink.parentNode.insertBefore(arse, thisLink);
389                                         } else {
390                                                 thisLink = $x1('//div[@id=\'DiscussTopic\']//td/h3',
391                                                                            document);
392                                                 if(thisLink)
393                                                         thisLink.parentNode.insertBefore(arse, thisLink.nextSibling);
394                                         } 
395                                 }
396                         } else if(document.location.pathname == "/groups_newtopic.gne") {
397                                 var arse = this.createCommenter();              
398                                 if(arse != null) {
399                                         var arse = this.createCommenter();
400                                         thisLink = $x1('//td[@id=\'GoodStuff\']/form/table/tbody/tr[2]/td[2]/textarea',
401                                                            document);
402                                         if(thisLink)
403                                                 thisLink.parentNode.insertBefore(arse, thisLink);
404                                 }
405                         }
406                 }
408         }
410         var clear_history = function() {
411                 for(var i=0;i<MEMORY;i++) {
412                                         GM_setValue("current_index",0);
413                                         GM_setValue(i+".id",'');
414                                         GM_setValue(i+".ownerurl",'');
415                                         GM_setValue(i+".ownername",'');
416                                         GM_setValue(i+".server",'');
417                                         GM_setValue(i+".secret",'');
418                                         GM_setValue(i+".title",'');
419                 }
420         };
421         GM_registerMenuCommand(localiser.localise('clear'), clear_history);
422         
423         
424         //======================================================================
425         // launch
426                 try {
427                 window.addEventListener("load", function () {
428                                                                         try {
429                                                                                 
430                                                                                 // update automatically (http://userscripts.org/scripts/show/2296)
431                                                                                 win.UserScriptUpdates.requestAutomaticUpdates(SCRIPT);
432                                                                         } catch (ex) {} 
433                                                                         
434         
435                 }, false);
436         } catch (ex) {}
437                 var flickrgp = new flickreasyphotopost();
438 })();