fixed sets... added support for user tags
[FlickrHacks.git] / _greasemonkey_ / flickrfollowcomments.user.js
blob31397b92efe16d67cc02bb204607d6c9e0cec1bd
1 // ==UserScript==
2 // @name Flickr Follow Comments
3 // @namespace http://6v8.gamboni.org/
4 // @description Filter the comment you've made to only follow the one that interest you.
5 // @version 0.6
6 // @identifier http://6v8.gamboni.org/IMG/js/flickrfollowcomments.user.js
7 // @date 2007-02-22
8 // @creator Pierre Andrews (mortimer.pa@free.fr)
9 // @include http://*flickr.com/photos_comments.gne
10 // @include http://*flickr.com/photos/*/*
11 // ==/UserScript==
13 // --------------------------------------------------------------------
15 // This is a Greasemonkey user script.
17 // To install, you need Greasemonkey: http://greasemonkey.mozdev.org/
18 // Then restart Firefox and revisit this script.
19 // Under Tools, there will be a new menu item to "Install User Script".
20 // Accept the default configuration and install.
22 // --------------------------------------------------------------------
23 // Copyright (C) 2006 Pierre Andrews
24 //
25 // This program is free software; you can redistribute it and/or
26 // modify it under the terms of the GNU General Public License
27 // as published by the Free Software Foundation; either version 2
28 // of the License, or (at your option) any later version.
29 //
30 // This program is distributed in the hope that it will be useful,
31 // but WITHOUT ANY WARRANTY; without even the implied warranty of
32 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 // GNU General Public License for more details.
34 //
35 // The GNU General Public License is available by visiting
36 // http://www.gnu.org/copyleft/gpl.html
37 // or by writing to
38 // Free Software Foundation, Inc.
39 // 51 Franklin Street, Fifth Floor
40 // Boston, MA 02110-1301
41 // USA
43 var FETCH_PHOTOS = 50;
45 (function () {
47 //update information
48 var SCRIPT = {
49 name: "Flickr Follow Comments",
50 namespace: "http://6v8.gamboni.org/",
51 description: "Filter the comment you've made to only follow the one that interest you.",
52 identifier: "http://6v8.gamboni.org/IMG/js/flickrfollowcomments.user.js",
53 version: "0.6", // version
54 date: (new Date("2006-02-22")) // update date
55 .valueOf()
58 var ALL = 0;
59 var CONTACTS = ALL+1;
60 var FRIENDS = CONTACTS+1;
61 var FAMILY = FRIENDS+1;
62 var IGNORED = FAMILY+1;
63 var FAVS = IGNORED+1;
66 function getObjectMethodClosure0(object, method, arg) {
67 return function() {
68 return object[method](arg);
72 function getObjectMethodClosure(object, method) {
73 return function(arg) {
74 return object[method](arg);
78 function M8_log() {
79 if(unsafeWindow.console)
80 unsafeWindow.console.log(arguments);
81 else
82 GM_log(arguments);
85 var flickrfollowcomments = function() {this.init();}
87 flickrfollowcomments.prototype = {
88 photo_blocks: new Array(),
89 user_photos: {},
90 done: 0,
91 table:'',
92 faulty_pages: new Array(),
93 fetched: 0,
95 type: ALL,
96 lessThanTen: false,
97 sinceLastVisit: false,
99 contA: null,
100 frieA: null,
101 famA: null,
102 allA: null,
103 favsA: null,
105 contacts: new Array(),
106 family: new Array(),
107 friend: new Array(),
109 favs: new Array(),
110 favs_pages: 1,
112 ignore: new Array(),
113 lastVisit: 0,
114 notupdated: false,
115 lastpoll: 0,
117 init: function() {
118 var ign = GM_getValue('ignoreComments');
119 if(ign) this.ignore = ign.split(',');
121 if(unsafeWindow.page_photo_id) {
122 var disc = document.getElementById('DiscussPhoto');
123 var sel = document.createElement('input');
124 sel.id = 'ignore_'+i;
125 sel.type = 'checkbox';
126 sel.checked = this.ignore.indexOf(unsafeWindow.page_photo_id+'') >= 0;
127 var self = this;
128 sel.addEventListener('click',function(evt) {
129 var s = evt.target;
130 if(s.checked) {
131 self.addIgnore(unsafeWindow.page_photo_id);
132 } else {
133 self.removeIgnore(unsafeWindow.page_photo_id);
135 }, true);
136 disc.appendChild(sel);
137 var lbl = disc.appendChild(document.createElement('label'));
138 lbl.innerHTML = 'ignore future comments here.';
139 lbl.htmlFor = 'ignore_'+i;
140 } else if(document.location.pathname == "/photos_comments.gne") {
141 GM_addStyle(".graph {"+
142 "width: 200px;"+
143 "border: 1px solid #FF0084;"+
144 "padding: 2px;"+
145 "margin: 1em;"+
146 "}"+
147 ".graph .bar {"+
148 "display: block;"+
149 "position: relative;"+
150 "background: #0063DC;"+
151 "text-align: center;"+
152 "color: #333;"+
153 "height: 2em;"+
154 "line-height: 2em;"+
155 "color: #FF0084"+
156 "}"+
157 ".graph .bar span { position: absolute; left: 1em; }");
159 var lastVisit = GM_getValue('lastVisit');
160 if(lastVisit) {
161 lastVisit = lastVisit.split(',');
162 this.lastVisit = parseInt(lastVisit[0]);
163 this.sinceLastVisit = eval(lastVisit[1]);
164 } else {
165 this.sinceLastVisit = false;
166 this.lastVisit = 0;
168 GM_setValue('lastVisit',Date.now()+','+this.sinceLastVisit);
170 var main = document.getElementById('Main');
171 var feeds = document.getElementById('Feeds');
172 main.style.display = 'none';
173 main.id = '';
174 var newMain = main.parentNode.insertBefore(document.createElement('div'),main);
175 newMain.id = 'Main';
176 var h1 = newMain.appendChild(document.createElement('h1'));
177 h1.innerHTML = 'Comments You\'ve Made';
178 this.table = newMain.appendChild(document.createElement('table'));
179 this.table.cellspacing = 0;
180 this.table.className = 'RecentActivity';
181 this.table = this.table.appendChild(document.createElement('tbody'));
182 this.table.innerHTML = '<tr><td><img src="http://www.flickr.com/images/pulser2.gif" style="margin:0;padding:0;margin-right:4px;border:0px #ffffff;height: 16px;" /></td></tr>';
183 newMain.appendChild(feeds);
184 this.lastpoll = GM_getValue('lastpoll');
185 var lastrsp = GM_getValue('lastrsp');
186 var self = this;
187 var listener = {
188 flickr_activity_userComments_onLoad: function(success, responseXML, responseText, params){
189 try{
190 var rsp = responseText.replace(/jsonFlickrApi\(/,'');
191 rsp = eval('('+rsp);
192 if(rsp.stat == 'ok') {
193 GM_setValue('lastrsp',true);
194 GM_setValue('lastrsp'+rsp.items.page,responseText);
195 self.parsePage(rsp);
196 } else
197 M8_log("Error2 "+responseText);
198 } catch (e) {
199 M8_log("Error1 "+responseText);
200 M8_log(e);
204 if(!lastrsp || !this.lastpoll || this.lastpoll && (Date.now()-this.lastpoll > 3600*1000)) {
205 var nbr_page = FETCH_PHOTOS/50;
206 for(i=0;i < nbr_page;i++) {
207 GM_setValue('lastpoll',Date.now()+"");
208 unsafeWindow.F.API.callMethod('flickr.activity.userComments', {
209 per_page:50,
210 page: i+1,
211 format: 'json'
212 }, listener);
214 } else {
215 this.notupdate = true;
216 var nbr_page = FETCH_PHOTOS/50;
217 for(i=1;i <= nbr_page;i++) {
218 var lastrsp = GM_getValue('lastrsp'+i);
219 listener.flickr_activity_userComments_onLoad(true,'',lastrsp,'');
226 parsePage: function(rsp) {
227 var i = 0;
228 for(i=0;i<rsp.items.item.length;i++) {
229 var item = rsp.items.item[i];
230 var photo_id = item.id;
231 var user_id = item.owner;
232 this.photo_blocks.push(item);
234 if(++this.fetched >= (FETCH_PHOTOS/50))
235 this.ready();
238 getFavs: function(page) {
239 if(this.contacts.length <= 0) {
240 //Trick to do it using the flickr API with authentication already embeded in the page.
241 var self = this;
242 var listener = {
243 flickr_favorites_getList_onLoad: function(success, responseXML, responseText, params){
244 try{
245 var rsp = responseText.replace(/jsonFlickrApi\(/,'');
246 rsp = eval('('+rsp);
247 if(rsp.stat == 'ok') {
248 self.process_favs(rsp);
249 } else
250 M8_log("ErrorFavs1 "+responseText);
251 } catch (e) {
252 M8_log("ErrorFavs2 "+responseText);
253 M8_log(e);
257 var the_page = page;
258 if(page <= 0) the_page = 1;
259 unsafeWindow.F.API.callMethod('flickr.favorites.getList', {per_page: 500,
260 page:the_page,
261 format: 'json'},
262 listener);
263 } else
264 this.doneGettingFavs();
268 process_favs: function(rsp) {
269 var pages = rsp.photos.pages;
270 if(this.favs_pages++ < pages)
271 this.getFavs(rsp.photos.page+1);
272 var i = 0;
273 for(i=0;i<rsp.photos.photo.length;i++) {
274 this.favs.push(rsp.photos.photo[i].id);
276 if(this.favs_pages >= pages)
277 this.doneGettingFavs();
280 getContacts: function() {
281 if(this.contacts.length <= 0) {
282 //Trick to do it using the flickr API with authentication already embeded in the page.
283 var self = this;
284 var listener = {
285 flickr_contacts_getList_onLoad: function(success, responseXML, responseText, params){
286 self.process_contactsID(responseText);
290 unsafeWindow.F.API.callMethod('flickr.contacts.getList', {}, listener);
291 } else
292 this.doneGettingContacts();
295 process_contactsID: function(req) {
296 var rsp = req.replace(/<\?xml.*\?>/,'');
297 rsp = new XML(rsp);
299 if (rsp == null) {
300 this.error( "Could not understand Flickr's response.", 0, req);
301 } else {
302 var stat = rsp.@stat;
303 if (stat == null) {
304 this.error( "Could not find status of Flickr request", 0, req);
305 } else if (stat != 'ok') {
306 if (stat == 'fail') {
307 var err_node = rsp.err[0];
308 var code = err_node.@code;
309 var err_msg = err_node.@msg;
310 this.error( err_msg, code, req);
311 } else {
312 this.error("Unknown error status: '" + stat + "'", 0, req)
314 } else {
315 for each(contact in rsp..contact) {
316 this.contacts.push(contact.@nsid+'');
317 if(contact.@family == '1') {
318 this.family.push(contact.@nsid+'');
320 if(contact.@friend == '1') {
321 this.friend.push(contact.@nsid+'');
322 this.friend.push(contact.@nsid+'');
325 this.doneGettingContacts();
330 doneGettingContacts: function() {
331 var photos = new Array();
332 var userList;
333 this.allA.setAttribute('style','');
334 this.ignoreA.setAttribute('style','');
336 this.contA.setAttribute('style','');
337 this.frieA.setAttribute('style','');
338 this.famA.setAttribute('style','');
339 switch(this.type) {
340 case CONTACTS:
341 userList = this.contacts;
342 this.contA.setAttribute('style','text-decoration:none;color:#FF0084;');
343 break;
344 case FRIENDS:
345 userList = this.friend;
346 this.frieA.setAttribute('style','text-decoration:none;color:#FF0084;');
347 break;
348 case FAMILY:
349 userList = this.family;
350 this.famA.setAttribute('style','text-decoration:none;color:#FF0084;');
351 break;
353 for each(user in userList) {
354 if(this.user_photos[user])
355 photos = photos.concat(this.user_photos[user]);
357 this.updateDisplay(photos,false);
360 doneGettingFavs: function() {
361 this.displayMain(FAVS);
364 makeTime: function(time,ago) {
365 var diff = Date.now() - time;
366 diff = diff/1000;
367 if(diff < 365*24*3600) {
368 if(diff > 30*24*3600) {
369 return parseInt(diff/(30*24*3600))+" month(s)"+ago;
370 } else if(diff > 7*24*3600) {
371 return parseInt(diff/(7*24*3600))+" week(s)"+ago;
372 } else if(diff > 24*3600) {
373 return parseInt(diff/(24*3600))+" day(s)"+ago;
374 } else if(diff>3600) {
375 return parseInt(diff/3600)+" hour(s)"+ago;
376 } else if(diff>60) {
377 return parseInt(diff/60)+" minute(s)"+ago;
378 } else return diff + "seconds"+ago;
379 } else return "on the "+(new Date(time)).toLocaleDateString();
382 /*The activity api has a bug and always returns the user id instead of the owner,
383 so we have to cheat to get the info about the authors.*/
384 getNameFor: function(id) {
385 var self = this;
386 var listener = {
387 flickr_photos_getInfo_onLoad: function(success, responseXML, responseText, params){
388 try{
389 var rsp = responseText.replace(/jsonFlickrApi\(/,'');
390 rsp = eval('('+rsp);
391 if(rsp.stat == 'ok') {
392 var person = rsp.photo.owner;
393 var icon_link = document.createElement('a');
394 icon_link.href = "/photos/"+person.nsid+"/";
395 var img = document.getElementById("hover_img" +person.nsid);
397 if(self.user_photos[person.nsid]) {
398 self.user_photos[person.nsid].push(rsp.photo.id);
399 } else {
400 self.user_photos[person.nsid] = new Array(rsp.photo.id);
403 if(img) {
404 var img2 = img.cloneNode(false);
405 img2.setAttribute('id','');
406 img2.setAttribute('class','');
407 img2.setAttribute('width','24');
408 img2.setAttribute('height','24');
409 img2.addEventListener('mouseover',getObjectMethodClosure(unsafeWindow.document.getElementById('person_hover'),'icon_mouseover'),true);
410 img2.addEventListener('mouseout',getObjectMethodClosure(unsafeWindow.document.getElementById("person_hover"),'icon_mouseout'),true);
411 icon_link.appendChild(img2);
412 } else {
413 icon_link.innerHTML = '>';
415 var html = 'From <a href="/photos/'+person.nsid+'"><b>'+person.username+'</b></a>';
417 var who = document.evaluate("/html/body//td[@class='Who m8_Who"+rsp.photo.id+"']",
418 document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null
419 ).singleNodeValue;
420 if(who) {
421 who.appendChild(icon_link);
422 who.innerHTML += html;
424 } else
425 M8_log("Error3 "+responseText);
426 } catch (e) {
427 M8_log("Error4 "+responseText);
428 M8_log(e);
432 unsafeWindow.F.API.callMethod('flickr.photos.getInfo', {
433 photo_id:id,
434 format: 'json'
435 }, listener);
439 updateDisplay: function(photos,showingIgnore){
440 var shown = 0;
441 if(this.notupdate) this.table.innerHTML="<tr><td colspan='3'>This page cannot be updated more than once an hour due to restrictions from Flickr service. Next update will be possible after: "+this.makeTime(this.lastpoll*1,'')+"</td></tr>";
442 else this.table.innerHTML = '';
443 for(i=0;i<this.photo_blocks.length;i++){
444 var photo_item = this.photo_blocks[i];
445 if(showingIgnore || this.ignore.indexOf(photo_item.id) < 0) {
446 if(!photos || photos.indexOf(photo_item.id) >= 0) {
447 var timestamp = photo_item.activity.event[0].dateadded*1000;
448 if(this.lastVisit == 0 || !this.sinceLastVisit || timestamp >= this.lastVisit) {
449 var cnt = photo_item.more+photo_item.activity.event.length;
450 if(!this.lessThanTen || cnt < 10) {
451 var tdt = this.table.appendChild(document.createElement('tr'));
452 tdt.setAttribute('valign','top');
453 var tdo = tdt.appendChild(document.createElement('td'));
454 tdo.setAttribute('class','Object');
455 tdo.innerHTML =
456 ' <p><a href="/photo.gne?id='+photo_item.id+'/" style="position: relative;"><img width="75" height="75" alt="'+photo_item.title._content+'" src="http://static.flickr.com/'+photo_item.server+'/'+photo_item.id+'_'+photo_item.secret+'_s.jpg"/></a></p>'+
457 ' <small>'+
458 ' <b>'+photo_item.views+'</b> views<br/>'+
459 ((photo_item.faves>0)?
460 ('<a href="/photo.gne?id='+photo_item.id+'">'+photo_item.faves+' people</a> call this a favorite'):'')+
461 ' </small>'+
462 ' <img width="100" height="1" style="border: medium none ;" alt="" src="/images/spaceball.gif"/> ';
463 var small = tdo.appendChild(document.createElement('small'));
464 var sel = document.createElement('input');
465 sel.id = 'ignore_'+photo_item.id;
466 sel.type = 'checkbox';
467 sel.checked = showingIgnore;
468 var self = this;
469 sel.addEventListener('click',function(evt) {
470 var s = evt.target;
471 var id = s.id.replace('ignore_','');
472 if(s.checked) {
473 s.parentNode.parentNode.parentNode.parentNode.removeChild(s.parentNode.parentNode.parentNode);
475 self.addIgnore(id);
476 } else {
477 s.parentNode.parentNode.parentNode.parentNode.removeChild(s.parentNode.parentNode.parentNode);
478 self.removeIgnore(id);
480 }, true);
481 small.appendChild(sel);
482 var lbl = small.appendChild(document.createElement('label'));
483 lbl.innerHTML = 'ignore future comments here.';
484 lbl.htmlFor = 'ignore_'+photo_item.id;
486 var tdguts = tdt.appendChild(document.createElement('td'));
487 tdguts.setAttribute('class','Guts');
488 var html =
489 ' <table width="100%" cellspacing="0" cellpadding="0">'+
490 ' <tbody><tr valign="bottom">'+
491 ' <td>'+
492 ' <h2>'+
493 ' <a title="'+photo_item.title._content+'" style="text-decoration: none;" href="/photo.gne?id='+photo_item.id+'/">'+photo_item.title._content+'</a><br/>'+
495 ' </h2>'+
496 ' '+
497 ' <div class="HowMany">'+
498 ' <a href="/photo.gne?id='+photo_item.id+'/">'+photo_item.comments+' comments</a>'+
500 ' (<b>'+(photo_item.more+photo_item.activity.event.length-((photo_item.more==0)?1:0))+' new</b> since yours'+((photo_item.more>0)?' - Here\'s the latest 10':'')+')'+
501 ' </div>'+
502 ' </td>'+
503 ' <td class="Who m8_Who'+photo_item.id+'">'+
504 ' </td>'+
505 ' </tr>'+
506 ' </tbody></table>';
509 tdguts.innerHTML += html;
510 this.getNameFor(photo_item.id);
511 var tab = tdguts.appendChild(document.createElement('table'));
512 tab.setAttribute('width',100);
513 tab.setAttribute('cellspacing',0);
514 tab.setAttribute('class',"NewComments");
515 var bod = tab.appendChild(document.createElement('tbody'));
517 for(j=0;j<photo_item.activity.event.length;j++) {
518 var ev = photo_item.activity.event[j];
519 var ligne = bod.appendChild(document.createElement('tr'));
520 ligne.setAttribute('valign','top');
522 var type = ligne.appendChild(document.createElement('td'));
523 var type_img = type.appendChild(document.createElement('img'));
524 type_img.src = '/images/icon_'+ev.type+'.gif';
525 var icon = ligne.appendChild(document.createElement('td'));
526 icon = icon.appendChild(document.createElement('a'));
527 icon.href = "/photos/"+ev.user+"/";
528 var img = document.getElementById("hover_img" +ev.user);
529 if(img) {
530 var img2 = img.cloneNode(false);
531 img2.setAttribute('class','');
532 img2.setAttribute('id','');
533 img2.setAttribute('width','24');
534 img2.setAttribute('height','24');
535 img2.addEventListener('mouseover',getObjectMethodClosure(unsafeWindow.document.getElementById('person_hover'),'icon_mouseover'),true);
536 img2.addEventListener('mouseout',getObjectMethodClosure(unsafeWindow.document.getElementById("person_hover"),'icon_mouseout'),true);
537 icon.appendChild(img2);
539 var html = '';
540 if(ev.user == unsafeWindow.global_nsid) {
541 //yours
542 type.setAttribute('class',"YouSaidIcon");
543 type_img.setAttribute('alt',"You added a new comment");
544 ligne.innerHTML += ' <td class="YouSaid"><b>'+((ev.type=='comment')?'You said':"You added a note")+':</b><br/>'+ev._content.replace(/\n/g,'<br/>')+'</td>'+
545 ' <td class="YouSaid"><small>Added '+this.makeTime(ev.dateadded*1000,' ago')+'</small></td>';
546 }else {
547 type.setAttribute('class',"YouSaidIcon");
548 type_img.setAttribute('alt',ev.username+' added a new '+ev.type);
549 ligne.innerHTML += ' <td><b><a href="/photos/'+ev.user+'/">'+ev.username+'</a>'+((ev.type=='comment')?' says':" added a note")+':</b><br/>'+ev._content.replace(/\n/g,'<br/>')+'</td>'+
550 ' <td><small>Added '+this.makeTime(ev.dateadded*1000,' ago')+'</small></td>';
553 shown++;
560 if(shown == 0) {
561 this.table.innerHTML = "<tr><td><strong>Nothing to see here</strong></td></tr>";
565 addIgnore: function(id) {
566 this.ignore.push(id+'');
567 GM_setValue('ignoreComments',this.ignore.join(','));
570 removeIgnore: function(id) {
571 this.ignore.splice(this.ignore.indexOf(id+''),1);
572 GM_setValue('ignoreComments',this.ignore.join(','));
575 displayLessThanTen: function() {
576 this.lessThanTen = true;
577 this.displayMain(this.type);
580 displayMoreThanTen: function() {
581 this.lessThanTen = false;
582 this.displayMain(this.type);
585 displayMain: function(type) {
586 if(type >= 0) this.type = type;
587 this.table.innerHTML = '<tr><td><img src="http://www.flickr.com/images/pulser2.gif" style="margin:0;padding:0;margin-right:4px;border:0px #ffffff;height: 16px;" /></td></tr>';
588 this.contA.setAttribute('style','');
589 this.frieA.setAttribute('style','');
590 this.famA.setAttribute('style','');
591 switch(this.type) {
592 case ALL:
593 this.allA.setAttribute('style','text-decoration:none;color:#FF0084;');
594 this.ignoreA.setAttribute('style','');
595 this.favsA.setAttribute('style','');
596 this.updateDisplay(false,false);
597 break;
598 case IGNORED:
599 this.ignoreA.setAttribute('style','text-decoration:none;color:#FF0084;');
600 this.allA.setAttribute('style','');
601 this.favsA.setAttribute('style','');
602 this.updateDisplay(this.ignore,true);
603 break;
604 case FAVS:
605 this.favsA.setAttribute('style','text-decoration:none;color:#FF0084;');
606 this.allA.setAttribute('style','');
607 this.ignoreA.setAttribute('style','');
608 this.updateDisplay(this.favs,false);
609 break;
610 default:
611 this.displayOnlyContacts(this.type);
615 displayOnlyContacts: function(type) {
616 this.table.innerHTML = '<tr><td><img src="http://www.flickr.com/images/pulser2.gif" style="margin:0;padding:0;margin-right:4px;border:0px #ffffff;height: 16px;" /></td></tr>';
617 this.type = type;
618 this.getContacts();
621 displayOnlyFavs: function() {
622 this.table.innerHTML = '<tr><td><img src="http://www.flickr.com/images/pulser2.gif" style="margin:0;padding:0;margin-right:4px;border:0px #ffffff;height: 16px;" /></td></tr>';
623 this.favsA.setAttribute('style','text-decoration:none;color:#FF0084;');
624 this.allA.setAttribute('style','');
625 this.ignoreA.setAttribute('style','');
626 this.type = FAVS;
627 this.getFavs(1);
630 separator: function() {
631 var img = document.createElement('img');
632 img.setAttribute('style',"float:none;margin: 0 2;");
633 img.width="1";
634 img.height="9";
635 img.src="http://www.flickr.com/images/subnavi_dots.gif";
636 return img;
639 ready: function() {
640 this.fetched = 0;
641 var div = this.table.parentNode.parentNode.insertBefore(document.createElement('div'),this.table.parentNode);
642 if(this.faulty_pages.length > 0) {
643 var h31=document.createElement('strong');
644 h31.setAttribute('style','color:red;font-size:85%;clear:left;');
645 var txt1=document.createTextNode('These pages couldn\'t be read:');
646 h31.appendChild(txt1);
647 var ul1=document.createElement('UL');
648 ul1.setAttribute('style','margin:0;padding:0;display:inline;');
649 for(fi=0;fi<this.faulty_pages.length;fi++){
650 var li1=document.createElement('LI');
651 li1.setAttribute('style','margin:0;padding:0;display: inline;list-style-type: none;');
652 ul1.appendChild(li1);
653 var a1=document.createElement('A');
654 a1.setAttribute('href','http://www.flickr.com/photos_comments.gne?page='+this.faulty_pages[fi]);
655 li1.appendChild(a1);
656 var txt1=document.createTextNode('Page '+this.faulty_pages[fi]);
657 a1.appendChild(txt1);
659 div.appendChild(h31);
660 div.appendChild(ul1);
661 div.appendChild(document.createElement('br'));
664 var since = document.createElement('input');
665 since.type = 'checkbox';
666 since.id = 'sinceLastVisit';
667 var self = this;
668 since.checked = this.sinceLastVisit;
669 since.addEventListener('click',function() {
670 if(since.checked) {
671 self.sinceLastVisit = true;
672 } else {
673 self.sinceLastVisit = false;
675 GM_setValue('lastVisit',Date.now()+','+self.sinceLastVisit);
676 self.displayMain(self.type);
677 },true);
678 div.appendChild(since);
679 var lblsince = div.appendChild(document.createElement('label'));
680 lblsince.setAttribute('style','font-size:90%;');
681 lblsince.innerHTML = 'since last visit.';
682 lblsince.htmlFor = 'sinceLastVisit';
684 var h3 = div.appendChild(document.createElement('h3'));
685 h3.innerHTML = 'On Photos by:';
686 this.allA = div.appendChild(document.createElement('a'));
687 this.allA.innerHTML = 'All';
688 this.allA.href="javascript:;";
689 this.allA.addEventListener('click',getObjectMethodClosure0(this,'displayMain',ALL),true);
690 div.appendChild(this.separator());
691 this.contA = div.appendChild(document.createElement('a'));
692 this.contA.innerHTML = 'Contacts';
693 this.contA.href="javascript:;";
694 this.contA.addEventListener('click',getObjectMethodClosure0(this,'displayOnlyContacts',CONTACTS),true);
695 div.appendChild(this.separator());
696 this.frieA = div.appendChild(document.createElement('a'));
697 this.frieA.innerHTML = 'Friends';
698 this.frieA.href="javascript:;";
699 this.frieA.addEventListener('click',getObjectMethodClosure0(this,'displayOnlyContacts',FRIENDS),true);
700 div.appendChild(this.separator());
701 this.famA = div.appendChild(document.createElement('a'));
702 this.famA.innerHTML = 'Family';
703 this.famA.href="javascript:;";
704 this.famA.addEventListener('click',getObjectMethodClosure0(this,'displayOnlyContacts',FAMILY),true);
705 div.appendChild(this.separator());
706 this.favsA = div.appendChild(document.createElement('a'));
707 this.favsA.innerHTML = 'Favorites';
708 this.favsA.href="javascript:;";
709 this.favsA.addEventListener('click',getObjectMethodClosure(this,'displayOnlyFavs'),true);
710 div.appendChild(this.separator());
711 this.ignoreA = div.appendChild(document.createElement('a'));
712 this.ignoreA.innerHTML = 'Ignored';
713 this.ignoreA.href="javascript:;";
714 this.ignoreA.addEventListener('click',getObjectMethodClosure0(this,'displayMain',IGNORED),true);
715 div.appendChild(this.separator());
716 div.appendChild(document.createElement('br'));
717 var check = document.createElement('input');
718 check.type = 'checkbox';
719 check.id = 'lessthanten';
720 var self = this;
721 check.addEventListener('click',function() {
722 if(check.checked) self.displayLessThanTen();
723 else self.displayMoreThanTen();
724 },true);
725 div.appendChild(check);
726 var lbl = div.appendChild(document.createElement('label'));
727 lbl.setAttribute('style','font-size:90%;');
728 lbl.innerHTML = 'with less than 10 answers since yours';
729 lbl.htmlFor = 'lessthanten';
732 this.displayMain(ALL);
735 //======================================================================
736 // launch
737 try {
738 window.addEventListener("load", function () {
739 try {
741 // update automatically (http://userscripts.org/scripts/show/2296)
742 win.UserScriptUpdates.requestAutomaticUpdates(SCRIPT);
743 } catch (ex) {}
745 var flickrgp = new flickrfollowcomments();
746 }, false);
747 } catch (ex) {}
748 })();