- Fixed a bunch of bugs for existing paginations
[FlickrHacks.git] / _greasemonkey_ / flickrmoresearch.user.js
blob85cdb414ba8eacd71b97c15f5a518a9948f91917
1 // Flickr More Search
2 // v0.8
3 // 2006-06-04
4 // Copyright (c) 2006, Pierre Andrews.
5 // Released under the GPL license
6 // http://www.gnu.org/copyleft/gpl.html
7 //
8 // ==UserScript==
9 // @name        Flickr More Search
10 // @namespace   http://6v8.gamboni.org/
11 // @description Search all of your contacts for photos, and more...
12 // @version        0.8
13 // @date           2006-06-04
14 // @creator        Pierre Andrews (mortimer.pa@free.fr)
15 // @include http://*flickr.com*
16 // @exclude http://*flickr.com/photo_sendto_group.gne*
17 // ==/UserScript==
19 (function () {
21         var win = (unsafeWindow || window.wrappedJSObject || window);
23         //======================================================================
24         var CONTACTS = 1;
25         var GROUPS = CONTACTS+1;
26         var FAMILY = GROUPS+1;
27         var FRIENDS = FAMILY+1;
28         var OTHER = FRIENDS+1;
30         var DETAILS = 1;
31         var THUMBS = DETAILS+1;
32         //======================================================================
34         //update information
35         var SCRIPT = {
36                 name: "Flickr More Search",
37                 namespace: "http://6v8.gamboni.org/",
38                 description: "Search for photos for all of your contacts, and more...",
39                 source: "http://6v8.gamboni.org/Flickr-more-search.html",                       // script homepage/description URL
40                 identifier: "http://6v8.gamboni.org/IMG/js/flickrmoresearch.user.js",
41                 version: "0.8",                                                         // version
42                 date: (new Date(2006, 6, 4))            // update date
43                 .valueOf()
44         };
46         //======================================================================
47         //to do the closure and get the right this.
48         //adapted from http://persistent.info/greasemonkey/gmail.user.js
50         function getObjectMethodClosure0(object, method, arg) {
51                 return function() {
52                         return object[method](arg); 
53                 }
54         }
56         function getObjectMethodClosure(object, method) {
57                 return function(arg) {
58                         return object[method](arg); 
59                 }
60         }
62         function getObjectMethodClosure11(object, method,args3) {
63                 return function(arg) {
64                         return object[method](arg,args3); 
65                 }
66         }
68         function getObjectMethodClosure12(object, method,args3,arg4) {
69                 return function(arg) {
70                         return object[method](arg,args3,arg4); 
71                 }
72         }
75         function getObjectMethodClosure2(object, method) {
76                 return function(arg,arg2) {
77                         return object[method](arg,arg2); 
78                 }
79         }
81         function M8_log() {
82                 if(unsafeWindow.console)
83                         unsafeWindow.console.log(arguments);
84                 else
85                         GM_log(arguments);
86         }
89         //======================================================================
90         
91         // constants
92         // http status constants
93         var OK = 200;
94         
95         // xmlhttprequest readystate
96         var COMPLETE = 4;
97         
98         var DEBUG = true;
99                 
100         win.FlickrMoreSearch = function() {this.init();}
102         win.FlickrMoreSearch.prototype = {
103                                 
104                 contactList: null,
105                 familyList: null,
106                 friendsList: null,
107                 contactsXML: null,
108                 contactSearchResult: null,
109                 groupsXML: null,
110                 groupSearchResult: null,
111                 groupID: '',
112                 userID: '',
113                 inSearchPage: false,
114                 inGroupsPage: false,
115                 inAdvancedPage : false,
117                 init: function() {
118                         this.inSearchPage = (/^\/search\/?$/.test(document.location.pathname));
119                         this.inGroupsPage = (/^\/search\/groups\/?$/.test(document.location.pathname));
120                         this.userID = this.getUserID();
122                         if((this.inSearchPage || this.inGroupsPage) &&
123                            GM_getValue('alwaysthumb') &&
124                            document.location.search &&
125                            (document.location.search.indexOf("z=t") < 0) &&
126                            (document.location.search.indexOf("tempdetails=t") < 0)) {
127                                 document.location = document.location+'&z=t';
128                                 return;
129                         }
130                         if(this.inSearchPage) {
131                                 //                              if(matches = /[?&]q2=([^&]+)/.exec(document.location.search)) document.getElementById('standard_q').value = matches[1];
132                                 if(document.getElementById('standard_q').value) this.insertFeeds(OTHER);
133                                 
134                                 var searchw = document.getElementById('searchw');
135                                 searchw.options[1].value = this.userID;
137                                 document.getElementById("mtext").disabled = false;
138                                 document.getElementById("mtags").disabled = false;
140                                 searchw.addEventListener('change',getObjectMethodClosure(this,"selectchanged"),false);
141                                 searchw.addEventListener('keyup',getObjectMethodClosure(this,"selectchanged"),false);
142                                 searchw.addEventListener('keydown',getObjectMethodClosure(this,"selectchanged"),false);
143                                 
144                                 this.initContactSearch();
145                                 //                              this.initGroupSearch();
146                         } 
147                         this.initHeaderSearch();
148                         this.initAdvancedSearch();
149                         this.initDefaultThumb();
150                 },
152                 initHeaderSearch: function() {
153                         
154                         var loc = new String(document.location);
155                         var matches;                            
156                         var searchbox = document.getElementById('headersearchform');
157                         var method = document.createElement('input');
158                         method.type = 'hidden';
159                         method.name = 'm';
160                         searchbox.appendChild(method);
161                         var thisthing = null;
162                         
163                         
164                         //insert the select to choose from groups/people/photo search
165                         var searchbutton = document.getElementById('headersearchbutton2');
166                         var select = searchbox.insertBefore(document.createElement('select'),searchbutton);
167                         select.innerHTML = '<option value="photos" selected="true">photos</option>\
168 <option value="discussions">discussions</option>\
169 <option value="groups">groups</option>\
170 <option value="people">people</option>';
171                         select.addEventListener('change',function(event) {
172                                 if(select.value == 'photos') {
173                                         if(span) span.style.display = 'inline';
174                                         if(thisthing && thisthing.checked && searchbox.action == 'http://www.flickr.com/search/groups/') {
175                                                 method.value="pool";
176                                         } else 
177                                                 searchbox.action = 'http://www.flickr.com/search/';
178                                 } else if(select.value == 'discussions') {
179                                         if(span) span.style.display = 'inline';
180                                         searchbox.action = 'http://www.flickr.com/search/groups/';
181                                         method.value="discuss";
182                                 } else {
183                                         method.value="";
184                                         if(span) span.style.display = 'none';
185                                         searchbox.action = 'http://www.flickr.com/search/'+select.options[select.selectedIndex].value+'/';
186                                 }
187                         },true);
190                         var span = null;
191                         if(matches = /^http:\/\/(www\.)?flickr.com\/(photos|people|groups)(\/[^\/]+\/?|_members.gne\?id=([^&]+))/.exec(loc)) {
193                                 // inserts the checkbox to search the curent group/user
194                                 searchbox.appendChild(document.createElement('br'));
195                                 span = document.createElement('span');
196                                 thisthing = span.appendChild(document.createElement('input'));
197                                 thisthing.name = 'w';
198                                 thisthing.value = this.userID;
199                                 thisthing.type = 'checkbox';
200                                 thisthing.id = 'thisthing';
201                                 thisthing.disabled = true;
202                                 var thisthinglabel = span.appendChild(document.createElement('label'));
203                                 thisthinglabel.htmlFor = "thisthing";
204                                 thisthinglabel.innerHTML = "search this ";
205                                 searchbox.appendChild(span);
207                                 if(matches[2] == 'photos' || matches[2] == 'people') {
208                                         if(matches[3].indexOf('/friends') < 0) {
209                                                 thisthinglabel.innerHTML += ' user.';
210                                                 var self = this;
211                                                 var listener = {
212                                                         flickr_urls_lookupUser_onLoad: function(success, responseXML, responseText, params){
213                                                                 if(success) {
214                                                                         var users = responseXML.documentElement.getElementsByTagName('user');
215                                                                         thisthing.value = users[0].getAttribute('id');
216                                                                         if(thisthing.value == self.userID) {
217                                                                                 thisthinglabel.innerHTML = "Search your photos.";
218                                                                         }
219                                                                         thisthing.disabled = false;
220                                                                 }
221                                                         }
222                                                 };
223                                                 
224                                                 unsafeWindow.F.API.callMethod('flickr.urls.lookupUser', {url:matches[0]}, listener);
225                                         } else {
226                                                 thisthing.value = this.userID;
227                                                 thisthinglabel.innerHTML = "Search your photos.";
228                                                 thisthing.disabled = false;
229                                         }
230                                 } else { //if(matches[2] == 'groups') {
231                                                 thisthinglabel.innerHTML += ' group.';
232                                                 thisthing.addEventListener('click',function(){
233                                                                                                            if(method.value == 'pool') method.value = '';
234                                                                                                            else method.value = 'pool';
235                                                                                                    }, true);
236                                                 thisthing.disabled = false;
237                                                 
238                                                 /*var title = document.evaluate("/html/body/div[@id='Main']/table[@id='SubNav']/tbody/tr/td[2]/h1|/html/body/div[@id='Main']/h1[@id='Tertiary']/a[2]",
239                                                   document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null
240                                                   ).singleNodeValue;    
241                                                   if(title) {
242                                                   var titlehidden =span.appendChild(document.createElement('input'));
243                                                   titlehidden.type = 'hidden';
244                                                   titlehidden.name = 'group_title';
245                                                   titlehidden.value=title.textContent.replace(/^\s+|\s+$/g,'');
246                                                   }*/
247                                                 if(matches[4]) {
248                                                         thisthing.value = matches[4];
249                                                         thisthing.form.action = "http://www.flickr.com/search/groups/";
250                                                 } else {
251                                                         var listener = {
252                                                                 flickr_urls_lookupGroup_onLoad: function(success, responseXML, responseText, params){
253                                                                         if(success) {
254                                                                                 var groups = responseXML.documentElement.getElementsByTagName('group');
255                                                                                 thisthing.value = groups[0].getAttribute('id');
256                                                                                 thisthing.form.action = "http://www.flickr.com/search/groups/";
257                                                                         }
258                                                                 }
259                                                         };
260                                                         
261                                                         unsafeWindow.F.API.callMethod('flickr.urls.lookupGroup', {url:matches[0]}, listener);
262                                                 }
263                                 }
264                         }               
265                 },
267                 initAdvancedSearch: function() {
268                         this.inAdvancedPage = (/^\/search\/advanced\/?$/.test(document.location.pathname));
269                         if(this.inAdvancedPage) {
270                                 document.forms[1].addEventListener('submit',getObjectMethodClosure(this,'processAdvancedFields'),true);
271                                 document.forms[1].action ='http://www.flickr.com/search/';
272                                 document.forms[1].method = 'get';
273                                 var trafter = document.evaluate("/html/body/div[@id='Main']/form/table/tbody/tr[4]",
274                                                                                                  document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null
275                                                                                                  ).singleNodeValue;     
276                                 var newtr = trafter.parentNode.insertBefore(document.createElement('tr'),trafter);
277                                 newtr.innerHTML = '<td class="Tip">\
278                         <h4>Search in</h4>\
279                         <small><i><b>Tip:</b> Use this option to look for photos in one of your contacts\' stream</i></small>\
280                 </td>\
281                 <td colspan="3">\
282 <img id="searchscopebuddyicon" src="http://www.flickr.com/images/buddyicon.jpg?" width="24" height="24" alt=" Buddy Icon" align="absmiddle" style="display: none;" />\
283                                 <select name="w" id="searchw" class="Fixed">\
284                                         <option value="all" selected>Everyone\'s Photos</option>\
285                                         <option value="'+this.userID+'">Your Photos</option>\
286                                         <option value="load" id="searchwloading">Choose from your Contacts...</option>\
287                                 </select>\
288                 </td>';
289                                 //add the listeners...
290                                 var searchw = document.getElementById('searchw');
292                                 searchw.addEventListener('change',getObjectMethodClosure(this,"selectchanged"),false);
293                                 searchw.addEventListener('keyup',getObjectMethodClosure(this,"selectchanged"),false);
294                                 searchw.addEventListener('keydown',getObjectMethodClosure(this,"selectchanged"),false);
296                                 var separator = trafter.parentNode.insertBefore(document.createElement('tr'),trafter);
297                                 separator.innerHTML = '<td colspan="4" valign="bottom"><p class="Separate">&nbsp;</p></td>';                    
298                         }
299                 },
301                 processAdvancedFields: function() {
302                         //Process the date.
303                         //earch/?q=cern+-test&l=cc&d=taken-20050525-20060502
304                         var mode = document.evaluate("/html/body/div[@id='Main']/form/table/tbody/tr//select[@name='date_mode']",
305                                                                                         document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null
306                                                                                         ).singleNodeValue.value;
307                         var afterdate = document.evaluate("/html/body/div[@id='Main']/form/table/tbody/tr//input[@name='date_lo']",
308                                                                                         document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null
309                                                                                         ).singleNodeValue.value;        
310                         var beforedate = document.evaluate("/html/body/div[@id='Main']/form/table/tbody/tr//input[@name='date_hi']",
311                                                                                         document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null
312                                                                                         ).singleNodeValue.value;
313                         if(afterdate) {
314                                 afterdate = afterdate.split('/');
315                                 var m_lo = ((afterdate[0] < 10)?'0':'')+afterdate[0];
316                                 var d_lo = ((afterdate[1] < 10)?'0':'')+afterdate[1];
317                                 afterdate = afterdate[2]+m_lo+d_lo;
318                         }
319                         if(beforedate) {
320                                 beforedate = beforedate.split('/');
321                                 var m_hi = ((beforedate[0] < 10)?'0':'')+beforedate[0];
322                                 var d_hi = ((beforedate[1] < 10)?'0':'')+beforedate[1];
323                                 beforedate = beforedate[2]+m_hi+d_hi;
324                         }
326                         if(beforedate || afterdate) {
327                                 var datehidden = document.createElement('input');
328                                 datehidden.type = 'hidden';
329                                 datehidden.value = mode+'-'+afterdate+'-'+beforedate;
330                                 datehidden.name = 'd';
331                                 document.forms[1].appendChild(datehidden);
332                         }
334                         //Process the licence
335                         var cc = document.getElementById('ccsearch').checked;
336                         var comm = document.getElementById('cccommercial').checked;
337                         var deriv = document.getElementById('ccderivs').checked;
338                         var l = '';
339                         if(cc) {
340                                 if(comm) l = 'comm';
341                                 if(deriv) l += 'deriv';
342                                 if(!l) l = 'cc';
343                                 var lhidden = document.createElement('input');
344                                 lhidden.type = 'hidden';
345                                 lhidden.value = l;
346                                 lhidden.name = 'l';                             
347                                 document.forms[1].appendChild(lhidden);
348                         }
349                 },
351                 initDefaultThumb: function() {
352                         
353                         var alwaysthumb = GM_getValue('alwaysthumb');
354                         
355                         if(alwaysthumb) {
356                                 var searchbox = document.createElement("input");
357                                 searchbox.id = "hidalwaysthumb";
358                                 searchbox.type = 'hidden';
359                                 searchbox.name= 'z';
360                                 searchbox.value = 't';
361                                 document.getElementById('headersearchform').appendChild(searchbox);
362                                 
363                                 if(this.inSearchPage || this.inGroupsPage) {
364                                         var input = document.createElement("input");
365                                         input.id = "hidalwaysthumb";
366                                         input.type = 'hidden';
367                                         input.name= 'z';
368                                         input.value = 't';
369                                         document.forms[1].appendChild(input);
370                                         var pages = document.evaluate("//div[@class='Paginator']/a",                                                                              
371                                                                                                   document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
372                                         
373                                         for(var i = 0; i < pages.snapshotLength; i++) {  
374                                                 var al = pages.snapshotItem(i);
375                                                 al.href += "&z=t";
376                                         }
378                                         unsafeWindow.GoQ = function GoQ(elm){
379                                                 var url = elm.href;
380                                                 var q = document.getElementById('standard_q');
381                                                 if (q.value.length){
382                                                         url += '?q='+q.value+'&z=t';
383                                                 }
384                                                 elm.href = url;
385                                                 return true;
386                                         }
387                                 }
388                         }
389                         
390                         if(this.inSearchPage || (this.inGroupsPage && (document.location.search.indexOf('m=pool') >= 0))) {
391                                 var d_switch = document.evaluate("/html/body/div[@id='Main']//div[@class='Switch']",                              
392                                                                                                  document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null
393                                                                                                  ).singleNodeValue;     
394                                 if(d_switch) {
395                                         d_switch.firstChild.href += "&tempdetails=t";
396                                         this.createAlwaysCheck(d_switch);
397                                 }
398                         }
399                 },
401                 initContactSearch: function() {
402                         var before = document.getElementById("searchwloading");
403                         var select = before.parentNode.insertBefore(document.createElement('option'),before);
404                         select.innerHTML = "All your contacts";
405                         select.value = 'allcontacts';
406                         var select = before.parentNode.insertBefore(document.createElement('option'),before);
407                         select.innerHTML = "Your family";
408                         select.value = 'allfamily';
409                         var select = before.parentNode.insertBefore(document.createElement('option'),before);
410                         select.innerHTML = "Your friends";
411                         select.value = 'allfriends';
412                 },
414                 initGroupSearch: function() {
415                         var before = document.getElementById("searchwloading");
416                         var select = before.parentNode.insertBefore(document.createElement('option'),before);
417                         select.innerHTML = 'Choose from your Groups...';
418                         select.id = "searchgrouploading";
420                         var matches;
421                         if(matches = /w=group_([^&]+)/.exec(document.location.search)) {
422                                 this.groupID = matches[1].replace(/%40/,'@');
423                                 this.getGroups();
424                                 select.selected = true;
425                                 this.selectRightGroup(this.groupID);
426                                 this.searchsubmitGroups();
427                         }
428                 },
430                 getUserID: function() {                 
431                         /*                      var scp = document.getElementsByTagName("script")[0].innerHTML;
432                         var matches = /global_nsid = '(.*?)'/m.exec(scp);
433                         if(matches)
434                         return matches[1];*/
435                         return unsafeWindow.global_nsid;
436                 },
438                 selectchanged: function(event) {
439                         var searchw = event.target;
440                         var url = false;
441                         var matches = null;
443                         var mtext = document.getElementById("mtext");
444                         var mtags = document.getElementById("mtags");
447                         if(searchw.value=="allcontacts") {
448                                 this.getContacts();
449                                 searchw.form.onsubmit = getObjectMethodClosure(this,"searchsubmitContacts");
450                                 if(mtext) mtext.disabled = true;
451                                 if(mtags) {
452                                         mtags.disabled = true;
453                                         mtags.checked = true;
454                                 }
455                                 url = 'http://www.flickr.com/images/buddyicon.jpg';
456                         } else if(searchw.value=="allfriends") {
457                                 this.getContacts();
458                                 searchw.form.onsubmit = getObjectMethodClosure(this,"searchsubmitFriends");
459                                 if(mtext) mtext.disabled = true;
460                                 if(mtags) {
461                                         mtags.disabled = true;
462                                         mtags.checked = true;
463                                 }
464                                 url = 'http://www.flickr.com/images/buddyicon.jpg';
465                         } else if(searchw.value=="allfamily") {
466                                 this.getContacts();
467                                 searchw.form.onsubmit = getObjectMethodClosure(this,"searchsubmitFamily");
469                                 if(mtext) mtext.disabled = true;
470                                 if(mtags) {
471                                         mtags.disabled = true;
472                                         mtags.checked = true;
473                                 }
474                                 url = 'http://www.flickr.com/images/buddyicon.jpg';
475                         } else if(matches = /^group_(.*)$/.exec(searchw.value)) {
476                                 searchw.form.onsubmit = getObjectMethodClosure(this,"searchsubmitGroups");      
477                                 
478                                 if(mtext) mtext.disabled = true;
479                                 if(mtags) {
480                                         mtags.disabled = true;
481                                         mtags.checked = true;
482                                 }
483                                 this.groupID = matches[1];
484                                 url = 'http://www.flickr.com/images/buddyicon.jpg';
485                                 var iconserver = this.groupsXML..group.(@nsid == this.groupID).@iconserver;
486                                 if (iconserver){
487                                         url = 'http://static.flickr.com/'+iconserver+'/buddyicons/'+this.groupID+'.jpg?1';
488                                 }
489                         } else if(searchw.options[searchw.selectedIndex].id == "searchgrouploading") {
490                                 
491                                 if(mtext) mtext.disabled = true;
492                                 if(mtags) {
493                                         mtags.disabled = true;
494                                         mtags.checked = true;
495                                 }
496                                 url = 'http://www.flickr.com/images/pulser2.gif';
497                                 this.getGroups();
498                         } else if(this.inAdvancedPage && searchw.options[searchw.selectedIndex].id == "searchwloading") {
499                                 url = 'http://www.flickr.com/images/pulser2.gif';               
500                                 
501                                 searchw.options[searchw.selectedIndex].text = '-- Loading... --';
502                                 this.getContacts();
503                         } else if(this.inAdvancedPage && searchw.value != 'all' && searchw.value != 'me') {
504                                 url = this.getContactLogo(searchw.value);
506                                 url = "http://www.flickr.com/images/buddyicon.jpg";
507                                 var server = this.contactsXML..contact.(@nsid == searchw.value).@iconserver;
508                                 if(server>0)
509                                         url = "http://static.flickr.com/"+server+"/buddyicons/"+searchw.value+".jpg";
510                         } else {
511                                 
512                                 if(mtext) mtext.disabled = false;
513                                 if(mtags) mtags.disabled = false;
514                                 
516                                 searchw.form.onsubmit = '';
517                         }
518                         this.changeIcon(url);
519                 },
521                 changeIcon: function(url) {
522                         var icn = document.getElementById('searchscopebuddyicon');
523                         icn.alt = '';
524                         
525                         if (url){
526                                 icn.addEventListener('load',function(){ this.style.display = 'inline'; },true);
527                                 icn.src = url;
528                         }else{
529                                 icn.style.display = 'none';
530                         }
531                 },
533                 //======================================================================
535                 getContacts: function() {
536                         if(!this.contactList) {
537                                 /*var details = {
538                                         method    : "POST",
539                                         onload    : getObjectMethodClosure(this,"process_contactsID"),
540                                         url       : "http://www.flickr.com/services/rest/?method=flickr.contacts.getPublicList&api_key=e8c3239ff04c102ce2d6ed885bf99005&user_id="+this.userID,
541                                 };
542                                 
544                                 GM_xmlhttpRequest( details );*/
546                                 //Trick to do it using the flickr API with authentication already embeded in the page.
547                                 var self = this;
548                                 var listener = {
549                                         flickr_contacts_getList_onLoad: function(success, responseXML, responseText, params){
550                                                 self.process_contactsID(responseText);
551                                         }
552                                 };
553                                 
554                                 unsafeWindow.F.API.callMethod('flickr.contacts.getList', {}, listener);
556                         } 
557                 },
559                 process_contactsID: function(req) {
560                         //                      M8_log(req);
561                         var rsp = req.replace(/<\?xml.*\?>/,'');
562                         rsp = new XML(rsp);
564                         if (rsp == null) {
565                                 this.error( "Could not understand Flickr's response.", 0, req);
566                         } else {                        
567                                 var stat = rsp.@stat;
568                                 if (stat == null) {
569                                         this.error( "Could not find status of Flickr request", 0, req);
570                                 } else if (stat != 'ok') {
571                                         if (stat == 'fail') {
572                                                 var err_node = rsp.err[0];
573                                                 var code = err_node.@code;
574                                                 var err_msg = err_node.@msg;
575                                                 this.error( err_msg, code, req,li);
576                                         } else {
577                                                 this.error("Unknown error status: '" + stat + "'", 0, req)
578                                         }
579                                 } else {
580                                         var contacts = new Array();
581                                         var family = new Array();
582                                         var friends = new Array();
583                                         var searchw;
584                                         this.contactsXML = rsp;
585                                         if(this.inAdvancedPage) searchw = document.getElementById('searchw');
586                                         for each(contact in rsp..contact) {
587                                                 contacts.push(contact.@nsid);
588                                                 if(this.inAdvancedPage) {
589                                                         var option = searchw.appendChild(document.createElement('option'));
590                                                         option.innerHTML = contact.@username;
591                                                         option.value = contact.@nsid;
592                                                         option.id = 'contact_'+contact.@nsid;
593                                                 }
594                                                 if(contact.@family == '1') family.push(contact.@nsid);
595                                                 if(contact.@friend == '1') friends.push(contact.@nsid);
596                                         }
597                                         if(this.inAdvancedPage) {
598                                                 var searchwloading = document.getElementById('searchwloading');
599                                                 searchwloading.text = '-- Select a contact --';
600                                                 this.changeIcon();
601                                         }
602                                         this.contactList = contacts.join(',');
603                                         this.familyList = family.join(',');
604                                         this.friendsList = friends.join(',');
605                                 }
606                         }
607                 },
609                 searchsubmitContacts: function() {
610                         this.insertFeeds(CONTACTS);
611                         this.wait("Searching in the last photos of your contacts...");
612                         if(this.contactList) {
613                                 this.searchPhotosContacts(this.contactList);
614                         } else {
615                                 this.waitForContactList(0,this.contactList);
616                         }
617                         return false;
618                 },
620                 searchsubmitFamily: function() {                        
621                         this.insertFeeds(FAMILY);
622                         this.wait("Searching in the last photos of your family...");
623                         if(this.contactList) {
624                                 this.searchPhotosContacts(this.familyList);
625                         } else {
626                                 this.waitForContactList(0,this.familyList);
627                         }
628                         return false;
629                 },
631                 searchsubmitFriends: function() {
632                         this.insertFeeds(FRIENDS);
633                         this.wait("Searching in the last photos of your friends...");
634                         if(this.contactList) {
635                                 this.searchPhotosContacts(this.friendsList);
636                         } else {
637                                 this.waitForContactList(0,this.friendsList);
638                         }
639                         return false;
640                 },
641                 
642                 waitForContactList: function(cnt,list) {
643                         if(this.contactList) {
644                                 this.searchPhotosContacts(list);
645                         } else if(cnt < 30) {
646                                 setTimeout(getObjectMethodClosure12(this,"waitForContactList",cnt++,list),1000);
647                         }
648                 },
650                 searchPhotosContacts: function(list) {
651                         //we query the rss feed as there are no handy method to search more than one user for tags.
652                         var url = "http://www.flickr.com/services/feeds/photos_public.gne?format=json&ids="+list+"&tags="+encodeURIComponent(document.getElementById("standard_q").value);
653                                 var details = {
654                                         method    : "GET",
655                                         onload    : getObjectMethodClosure11(this,"displayResultsContacts",false),
656                                         url       : url
657                                 };
658                                 
659                                 GM_xmlhttpRequest( details );
660                 },
662                 displayResultsContacts: function(req,forceThumb) {
663                          
664                         //                      M8_log(req.responseText);
665                         
666                         var rsp;
667                         if(req) {
668                                 rsp = req.responseText;
669                                 rsp = rsp.substr(15);
670                                 rsp = eval('('+rsp);
671                                 this.contactSearchResult = rsp;
672                         } else {
673                                 rsp = this.contactSearchResult;
674                         }
676                         if (rsp == null) {
677                                 this.error( "Could not understand answer.", 0, req,li);
678                                 return;
679                         } else {                
680                                 var months = new Array('January','February','March','April','May','June','July','August','September','October','November','December');
681                                 
682                                 if(forceThumb == THUMBS) thumbs = true;
683                                 else if(forceThumb == DETAILS) thumbs = false;
684                                 else thumbs = (document.location.search.indexOf('z=t') >= 0) || GM_getValue('alwaysthumb');     
686                                 var results = this.createResultContainer(CONTACTS,thumbs?THUMBS:DETAILS);
688                                 this.buildResultSet(CONTACTS,rsp.items.length,getObjectMethodClosure2(this,'displayResultsContacts'),thumbs,results);
690                                 var html = '';
691                                 var entry;
692                                 var re = /href=&quot;(http:\/\/www.flickr.com\/people\/(.*?)\/)&quot;.*img src=&quot;(http:\/\/static\.flickr\.com\/.*?)&quot; width=&quot;([0-9]+)&quot; height=&quot;([0-9]+)&quot;/;
693                                 for each(entry in rsp.items) {
694                                         var desc = entry.description;
695                                         var matches = re.exec(desc);
696                                         var src = '';
697                                         var user_profile = '';
698                                         var url_id = '';
699                                         var logo = '';
700                                         var width = '240';
701                                         var height = '180';
702                                         var authorName = entry.author.replace(/nobody@flickr\.com \((.+?)\)$/,'$1');
703                                         if(matches) {
704                                                 user_profile = matches[1];
705                                                 url_id = matches[2];
706                                                 src = matches[3];
707                                                 width = matches[4];
708                                                 height = matches[5]
709                                                 logo = this.getContactLogo(authorName);
710                                         }
711                                         
712                                         if(thumbs) {
713                                                 src = src.replace(/_m/,"_t");
714                                         }
715                                         var date = entry.published.substr(0,10).split('-');
716                                         var longdate = date[2]+' '+months[parseInt(date[1])-1]+' '+date[0];
717                                         var urldate = date[0]+'/'+date[1]+'/'+date[2]+'/';
718                                         html += this.generateSearchLine(entry.title,
719                                                                                           src,
720                                                                                           width,
721                                                                                           height,
722                                                                                           entry.link,
723                                                                                           "/photos/"+url_id,
724                                                                                           logo,
725                                                                                           authorName,
726                                                                                           user_profile,
727                                                                                           urldate,
728                                                                                           longdate,
729                                                                                                                    entry.tags.split(' ' ),
730                                                                                                                    thumbs);
731                                 }
732                                 results.innerHTML = html;
733                                 if(thumbs) {
734                                                 var br = results.parentNode.appendChild(document.createElement('br'));
735                                                 br.clear = 'all';                                               
736                                 }
737                                 this.wait();
738                         }
739                 },
741                 
742                 getContactLogo: function(uname) {
743                         var server = this.contactsXML..contact.(@username == uname);
744                         var nsid = server.@nsid;
745                         server = server.@iconserver;
746                         if(server>0) {
747                                 return "http://static.flickr.com/"+server+"/buddyicons/"+nsid+".jpg";
748                         } else
749                                 return "http://www.flickr.com/images/buddyicon.jpg";
750                 },
751                 
752                 //======================================================================
753                 
754                 getGroups: function() {
755                         if(!this.contactList) {
756                                 var select = document.getElementById('searchgrouploading');
757                                 select.innerHTML = '-- Loading... --';
758                                 /*var details = {
759                                         method    : "POST",
760                                         onload    : getObjectMethodClosure(this,"process_groupsID"),
761                                         url       : "http://www.flickr.com/services/rest/?method=flickr.people.getPublicGroups&api_key=e8c3239ff04c102ce2d6ed885bf99005&user_id="+this.userID,
762                                 };
763                                 
765                                 GM_xmlhttpRequest( details );*/
766                                 var self = this;
767                                 var listener = {
768                                         flickr_groups_pools_getGroups_onLoad: function(success, responseXML, responseText, params){
769                                                 self.process_groupsID(responseText);
770                                         }
771                                 };
772                                 
773                                 unsafeWindow.F.API.callMethod('flickr.groups.pools.getGroups', {}, listener);
774                         } 
775                 },
777                 process_groupsID: function(req) {
778                         //                      M8_log(req);
779                         var rsp = req.replace(/<\?xml.*\?>/,'');
780                         rsp = new XML(rsp);
781                         
782                         if (rsp == null) {
783                                 this.error( "Could not understand Flickr's response.", 0, req);
784                         } else {                        
785                                 var stat = rsp.@stat;
786                                 if (stat == null) {
787                                         this.error( "Could not find status of Flickr request", 0, req);
788                                 } else if (stat != 'ok') {
789                                         if (stat == 'fail') {
790                                                 var err_node = rsp.err[0];
791                                                 var code = err_node.@code;
792                                                 var err_msg = err_node.@msg;
793                                                 this.error( err_msg, code, req,li);
794                                         } else {
795                                                 this.error("Unknown error status: '" + stat + "'", 0, req)
796                                         }
797                                 } else {
798                                         var searchw = document.getElementById("searchw");
799                                         var before = document.getElementById("searchwloading");
800                                         var select = document.getElementById('searchgrouploading');
801                                         this.changeIcon('');
802                                         select.innerHTML = '-- Select a group --';
803                                         for each(group in rsp..group) {
804                                                 select = searchw.insertBefore(document.createElement('option'),before);
805                                                 select.innerHTML = group.@name;
806                                                 select.value = 'group_'+group.@nsid;
807                                                 select.id = 'group_'+group.@nsid;
808                                         }
809                                         select = searchw.insertBefore(document.createElement('option'),before);
810                                         select.innerHTML = '----';
811                                         this.groupsXML = rsp;
812                                 }
813                         }
814                 },
816                 searchsubmitGroups: function() {
817                         this.searchGroups(1);
818                         return false;
819                 },
821                 searchGroups: function(page) {
822                         if(this.groupsXML) {
823                                 var groupTitle = this.groupsXML..group.(@nsid == this.groupID);
824                                 this.wait("Searching in the group "+groupTitle.@name);
825                         } else this.wait("Searching in the group");
827                         /*var url ="http://www.flickr.com/services/rest/?method=flickr.groups.pools.getPhotos&api_key=e8c3239ff04c102ce2d6ed885bf99005&per_page=24&extras=date_upload,icon_server&group_id="+this.groupID+"&tags="+encodeURIComponent(document.getElementById("standard_q").value)+"&page="+page;
828                         var details = {
829                                         method    : "GET",
830                                         onload    : getObjectMethodClosure11(this,"displayResultsGroups",false),
831                                         url       : url
832                                         };
833                                 
834                         GM_xmlhttpRequest( details );*/
835                         var self = this;
836                         var listener = {
837                                 flickr_groups_pools_getPhotos_onLoad: function(success, responseXML, responseText, params){
838                                         self.displayResultsGroups(responseText,false);
839                                 }
840                         };
841                         
842                         unsafeWindow.F.API.callMethod('flickr.groups.pools.getPhotos', {
843                                 per_page: 24,
844                                                           extras: 'date_upload,icon_server',
845                                                           page:page,
846                                                           tags: document.getElementById("standard_q").value,
847                                                           group_id: this.groupID
848                         }, listener);
849                 },
851                 displayResultsGroups: function(req,forceThumb) {
852                          
853                         //M8_log(req);
854                         
855                         var rsp;
856                         if(req) {
857                                 rsp = req.replace(/<\?xml.*\?>/,'');
858                                 rsp = new XML(rsp);
859                                 this.groupSearchResult = rsp;
860                         } else {
861                                 rsp = this.groupSearchResult;
862                         }
864                         if (rsp == null) {
865                                 this.error( "Could not understand answer.", 0, req,li);
866                                 return;
867                         } else {                
868                                 if(rsp.@stat == 'ok') {
869                                         var months = new Array('January','February','March','April','May','June','July','August','September','October','November','December');
870                                         
871                                         var thumbs;
872                                         if(forceThumb == THUMBS) thumbs = true;
873                                         else if(forceThumb == DETAILS) thumbs = false;
874                                         else thumbs = (document.location.search.indexOf('z=t') >= 0) || GM_getValue('alwaysthumb');
876                                         var results = this.createResultContainer(GROUPS,thumbs?THUMBS:DETAILS);
877                                                                 
878                                         var thumbs;
879                                         if(forceThumb == THUMBS) thumbs = true;
880                                         else if(forceThumb == DETAILS) thumbs = false;
881                                         else thumbs = (document.location.search.indexOf('z=t') >= 0) || GM_getValue('alwaysthumb');
883                                         this.buildResultSet(GROUPS,rsp.photos.@total,getObjectMethodClosure2(this,'displayResultsGroups'),thumbs,results);
885                                         var html = '';
886                                         for each(photo in rsp..photo) {
888                                                 var src = "http://static.flickr.com/"+photo.@server+"/"+photo.@id+"_"+photo.@secret;
889                                                 if(thumbs) src += "_t.jpg";
890                                                 else src += "_m.jpg"
891                                                 var url_id = photo.@owner;
892                                                 var user_profile = '/people/'+url_id;
893                                                 var authorName = photo.@ownername;
894                                                 var date = new Date(photo.@dateupload*1000);
895                                                 date_url = date.getFullYear()+"/"+date.getMonth()+"/"+date.getDay();
896                                                 date = date.getDay()+" "+months[date.getMonth()]+" "+date.getFullYear();
897                                                 var logo =  "http://www.flickr.com/images/buddyicon.jpg";
898                                                 if(photo.@iconserver>0) {
899                                                         logo= "http://static.flickr.com/"+photo.@iconserver+"/buddyicons/"+photo.@owner+".jpg";
900                                                 } 
901                                                 //var longdate = date[2]+' '+months[parseInt(date[1])-1]+' '+date[0];
902                                                 //var urldate = date[0]+'/'+date[1]+'/'+date[2]+'/';
903                                                 html += this.generateSearchLine(photo.@title,
904                                                                                                                            src,
905                                                                                                                            '',
906                                                                                                                            '',
907                                                                                                                            "/photos/"+url_id+"/"+photo.@id,
908                                                                                                                            "/photos/"+url_id,
909                                                                                                                            logo,
910                                                                                                                            authorName,
911                                                                                                                            user_profile,
912                                                                                                                            date_url,
913                                                                                                                            date,
914                                                                                                                 null,
915                                                                                                                 thumbs);
916                                         }
917                                         results.innerHTML = html;
918                                         if(thumbs) {
919                                                 var br = results.parentNode.appendChild(document.createElement('br'));
920                                                 br.clear = 'all';                                               
921                                         }
922                                         if(rsp.photos.@pages > 1) results.parentNode.appendChild(this.paginate(rsp.photos.@page,rsp.photos.@pages,rsp.photos.@total,'searchGroups'));
923                                         this.wait();
924                                 } else if(rsp.@stat == 'fail') {
925                                         this.error(rsp.err.@msg,rsp.err.@code,req);
926                                 } else {
927                                         this.error("unknown error with group search",0,req);
928                                 }
929                         }
930                 },
932                 selectRightGroup: function(id) {
933                         var searchw = document.getElementById('group_'+id);
934                         if(searchw) searchw.selected = true;
935                         else {
936                                 var matches;
937                                 if(matches = /[&?]group_title=([^&]+)/.exec(document.location.search)) {
938                                         searchw = document.getElementById('searchw').appendChild(document.createElement('option'));
939                                         searchw.innerHTML = matches[1];
940                                         searchw.value = id;
941                                         searchw.name = 'group_'+id;
942                                         searchw.id = 'group_'+id;
943                                         searchw.selected = true;
944                                 } else {
945                                         setTimeout(getObjectMethodClosure0(this,'selectRightGroup',id),true);
946                                 }
947                         }                       
948                 },
950                 //======================================================================
952                 buildResultSet: function(type,total,callback,thumbs,results) {          
953                         var found = document.getElementById('ResultSetFound');
954                         var link;
955                         
956                         if(!found) {
957                                 var set = results.parentNode.insertBefore(document.createElement('div'),results);
958                                 set.className = "ResultSet";
959                                 var div = set.appendChild(document.createElement('div'));
960                                 div.className = 'Switch';
961                                 link = div.appendChild(document.createElement('a'));
962                                 link.id = "switcha";
963                                 link.href="javascript:;";
964                                 this.createAlwaysCheck(div);
965                                 
966                                 found = set.appendChild(document.createElement('div'));
967                         }
968                         if(!link) link = document.getElementById('switcha');
969                         if(thumbs) link.innerHTML = "Show details";
970                         else link.innerHTML = "Show Thumbnails";
972                         link.addEventListener('click',function() {callback(null,thumbs?DETAILS:THUMBS);},true);
974                         if(total < 1) link.style.display = 'none';
976                         found.id = "ResultSetFound";
977                         if(total > 0) {
978                                 found.className = 'Found';
979                                 var html = 'We found '+total+' photos about <span class="queryterm">'+document.getElementById('standard_q').value+'</span>';
980                                 if(type == GROUPS) {
981                                         if(this.groupsXML) {
982                                                 var groupTitle = this.groupsXML..group.(@nsid == this.groupID);
983                                                 html +=" in the pool of "+groupTitle.@name;
984                                         }
985                                 } else if(type == CONTACTS) {
986                                         html +=" in your contacts' photos";
987                                 }
988                                 html += '.<div class="SortOptions">&nbsp;</div>';
989                                 found.innerHTML = html;
990                         } else {
991                                 found.className = 'NoneFound';
992                                 var html = 'We cannot find any results matching your request.';
993                                 if(type == GROUPS) {
994                                         if(this.groupsXML) {
995                                                 var groupTitle = this.groupsXML..group.(@nsid == this.groupID);
996                                                 html +=" in the group "+groupTitle.@name+" pool";
997                                         }
998                                 } else if(type == CONTACTS) {
999                                         html +=" in your contacts' photos";
1000                                 }                               
1001                                 html += '<div class="SortOptions">&nbsp;</div><p>We give up!</p>';
1002                                 found.innerHTML = found;
1003                         }
1004                         return found.parentNode;
1005                 },
1007                 generateSearchLine: function(title,src,width,height,url,user_url,user_logo,user_name,user_profile,date,longdate,tags,thumbs) {
1008                 
1009                         if(!thumbs) {
1010                                 var toreturn = '<tr valign="top">\
1011                         <td class="DetailPic">\
1012                                 <a href="'+url+'" title="'+title+'"><img src="'+src+'" width="'+width+'" height="'+height+'" alt="'+title+'" /></a>\
1013                         </td>\
1014                         <td class="PicDesc">\
1015                                 <h3>'+title+'\
1016                                         <br />\
1017                                         <small>Uploaded on <a href="'+user_url+'/archives/date-posted/'+date+'" style="text-decoration: none;">'+longdate+'</a></small>\
1018                                 </h3>\
1019                                 <p class="PicFrom">\
1020                                         <a href="'+user_url+'"><img src="'+user_logo+'" width="48" height="48" alt="Click '+user_name+'\' Buddy Icon to see more photos" /></a>\
1021                                         By <b><a href="'+user_url+'" style="text-decoration: none;">'+user_name+'</a></b><br />\
1022                                         <span style="font-size: 12px;">See <a href="'+user_url+'" style="text-decoration: none;">more photos</a>, or visit his <a style="text-decoration: none;" href="'+user_profile+'">profile</a>.</span>\
1023                                 </p>\
1024                                 <p class="ListTags">';
1025                                 if(tags) {
1026                                         toreturn += '<img src="/images/icon_tag.gif" alt="Tagged with..." width="16" height="16" align="absmiddle" style="border: none;" />';
1027                                         var cnt = 0;
1028                                         for each(tag in tags) {
1029                                                 if(cnt++ > 3) break;
1030                                                 toreturn += this.tagLine(tag);
1031                                         }
1032                                         if(cnt > 3) toreturn += "...</p>";
1033                                 }
1034                                 toreturn += "</td></tr>";
1035                         } else {
1036                                 var toreturn = '<div>\
1037                                   <a title="'+title+' by '+user_name+'" href="'+url+'">\
1038                                   <img src="'+src+'"/>\
1039                                   </a>\
1040                                   <p>\
1041                                   <a href="'+user_url+'">'+user_name+'</a>\
1042                                   </p>\
1043                                   </div>';
1044                         }
1045                         return toreturn;
1046                 },
1048                 createResultContainer: function(type,dispType) {
1049                         
1050                         var pages = document.evaluate("//div[@class='Pages']",                              
1051                                                                                   document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null
1052                                                                                   ).singleNodeValue;    
1053                         if(pages) pages.parentNode.removeChild(pages);
1054                         var rs = document.evaluate("//div[@class='ResultSet']",                              
1055                                                                            document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null
1056                                                                            ).singleNodeValue;   
1057                         if(rs) rs.parentNode.removeChild(rs);
1058                         rs = document.evaluate("//div[@class='ResultsThumbs']",                              
1059                                                                    document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null
1060                                                                    ).singleNodeValue;   
1061                         if(rs) rs.parentNode.removeChild(rs);
1063                         if(type == GROUPS) {
1064                                 rs = document.getElementById('Feeds');  
1065                                 if(rs) rs.parentNode.removeChild(rs);
1066                         }
1068                         var results;
1069                         if(dispType == DETAILS) {
1070                                 results = document.evaluate("/html/body/div[@id='Main']/table",                              
1071                                                                                 document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null
1072                                                                                 ).singleNodeValue;              
1073                                 if(results) results.id = "ResultsTable";
1074                                 var tab = document.getElementById('ResultsDiv');
1075                                 if(tab) tab.style.display = 'none';
1076                         } else if(dispType == THUMBS) {
1077                                 results = document.evaluate("/html/body/div[@id='Main']//div[@class='ResultsThumbs']",                              
1078                                                                                 document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null
1079                                                                                 ).singleNodeValue;      
1080                                 if(results) results.id = "ResultsDiv";
1081                                 var tab = document.getElementById('ResultsTable');
1082                                 if(tab) tab.style.display = 'none';
1083                         }
1084                                 
1085                         if(!results) {
1086                                 if(dispType == THUMBS) {
1087                                         results = document.createElement("div");
1088                                         results.className = "ResultsThumbs";
1089                                         results.id = "ResultsDiv";
1090                                 } else {
1091                                         results = document.createElement("table");
1092                                         results.cellspacing="0";
1093                                         results.className="DetailResults";
1094                                         results.id = "ResultsTable";
1095                                 }
1096                                 var insertAfter = document.getElementById('searchwaitdiv');
1097                                 if(!insertAfter) insertAfter = document.forms[1];
1098                                 insertAfter.parentNode.insertBefore(results,insertAfter.nextSibling);
1099                         } 
1100                         results.style.display = '';
1101                         return results;
1102                 },
1104                 paginate: function(page,number,total,callback) {
1105                         page = parseInt(page);
1106                         number = parseInt(number);
1107                         total = parseInt(total);
1108                         var pagesD = document.evaluate("//div[@class='Paginator']",                              
1109                                                                                   document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null
1110                                                                                   ).singleNodeValue;
1111                         var pagesA;
1112                         if(!pagesD) {
1113                                 pagesA = document.createElement('div');
1114                                 pagesA.className = "Pages";
1115                                 var pagesD = pagesA.appendChild(document.createElement('div'));
1116                                 pagesD.className = "Paginator";
1117                         } else {
1118                                 pagesA = pagesD.parentNode;
1119                                 pagesD.innerHTML = '';
1120                                 pagesA.removeChild(pagesD.nextSibling);
1121                         }
1122                         
1123                         if(page == 1) {
1124                                 var span = pagesD.appendChild(document.createElement('span'));
1125                                 span.className = "AtStart";
1126                                 span.innerHTML =  '&lt; Prev';
1127                         } else {
1128                                 var a = pagesD.appendChild(document.createElement('a'));
1129                                 a.innerHTML = "&lt; Prev";
1130                                 a.className = "Prev";
1131                                 a.href="javascript:;";
1132                                 var self = this;
1133                                 a.addEventListener("click",getObjectMethodClosure0(this,callback,page-1),true);
1134                         }
1135                         
1136                         var start = page-3;
1137                         if(start < 7) start = 1;
1138                         if(start > 1){
1139                                 var span = pagesD.appendChild(document.createElement('span'));
1140                                 span.className = "break";
1141                                 span.innerHTML =  '...';
1142                         }
1143                         var stop = page+3;
1144                         if(stop < 13)
1145                                 stop = 10;
1146                         for(var i=start;i<=stop && i <= number;i++) {
1147                                 if(i == page) {
1148                                         var span = pagesD.appendChild(document.createElement('span'));
1149                                         span.className = "this-page";
1150                                         span.innerHTML =  page;
1151                                 } else {
1152                                         var a =pagesD.appendChild(document.createElement('a'));
1153                                         a.innerHTML = i;
1154                                         a.href="javascript:;";
1155                                         var self = this;
1156                                         var p = i;
1157                                         a.addEventListener("click",getObjectMethodClosure0(this,callback,i),true);
1158                                 }
1159                         }
1160                         if(number-start > 10) {
1161                                 var span = pagesD.appendChild(document.createElement('span'));
1162                                 span.className = "break";
1163                                 span.innerHTML =  '...';
1164                         }
1165                         if(page < number) {                             
1166                                 var a = document.createElement('A');
1167                                 pagesD.appendChild(a);
1168                                 a.innerHTML = "Next &gt;";
1169                                 a.className = "Next";
1170                                 a.href="javascript:;";
1171                                 var self = this;
1172                                 a.addEventListener("click",getObjectMethodClosure0(this,callback,page+1),true);
1173                         }
1174                         var rstot = pagesA.appendChild(document.createElement('div'));
1175                         rstot.className = "Results";
1176                         rstot.innerHTML = '('+total+' photos, '+number+' pages)';
1177                         return pagesA;
1178                 },
1179                 
1180                 error: function(msg,code,req) {
1181                         M8_log(msg,req);
1182                 },
1183                 
1184                 tagLine: function(tag) {
1185                         return '<a href="/photos/tags/'+tag+'/clusters/">'+tag+'</a>, ';
1186                 },
1188                 insertFeeds: function(type) {
1189                         var feeds = document.getElementById('Feeds');
1190                         if(!feeds ) feeds = document.getElementById('Main').appendChild(document.createElement('div'));
1191                         feeds.id = "Feeds";
1192                         var feedurl = "/services/feeds/photos_public.gne?format=rss_200";
1193                         var title = '';
1194                         if(type == CONTACTS) {
1195                                 feedurl += "&ids="+this.contactList;
1196                                 title = "&ndash; Subscribe to your contacts' photos tagged "+document.getElementById("standard_q").value;
1197                         } else if(type == FAMILY) {
1198                                 feedurl += "&ids="+this.familyList;
1199                                 title = "&ndash; Subscribe to your family's photos tagged "+document.getElementById("standard_q").value;
1200                         } else if(type == FRIENDS) {
1201                                 feedurl += "&ids="+this.friendsList;
1202                                 title = "&ndash; Subscribe to your friends' photos tagged "+document.getElementById("standard_q").value;
1203                         } else {
1204                                 if(document.location.search.indexOf('w=me') >= 0) {
1205                                         feedurl += "&id="+this.userID;
1206                                         title = "&ndash; Subscribe to your photos tagged "+document.getElementById("standard_q").defaultValue;
1207                                 } else if(document.location.search.indexOf('w=all') < 0) {
1208                                         feedurl += "&id="+document.getElementById('searchw').value;
1209                                         var matches = /^Flickr: Search (.*) photos$/.exec(document.title);
1210                                         if(matches) title = "&ndash; Subscribe to "+matches[1]+" photos tagged "+document.getElementById("standard_q").value;
1211                                 } else {
1212                                         title = "&ndash; Subscribe to public photos tagged "+document.getElementById("standard_q").value;
1213                                 }
1214                         }
1215                         feedurl += "&tags="+encodeURIComponent(document.getElementById("standard_q").value);
1216                         feeds.innerHTML = '<div id="AtomRSS">\
1217                   <a title="RSS 2.0 feed" href="'+feedurl+'">\
1218                      <img width="16" height="16" align="absmiddle" alt="Subscribe to a feed of stuff on this page..." src="/images/feed-icon-16x16.png"/>\
1219                   </a>\
1220                   <a title="RSS 2.0 feed" href="'+feedurl+'">Feed</a>'+title+
1221                         '</div>                                                         \
1222               <div id="AddToYahoo">\
1223                   <a href="http://us.rd.yahoo.com/my/atm/Flickr/Users/*http://add.my.yahoo.com/rss?url=http%3A%2F%2Fwww.flickr.com%2F'+encodeURIComponent(feedurl)+'"> \
1224                     <img width="62" height="17" alt="Add to My Yahoo!" src="/images/addtomyyahoo6.gif"/>\
1225                   </a>\
1226               </div>';
1227                 },
1228                 
1229                 createAlwaysCheck: function(parent) {
1230                         
1231                         parent.appendChild(document.createElement('br'));
1232                         var check =  document.createElement('input');
1233                         check.type = "checkbox";
1234                         check.checked = GM_getValue('alwaysthumb');
1235                         check.id = 'alwaysthumb';
1236                         check.addEventListener('change',function(event) {       
1237                                                                            GM_setValue('alwaysthumb',check.checked);
1238                                                                            if(check.checked) {
1239                                                                                    var input = document.forms[1].appendChild(document.createElement("input"));
1240                                                                                    input.id = "hidalwaysthumb";
1241                                                                                    input.type = 'hidden';
1242                                                                                    input.name= 'z';
1243                                                                                    input.value = 't';
1244                                                                                    var pages = document.evaluate("      //div[@class='Paginator']/a",                                                                             
1245                                                                                                                                                  document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
1246                                                                                    
1247                                                                                    for(var i = 0; i < pages.snapshotLength; i++) {  
1248                                                                                            var al = pages.snapshotItem(i);
1249                                                                                            al.href += "&z=t";
1250                                                                                    }
1251                                                                            } else {
1252                                                                                    var hide = document.getElementById("hidalwaysthumb");
1253                                                                                    hide.parentNode.removeChild(hide);
1254                                                                            }
1255                                                                    },true);
1256                         parent.appendChild(check);
1257                         parent.appendChild(document.createTextNode("Always show thumbnails"));
1258                 },
1260                 wait: function(message) {
1261                         var wait = document.getElementById('searchwaitdiv');
1262                         if(wait) {
1263                                 if(message) {
1264                                         wait.innerHTML = '<img src="http://www.flickr.com/images/pulser2.gif" style="vertical-align:middle;margin-right:4px;border:0px #ffffff" />'+message;
1265                                 } else {
1266                                         wait.style.display = 'none';
1267                                 }
1268                         } else if(message) {
1269                                 wait = document.forms[1].parentNode.insertBefore(document.createElement('div'),document.forms[1].nextSibling);
1270                                 wait.innerHTML = '<img src="http://www.flickr.com/images/pulser2.gif" style="vertical-align:middle;margin-right:4px;border:0px #ffffff" />'+message;
1271                                 wait.id = 'searchwaitdiv';
1272                                 wait.style.textAlign = "center";
1273                         }
1274                 }
1275                 
1276         }
1277                 
1278         //======================================================================
1279         // launch
1280         try {
1281                 window.addEventListener("load", function () {
1282                                                                         try {
1283                                                                                 
1284                                                                                 // update automatically (http://userscripts.org/scripts/show/2296)
1285                                                                                 win.UserScriptUpdates.requestAutomaticUpdates(SCRIPT);
1286                                                                         } catch (ex) {} 
1287                                                                         
1288                                                                         var flickrgp = new win.FlickrMoreSearch();
1289                 }, false);
1290         } catch (ex) {}
1292 })();