fixed sets... added support for user tags
[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()
64 function M8_log() {
65 if(unsafeWindow.console)
66 unsafeWindow.console.log(arguments);
67 else
68 GM_log(arguments);
72 Xpath trickery, from:
73 http://ecmanaut.blogspot.com/2006/07/expressive-user-scripts-with-xpath-and.html
75 function $x( xpath, root )
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;
86 function $x1(xpath) {
87 return document.evaluate(
88 xpath,
89 document,
90 null,
91 XPathResult.FIRST_ORDERED_NODE_TYPE, null
92 ).singleNodeValue;
95 function foreach( xpath, cb, root )
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;
104 /***********************************************************************
105 * Flickr Localisation
106 **********************************************************************/
108 var FlickrLocaliser = function(locals) {
109 this.init(locals);
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;
124 return false;
125 } else return this.selectedLang;
128 init: function(locals) {
129 this.localisations = locals;
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];
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]);
146 local =local.replace(/@[^@]+@/g,'');
147 return local;
148 } else return undefined;
153 /*****************************Flickr Localisation**********************/
156 function getObjectMethodClosure(object, method) {
157 return function(arg) {
158 return object[method](arg);
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"
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"
181 'de-de': {
182 // M
183 'medium' : 'Mittel',
184 // S
185 'small' : 'Klein',
186 'square' : 'Quadrat',
187 // T
188 'thumbnail' : 'Thumbnail'
190 'es-us': {
191 // M
192 'medium' : 'Mediano',
193 // S
194 'small' : 'Peque&ntilde;o',
195 'square' : 'Cuadrato',
196 // T
197 'thumbnail' : 'Miniatura'
199 'it-it': {
200 // M
201 'medium' : 'Medie',
202 // S
203 'small' : 'Picolle',
204 'square' : 'Quadrate',
205 // T
206 'thumbnail' : 'Miniature'
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;'
217 'pt-br': {
218 // M
219 'medium' : 'M&eacute;dio',
220 // S
221 'small' : 'Pequeno',
222 'square' : 'Quadrado',
223 // T
224 'thumbnail' : 'Miniatura'
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;'
235 defaultLang: 'en-us'
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);
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);
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;
295 var name = GM_getValue(index+".ownername");
296 if(!name) {
297 name = GM_getValue(index+".ownerurl").replace('photos','').replace(/\//g,'');
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;
316 },true);
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;
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 '';
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;}
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);
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);
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);
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);
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);
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",'');
421 GM_registerMenuCommand(localiser.localise('clear'), clear_history);
424 //======================================================================
425 // launch
426 try {
427 window.addEventListener("load", function () {
428 try {
430 // update automatically (http://userscripts.org/scripts/show/2296)
431 win.UserScriptUpdates.requestAutomaticUpdates(SCRIPT);
432 } catch (ex) {}
435 }, false);
436 } catch (ex) {}
437 var flickrgp = new flickreasyphotopost();
438 })();