The version of vichan running on lainchan.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

188 line
5.4KB

  1. /* image-hover.js
  2. * This script is copied almost verbatim from https://github.com/Pashe/8chanX/blob/2-0/8chan-x.user.js
  3. * All I did was remove the sprintf dependency and integrate it into 8chan's Options as opposed to Pashe's.
  4. * I also changed initHover() to also bind on new_post.
  5. * Thanks Pashe for using WTFPL.
  6. */
  7. if (active_page === "catalog" || active_page === "thread" || active_page === "index" || active_page === "ukko") {
  8. $(document).on('ready', function(){
  9. if (window.Options && Options.get_tab('general')) {
  10. Options.extend_tab("general",
  11. "<fieldset><legend>Image hover</legend>"
  12. + ("<label class='image-hover' id='imageHover'><input type='checkbox' /> "+_('Image hover')+"</label>")
  13. + ("<label class='image-hover' id='catalogImageHover'><input type='checkbox' /> "+_('Image hover on catalog')+"</label>")
  14. + ("<label class='image-hover' id='imageHoverFollowCursor'><input type='checkbox' /> "+_('Image hover should follow cursor')+"</label>")
  15. + "</fieldset>");
  16. }
  17. $('.image-hover').on('change', function(){
  18. var setting = $(this).attr('id');
  19. localStorage[setting] = $(this).children('input').is(':checked');
  20. });
  21. if (!localStorage.imageHover || !localStorage.catalogImageHover || !localStorage.imageHoverFollowCursor) {
  22. localStorage.imageHover = 'false';
  23. localStorage.catalogImageHover = 'false';
  24. localStorage.imageHoverFollowCursor = 'false';
  25. }
  26. if (getSetting('imageHover')) $('#imageHover>input').prop('checked', 'checked');
  27. if (getSetting('catalogImageHover')) $('#catalogImageHover>input').prop('checked', 'checked');
  28. if (getSetting('imageHoverFollowCursor')) $('#imageHoverFollowCursor>input').prop('checked', 'checked');
  29. function getFileExtension(filename) { //Pashe, WTFPL
  30. if (filename.match(/\.([a-z0-9]+)(&loop.*)?$/i) !== null) {
  31. return filename.match(/\.([a-z0-9]+)(&loop.*)?$/i)[1];
  32. } else if (filename.match(/https?:\/\/(www\.)?youtube.com/)) {
  33. return 'Youtube';
  34. } else {
  35. return "unknown: " + filename;
  36. }
  37. }
  38. function isImage(fileExtension) { //Pashe, WTFPL
  39. return ($.inArray(fileExtension, ["jpg", "jpeg", "gif", "png"]) !== -1);
  40. }
  41. function isVideo(fileExtension) { //Pashe, WTFPL
  42. return ($.inArray(fileExtension, ["webm", "mp4"]) !== -1);
  43. }
  44. function isOnCatalog() {
  45. return window.active_page === "catalog";
  46. }
  47. function isOnThread() {
  48. return window.active_page === "thread";
  49. }
  50. function isOnUkko() {
  51. return window.active_page === "ukko";
  52. }
  53. function getSetting(key) {
  54. return (localStorage[key] == 'true');
  55. }
  56. function initImageHover() { //Pashe, influenced by tux, et al, WTFPL
  57. if (!getSetting("imageHover") && !getSetting("catalogImageHover")) {return;}
  58. var selectors = [];
  59. if (getSetting("imageHover")) {selectors.push("img.post-image", "canvas.post-image");}
  60. if (getSetting("catalogImageHover") && isOnCatalog()) {
  61. selectors.push(".thread-image");
  62. $(".theme-catalog div.thread").css("position", "inherit");
  63. }
  64. function bindEvents(el) {
  65. $(el).find(selectors.join(", ")).each(function () {
  66. if ($(this).parent().data("expanded")) {return;}
  67. var $this = $(this);
  68. $this.on("mousemove", imageHoverStart);
  69. $this.on("mouseout", imageHoverEnd);
  70. $this.on("click", imageHoverEnd);
  71. });
  72. }
  73. bindEvents(document.body);
  74. $(document).on('new_post', function(e, post) {
  75. bindEvents(post);
  76. });
  77. }
  78. function imageHoverStart(e) { //Pashe, anonish, WTFPL
  79. var hoverImage = $("#chx_hoverImage");
  80. if (hoverImage.length) {
  81. if (getSetting("imageHoverFollowCursor")) {
  82. var scrollTop = $(window).scrollTop();
  83. var imgY = e.pageY;
  84. var imgTop = imgY;
  85. var windowWidth = $(window).width();
  86. var imgWidth = hoverImage.width() + e.pageX;
  87. if (imgY < scrollTop + 15) {
  88. imgTop = scrollTop;
  89. } else if (imgY > scrollTop + $(window).height() - hoverImage.height() - 15) {
  90. imgTop = scrollTop + $(window).height() - hoverImage.height() - 15;
  91. }
  92. if (imgWidth > windowWidth) {
  93. hoverImage.css({
  94. 'left': (e.pageX + (windowWidth - imgWidth)),
  95. 'top' : imgTop,
  96. });
  97. } else {
  98. hoverImage.css({
  99. 'left': e.pageX,
  100. 'top' : imgTop,
  101. });
  102. }
  103. hoverImage.appendTo($("body"));
  104. }
  105. return;
  106. }
  107. var $this = $(this);
  108. var fullUrl;
  109. if ($this.parent().attr("href").match("src")) {
  110. fullUrl = $this.parent().attr("href");
  111. } else if (isOnCatalog()) {
  112. fullUrl = $this.attr("data-fullimage");
  113. if (!isImage(getFileExtension(fullUrl))) {fullUrl = $this.attr("src");}
  114. }
  115. if (isVideo(getFileExtension(fullUrl))) {return;}
  116. hoverImage = $('<img id="chx_hoverImage" src="'+fullUrl+'" />');
  117. if (getSetting("imageHoverFollowCursor")) {
  118. var size = $this.parents('.file').find('.unimportant').text().match(/\b(\d+)x(\d+)\b/),
  119. maxWidth = $(window).width(),
  120. maxHeight = $(window).height();
  121. var scale = Math.min(1, maxWidth / size[1], maxHeight / size[2]);
  122. hoverImage.css({
  123. "position" : "absolute",
  124. "z-index" : 101,
  125. "pointer-events": "none",
  126. "width" : size[1] + "px",
  127. "height" : size[2] + "px",
  128. "max-width" : (size[1] * scale) + "px",
  129. "max-height" : (size[2] * scale) + "px",
  130. 'left' : e.pageX,
  131. 'top' : imgTop,
  132. });
  133. } else {
  134. hoverImage.css({
  135. "position" : "fixed",
  136. "top" : 0,
  137. "right" : 0,
  138. "z-index" : 101,
  139. "pointer-events": "none",
  140. "max-width" : "100%",
  141. "max-height" : "100%",
  142. });
  143. }
  144. hoverImage.appendTo($("body"));
  145. if (isOnThread()) {$this.css("cursor", "none");}
  146. }
  147. function imageHoverEnd() { //Pashe, WTFPL
  148. $("#chx_hoverImage").remove();
  149. }
  150. initImageHover();
  151. });
  152. }