Dead Image Size Revealer

Shows the size of broken images

  1. // ==UserScript==
  2. // @name Dead Image Size Revealer
  3. // @namespace DoomTay
  4. // @description Shows the size of broken images
  5. // @include *
  6. // @version 1.0.0
  7. // @exclude *.svg
  8. // @grant none
  9.  
  10.  
  11. // ==/UserScript==
  12.  
  13. var pics = document.images;
  14.  
  15. function relativeToAbsolute(relativeURL)
  16. {
  17. var testLink = document.createElement("A");
  18. testLink.href = relativeURL;
  19. return testLink.href;
  20. }
  21.  
  22. function addSize(pic) {
  23. if(pic && pic.src && !getDivSign(pic))
  24. {
  25. var offset = getOffset(pic);
  26. var sizeDiv = document.createElement("div");
  27. sizeDiv.innerHTML = pic.width + " x " + pic.height;
  28. sizeDiv.className = "imageSize";
  29. var bindingClass = randomString();
  30. sizeDiv.classList.add(bindingClass);
  31. pic.classList.add(bindingClass);
  32. pic.parentNode.insertBefore(sizeDiv, pic.nextSibling);
  33. sizeDiv.style.left = Math.round(offset.left) + "px";
  34. sizeDiv.style.top = Math.round(offset.top) + "px";
  35. }
  36. }
  37.  
  38. var sizeDivStyle = document.createElement("style");
  39. sizeDivStyle.type = "text/css";
  40. sizeDivStyle.innerHTML = ".imageSize { background-color:#333; color: white; position: absolute; font-family: Arial; font-size: 12px; font-weight:normal }";
  41. document.head.appendChild(sizeDivStyle);
  42.  
  43. for(var i = 0; i < pics.length; i++)
  44. {
  45. if(window.getComputedStyle(pics[i]) && window.getComputedStyle(pics[i]).width != "auto" && pics[i].width > 40 && pics[i].height > 15)
  46. {
  47. if(pics[i].complete && pics[i].naturalWidth == 0) addSize(pics[i]);
  48. pics[i].addEventListener("load", e => {
  49. if(getDivSign(e.target))
  50. {
  51. var divToRemove = getDivSign(e.target);
  52. divToRemove.parentNode.removeChild(divToRemove);
  53. e.target.className = e.target.className.substring(0,e.target.className.length - 6);
  54. }
  55. }, true);
  56. pics[i].addEventListener("error", e => { addSize(e.target); }, true);
  57. }
  58. }
  59.  
  60. function randomString()
  61. {
  62. var string = "";
  63. for(var i = 0; i < 5; i++)
  64. {
  65. string += String.fromCharCode(Math.random() * 26 + 97);
  66. }
  67. return string;
  68. }
  69.  
  70. function getDivSign(image)
  71. {
  72. for(var c = 0; c < image.classList.length; c++)
  73. {
  74. var possibleDiv = image.parentNode.querySelector("div." + image.classList[c]);
  75. if(possibleDiv) return possibleDiv;
  76. }
  77. return null;
  78. }
  79.  
  80. function getOffset(element)
  81. {
  82. var elementCoords = element.getBoundingClientRect();
  83. var positioningParent = getPositioningElement(element);
  84. if(positioningParent != null)
  85. {
  86. var parentCoords = positioningParent.getBoundingClientRect();
  87. var left = elementCoords.left - parentCoords.left;
  88. var top = elementCoords.top - parentCoords.top;
  89. //var left = elementCoords.left;
  90. //var top = elementCoords.top;
  91. }
  92. else
  93. {
  94. var left = elementCoords.left + window.scrollX;
  95. var top = elementCoords.top + window.scrollY;
  96. }
  97. return {left:left, top:top};
  98. }
  99.  
  100. function getPositioningElement(start)
  101. {
  102. var startingPoint = start.parentNode;
  103. while(startingPoint != document.body)
  104. {
  105. if(window.getComputedStyle(startingPoint).position == "relative" && window.getComputedStyle(startingPoint).position != "absolute") return startingPoint;
  106. startingPoint = startingPoint.parentNode;
  107. }
  108. return null;
  109. }
  110.  
  111. var observer = new MutationObserver(function(mutations) {
  112. mutations.forEach(function(mutation) {
  113. var sizeDivs = document.querySelectorAll(".imageSize");
  114. observer.disconnect();
  115. Array.prototype.forEach.call(sizeDivs,
  116. div => {
  117. var offset = getOffset(document.querySelector("img." + div.classList[1]));
  118. if(div.style.left != Math.round(offset.left) + "px") div.style.left = Math.round(offset.left) + "px";
  119. if(div.style.top != Math.round(offset.top) + "px") div.style.top = Math.round(offset.top) + "px";
  120. }
  121. );
  122. observer.observe(document.body, config);
  123. if(mutation.target.nodeName == "IMG" && mutation.attributeName == "src" && getDivSign(mutation.target))
  124. {
  125. var divToRemove = getDivSign(mutation.target);
  126. divToRemove.parentNode.removeChild(divToRemove);
  127. mutation.target.className = mutation.target.className.substring(0,mutation.target.className.length - 6);
  128. }
  129. });
  130. });
  131.  
  132. var config = { attributes: true, subtree: true, childList: true, attributeOldValue: true };
  133. observer.observe(document.body, config);