Reddit Inline YouTube Viewer

Add an inline expand button for YouTube links like RES does for images.

当前为 2014-07-28 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Reddit Inline YouTube Viewer
  3. // @namespace reddit_youtube_expando
  4. // @description Add an inline expand button for YouTube links like RES does for images.
  5. // @include http://*.reddit.com/*
  6. // @include https://*.reddit.com/*
  7. // @match http://*.reddit.com/*
  8. // @match https://*.reddit.com/*
  9. // @version 1.2
  10. // ==/UserScript==
  11.  
  12. // This work is licensed under the Creative Commons Attribution 2.0 Generic License.
  13. // To view a copy of this license, visit http://creativecommons.org/licenses/by/2.0/.
  14.  
  15. // This version of the regex can scrub some technicaly invalid links into valid ones, but I'm not sure
  16. // the list of video ID characters is correct.
  17. var youtubeLinkRegex = new RegExp("(?:^https?://(?:www\\.)?youtube\\.com/watch\\?(?:.*&)*v=([a-zA-Z0-9\\-_]+)(?:#t=(.*$))?)|(?:^http://youtu.be/([a-zA-Z0-9\\-_]+))")
  18.  
  19. /*
  20. // Flash Embed
  21. var starTimeRegex = new RegExp("(?:(\\d+)m)?(\\d+)s")
  22. function addYouTubeEmbed(videoID, startTime) {
  23. var videoURL = "http://www.youtube.com/v/" + videoID
  24. if (startTime) {
  25. starTimeResult = starTimeRegex.exec(startTime)
  26. if (starTimeResult) {
  27. minutes = parseInt(starTimeResult[1])
  28. if (!minutes) {
  29. minutes = 0
  30. }
  31. seconds = parseInt(starTimeResult[2])
  32. seconds += minute * 60
  33. videoURL = videoURL + "&start=" + seconds
  34. }
  35. }
  36. var embedDiv = document.createElement("div")
  37. var embedObject = document.createElement("object")
  38. embedObject.setAttribute("type", "application/x-shockwave-flash")
  39. embedObject.setAttribute("style", "width:450px; height:366px; float: left")
  40. embedObject.setAttribute("data", videoURL)
  41. var paramElm = document.createElement("param")
  42. paramElm.setAttribute("name", "movie")
  43. paramElm.setAttribute("value", videoURL)
  44. embedObject.appendChild(paramElm)
  45. embedDiv.appendChild(embedObject)
  46. return embedDiv
  47. }
  48. */
  49.  
  50.  
  51. // IFrame Embed
  52. function addYouTubeEmbed(videoID, startTime) {
  53. var embedDiv = document.createElement("div")
  54. var embedObject = document.createElement("iframe")
  55. embedObject.setAttribute("class", "youtube-player")
  56. embedObject.setAttribute("type", "text/html")
  57. embedObject.setAttribute("width", "450")
  58. embedObject.setAttribute("height", "366")
  59. if (startTime) {
  60. embedObject.setAttribute("src", "http://www.youtube.com/embed/" + videoID + "#t=" + startTime)
  61. }
  62. else {
  63. embedObject.setAttribute("src", "http://www.youtube.com/embed/" + videoID)
  64. }
  65. embedObject.setAttribute("frameborder", "0")
  66. embedDiv.appendChild(embedObject)
  67. return embedDiv
  68. }
  69.  
  70. var commentExpandoStyle = "vertical-align:top !important; float: none; width: 23px; height: 23px;" +
  71. "max-width: 23px; max-height: 23px; display: inline-block;" +
  72. "margin-right: 6px; cursor: pointer; padding: 0px;"
  73.  
  74. function addButtons(postDiv) {
  75. var innerLinks = Array.prototype.slice.call(postDiv.getElementsByTagName("a"));
  76. for (var j in innerLinks) {
  77. //innerLinks[j].className += " youtubeScanned"
  78. linkResult = youtubeLinkRegex.exec(innerLinks[j].href)
  79. if (linkResult) {
  80. innerLinks[j].className = innerLinks[j].className + " youtubeLinkFound"
  81. function genClickFunc() {
  82. // Capture these values with closure for the button function
  83. var theDiv = document.createElement("div")
  84. var embedObject = null
  85. // videoID from a youtube.com link || from a youtu.be link
  86. var videoID = linkResult[1] || linkResult[3]
  87. var startTime = linkResult[2]
  88. theDiv.setAttribute("class", "expando-button collapsed video")
  89. theDiv.setAttribute("style", commentExpandoStyle)
  90. var clickFunc = function () {
  91. if(theDiv.className.indexOf("collapsed") != -1) {
  92. theDiv.setAttribute("class", "expando-button expanded video")
  93. if (!embedObject) {
  94. embedObject = addYouTubeEmbed(videoID, startTime)
  95. }
  96. theDiv.parentNode.insertBefore(embedObject, theDiv.nextSibling)
  97. }
  98. else {
  99. theDiv.setAttribute("class", "expando-button collapsed video")
  100. theDiv.parentNode.removeChild(embedObject)
  101. }
  102. }
  103. innerLinks[j].parentNode.insertBefore(theDiv, innerLinks[j].nextSibling)
  104. theDiv.addEventListener('click', clickFunc, true)
  105. }
  106. genClickFunc()
  107. }
  108. }
  109. }
  110.  
  111. var mdElements = document.getElementsByClassName("md")
  112.  
  113. // Find all user created comment sections
  114. for (var i in mdElements) {
  115. if (mdElements[i].tagName == 'DIV') {
  116. addButtons(mdElements[i]);
  117. }
  118. }
  119.  
  120. // hasClass, stolen from the Reddit Enhancement Suite
  121. function hasClass(ele,cls) {
  122. if ((typeof(ele) == 'undefined') || (ele == null)) {
  123. console.log(arguments.callee.caller);
  124. return false;
  125. }
  126. return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
  127. }
  128.  
  129. // Add a listener for the DOMNodeInserted event so we can expand emotes in new comments
  130. // created by either a reply or by clicking "load more comments" in large threads.
  131. function handleInsertion( event ) {
  132. // The actual even we see will be the insertion of the outer "thing" div
  133. if ((event.target.tagName == 'DIV') && (hasClass(event.target, "thing"))) {
  134. var mdElements = event.target.getElementsByClassName("md")
  135. for (var i in mdElements) {
  136. if (mdElements[i].tagName == 'DIV') {
  137. addButtons(mdElements[i]);
  138. }
  139. }
  140. }
  141. }
  142.  
  143. document.body.addEventListener('DOMNodeInserted', handleInsertion, false);