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.
6 // @identifier http://6v8.gamboni.org/IMG/js/flickreasyphotopost.user.js
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*
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
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.
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.
40 // The GNU General Public License is available by visiting
41 // http://www.gnu.org/copyleft/gpl.html
43 // Free Software Foundation, Inc.
44 // 51 Franklin Street, Fifth Floor
45 // Boston, MA 02110-1301
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
65 if(unsafeWindow
.console
)
66 unsafeWindow
.console
.log(arguments
);
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
;
80 while( next
= got
.iterateNext() )
87 return document
.evaluate(
91 XPathResult
.FIRST_ORDERED_NODE_TYPE
, null
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;
104 /***********************************************************************
105 * Flickr Localisation
106 **********************************************************************/
108 var FlickrLocaliser = function(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')]");
118 var matches
= /\/change_language.gne\?lang=([^&]+)&.*/.exec(langA
.href
);
119 if(matches
&& matches
[1]) {
120 this.selectedLang
= matches
[1];
121 return this.selectedLang
;
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
];
138 local
= this.localisations
[this.localisations
.defaultLang
][string
];
143 var rep
= new RegExp('@'+arg
+'@','g');
144 local
= local
.replace(rep
,params
[arg
]);
146 local
=local
.replace(/@[^@]+@/g,'');
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({
164 'post' : 'Post a photo ...',
167 'thumbnail' : 'Thumbnail',
169 'hide' : 'Hide thumbnails',
170 'clear' : "Clear EasyPhotoPost History"
173 'post' : 'Ajouter une photo ...',
176 'thumbnail' : 'Miniature',
177 'square' : 'Carré',
178 'hide' : 'Caché les miniatures',
179 'clear' : "Vider l'historique d'EasyPhotoPost"
186 'square' : 'Quadrat',
188 'thumbnail' : 'Thumbnail'
192 'medium' : 'Mediano',
194 'small' : 'Pequeño',
195 'square' : 'Cuadrato',
197 'thumbnail' : 'Miniatura'
204 'square' : 'Quadrate',
206 'thumbnail' : 'Miniature'
210 'medium' : '中等',
212 'small' : '小圖',
213 'square' : '正方形',
215 'thumbnail' : '縮圖'
219 'medium' : 'Médio',
222 'square' : 'Quadrado',
224 'thumbnail' : 'Miniatura'
228 'medium' : '中等',
230 'small' : '小圖',
231 'square' : '正方形',
233 'thumbnail' : '縮圖'
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
= '';
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;");
267 for(i
=0;i
<MEMORY
;i
++) {
268 var id
= GM_getValue(i
+".id");
269 if(id
!= undefined && id
!= '') {
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");
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_','');
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
;
295 var name
= GM_getValue(index
+".ownername");
297 name
= GM_getValue(index
+".ownerurl").replace('photos','').replace(/\//g,'');
300 var mesg
= """+GM_getValue(index
+".title")+"" 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
];
305 thisTextArea
.value
= thisTextArea
.value
.substr(0,thisTextArea
.selectionStart
)
307 + thisTextArea
.value
.substr(thisTextArea
.selectionStart
);
309 /* var iframe = $x1('//form//iframe',unsafeWindow.document);
310 M8_log(iframe.contentDocument.getSelection().focusOffset);*/
311 thisTextArea
.value
+= mesg
;
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';
325 hide
.href
="javascript:;";
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]",
337 return uploadedBy
.parentNode
.parentNode
.getElementsByTagName('a').item(2).innerHTML
;
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
];
348 for(i
=0;i
<MEMORY
;i
++) {
349 if(GM_getValue(i
+".id") == unsafeWindow
.page_photo_id
) {exist
= true; break;}
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();
364 var allLinks
, thisLink
;
365 allLinks
= $x('//div[@id="DiscussPhoto"]/h3',
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();
375 thisLink
= $x1('//td[@id=\'GoodStuff\']/h3',
379 thisLink
.parentNode
.insertBefore(arse
, thisLink
.nextSibling
);
381 } else if(document
.location
.pathname
.indexOf('discuss/') >= 0) {
382 var arse
= this.createCommenter();
384 if(document
.location
.pathname
.indexOf('edit') >= 0) {
385 thisLink
= $x1('//td[@id=\'GoodStuff\']/form/p[1]/textarea',
388 thisLink
.parentNode
.insertBefore(arse
, thisLink
);
390 thisLink
= $x1('//div[@id=\'DiscussTopic\']//td/h3',
393 thisLink
.parentNode
.insertBefore(arse
, thisLink
.nextSibling
);
396 } else if(document
.location
.pathname
== "/groups_newtopic.gne") {
397 var arse
= this.createCommenter();
399 var arse
= this.createCommenter();
400 thisLink
= $x1('//td[@id=\'GoodStuff\']/form/table/tbody/tr[2]/td[2]/textarea',
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 //======================================================================
427 window
.addEventListener("load", function () {
430 // update automatically (http://userscripts.org/scripts/show/2296)
431 win
.UserScriptUpdates
.requestAutomaticUpdates(SCRIPT
);
437 var flickrgp
= new flickreasyphotopost();