2 // Copyright (c) 2007, Pierre Andrews.
3 // Released under the GPL license
4 // http://www.gnu.org/copyleft/gpl.html
7 // @name Flickr Auto Page
8 // @namespace http://6v8.gamboni.org/Flickr-Auto-Pagination.html
9 // @description removes the need to paginate when browsing flickr
12 // @creator Pierre Andrews (mortimer.pa@free.fr) , pt translation by Perla* <http://www.flickr.com/photos/bobnperla/>
13 // @include http://*flickr.com/groups/*/pool*
14 // @include http://*flickr.com/groups/*/admin
15 // @include http://*flickr.com/groups/*/discuss*
16 // @include http://*flickr.com/photos/*/*
17 // @include http://*flickr.com/photos/*/*/sets/*/detail*
18 // @include http://*flickr.com/recent_activity.gne*
19 // @include http://*flickr.com/photos_comments.gne*
20 // @include http://*flickr.com/search*
21 // @include http://*flickr.com/photos/friends*
22 // @include http://*flickr.com/help/forum*
23 // @include http://*flickr.com/explore/intersting/*
24 // @include http://*flickr.com/people/*/contacts*
25 // @include http://*flickr.com/creativecommons/*
26 // @include http://*flickr.com/groups_members_detail.gne*
27 // @exclude http://*flickr.com/*#disableautopage
31 //TODO javascript oddness
37 if(matches = /\/photos\/friends\/?(page([0-9]+))?\/?$/.exec(document.location.pathname)) {
45 name: "Flickr Auto Page",
46 namespace: "http://6v8.gamboni.org/Flickr-Auto-Pagination.html",
47 description: "removes the need to paginate when browsing flickr.",
48 source: "http://6v8.gamboni.org/Flickr-Auto-Page.html", // script homepage/description URL
49 identifier: "http://6v8.gamboni.org/IMG/js/flickrautopage.user.js",
50 version: "0.99", // version
51 date: (new Date(2007, 07,22)) // update date
55 //======================================================================
56 //to do the closure and get the right this.
57 //adapted from http://persistent.info/greasemonkey/gmail.user.js
59 function getObjectMethodClosure3(object, method,args,args1,args2,args3) {
61 return object[method](args,args1,args2,args3);
64 function getObjectMethodClosure2(object, method,args,args1,args2) {
66 return object[method](args,args1,args2);
69 function getObjectMethodClosure1(object, method,args,args1) {
71 return object[method](args,args1);
75 function getObjectMethodClosure0(object, method,args) {
77 return object[method](args);
81 function getObjectMethodClosure(object, method) {
82 return function(args) {
83 return object[method](args);
89 http://ecmanaut.blogspot.com/2006/07/expressive-user-scripts-with-xpath-and.html
91 function $x( xpath, root )
93 var doc = root ? root.evaluate?root:root.ownerDocument : document;
94 var got = doc.evaluate( xpath, root||doc, null, 0, null ), next;
96 while( next = got.iterateNext() )
102 function $x1(xpath) {
103 return document.evaluate(
107 XPathResult.FIRST_ORDERED_NODE_TYPE, null
111 function foreach( xpath, cb, root )
113 var nodes = $x( xpath, root ), e = 0;
114 for( var i=0; i<nodes.length; i++ )
115 e += cb( nodes[i], i ) || 0;
120 /***********************************************************************
121 * Flickr Localisation
122 **********************************************************************/
124 var FlickrLocaliser = function(locals) {
127 FlickrLocaliser.prototype = {
128 selectedLang: undefined,
129 localisations: undefined,
130 getLanguage: function() {
131 if(!this.selectedLang) {
132 var langA = $x1("//p[@class='LanguageSelector']//a[contains(@class,'selected')]");
134 var matches = /\/change_language.gne\?lang=([^&]+)&.*/.exec(langA.href);
135 if(matches && matches[1]) {
136 this.selectedLang = matches[1];
137 return this.selectedLang;
141 } else return this.selectedLang;
144 init: function(locals) {
145 this.localisations = locals;
148 localise: function(string, params) {
149 if(this.localisations && this.getLanguage()) {
150 var currentLang = this.localisations[this.selectedLang];
151 if(!currentLang) currentLang = this.localisations[this.localisations.defaultLang];
152 var local = currentLang[string];
154 local = this.localisations[this.localisations.defaultLang][string];
156 if(!local) return string;
158 var rep = new RegExp('@'+arg+'@','g');
159 local = local.replace(rep,params[arg]);
161 local =local.replace(/@[^@]+@/g,'');
163 } else return undefined;
168 /*****************************Flickr Localisation**********************/
173 if(unsafeWindow.console)
174 unsafeWindow.console.log(arguments);
179 win.FlickrAutoPage = function() {
183 win.FlickrAutoPage.prototype = {
184 localiser: new FlickrLocaliser({
186 'loading':'Fetching page:@nbrpage@/@total@.',
187 'showing':'Showing page:@page@/@total@.',
188 'enable':'Enable Auto Page',
189 'nophoto':'No more Photos',
190 'nodiscussion': "No more Discussions",
191 'noreply':'No more Replies',
192 'notopic':'No more Topics',
193 'nocomment':'No more Comments',
194 'nopeople':'No more People',
195 'nocontact':'No more Contacts'
198 'loading':'Chargement de la page:@nbrpage@/@total@.',
199 'showing':'Page Actuelle:@page@/@total@.',
200 'enable':'Activer l\'Auto Pagination',
201 'nophoto':'Plus de Photos',
202 'nodiscussion': "Plus de Discussions",
203 'noreply':'Pas d\'autre réponse',
204 'notopic':'Pas d\'autre sujet',
205 'nocomment':'Pas d\'autre commentaire',
206 'nopeople':'Pas d\'autre Membre',
207 'nocontact':'Pas d\'autre Contact'
211 'enable' : 'Capacitar',
213 'loading' : 'Procurar página:@nbrpage@/@total@.',
215 'nocomment' : 'Sem mais comentários',
216 'nocontact' : 'Sem mais contatos',
217 'nodiscussion' : 'Sem mais discussões',
218 'nopeople' : 'Mais ninguém',
219 'nophoto' : 'Mais nenhuma foto',
220 'noreply' : 'Sem mais respostas',
221 'notopic' : 'Mais nenhum tópico',
223 'showing' : 'Mostrando a página:@page@/@total@.'
231 paginator: undefined,
239 //inspired by http://squarefree.com/userscripts
240 //using iframes instead of xmlhttpRequest applies javascripts and other GM scripts to the page :D
241 pullMore: function(url,processReply, special) {
242 var iframe = document.createElement("iframe");
246 iframe.style.display = "none";
247 iframe.id = 'autopageframe';
248 document.body.appendChild(iframe);
249 iframe.addEventListener("load",
251 self.msg_div.innerHTML = '';
253 if(url.indexOf('photos/friends') >= 0) self.insert.innerHTML += '<br clear="all" />';
256 var anchor = self.insert.appendChild(document.createElement('a'));
257 anchor.name = 'infinitepage'+(self.next_request-1);
259 var b = iframe.contentDocument.body;
261 //self.insert.innerHTML =
262 processReply(b, self.insert);
264 self.received = true;
268 link = $x1("//div[@id='Pages']//div[@class='Paginator']//a[text()='"+(self.next_request-1)+"']");
271 link = $x1("//div[@class='Paginator']//a[text()='"+(self.next_request-1)+"']");
276 link = $x1("//div[@id='Pages']//div[@class='Paginator']//span[text()='...']");
279 link = $x1("//div[@class='Paginator']//span[text()='...']");
281 var a = link.parentNode.insertBefore(document.createElement('a'),link);
282 a.className = 'this-page';
283 a.setAttribute('style',"margin: 0pt; display: block; width: 2em;");
284 a.href='#infinitepage'+(self.next_request-1);
285 a.innerHTML = (self.next_request-1);
287 link.href='#infinitepage'+(self.next_request-1);
288 link.className += 'this-page';
292 if(matches = /\/photos\/friends\/?(page([0-9]+))?\/?$/.exec(document.location.pathname))
293 document.location.hash = 'infinitepage'+(self.next_request-1);
295 setTimeout( function() { iframe.parentNode.removeChild(iframe); }, 1500);
297 iframe.src = url+'#disableautopage';
300 cb_shortcut: function(url,msg,processReply,special) {
302 if(this.next_request > this.nbr_page) {
303 this.msg_div.innerHTML = self.localiser.localise('showing',{'page':(self.next_request-1),'total':self.nbr_page})+' '+msg;
304 } else if(this.insert) {
308 this.msg_div.innerHTML = this.localiser.localise('loading',{
309 'nbrpage':(this.next_request-1),
310 'total': this.nbr_page
311 })+ '<br/><img id="flickrphotocompass_wait" src="http://'+document.location.host+'/images/pulser2.gif" style="margin:0;padding:0;margin-right:4px;border:0px #ffffff;height: 16px;" />';
312 this.received = false;
313 this.pullMore(url,processReply,special);
319 generic_cb: function(msg,url,xpath,additionalBits) {
320 url = url.replace('@P@',this.next_request);
322 var processReply = function(body,insert) {
329 var node = document.importNode(elt,true);
330 insert.appendChild(node);
331 elt.className += ' AutoPageAddition'+self.next_request;
336 //fix the buddy icons over for the moved element
337 foreach("//.[contains(@class,'AutoPageAddition"+self.next_request+"')]//img[contains(@src,'buddyicon')]",
339 img.addEventListener('mouseover',getObjectMethodClosure(unsafeWindow.document.getElementById('person_hover'),'icon_mouseover'),true);
340 img.addEventListener('mouseout',getObjectMethodClosure(unsafeWindow.document.getElementById("person_hover"),'icon_mouseout'),true);
342 if(img.src.indexOf('buddyicon.jpg') >= 0) {
343 nsid = img.src.replace(/.*\?/,'');
345 nsid = img.src.replace(/.*\/(.*)\.jpg(\?.*)?$/,'$1');
349 var hover_insert = document.getElementById("person_hover_link")
350 if(!document.getElementById('hover_img'+nsid) && (hover = body.ownerDocument.getElementById('hover_img'+nsid))) {
351 hover_insert.appendChild(hover);
354 additionalBits("AutoPageAddition"+self.next_request,body);
356 this.cb_shortcut(url,msg,processReply);
359 /* messages_cb: function(query) {
360 var msg = 'No More Messages';
361 url = "http://"+document.location.host+"/messages.gne?ok=1&page="+(this.next_request);
363 var processReply = function(text,html) {
368 start = text.indexOf('<table id="InBox" cellspacing="0" width="100%">');
370 end = text.indexOf('</table>',start);
371 text = text.slice(start,end);
376 this.cb_shortcut(url,msg,processReply);
387 var additionalBits = function() {};
390 if(matches = /\/groups\/(.*)\/pool\/?(page([0-9]+))?\/?$/.exec(document.location.pathname)) {
392 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
393 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
394 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/30);
396 if(matches[3]) this.next_request= parseInt(matches[3]);
397 this.insert = $x1("//div[@class='HoldPhotos']");
398 msg = this.localiser.localise('nophoto');
399 url = "http://"+document.location.host+"/groups/"+matches[1]+"/pool/page@P@";
400 xpath = "//div[@class='HoldPhotos']/p";
401 } //for the group discuss
402 else if(matches = /\/groups\/(.*)\/discuss\/?(page([0-9]+))?\/?$/.exec(document.location.pathname)) {
404 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
405 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
406 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/20);
408 if(matches[3]) this.next_request= parseInt(matches[3]);
409 this.insert = $x1("//table[@class='TopicListing']/tbody");
411 url = "http://"+document.location.host+"/groups/"+matches[1]+"/discuss/page@P@";
412 msg = this.localiser.localise('nodiscussion');
413 xpath = "//table[@class='TopicListing']/tbody/tr";
414 } //for the group topics
415 else if(matches = /\/groups\/(.*)\/discuss\/([0-9]+)\/?(page([0-9]+))?\/?$/.exec(document.location.pathname)) {
417 var otherpage = $x1("//div[@id='DiscussTopic']/div[@class='Pages']/div[@class='Paginator']");
419 otherpage.className = '';
420 otherpage.parentNode.style.display = 'none';
422 this.paginator = $x1("//div[@id='Pages']/div/div[@class='Paginator']");
423 var pp = $x1("//div[@id='Pages']/div/div[@class='Results']");
424 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/100);
426 if(matches[4]) this.next_request= parseInt(matches[4]);
427 this.insert = $x1("//table[@class='TopicReply']/tbody");
429 msg = this.localiser.localise('noreply');
430 url = "http://"+document.location.host+"/groups/"+matches[1]+"/discuss/"+matches[2]+"/page@P@";
431 xpath = "//table[@class='TopicReply']/tbody/tr";
432 } //for the help topics
433 else if(matches = /\/help\/forum\/([A-Za-z-]+)\/([0-9]+)\/?(page([0-9]+))?\/?$/.exec(document.location.pathname)) {
435 var otherpage = $x1("//div[@id='DiscussTopic']/div[@class='Pages']/div[@class='Paginator']");
437 otherpage.className = '';
438 otherpage.parentNode.style.display = 'none';
440 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
442 var pp = $x1("//div[@class='Pages']//div[@class='Results']");
443 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/100);
445 if(matches[4]) this.next_request= parseInt(matches[4]);
446 this.insert = $x1("//table[@class='TopicReply']/tbody");
447 url = "http://"+document.location.host+"/help/forum/"+matches[1]+'/'+matches[2]+"/page@P@";
448 xpath = "//table[@class='TopicReply']/tbody/tr";
449 msg = this.localiser.localise('nodiscussion');
450 } //for the help forum
451 else if(document.location.pathname.indexOf('/help/forum') >= 0) {
452 matches = /([?&]page=([0-9]+))?/.exec(document.location.search);
454 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
455 var as = this.paginator.getElementsByTagName('a');
457 if(as && as.length >0) {
458 var tmp = /\/help\/forum\/([^\/]+)\//.exec(as[0].href);
459 if(tmp) lang = tmp[1];
462 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
463 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/20);
465 this.insert = $x1("//table[@class='TopicListing'][2]/tbody");
466 if(matches[3]) this.next_request= parseInt(matches[2]);
467 msg = this.localiser.localise('noreply');
468 url = "http://"+document.location.host+"/help/forum/"+lang+"/?page=@P@";
469 xpath = "//table[@class='TopicListing']/tbody/tr";
470 } //for the contacts photo
471 else if(matches = /\/photos\/friends\/?(page([0-9]+))?\/?$/.exec(document.location.pathname)) {
472 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
473 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
474 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/24);
476 if(matches[2]) this.next_request= parseInt(matches[2]);
477 this.insert = $x1("//div[@class='HoldPhotos']");
478 url = "http://"+document.location.host+"/photos/friends/page@P@";
479 xpath = "//div[@class='HoldPhotos']/p";
480 msg = this.localiser.localise('nophoto');
481 } //for everyone's tag
482 else if(matches = /\/photos\/tags\/([^\/]+)\/?(interesting)?\/?$/.exec(document.location.pathname)) {
484 var matches2 = /\?page=([0-9]+)$/.exec(document.location.search);
486 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
487 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
488 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/20);
490 if(matches2 && matches2[1]) this.next_request= parseInt(matches2[1]);
491 this.insert = $x1("//td[@id='GoodStuff']/div");
492 url = "http://"+document.location.host+"/photos/tags/"+matches[1];
493 if(matches[2]) url += "/interesting"
495 msg = this.localiser.localise('nophoto');
496 xpath = "//td[@id='GoodStuff']/div/p";
498 else if(matches = /\/photos\/tags\/([^\/]+)\/clusters\/([^\/]+)\/?(page([0-9]+))?\/?$/.exec(document.location.pathname)) {
500 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
501 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
502 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/20);
504 if(matches[3]) this.next_request= parseInt(matches[3]);
505 this.insert = $x1("//div[@id='tagThumbs']");
507 url = "http://"+document.location.host+"/photos/tags/"+matches[1]+"/clusters/"+matches[2]+"/page@P@";
508 msg = this.localiser.localise('nophoto');
509 xpath = "//div[@id='tagThumbs']/p";
511 else if(matches = /\/photos\/([^\/]+)\/tags\/([^\/]+)\/?(page([0-9]+))?\/?$/.exec(document.location.pathname)) {
513 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
514 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
515 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/20);
517 if(matches[4]) this.next_request= parseInt(matches[4]);
518 this.insert = $x1("//td[@id='GoodStuff']/div");
519 url = "http://"+document.location.host+"/photos/"+matches[1]+"/tags/"+matches[2]+"/page@P@";
520 msg = this.localiser.localise('nophoto');
521 xpath = "//td[@id='GoodStuff']/div/p";
522 } //for interesting-popular page
523 else if(matches = /\/photos\/([^\/]+)\/popular-interesting\/?(page([0-9]+))?\/?$/.exec(document.location.pathname)) {
525 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
526 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
527 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/20);
529 if(matches[2]) this.next_request= parseInt(matches[2]);
530 this.insert = $x1("//table[@class='PopularPic']/tbody");
531 url = "http://"+document.location.host+"/photos/"+matches[1]+"/popular-interesting/page@P@";
533 msg = this.localiser.localise('nophoto');
534 xpath = "//table[@class='PopularPic']/tbody/tr";
535 } //for popular-view page
536 else if(matches = /\/photos\/([^\/]+)\/popular-views\/?(page([0-9]+))?\/?$/.exec(document.location.pathname)) {
538 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
539 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
540 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/20);
542 if(matches[2]) this.next_request= parseInt(matches[2]);
543 this.insert = $x1("//table[@class='PopularPic']/tbody");
544 url = "http://"+document.location.host+"/photos/"+matches[1]+"/popular-views/page@P@";
545 msg = this.localiser.localise('nophoto');
546 xpath = "//table[@class='PopularPic']/tbody/tr";
547 } //for popular-comments page
548 else if(matches = /\/photos\/([^\/]+)\/popular-comments\/?(page([0-9]+))?\/?$/.exec(document.location.pathname)) {
550 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
551 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
552 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/20);
554 if(matches[2]) this.next_request= parseInt(matches[2]);
555 this.insert = $x1("//table[@class='PopularPic']/tbody");
556 url = "http://"+document.location.host+"/photos/"+matches[1]+"/popular-comments/page@P@";
558 msg = this.localiser.localise('nophoto');
559 xpath = "//table[@class='PopularPic']/tbody/tr";
560 } //for popular-faves page
561 else if(matches = /\/photos\/([^\/]+)\/popular-faves\/?(page([0-9]+))?\/?$/.exec(document.location.pathname)) {
563 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
564 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
565 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/20);
567 if(matches[2]) this.next_request= parseInt(matches[2]);
568 this.insert = $x1("//table[@class='PopularPic']/tbody");
569 url = "http://"+document.location.host+"/photos/"+matches[1]+"/popular-faves/page@P@";
570 msg = this.localiser.localise('nophoto');
571 xpath = "//table[@class='PopularPic']/tbody/tr";
572 } //for comments on a photo
573 else if(unsafeWindow.page_photo_id) {
576 var otherpage = $x1("//div[@id='DiscussPhoto']/div[@class='Pages']/div[@class='Paginator']");
578 otherpage.className = '';
579 otherpage.parentNode.style.display = 'none';
583 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
584 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
585 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/100);
587 matches = /\/page([0-9]+)/.exec(document.location.pathname);
588 if(matches && matches[1]) this.next_request= parseInt(matches[1]);
589 this.insert = $x1("//div[@id='DiscussPhoto']/table/tbody");
590 msg = this.localiser.localise('nophoto');
592 xpath = "//div[@id='DiscussPhoto']/table/tbody/tr";
593 url = "http://"+document.location.host+unsafeWindow.global_photos[unsafeWindow.page_photo_id].ownersUrl+unsafeWindow.page_photo_id+"/page@P@";
595 } //for the user that faved a shot
596 else if(matches = /\/photos\/([^\/]+)\/([^\/]+)\/favorites\/?$/.exec(document.location.pathname)) {
597 var matches2 = /\?page=([0-9]+)$/.exec(document.location.search);
599 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
600 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
601 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/20);
604 if(matches2 && matches2[1]) this.next_request= parseInt(matches[1]);
605 this.insert = $x1("//table[@id='InBox']/tbody");
606 msg = this.localiser.localise('nopeople');
607 url = "http://"+document.location.host+matches[0]+"/?page=@P@";
608 xpath = "//table[@id='InBox']/tbody/tr";
609 } //for the user stream
610 else if(matches = /\/photos\/([^\/]+)\/?(page([0-9]+))?\/?$/.exec(document.location.pathname)) {
611 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
612 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
614 if(matches[3]) this.next_request= parseInt(matches[3]);
615 this.insert = $x1("/html/body/div[3]/table[2]/tbody/tr/td/table");
617 var tot = this.findTotalPage(pp.innerHTML);
619 this.insert = $x1("//td[contains(@class,'Big5Column')]");
621 if(tot > 5) this.nbr_page = 1+Math.ceil((tot-5)/18);
622 else this.nbr_page = 1;
624 this.nbr_page = Math.ceil(tot/18);
626 msg = this.localiser.localise('nophoto');
627 url = "http://"+document.location.host+"/photos/"+matches[1]+"/page@P@";
628 xpath = "//tbody/tr/td/table[@width='100%']/tbody/tr";
630 for(p in unsafeWindow.global_photos) return true;
633 additionalBits = function(id,body) {
634 var photos = new Array();
635 foreach("//.[contains(@class,'AutoPageAddition"+self.next_request+"')]//h4[contains(@id,'title_div')]|//.[contains(@class,'AutoPageAddition"+self.next_request+"')]//div[contains(@id,'description_div')]",
640 var photo_id = elt.id.replace(/description_div|title_div/,'');
641 if(photos.indexOf(photo_id) < 0) photos.push(photo_id);
642 if(!unsafeWindow.global_photos[photo_id]) {
643 unsafeWindow.global_photos[photo_id] = new Object();
644 unsafeWindow.global_photos[photo_id].title = '';
645 unsafeWindow.global_photos[photo_id].description = '';
647 if(elt.id.indexOf('title_div') == 0) {
648 unsafeWindow.global_photos[photo_id].title = elt.innerHTML.replace('\n','');
650 unsafeWindow.global_photos[photo_id].description = elt.innerHTML.replace('<i style="color: rgb(136, 136, 136);">click here to add a description</i>','');
653 unsafeWindow.document
655 photos.forEach(function(photo_id,i,a) {
656 unsafeWindow.insitu_init_page_photos_user_title_div(photo_id,240);
657 unsafeWindow.insitu_init_page_photos_user_description_div(photo_id,240);
662 else if(matches = /\/photos\/([^\/]+)\/sets\/([^\/]+)\/detail\/?$/.exec(document.location.pathname)) {
664 var matches2 = /\?page=([0-9]+)$/.exec(document.location.search);
665 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
666 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
667 var tot = this.findTotalPage(pp.innerHTML);
669 this.nbr_page = Math.ceil(tot/18);
671 this.nbr_page = Math.ceil(tot/20);
673 if(matches2 && matches2[1]) this.next_request= parseInt(matches2[1]);
674 this.insert = $x1("/html/body/div[3]/table[2]/tbody");
675 url = "http://"+document.location.host+"/photos/"+matches[1]+"/sets/"+matches[2]+"/detail/?page=@P@";
676 xpath = "//div[@id='Main']/table[@width='100%']/tbody/tr";
677 msg = this.localiser.localise('nophoto');
679 for(p in unsafeWindow.global_photos) return true;
682 additionalBits = function(id,body) {
683 var photos = new Array();
684 foreach("//.[contains(@class,'AutoPageAddition"+self.next_request+"')]//h4[contains(@id,'title_div')]|//.[contains(@class,'AutoPageAddition"+self.next_request+"')]//div[contains(@id,'description_div')]",
689 var photo_id = elt.id.replace(/description_div|title_div/,'');
690 if(photos.indexOf(photo_id) < 0) photos.push(photo_id);
691 if(!unsafeWindow.global_photos[photo_id]) {
692 unsafeWindow.global_photos[photo_id] = new Object();
693 unsafeWindow.global_photos[photo_id].title = '';
694 unsafeWindow.global_photos[photo_id].description = '';
696 if(elt.id.indexOf('title_div') == 0) {
697 unsafeWindow.global_photos[photo_id].title = elt.innerHTML.replace('\n','');
699 unsafeWindow.global_photos[photo_id].description = elt.innerHTML.replace('<i style="color: rgb(136, 136, 136);">click here to add a description</i>','');
702 unsafeWindow.document
704 photos.forEach(function(photo_id,i,a) {
705 unsafeWindow.insitu_init_page_photos_user_title_div(photo_id,240);
706 unsafeWindow.insitu_init_page_photos_user_description_div(photo_id,240);
712 else if(matches = /\/photos\/([^\/]+)\/sets\/([^\/]+)\/?$/.exec(document.location.pathname)) {
714 var matches2 = /\?page=([0-9]+)$/.exec(document.location.search);
715 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
716 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
717 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/60);
719 if(matches2 && matches2[1]) this.next_request= parseInt(matches2[1]);
720 this.insert = document.getElementById('setThumbs');
721 url = "http://"+document.location.host+"/photos/"+matches[1]+"/sets/"+matches[2]+"/?page=@P@";
722 msg = this.localiser.localise('nophoto');
723 xpath = "//div[@id='setThumbs']/a";
724 } //for comments on your photos
725 else if(document.location.pathname == '/recent_activity.gne') {
726 matches = /(\?days=([0-9]+))?([?&]page=([0-9]+))?$/.exec(document.location.search);
727 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
728 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
729 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/10);
731 if(matches && matches[4]) this.next_request= parseInt(matches[4]);
732 this.insert = $x1("//table[@class='RecentActivity']/tbody");
733 msg = this.localiser.localise('nocomment');
734 url = "http://"+document.location.host+"/recent_activity.gne?page=@P@";
735 if(parseInt(matches[2])>0) url += "&days="+matches[2];
736 xpath = "//table[@class='RecentActivity']/tbody/tr";
737 } //for comments you've made
738 else if(document.location.pathname == '/photos_comments.gne') {
739 matches = /\?page=([0-9]+)$/.exec(document.location.search);
740 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
741 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
742 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/10);
744 if(matches && matches[1]) this.next_request= parseInt(matches[1]);
745 this.insert = $x1("//table[@class='RecentActivity']/tbody");
746 if(this.paginator && this.paginator.parentNode.parentNode.style.display != 'none') {
747 msg = this.localiser.localise('nocomment');
748 url = "http://"+document.location.host+"/photos_comments.gne?page=@P@";
749 xpath = "//table[@class='RecentActivity']/tbody/tr";
751 } //for people search
752 else if(document.location.pathname == '/search/people/') {
753 var reg = /[?&]page=([0-9]+)/g;
756 var search = document.location.search;
758 if(matches = reg.exec(search)) {
759 if(matches[1]) this.next_request= parseInt(matches[1]);
760 search = search.replace(matches[0],'');
762 query = search.replace(/^[?&]/,'?');
765 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
766 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
767 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/10);
768 this.insert = $x1("//table[@class='PeopleResults']/tbody");
769 if(this.paginator && query) {
770 url = "http://"+document.location.host+"/search/people/"+query+"&page=@P@";
771 xpath = "//table[@class='PeopleResults']/tbody/tr";
772 msg = this.localiser.localise('nopeople');
775 else if(document.location.pathname == '/search/groups/') {
776 var reg = /[?&]page=([0-9]+)/g;
779 var search = document.location.search;
781 if(matches = reg.exec(search)) {
782 if(matches[1]) this.next_request= parseInt(matches[1]);
783 search = search.replace(matches[0],'');
785 query = search.replace(/^[?&]/,'?');
788 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
789 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
790 url = "http://"+document.location.host+"/search/groups/"+query+"&page=@P@";
792 if(query.indexOf('w=') >= 0) {
793 if(query.indexOf('m=pool') >= 0) {
794 msg = this.localiser.localise('nophoto');
795 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/24);
797 if(query.indexOf('z=t') >= 0) {
798 this.insert = $x1("//div[@class='ResultsThumbs']");
799 xpath = "//div[@class='ResultsThumbs']/div";
801 this.insert = $x1("//table[@class='DetailResults']/tbody");
802 xpath = "//table[@class='DetailResults']/tbody/tr";
805 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/15);
806 this.insert = $x1("//table[@class='DiscussionResults']/tbody");
807 msg = this.localiser.localise('notopic');
808 xpath = "//table[@class='DiscussionResults']/tbody/tr";
811 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/15);
812 this.insert = $x1("//table[@class='GroupsResults']/tbody");
813 msg = this.localiser.localise('nogroup');
814 xpath = "//table[@class='GroupsResults']/tbody/tr";
816 }//for help topic search
817 else if(document.location.pathname == '/search/forum/') {
818 var reg = /[?&]page=([0-9]+)/g;
821 var search = document.location.search;
823 if(matches = reg.exec(search)) {
824 if(matches[1]) this.next_request= parseInt(matches[1]);
825 search = search.replace(matches[0],'');
827 query = search.replace(/^[?&]/,'?');
830 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
831 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
833 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/15);
834 this.insert = $x1("//table[@class='DiscussionResults']/tbody");
835 msg = this.localiser.localise('notopic');
836 url = "http://"+document.location.host+"/search/forum/"+query+"&page=@P@";
837 xpath = "//table[@class='DiscussionResults']/tbody/tr";
839 else if(document.location.pathname == '/search/') {
840 var reg = /[?&]page=([0-9]+)/g;
843 var search = document.location.search;
845 if(matches = reg.exec(search)) {
846 if(matches[1]) this.next_request= parseInt(matches[1]);
847 search = search.replace(matches[0],'');
849 query = search.replace(/^[?&]/,'?');
852 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
853 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
854 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/24);
857 msg = this.localiser.localise('nophoto');
858 url = "http://"+document.location.host+"/search/"+query+"&page=@P@";
860 if(query.indexOf('z=t')>=0) {
861 this.insert = $x1("//div[@class='ResultsThumbs']");
862 xpath = "//div[@class='ResultsThumbs']/div";
864 this.insert = $x1("//table[@class='DetailResults']/tbody");
865 xpath = "//table[@class='DetailResults']/tbody/tr";
867 } //for explore calendar
868 else if(matches = /\/explore\/interesting\/([0-9\/]+)\/?(page([0-9]+))?/.exec(document.location.pathname)) {
869 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
870 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
871 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/10);
873 if(matches[3]) this.next_request= parseInt(matches[3]);
874 this.insert = $x1("//table[@class='DayView']/tbody");
875 msg = this.localiser.localise('nophoto');
876 url = "http://"+document.location.host+"/explore/interesting/"+matches[1]+"/page@P@";
877 xpath ="//table[@class='DayView']/tbody/tr";
878 } //for the user favorites
879 else if(matches = /\/photos\/([^\/]+)\/favorites\/?(page([0-9]+))?\/?$/.exec(document.location.pathname)) {
881 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
882 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
885 if(matches[3]) this.next_request= parseInt(matches[3]);
886 this.insert = document.getElementById('favoriteThumbs');
888 var tot = this.findTotalPage(pp.innerHTML);
889 this.nbr_page = Math.ceil(tot/36);
890 url = "http://"+document.location.host+"/photos/"+matches[1]+"/favorites/page@P@";
891 xpath = "//div[@id='favoriteThumbs']/a"
892 msg = this.localiser.localise('nophoto');
893 } //for the list of contacts
894 else if(matches = /\/people\/([^\/]+)\/contacts\/?$/.exec(document.location.pathname)) {
895 var matches2 = /[\?&]page=([0-9]+)$/.exec(document.location.search);
896 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
897 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
899 var query = document.location.search;
900 if(matches2 && matches2[1]) {
901 this.next_request= parseInt(matches2[1]);
902 query = query.replace(matches[0],'');
904 if(query) query+='&';
906 this.insert = $x1("//table[@class='PeopleResults']/tbody");
907 var tot = this.findTotalPage(pp.innerHTML);
908 this.nbr_page = Math.ceil(tot/30);
912 url = "http://"+document.location.host+"/people/"+matches[1]+"/contacts/"+query+"page=@P@";
913 msg = this.localiser.localise('nocontacts');
914 xpath = "//table[@class='PeopleResults']/tbody/tr";
915 } //for the reverse list of contacts
916 else if(matches = /\/people\/([^\/]+)\/contacts\/rev\/?$/.exec(document.location.pathname)) {
917 var matches2 = /\?page=([0-9]+)$/.exec(document.location.search);
918 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
919 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
921 if(matches2 && matches2[1]) this.next_request= parseInt(matches2[1]);
922 this.insert = $x1("//table[@class='PeopleResults']/tbody");
923 var tot = this.findTotalPage(pp.innerHTML);
924 this.nbr_page = Math.ceil(tot/40);
926 url = "http://"+document.location.host+"/people/"+matches[1]+"/contacts/rev/?page=@P@";
927 msg = this.localiser.localise('nocontacts');
928 xpath = "//table[@class='PeopleResults']/tbody/tr";
929 } //for the creative commons by
930 else if(matches = /\/creativecommons\/([^\/]+)\/?(page([0-9]+))?\/?$/.exec(document.location.pathname)) {
931 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
932 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
934 if(matches[2]) this.next_request= parseInt(matches[2]);
935 this.insert = $x1("//div[@class='RecentPhotos']");
936 var tot = this.findTotalPage(pp.innerHTML);
937 this.nbr_page = Math.ceil(tot/24);
939 url = "http://"+document.location.host+"/creativecommons/"+matches[1]+"/page@P@";
940 msg = this.localiser.localise('nocontacts');
941 xpath = "//div[@class='RecentPhotos']/p";
942 } //for the group members
943 else if(document.location.pathname == '/groups_members_detail.gne') {
944 var matches2 = /\?page=([0-9]+)$/.exec(document.location.search);
945 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
946 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
948 if(matches2 && matches2[1]) this.next_request= parseInt(matches2[1]);
949 var tot = this.findTotalPage(pp.innerHTML);
950 this.nbr_page = Math.ceil(tot/30);
952 url = "http://"+document.location.host+"/groups_members_detail.gne"+document.location.search+"&page=@P@";
953 if(matches2) url.replace(matches2[0],'')
954 msg = this.localiser.localise('nocontacts');
955 var insertBefore = $x1("/html/body/div[@id='Main']/br[@clear='all']");
958 var curl = url.replace('@P@',self.next_request);
960 if(self.next_request > self.nbr_page) {
961 self.msg_div.innerHTML = self.localiser.localise('showing',{'page':(self.next_request-1),'total':self.nbr_page})+' '+msg;
966 self.msg_div.innerHTML = self.localiser.localise('loading',{'nbrpage':(self.next_request-1),'total':self.nbr_page})+' <br/><img id="flickrphotocompass_wait" src="http://'+document.location.host+'/images/pulser2.gif" style="margin:0;padding:0;margin-right:4px;border:0px #ffffff;height: 16px;" />';
967 self.received = false;
969 function(body,insert) {
970 foreach("//div[@class='MembersList']",
972 insertBefore.parentNode.insertBefore(elt,insertBefore);
986 /* else if(document.location.pathname == '/messages.gne') {
987 matches = /\?page=([0-9]+)$/.exec(document.location.search);
988 this.paginator = $x1("//div[@class='Pages']/div[@class='Paginator']");
989 var pp = $x1("//div[@class='Pages']/div[@class='Results']");
990 this.nbr_page = Math.ceil(this.findTotalPage(pp.innerHTML)/20);
992 if(matches && matches[1]) this.next_request= parseInt(matches[1]);
993 this.insert = document.getElementById('InBox');
995 cb = getObjectMethodClosure(this,'messages_cb');
996 msg = 'No more messages';
1001 if(this.paginator) {
1003 var checkboxDiv = this.paginator.appendChild(document.createElement('div'));
1004 checkboxDiv.id = 'enableScrollContainer';
1005 checkboxDiv.setAttribute('style','font-size:80%;text-align:left;');
1006 var checkbox = document.createElement('input');
1007 checkbox.id = 'enableScroll';
1008 checkbox.checked = true;
1009 checkbox.type = 'checkbox';
1011 checkbox.addEventListener('CheckboxStateChange',function() {
1012 if(checkbox.checked) {
1013 setTimeout(self.watch_cb,100);
1014 self.stop_watch = false;
1016 self.stop_watch = true;
1019 checkboxDiv.appendChild(checkbox);
1020 var label = checkboxDiv.appendChild(document.createElement('label'));
1021 label.htmlFor = 'enableScroll';
1022 label.innerHTML = this.localiser.localise('enable');
1023 this.msg_div = this.paginator.appendChild(document.createElement('div'));
1024 this.msg_div.setAttribute('style','font-size:80%;text-align:left;margin-top:10px;');
1027 this.paginator.parentNode.setAttribute('style',
1028 'position:absolute;'+
1034 var link = $x1("//div[@class='Paginator']//span[text()='"+(this.next_request)+"']");
1037 var new_link = link.parentNode.insertBefore(document.createElement('a'),link);
1038 link.style.display = 'none';
1039 new_link.innerHTML = this.next_request;
1040 new_link.href='#infinitepage'+(this.next_request);
1041 new_link.className += 'this-page';
1043 for(i=0;i<this.paginator.childNodes.length;i++) {
1044 var item = this.paginator.childNodes.item(i);
1045 if(item.nodeType == 1 && item != link && item.id != 'enableScrollContainer' && item != this.msg_div) {
1046 item.style.display='block';
1047 item.style.width='2em';
1048 item.style.margin='0';
1055 prev = $x1("//div[@id='Pages']//div[@class='Paginator']//span[@class='AtStart']|//div[@id='Pages']//div[@class='Paginator']//a[@class='Prev']");
1056 next = $x1("//div[@id='Pages']//div[@class='Paginator']//span[@class='AtEnd']|//div[@id='Pages']//div[@class='Paginator']//a[@class='Next']");
1059 prev = $x1("//div[@class='Paginator']//span[@class='AtStart']|//div[@class='Paginator']//a[@class='Prev']");
1060 next = $x1("//div[@class='Paginator']//span[@class='AtEnd']|//div[@class='Paginator']//a[@class='Next']");
1062 if(prev) prev.style.display = 'none';
1063 if(next) next.style.display = 'none';
1066 if(!cb && msg && url && xpath) cb = getObjectMethodClosure3(this,'generic_cb',msg,url,xpath,additionalBits);
1070 var new_a = document.createElement('a');
1071 new_a.name='infinitepage'+this.next_request;
1072 this.insert.insertBefore(new_a,this.insert.firstChild);
1074 this.next_request++;
1075 this.watch_cb = getObjectMethodClosure1(this,'watch_scroll',cb,msg);
1076 setTimeout(this.watch_cb,100);
1080 //scroll watch code, from GoogleAutoPage:
1081 //http://la.ma.la/misc/demo/googleautopager.htm
1082 watch_scroll: function(cb,msg){
1084 var sc = document.body.scrollTop;
1085 var wh = window.innerHeight ? window.innerHeight : document.body.clientHeight;
1086 var total = (document.body.scrollHeight - wh);
1087 var remain = total - sc;
1089 if(remain < THRESHOLD){
1095 if(this.next_request <= this.nbr_page+1) {
1096 if(!this.stop_watch) setTimeout(getObjectMethodClosure1(this,'watch_scroll',cb,msg),100);
1098 this.msg_div.innerHTML = self.localiser.localise('showing',{'page':this.nbr_page,'total':this.nbr_page})+' '+msg;
1101 findTotalPage: function(string) {
1103 while(matches = /([0-9, '.]+)/g.exec(string)) {
1104 var x = parseInt(matches[1].replace(',',''));
1105 if(x > nbr) nbr = x;
1114 //======================================================================
1115 //======================================================================
1118 window.addEventListener("load", function () {
1121 // update automatically (http://userscripts.org/scripts/show/2296)
1122 unsafeWindow.UserScriptUpdates.requestAutomaticUpdates(SCRIPT);
1124 var flickrgp = new win.FlickrAutoPage();