DOGGO

Replace all images on a page with dogs

  1. // ==UserScript==
  2. // @name DOGGO
  3. // @namespace https://davidjb.online/
  4. // @version 0.1.1
  5. // @description Replace all images on a page with dogs
  6. // @author David Bailey
  7. // @match *://*/*
  8. // @grant GM.getValue
  9. // @grant GM.setValue
  10. // @grant GM.deleteValue
  11. // ==/UserScript==
  12.  
  13. async function getDataUrl(url) {
  14. const blob = await fetch(url).then(r => r.blob());
  15. return await new Promise(resolve => {
  16. const reader = new FileReader();
  17. reader.onload = () => resolve(reader.result);
  18. reader.readAsDataURL(blob);
  19. });
  20. }
  21.  
  22. async function loadImageUrls(otherUrls, count=0) {
  23. const urls = otherUrls || [];
  24. if (count === 0) {
  25. window.alert('Loading doggo images...');
  26. }
  27.  
  28. if (urls.length < 50) {
  29. window.scrollTo(0, 1000 * count);
  30.  
  31. const images = document.querySelectorAll('.Post-item-media img');
  32. for (const image of images) {
  33. if (urls.indexOf(image.src) === -1) {
  34. const url = await getDataUrl(image.src);
  35. if (!url.match(/^data:text/)) {
  36. urls.push(url);
  37. }
  38. }
  39. }
  40.  
  41. window.setTimeout(() => loadImageUrls(urls, count + 1), 2000);
  42. } else {
  43. GM.setValue('imageUrls', JSON.stringify(urls));
  44. window.alert('Doggo images loaded!');
  45. }
  46. }
  47.  
  48. function createImageLoader() {
  49. const frame = document.createElement('iframe');
  50. const blocker = document.createElement('div');
  51.  
  52. const refreshButton = document.querySelector('#doggo-refresh');
  53. refreshButton.onclick = async () => {
  54. if (await GM.getValue('imageUrls')) {
  55. refresh();
  56. refreshButton.onclick = refresh;
  57. } else {
  58. window.alert('Already loading images; please wait...');
  59. }
  60. };
  61.  
  62. for (const el of [frame, blocker]) {
  63. el.width = 1000;
  64. el.height = 1000;
  65. el.style.position = 'absolute';
  66. el.style.top = '0';
  67. el.style.left = '0';
  68. el.style.opacity = '0';
  69. }
  70.  
  71. frame.style.zIndex = '-9999';
  72. blocker.style.zIndex = '-9998';
  73.  
  74. frame.src = 'https://imgur.com/t/dog';
  75. document.body.appendChild(frame);
  76. }
  77.  
  78. async function getImageUrls() {
  79. const urls = await GM.getValue('imageUrls');
  80. if (!urls) {
  81. window.alert('Doggo images haven\'t loaded yet - if this is your first time using the extension, press the \'refresh\' button.');
  82. return false;
  83. }
  84.  
  85. return JSON.parse(urls);
  86. }
  87.  
  88. function resetUrls() {
  89. GM.deleteValue('imageUrls');
  90. }
  91.  
  92. function randomArrayItem(array) {
  93. const index = Math.floor(Math.random()*array.length);
  94. return array[index];
  95. }
  96.  
  97. async function doggify() {
  98. const urls = await getImageUrls();
  99. if (!urls) return;
  100.  
  101. const images = document.querySelectorAll('img');
  102. for (const image of images) {
  103. [image.width, image.height] = [image.width, image.height]; // this sets the HTML attributes if not present
  104. image.srcset = '';
  105. image.src = randomArrayItem(urls);
  106. }
  107. }
  108.  
  109. function refresh() {
  110. resetUrls();
  111. createImageLoader();
  112. }
  113.  
  114. function createButtons() {
  115. const doggoButton = document.createElement('a');
  116. const refreshButton = document.createElement('a');
  117.  
  118. for (const button of [doggoButton, refreshButton]) {
  119. button.href = 'javascript:';
  120.  
  121. button.style.position = 'fixed';
  122. button.style.top = '10px';
  123. button.style.right = '10px';
  124.  
  125. button.style.zIndex = '9999';
  126. button.style.display = 'block';
  127. button.style.width = '30px';
  128. button.style.height = '30px';
  129.  
  130. button.style.textAlign = 'center';
  131. button.style.fontSize = '18px';
  132. button.style.lineHeight = '30px';
  133. button.style.textDecoration = 'none';
  134.  
  135. button.style.borderRadius = '5px';
  136. button.style.backgroundColor = 'white';
  137. button.style.boxShadow = '0 0 10px rgba(0,0,0,0.25)';
  138. }
  139.  
  140. doggoButton.onclick = doggify;
  141. doggoButton.textContent = '?';
  142. doggoButton.style.right = '50px';
  143.  
  144. refreshButton.id = 'doggo-refresh';
  145. refreshButton.onclick = refresh;
  146. refreshButton.textContent = '?';
  147. refreshButton.style.right = '10px';
  148.  
  149. document.body.appendChild(doggoButton);
  150. document.body.appendChild(refreshButton);
  151. }
  152.  
  153. if (location.href === 'https://imgur.com/t/dog' && window.self !== window.top) {
  154. loadImageUrls();
  155. } else {
  156. createButtons();
  157. }