4chan Archive Image Expander

Adds inline image expansion to 4chan archives.

2018-08-02 يوللانغان نەشرى. ئەڭ يېڭى نەشرىنى كۆرۈش.

  1. // ==UserScript==
  2. // @name 4chan Archive Image Expander
  3. // @description Adds inline image expansion to 4chan archives.
  4. // @author Hen Tie
  5. // @homepage http://hen-tie.tumblr.com/
  6. // @namespace https://greasyfork.org/en/users/8336
  7. // @include /https?:\/\/(desuarchive.org|archived.moe)\/.*\/thread\/.*/
  8. // @grant none
  9. // @require https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js
  10. // @require https://greasyfork.org/scripts/39415-jquery-initialize/code/jQuery%20Initialize.js?version=258071
  11. //// @icon URL
  12. // @version 1.5
  13. // ==/UserScript==
  14. $(function () {
  15. //index all images for gallery modal
  16. //var fullImage = [];
  17. //var thumbnail = [];
  18. //var dialog = $("<modal></modal>");
  19. //$("body").append(dialog);
  20.  
  21. //$('a.thread_image_link').each(function() {
  22. // fullImage.push('<img src="' + $(this).attr('href') + '" />');
  23. // thumbnail.push('<img src="' + $(this).children('img').attr('src') + '" />');
  24. //});
  25. //$('modal').append(fullImage[0]).append(thumbnail[0]);
  26.  
  27. //catches image load event
  28. $.initialize('.init', function() {
  29. $(this).parent().removeClass('spinner');
  30. });
  31.  
  32. //insert download image links
  33. $('.post_file_filename').each(function() {
  34. $(this).attr('download',true);
  35. });
  36.  
  37.  
  38. $('<style type="text/css">.spinner:before{content:"";box-sizing:border-box;position:absolute;top:50%;left:50%;width:20px;height:20px;margin-top:-10px;margin-left:-10px;border-radius:50%;border-top:2px solid #CCC;border-right:2px solid transparent;animation:spinner 0.6s linear infinite}@keyframes spinner{to{transform:rotate(360deg)}}</style>').appendTo('head');
  39. //$('<style type="text/css">modal{display:block;position:fixed;top:0;left:0;overflow:auto;width:100%;height:20%;background:#000;}</style>').appendTo("head");
  40. //video settings
  41. var vidAttr = 'loop autoplay controls';
  42. var imgCSS = {
  43. 'max-width': '100%',
  44. 'height': 'auto'
  45. };
  46. var webmCSS = {
  47. 'max-width': '100%',
  48. 'height': 'auto'
  49. };
  50. //indicate webm thumbnail
  51. $('.post_file_filename[href$=".webm"]').parent().next().find('.post_image').css('border', '3px solid #5f89ac');
  52.  
  53. //prevent weird wrapping around expanded images
  54. $('.theme_default .post header').css('display', 'inline-block');
  55.  
  56. $('.thread_image_box a').on('click', function (e) {
  57. var myHref = $(this).attr('href');
  58. var myHeight = $(this).children('img').outerHeight();
  59. var myWidth = $(this).children('img').outerWidth();
  60. $(this).parent().addClass('spinner').css({
  61. 'min-height': myHeight,
  62. 'min-width': myWidth,
  63. 'position': 'relative'
  64. });
  65.  
  66. //new elements containing full size href as src
  67. var img = $('<img />').attr({
  68. 'src': myHref,
  69. 'class': 'openItem'
  70. }).css(imgCSS).load(function(){
  71. $(this).addClass('init');
  72. });
  73.  
  74.  
  75. var webm = $('<video style="background-color: #222;" poster="data:image/gif,AAAA" ' + vidAttr + ' id="vid"><source type="video/webm" src="' + myHref + '"/></video>').attr('class', 'openItem').css(webmCSS);
  76. //check filetype, hide thumbnail, insert full size file
  77. if (myHref.match(/.gif$|.png$|.jpg$/g)) {
  78. e.preventDefault();
  79. $(this).fadeTo('fast', 0, function () {
  80. $(this).hide();
  81. $(this).after(img);
  82. });
  83. } else if (myHref.match(/.webm$/g)) {
  84. e.preventDefault();
  85. $(this).hide();
  86. $(this).after(webm);
  87. var vid = document.getElementById("vid");
  88. //video proven to be loadable, cancel spinner
  89. vid.ondurationchange = function() {
  90. $(this).parent().removeClass('spinner');
  91. };
  92. } else {
  93. console.log('"4chan Archive Image Expander"\nUnsupported filetype, please report.\nSee @homepage or @namespace for contact info.');
  94. }
  95. //if src is broken insert placeholder, stop infinite spinner
  96. setTimeout(function(){
  97. var checkBroken = $('.openItem');
  98. if (checkBroken.width() === 16 && checkBroken.height() === 16) {
  99. checkBroken.addClass('init').attr('src','http://via.placeholder.com/'+myWidth + 'x' + myHeight+'/1d1f21/888888?text=ERR.');
  100. console.log('broken image');
  101. } else if (checkBroken.is('video')) {
  102. //if readyState has no metadata
  103. if (vid.readyState === 0) {
  104. checkBroken.addClass('init');
  105. console.log('broken video');
  106. }
  107. } else {
  108. return false;
  109. }
  110. }, 3000);
  111. });
  112.  
  113. //on reclick, remove full size, show thumbnail again
  114. $(document).on('click', '.openItem', function () {
  115. //video not loaded or timed out, remove spinner on close
  116. if ($(this).is('video')) {
  117. $(this).parent('.spinner').removeClass('spinner');
  118. }
  119. $(this).prev().show().fadeTo(0, 1);
  120. $(this).remove();
  121. });
  122. });