The version of vichan running on lainchan.org
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

245 строки
8.8KB

  1. /* This file is dedicated to the public domain; you may do as you wish with it. */
  2. /* Note: This code expects the global variable configRoot to be set. */
  3. if (typeof _ == 'undefined') {
  4. var _ = function(a) { return a; };
  5. }
  6. function setupVideo(thumb, url) {
  7. if (thumb.videoAlreadySetUp) return;
  8. thumb.videoAlreadySetUp = true;
  9. var video = null;
  10. var videoContainer, videoHide;
  11. var expanded = false;
  12. var hovering = false;
  13. var loop = true;
  14. var loopControls = [document.createElement("span"), document.createElement("span")];
  15. var fileInfo = thumb.parentNode.querySelector(".fileinfo");
  16. var mouseDown = false;
  17. function unexpand() {
  18. if (expanded) {
  19. expanded = false;
  20. if (video.pause) video.pause();
  21. videoContainer.style.display = "none";
  22. thumb.style.display = "inline";
  23. video.style.maxWidth = "inherit";
  24. video.style.maxHeight = "inherit";
  25. }
  26. }
  27. function unhover() {
  28. if (hovering) {
  29. hovering = false;
  30. if (video.pause) video.pause();
  31. videoContainer.style.display = "none";
  32. video.style.maxWidth = "inherit";
  33. video.style.maxHeight = "inherit";
  34. }
  35. }
  36. // Create video element if does not exist yet
  37. function getVideo() {
  38. if (video == null) {
  39. video = document.createElement("video");
  40. video.src = url;
  41. video.loop = loop;
  42. video.innerText = _("Your browser does not support HTML5 video.");
  43. videoHide = document.createElement("img");
  44. videoHide.src = configRoot + "static/collapse.gif";
  45. videoHide.alt = "[ - ]";
  46. videoHide.title = "Collapse video";
  47. videoHide.style.marginLeft = "-15px";
  48. videoHide.style.cssFloat = "left";
  49. videoHide.addEventListener("click", unexpand, false);
  50. videoContainer = document.createElement("div");
  51. videoContainer.style.paddingLeft = "15px";
  52. videoContainer.style.display = "none";
  53. videoContainer.appendChild(videoHide);
  54. videoContainer.appendChild(video);
  55. thumb.parentNode.insertBefore(videoContainer, thumb.nextSibling);
  56. // Dragging to the left collapses the video
  57. video.addEventListener("mousedown", function(e) {
  58. if (e.button == 0) mouseDown = true;
  59. }, false);
  60. video.addEventListener("mouseup", function(e) {
  61. if (e.button == 0) mouseDown = false;
  62. }, false);
  63. video.addEventListener("mouseenter", function(e) {
  64. mouseDown = false;
  65. }, false);
  66. video.addEventListener("mouseout", function(e) {
  67. if (mouseDown && e.clientX - video.getBoundingClientRect().left <= 0) {
  68. unexpand();
  69. }
  70. mouseDown = false;
  71. }, false);
  72. }
  73. }
  74. // Clicking on thumbnail expands video
  75. thumb.addEventListener("click", function(e) {
  76. if (setting("videoexpand") && !e.shiftKey && !e.ctrlKey && !e.altKey && !e.metaKey) {
  77. getVideo();
  78. expanded = true;
  79. hovering = false;
  80. video.style.position = "static";
  81. video.style.pointerEvents = "inherit";
  82. video.style.display = "inline";
  83. videoHide.style.display = "inline";
  84. videoContainer.style.display = "block";
  85. videoContainer.style.position = "static";
  86. video.parentNode.parentNode.removeAttribute('style');
  87. thumb.style.display = "none";
  88. video.muted = (setting("videovolume") == 0);
  89. video.volume = setting("videovolume");
  90. video.controls = true;
  91. if (video.readyState == 0) {
  92. video.addEventListener("loadedmetadata", expand2, false);
  93. } else {
  94. setTimeout(expand2, 0);
  95. }
  96. video.play();
  97. e.preventDefault();
  98. }
  99. }, false);
  100. function expand2() {
  101. video.style.maxWidth = "100%";
  102. video.style.maxHeight = window.innerHeight + "px";
  103. var bottom = video.getBoundingClientRect().bottom;
  104. if (bottom > window.innerHeight) {
  105. window.scrollBy(0, bottom - window.innerHeight);
  106. }
  107. // work around Firefox volume control bug
  108. video.volume = Math.max(setting("videovolume") - 0.001, 0);
  109. video.volume = setting("videovolume");
  110. }
  111. // Hovering over thumbnail displays video
  112. thumb.addEventListener("mouseover", function(e) {
  113. if (setting("videohover")) {
  114. getVideo();
  115. expanded = false;
  116. hovering = true;
  117. var docRight = document.documentElement.getBoundingClientRect().right;
  118. var thumbRight = thumb.querySelector("img, video").getBoundingClientRect().right;
  119. var maxWidth = docRight - thumbRight - 20;
  120. if (maxWidth < 250) maxWidth = 250;
  121. video.style.position = "fixed";
  122. video.style.right = "0px";
  123. video.style.top = "0px";
  124. var docRight = document.documentElement.getBoundingClientRect().right;
  125. var thumbRight = thumb.querySelector("img, video").getBoundingClientRect().right;
  126. video.style.maxWidth = maxWidth + "px";
  127. video.style.maxHeight = "100%";
  128. video.style.pointerEvents = "none";
  129. video.style.display = "inline";
  130. videoHide.style.display = "none";
  131. videoContainer.style.display = "inline";
  132. videoContainer.style.position = "fixed";
  133. video.muted = (setting("videovolume") == 0);
  134. video.volume = setting("videovolume");
  135. video.controls = false;
  136. video.play();
  137. }
  138. }, false);
  139. thumb.addEventListener("mouseout", unhover, false);
  140. // Scroll wheel on thumbnail adjusts default volume
  141. thumb.addEventListener("wheel", function(e) {
  142. if (setting("videohover")) {
  143. var volume = setting("videovolume");
  144. if (e.deltaY > 0) volume -= 0.1;
  145. if (e.deltaY < 0) volume += 0.1;
  146. if (volume < 0) volume = 0;
  147. if (volume > 1) volume = 1;
  148. if (video != null) {
  149. video.muted = (volume == 0);
  150. video.volume = volume;
  151. }
  152. changeSetting("videovolume", volume);
  153. e.preventDefault();
  154. }
  155. }, false);
  156. // [play once] vs [loop] controls
  157. function setupLoopControl(i) {
  158. loopControls[i].addEventListener("click", function(e) {
  159. loop = (i != 0);
  160. thumb.href = thumb.href.replace(/([\?&])loop=\d+/, "$1loop=" + i);
  161. if (video != null) {
  162. video.loop = loop;
  163. if (loop && video.currentTime >= video.duration) {
  164. video.currentTime = 0;
  165. }
  166. }
  167. loopControls[i].style.fontWeight = "bold";
  168. loopControls[1-i].style.fontWeight = "inherit";
  169. }, false);
  170. }
  171. loopControls[0].textContent = _("[play once]");
  172. loopControls[1].textContent = _("[loop]");
  173. loopControls[1].style.fontWeight = "bold";
  174. for (var i = 0; i < 2; i++) {
  175. setupLoopControl(i);
  176. loopControls[i].style.whiteSpace = "nowrap";
  177. fileInfo.appendChild(document.createTextNode(" "));
  178. fileInfo.appendChild(loopControls[i]);
  179. }
  180. }
  181. function setupVideosIn(element) {
  182. var thumbs = element.querySelectorAll("a.file");
  183. for (var i = 0; i < thumbs.length; i++) {
  184. if (/\.webm$|\.mp4$/.test(thumbs[i].pathname)) {
  185. setupVideo(thumbs[i], thumbs[i].href);
  186. } else {
  187. var m = thumbs[i].search.match(/\bv=([^&]*)/);
  188. if (m != null) {
  189. var url = decodeURIComponent(m[1]);
  190. if (/\.webm$|\.mp4$/.test(url)) setupVideo(thumbs[i], url);
  191. }
  192. }
  193. }
  194. }
  195. onready(function(){
  196. // Insert menu from settings.js
  197. if (typeof settingsMenu != "undefined" && typeof Options == "undefined")
  198. document.body.insertBefore(settingsMenu, document.getElementsByTagName("hr")[0]);
  199. // Setup Javascript events for videos in document now
  200. setupVideosIn(document);
  201. // Setup Javascript events for videos added by updater
  202. if (window.MutationObserver) {
  203. var observer = new MutationObserver(function(mutations) {
  204. for (var i = 0; i < mutations.length; i++) {
  205. var additions = mutations[i].addedNodes;
  206. if (additions == null) continue;
  207. for (var j = 0; j < additions.length; j++) {
  208. var node = additions[j];
  209. if (node.nodeType == 1) {
  210. setupVideosIn(node);
  211. }
  212. }
  213. }
  214. });
  215. observer.observe(document.body, {childList: true, subtree: true});
  216. }
  217. });