DealExtreme Photo Preview

Preview thumbnail product images from search on DealExtreme

  1. // ==UserScript==
  2. // @name DealExtreme Photo Preview
  3. // @namespace https://github.com/marki555
  4. // @description Preview thumbnail product images from search on DealExtreme
  5. // @include http://*.dealextreme.com/*
  6. // @include http://dx.com/*
  7. // @include http://*.dx.com/*
  8. // @include https://dx.com/*
  9. // @include https://*.dx.com/*
  10. // @version 0.3
  11. // @icon http://dx.com/favicon.ico
  12. // @license GPL
  13. // ==/UserScript==
  14.  
  15. // Code based on FFixer http://userscripts.org/scripts/show/8861 and my own PokecPreview
  16. // 2013-04-23: add preview of customer photos
  17. // 2013-05-02: fix urls of some images
  18. // 2014-06-26: some more image urls
  19.  
  20. (function() {
  21.  
  22. var showPopupPicTimeout;
  23. var hidePopupPicTimeout;
  24. var displayTimeout=250; // how much miliseconds to wait before displaying te preview image
  25.  
  26. //
  27. // Add styles used by script
  28. //
  29. addStyle(
  30. '.fbfPopup { padding:10px; background:#f6f6f6; border:3px double #666666; -moz-border-radius:5px; -webkit-border-radius:5px; -khtml-border-radius:5px; border-radius:5px; }'+
  31. '.ff-popup-default { max-width:450px; margin:100px auto; }'+
  32. '.fbfPopupContainer { display:none; top:0; right:0; bottom:0; left:0; }'+
  33. '#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; }'+
  34. '.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); }'+
  35. '.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); }'+
  36. '.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); }'+
  37. '#ff-popup-pic-div img { max-height: ' + (window.innerHeight-35) + 'px; }'+
  38. '#qq-pic-close { display:none; position:absolute; top:4px; right:10px; color:#ff9999; cursor:pointer; font-weight:bold; font-size:14px; }'+
  39. '#qq-popup-div:hover #ff-popup-pic-close { display:block; }'+
  40. '#qq-pic-close:hover { color:#aa6666; }'+
  41. '#ff-popup-pic-image { text-align:center; }'+
  42. '#ff-popup-pic-image img { color:#999999; display:block; }'+
  43. '#fbfUpdatePopup { max-width:450px; margin:100px auto; padding:10px; }'+
  44. '.fbfImportant { font-weight:bold; }'+
  45. '.fbfNote { color:#777777; }'+
  46. '.fbfRight { text-align:right; }'+
  47. '.ad_story .social_ad_advert { z-index:0; }'
  48. );
  49.  
  50.  
  51. //
  52. // Add div for showing big profile pics
  53. //
  54. var popupPicDiv = document.createElement('div');
  55. popupPicDiv.id = 'qq-popup-div';
  56. popupPicDiv.className = 'fbfPopup qq-popup-div';
  57. popupPicDiv.innerHTML = '<div id="qq-pic-close" title="Close">x</div><div id="ff-popup-pic-image"><span></span></div>';
  58.  
  59. try {
  60. document.body.insertBefore(popupPicDiv, document.body.lastChild.nextSibling);
  61. document.getElementById('qq-pic-close').addEventListener('click', function() { document.getElementById('qq-popup-div').style.display='none'; }, false);
  62. } catch(x) {
  63. var fbppdivAdder = setInterval(function() {
  64. try {
  65. document.body.insertBefore(popupPicDiv, document.body.lastChild.nextSibling);
  66. document.getElementById('qq-pic-close').addEventListener('click', function() { document.getElementById('qq-popup-div').style.display='none'; }, false);
  67. if ($('#qq-popup-div')) { clearInterval(fbppdivAdder); }
  68. } catch(x) {}
  69. }, 500);
  70. }
  71. // Listeners are added by the code for showing the popups
  72.  
  73. //
  74. // Listen for image mouseovers/mouseouts to show/hide popups
  75. //
  76. // preview: http://img.dxcdn.com/productimages/sku_3206_1_small.jpg (or _thumb.jpg)
  77. // full: http://img.dxcdn.com/productimages/sku_3206_1.jpg
  78. // preview: http://www.dealextreme.com/customerphotos/quarantined/201107/54348-thumb-0a330001-5618-4f07-ba81-6e78d38084e7-80x60.jpg
  79. // full: http://www.dealextreme.com/customerphotos/quarantined/201107/54348-0a330001-5618-4f07-ba81-6e78d38084e7.jpg
  80. // preview: http://www.dealextreme.com/customerphotos/quarantined/7055-thumb-9867ff97-98a8-4324-b107-59d90699f38d-80x60.jpg
  81. // full: http://www.dealextreme.com/customerphotos/quarantined/7055-f9c01841-7f99-472f-bd71-feaaa3266a22.jpg
  82. // preview: http://m2.dealextreme.com/upload/reviewpicture/201302/thumb_b094c67c-b40c-431c-9e07-82d5b2988c36.jpg
  83. // full: http://m2.dealextreme.com/upload/reviewpicture/201302/b094c67c-b40c-431c-9e07-82d5b2988c36.jpg
  84. // preview: http://svc.dxcdn.com/upload/reviewpicture/201306/thumb_2d949d58-b410-43ee-87e9-5fce015f4018.jpg
  85. // full: http://svc.dxcdn.com/upload/reviewpicture/201306/2d949d58-b410-43ee-87e9-5fce015f4018.jpg
  86.  
  87. picRegex = /https?:\/\/((img\.dxcdn\.com)\/productimages\/sku_([0-9_]+_(small|thumb)\.jpg))|(www\.dealextreme\.com\/customerphotos\/quarantined\/([0-9]+\/)?[0-9]+-thumb-[0-9a-f-]+-[0-9]+x[0-9]+.jpg)|(.*\.(dealextreme|dxcdn)\.com\/upload\/reviewpicture\/[0-9]+\/thumb_[0-9a-f-]+\.jpg)/;
  88.  
  89. function showPopupPic(e) {
  90. try {
  91. var t = e.target;
  92. var oldSrc;
  93. var newSrc;
  94. var title;
  95.  
  96. if (t.tagName == 'IMG' && picRegex.test(t.src)) { newSrc = t.src.replace(/_small|_thumb|thumb_|-thumb|-[0-9]+x[0-9]+/g, ""); }
  97.  
  98. if (oldSrc || newSrc) {
  99. clearTimeout(hidePopupPicTimeout);
  100. t.removeEventListener('mouseout', hidePopupPic, false);
  101. t.addEventListener('mouseout', hidePopupPic, false);
  102. showPopupPicTimeout = setTimeout(function(){
  103. $('#ff-popup-pic-image').innerHTML = '<img src="' + newSrc + '" alt="Preview - Loading..." style="max-height:' + (window.innerHeight-35) + 'px;"/>'; // + title;
  104. $('#qq-popup-div').style.display = 'block';
  105. // $('#qq-popup-div').className = 'fbfPopup qq-popup-div';
  106. $('#qq-popup-div').className = 'fbfPopup qq-popup-div-' + (e.pageX>document.body.clientWidth/2 ? 'left' : 'right');
  107. }, displayTimeout);
  108. }
  109. } catch(x) { logError('Popup Pic', x); }
  110. }
  111.  
  112. $('#qq-popup-div').addEventListener('mouseover', function(e) { clearTimeout(hidePopupPicTimeout); }, false);
  113. $('#qq-popup-div').addEventListener('mouseout', function(e) {
  114. var r = e.relatedTarget;
  115. if (!e.shiftKey && !e.ctrlKey && !e.altKey) {
  116. while (r.parentNode && r.id!='qq-popup-div') { r = r.parentNode; }
  117. if (r.id!='qq-popup-div') { document.getElementById('qq-popup-div').style.display = 'none'; }
  118. }
  119. }, false);
  120.  
  121. window.addEventListener('mouseover', function(e) {
  122. if (!e.shiftKey && !e.ctrlKey && !e.altKey) { showPopupPic(e); }
  123. }, false);
  124.  
  125. function hidePopupPic(e) {
  126. clearTimeout(showPopupPicTimeout);
  127. if (!e.shiftKey && !e.ctrlKey && !e.altKey) {
  128. hidePopupPicTimeout = setTimeout(function() { document.getElementById('qq-popup-div').style.display = 'none'; }, 30);
  129. }
  130. }
  131.  
  132. // Log an error
  133. function logError(category, x) {
  134. msg = "FBF Error (" + category + ") - " + x.name + ' - ' + x.message + ' in file <' + x.fileName + '> on line ' + x.lineNumber + ' while viewing ' + page;
  135. log(msg);
  136. }
  137.  
  138. function log(str) {
  139. if (typeof debug !== 'undefined') { debug(str); }
  140. if (typeof GM_log !== 'undefined') { GM_log(str); return true; }
  141. else if (typeof console !== 'undefined' && console.log) { console.log(str); return true; }
  142. return false;
  143. }
  144.  
  145. function $(q, root, single) {
  146. root = root || document;
  147. if (q[0]=='#') { return root.getElementById(q.substr(1)); }
  148. else if (q[0]=='/' || (q[0]=='.' && q[1]=='/')) {
  149. if (single) { return document.evaluate(q, root, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; }
  150. return document.evaluate(q, root, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  151. }
  152. else if (q[0]=='.') { return root.getElementsByClassName(q.substr(1)); }
  153. return root.getElementsByTagName(q);
  154. }
  155.  
  156. function addStyle(css) {
  157. if (typeof GM_addStyle !== 'undefined') { return GM_addStyle(css); }
  158. else if (heads = document.getElementsByTagName('head')) {
  159. var style = document.createElement('style');
  160. try { style.innerHTML = css; }
  161. catch(x) { style.innerText = css; }
  162. style.type = 'text/css';
  163. heads[0].appendChild(style);
  164. }
  165. }
  166.  
  167. }) ();