Pokec Preview

Preview profile images on Pokec/AZet

  1. // ==UserScript==
  2. // @name Pokec Preview
  3. // @namespace marki
  4. // @description Preview profile images on Pokec/AZet
  5. // @include http://*.azet.sk/*
  6. // @include http://*.aktuality.sk/*
  7. // @include http://*.zive.sk/*
  8. // @icon http://www.azet.sk/favicon.ico
  9. // @grant GM_setValue
  10. // @grant GM_getValue
  11. // @grant GM_xmlhttpRequest
  12. // @version 1.2
  13. // ==/UserScript==
  14.  
  15. // Code based on FFixer http://userscripts.org/scripts/show/8861
  16. // v0.2 - preview also for photo albums, also profile pic in comments
  17. // v0.3 - 2011-03-09 - fixed images URL due to change on azet, change in photoalbum big picture filename
  18. // v0.4 - 2011-06-14 - show popup on left if thumbnail is on right
  19. // v0.5 - 2012-01-23 - added support for new image urls, added icon, added search URL aktuality.sk
  20. // v0.6 - 2012-04-05 - again new URL (m1.aimg.sk instead of m.aimg.sk)
  21. // v1.1 - 2015-04-17 - all profile pics are now protected; need to fetch user profile to get URL of full size pic
  22. // v1.2 - 2015-05-03 - on profile page, show date of last visit
  23. // 2015-05-09 - show date of last visit also on list of users page
  24.  
  25. // *** WARNING: ***
  26. // This version won't work without changing URL http://XXXX/azet_prof_img.php to your copy of PHP script
  27.  
  28. (function() {
  29.  
  30. var showPopupPicTimeout;
  31. var hidePopupPicTimeout;
  32.  
  33. //
  34. // Add styles used by script
  35. //
  36. addStyle(
  37. '.fbfPopup { padding:10px; background:#f6f6f6; border:3px double #666666; -moz-border-radius:5px; -webkit-border-radius:5px; -khtml-border-radius:5px; border-radius:5px; }'+
  38. '#qq-popup-div { display:none; background:white; border:1px solid #333; position:fixed !important; top:3px !important; padding:4px; min-width:130px; z-index:99999 !important; -moz-border-radius:3px; -webkit-border-radius:3px; -khtml-border-radius:3px; border-radius:3px; }'+
  39. '.qq-popup-div { right:3px !important; left:auto !important; -moz-box-shadow:-5px 5px 5px rgba(0,0,0,0.6); -webkit-box-shadow:-5px 5px 5px rgba(0,0,0,0.6); -khtml-box-shadow:-5px 5px 5px rgba(0,0,0,0.6); box-shadow:-5px 5px 5px rgba(0,0,0,0.6); }'+
  40. '.qq-popup-div-left { left: 3px !important; right:auto !important; -moz-box-shadow:5px 5px 5px rgba(0,0,0,0.6); -webkit-box-shadow:5px 5px 5px rgba(0,0,0,0.6); -khtml-box-shadow:5px 5px 5px rgba(0,0,0,0.6); box-shadow:5px 5px 5px rgba(0,0,0,0.6); }'+
  41. '.qq-popup-div-right { right:3px !important; left:auto !important; -moz-box-shadow:-5px 5px 5px rgba(0,0,0,0.6); -webkit-box-shadow:-5px 5px 5px rgba(0,0,0,0.6); -khtml-box-shadow:-5px 5px 5px rgba(0,0,0,0.6); box-shadow:-5px 5px 5px rgba(0,0,0,0.6); }'+
  42. '#qq-pic-close { display:none; position:absolute; top:4px; right:10px; color:#ff9999; cursor:pointer; font-weight:bold; font-size:14px; }'+
  43. '#qq-popup-div:hover #ff-popup-pic-close { display:block; }'+
  44. '#qq-pic-close:hover { color:#aa6666; }'+
  45. '#ff-popup-pic-image { text-align:center; }'+
  46. '#ff-popup-pic-image img { color:#999999; display:block; }'+
  47. '#visitDiv { text-align: center; }'
  48. );
  49.  
  50.  
  51. // profile page visits
  52. function insertAfter(newNode, referenceNode) { referenceNode.parentNode.insertBefore( newNode, referenceNode.nextSibling );}
  53. var last, Nick, text;
  54. if (/http:\/\/pokec\.azet\.sk\/[^/]+\/?\?i9/.test(location)) {
  55. Nick = location.toString().replace(/\/?\?.*$/, "");
  56. Nick = Nick.replace(/http:\/\/pokec\.azet\.sk\//, "");
  57. console.log("Profile page for "+Nick);
  58. last = GM_getValue("lastProf-"+Nick,"");
  59. if (!last) text="<b>Profil este nebol pozrety</b>"; else text="Posledna navsteva: <b>"+last+"</b>";
  60. var metaViz = document.evaluate("//div[@class='metaVizitka']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
  61. var visitDiv = document.createElement('div');
  62. visitDiv.id = 'visitDiv';
  63. visitDiv.innerHTML = '<div>'+text+'</div>';
  64. insertAfter(visitDiv, metaViz);
  65. last = new Date();
  66. text = last.getDate() +"."+ (last.getMonth()+1) +"."+ last.getFullYear();
  67. GM_setValue("lastProf-"+Nick, text);
  68. }
  69.  
  70.  
  71. // list of users (add profile visits)
  72. var allLinks, thisLink, i;
  73. if (/http:\/\/pokec\.azet\.sk\/sluzby\/pouzivatelia\//.test(location)) {
  74. allLinks = document.evaluate('//div[@class="userContainer"]//h3//a', document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
  75. for (var i = 0; i < allLinks.snapshotLength; i++) {
  76. thisLink = allLinks.snapshotItem(i);
  77. Nick = thisLink.href.toString().replace(/\/?\?.*$/, "");
  78. Nick = Nick.replace(/http:\/\/pokec\.azet\.sk\//, "");
  79. //console.log("Profile link found for "+Nick);
  80. last = GM_getValue("lastProf-"+Nick,"");
  81. if (last) {
  82. visitDiv = document.createElement('div');
  83. visitDiv.innerHTML = '<div style="padding-left:10px;font-weight:bold;font-size:80%;color:#3878C0">'+last+'</div>';
  84. insertAfter(visitDiv, thisLink);
  85. }
  86. }
  87. }
  88.  
  89. //
  90. // Add div for showing big profile pics
  91. //
  92. var popupPicDiv = document.createElement('div');
  93. popupPicDiv.id = 'qq-popup-div';
  94. popupPicDiv.className = 'fbfPopup qq-popup-div';
  95. popupPicDiv.innerHTML = '<div id="qq-pic-close" title="Close">x</div><div id="ff-popup-pic-image"><span></span></div>';
  96.  
  97. try {
  98. document.body.insertBefore(popupPicDiv, document.body.lastChild.nextSibling);
  99. document.getElementById('qq-pic-close').addEventListener('click', function() { document.getElementById('qq-popup-div').style.display='none'; }, false);
  100. } catch(x) {
  101. var fbppdivAdder = setInterval(function() {
  102. try {
  103. document.body.insertBefore(popupPicDiv, document.body.lastChild.nextSibling);
  104. document.getElementById('qq-pic-close').addEventListener('click', function() { document.getElementById('qq-popup-div').style.display='none'; }, false);
  105. if ($('#qq-popup-div')) { clearInterval(fbppdivAdder); }
  106. } catch(x) {}
  107. }, 250);
  108. }
  109. // Listeners are added by the code for showing the popups
  110.  
  111. //
  112. // Listen for image mouseovers/mouseouts to show/hide popups
  113. //
  114. // http://213.215.107.127/fotky/1272/79/n_12727989.jpg?v=4
  115. // http://213.215.107.125/fotky/1518/42/n_15184211.jpg?v=5 -- thumb
  116. // http://213.215.107.125/fotky/1171/72/n_11717223.jpg?v=5 -- profil
  117. // http://213.215.107.127/fotky/ 622/47/s_6224758 .jpg?v=2 -- zoznam priatelov
  118. // http://213.215.107.127/fotky/ 622/47/m_6224758 .jpg?v=2 -- komentare v profile
  119. // http://213.215.107.125/fotky/ 542/71/ 5427111 .jpg?v=3 -- big
  120.  
  121. // http://213.215.107.78/fotoalbumy/356/357/nf_356357110_be87b7135c37a25cb494877aa5bd4480.jpg - thumb
  122. // http://213.215.107.78/fotoalbumy/356/357/ f_356357110_be87b7135c37a25cb494877aa5bd4480.jpg - big photo
  123. // http://213.215.107.78/fotoalbumy/356/357/mf_356357110_be87b7135c37a25cb494877aa5bd4480.jpg - 2011-03-09 big photo
  124. // http://213.215.107.77/fotoalbumy/356/357/ f_356357907_fe56924742d842826c03c551811c0dbc.jpg
  125.  
  126. // found 2012-01-23
  127. // http://m.aimg.sk/profil/m_15702354.jpg?v=5
  128. // http://m.aimg.sk/profil/s_15702354.jpg?v=5
  129. // http://m.aimg.sk/profil/ 15702354.jpg?v=5
  130.  
  131. picRegex = /http:\/\/(u\.aimg\.sk|213\.215\.107\.[0-9]+)\/fotky\/[0-9]+\/[0-9]{2}\/[nsm]_([0-9]+\.jpg)/;
  132. albRegex = /http:\/\/(u\.aimg\.sk|213\.215\.107\.[0-9]+)\/fotoalbumy\/[0-9]+\/[0-9]+\/nf_[0-9]+_[0-9a-f]+\.jpg/;
  133. newRegex = /http:\/\/m[0-9]*\.aimg\.sk\/profil\/[nsm]_([0-9]+\.jpg)/;
  134. proRegex = /http:\/\/t[0-9]*\.aimg\.sk\/pokec\/fotoalbumy\/[0-9]+\/[0-9a-f_]+\.jpg/;
  135.  
  136. function showPopupPic(e) {
  137. try {
  138. var t = e.target;
  139. var oldSrc;
  140. var newSrc;
  141.  
  142. if (t.tagName == 'IMG' && picRegex.test(t.src)) { newSrc = t.src.replace(/[nsm]_/, ""); }
  143. if (t.tagName == 'IMG' && albRegex.test(t.src)) { newSrc = t.src.replace(/nf_/ , "mf_"); }
  144. if (t.tagName == 'IMG' && newRegex.test(t.src)) { newSrc = t.src.replace(/[nsm]_/, ""); }
  145. if (t.tagName == 'IMG' && proRegex.test(t.src)) { newSrc = GM_getValue(t.src, ""); if (newSrc) console.log("From cache: "+newSrc); } // fetch URL from local storage
  146.  
  147. if (oldSrc || newSrc) {
  148. clearTimeout(hidePopupPicTimeout);
  149. t.removeEventListener('mouseout', hidePopupPic, false);
  150. t.addEventListener('mouseout', hidePopupPic, false);
  151. showPopupPicTimeout = setTimeout(function(){
  152. $('#ff-popup-pic-image').innerHTML = '<img src="' + newSrc + '" alt="PokecPreview - Nacitavam..." style="max-height:' + (window.innerHeight-35) + 'px;"/>';
  153. $('#qq-popup-div').style.display = 'block';
  154. $('#qq-popup-div').className = 'fbfPopup qq-popup-div-' + (e.pageX>document.body.clientWidth/2 ? 'left' : 'right');
  155. }, 250);
  156. }
  157. /* 2015-04-17: all profile photos are now fotoalbum protected images; 1st fetch users profile */
  158. // on List of users, there is parent DIV, then A
  159. if (!newSrc && t.tagName == 'IMG' && proRegex.test(t.src) && ((t.parentNode.tagName=='A') || (t.parentNode.parentNode.tagName=='A'))) {
  160. var nick;
  161. if (t.parentNode.tagName=='A') nick = t.parentNode.href; else nick = t.parentNode.parentNode.href;
  162. if (!/http:\/\/pokec\.azet\.sk\/[^/]+\/?\?i9/.test(nick)) { console.log("No profile: "+nick); return; }
  163. nick = nick.replace(/\/\?.*$/, "");
  164. nick = nick.replace(/http:\/\/pokec\.azet\.sk\//, "");
  165. clearTimeout(hidePopupPicTimeout);
  166. t.removeEventListener('mouseout', hidePopupPic, false);
  167. t.addEventListener('mouseout', hidePopupPic, false);
  168. showPopupPicTimeout = setTimeout(function(){
  169. newSrc = "";
  170. $('#ff-popup-pic-image').innerHTML = '<img src="' + newSrc + '" alt="PokecPreview - Nacitavam..." style="max-height:' + (window.innerHeight-35) + 'px;"/>';
  171. $('#qq-popup-div').style.display = 'block';
  172. $('#qq-popup-div').className = 'fbfPopup qq-popup-div-' + (e.pageX>document.body.clientWidth/2 ? 'left' : 'right');
  173. GM_xmlhttpRequest({ method: "GET", url: "http://XXXX/azet_prof_img.php?nick="+nick, timeout: 5000, onload: function(resp) {
  174. var r = resp.responseText;
  175. $('#ff-popup-pic-image').innerHTML = '<img src="' +r+ '" alt="Foto '+nick+'" style="max-height:'+(window.innerHeight-35)+'px;"/>';
  176. //console.log("Image big: "+r);
  177. if (/jpg/.test(r)) GM_setValue(t.src, r);
  178. //var match;
  179. //if (match = /property="og:image" content="(.*)"/.exec(resp.responseText)) { $('#ff-popup-pic-image').innerHTML = '<img src="' + match[1] + '" style="max-height:'+(window.innerHeight-35)+'px;"/>'; console.log("Image big: "+match[1]); }
  180. } });
  181. }, 250);
  182. }
  183.  
  184. } catch(x) { logError('Popup Pic', x); }
  185. }
  186.  
  187. $('#qq-popup-div').addEventListener('mouseover', function(e) { clearTimeout(hidePopupPicTimeout); }, false);
  188. $('#qq-popup-div').addEventListener('mouseout', function(e) {
  189. var r = e.relatedTarget;
  190. if (!e.shiftKey && !e.ctrlKey && !e.altKey) {
  191. while (r.parentNode && r.id!='qq-popup-div') { r = r.parentNode; }
  192. if (r.id!='qq-popup-div') { document.getElementById('qq-popup-div').style.display = 'none'; }
  193. }
  194. }, false);
  195.  
  196. window.addEventListener('mouseover', function(e) {
  197. if (!e.shiftKey && !e.ctrlKey && !e.altKey) { showPopupPic(e); }
  198. }, false);
  199.  
  200. function hidePopupPic(e) {
  201. clearTimeout(showPopupPicTimeout);
  202. if (!e.shiftKey && !e.ctrlKey && !e.altKey) {
  203. hidePopupPicTimeout = setTimeout(function() { document.getElementById('qq-popup-div').style.display = 'none'; }, 30);
  204. }
  205. }
  206.  
  207. function logError(category, x) {
  208. msg = "PokecPreview Error (" + category + ") - " + x.name + ' - ' + x.message + ' in file <' + x.fileName + '> on line ' + x.lineNumber;
  209. console.log(msg);
  210. }
  211.  
  212. function $(q, root, single) {
  213. root = root || document;
  214. if (q[0]=='#') { return root.getElementById(q.substr(1)); }
  215. else if (q[0]=='/' || (q[0]=='.' && q[1]=='/')) {
  216. if (single) { return document.evaluate(q, root, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; }
  217. return document.evaluate(q, root, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  218. }
  219. else if (q[0]=='.') { return root.getElementsByClassName(q.substr(1)); }
  220. return root.getElementsByTagName(q);
  221. }
  222.  
  223. function addStyle(css) {
  224. if (typeof GM_addStyle !== 'undefined') { return GM_addStyle(css); }
  225. else if (heads = document.getElementsByTagName('head')) {
  226. var style = document.createElement('style');
  227. try { style.innerHTML = css; }
  228. catch(x) { style.innerText = css; }
  229. style.type = 'text/css';
  230. heads[0].appendChild(style);
  231. }
  232. }
  233.  
  234. }) ();