Reddit Inline YouTube Viewer

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

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(У мене вже є менеджер скриптів, дайте мені встановити його!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name           Reddit Inline YouTube Viewer
// @namespace      reddit_youtube_expando
// @description    Add an inline expand button for YouTube links like RES does for images.
// @include        http://*.reddit.com/*
// @include        https://*.reddit.com/*
// @match          http://*.reddit.com/*
// @match          https://*.reddit.com/*
// @version        1.3
// @grant          none
// ==/UserScript==

// This work is licensed under the Creative Commons Attribution 2.0 Generic License.
// To view a copy of this license, visit http://creativecommons.org/licenses/by/2.0/.

// This version of the regex can scrub some technicaly invalid links into valid ones, but I'm not sure
// the list of video ID characters is correct.
var youtubeLinkRegex = new RegExp("(?:^https?://(?:www\\.)?youtube\\.com/watch\\?(?:.*&)*v=([a-zA-Z0-9\\-_]+)[^#]*(?:#t=(.*$))?)|(?:^http://youtu.be/([a-zA-Z0-9\\-_]+))")

/*
 // Flash Embed
 var starTimeRegex = new RegExp("(?:(\\d+)m)?(\\d+)s")
 function addYouTubeEmbed(videoID, startTime) {
 var videoURL = "http://www.youtube.com/v/" + videoID
 if (startTime) {
 starTimeResult = starTimeRegex.exec(startTime)
 if (starTimeResult) {
 minutes = parseInt(starTimeResult[1])
 if (!minutes) {
 minutes = 0
 }
 seconds = parseInt(starTimeResult[2])
 seconds += minute * 60
 videoURL = videoURL + "&start=" + seconds
 }
 }
 
 var embedDiv = document.createElement("div")
 var embedObject = document.createElement("object")
 embedObject.setAttribute("type",  "application/x-shockwave-flash")
 embedObject.setAttribute("style", "width:450px; height:366px; float: left")
 embedObject.setAttribute("data", videoURL)
 var paramElm = document.createElement("param")
 paramElm.setAttribute("name",  "movie")
 paramElm.setAttribute("value", videoURL)
 embedObject.appendChild(paramElm)
 embedDiv.appendChild(embedObject)
 
 return embedDiv
 }
 */


// IFrame Embed
function addYouTubeEmbed(videoID, startTime) {
    var embedDiv = document.createElement("div")
    var embedObject = document.createElement("iframe")
    embedObject.setAttribute("class",  "youtube-player")
    embedObject.setAttribute("type",   "text/html")
    embedObject.setAttribute("width",  "450")
    embedObject.setAttribute("height", "366")
    embedObject.setAttribute("allowfullscreen", "allowfullscreen")
    embedObject.setAttribute("mozallowfullscreen", "mozallowfullscreen")
    embedObject.setAttribute("webkitallowfullscreen", "webkitallowfullscreen")

    linkProto = ('https:' == document.location.protocol ? 'https:' : 'http:')

    if (startTime) {
        embedObject.setAttribute("src", linkProto + "//www.youtube.com/embed/" + videoID + "#t=" + startTime)
    }
    else {
        embedObject.setAttribute("src", linkProto + "//www.youtube.com/embed/" + videoID)
    }
    embedObject.setAttribute("frameborder", "0")
    embedDiv.appendChild(embedObject)
    
    return embedDiv
}

var commentExpandoStyle = "vertical-align:top !important; float: none; width: 23px; height: 23px;" +
"max-width: 23px; max-height: 23px; display: inline-block;" +
"margin-right: 6px; cursor: pointer;  padding: 0px;"

function addButtons(postDiv) {
    var innerLinks = Array.prototype.slice.call(postDiv.getElementsByTagName("a"));
    for (var j in innerLinks) {
        //innerLinks[j].className += " youtubeScanned"
        linkResult = youtubeLinkRegex.exec(innerLinks[j].href)
        if (linkResult) {
            innerLinks[j].className = innerLinks[j].className + " youtubeLinkFound"
            
            function genClickFunc() {
                // Capture these values with closure for the button function
                var theDiv = document.createElement("div")
                var embedObject = null
                // videoID from a youtube.com link || from a youtu.be link
                var videoID = linkResult[1] || linkResult[3]
                var startTime = linkResult[2]
                
                theDiv.setAttribute("class", "expando-button collapsed video")
                theDiv.setAttribute("style", commentExpandoStyle)
                
                var clickFunc = function () {
                    if(theDiv.className.indexOf("collapsed") != -1) {
                        theDiv.setAttribute("class", "expando-button expanded video")
                        if (!embedObject) {
                            embedObject = addYouTubeEmbed(videoID, startTime)
                        }
                        theDiv.parentNode.insertBefore(embedObject, theDiv.nextSibling)
                    }
                    else {
                        theDiv.setAttribute("class", "expando-button collapsed video")
                        theDiv.parentNode.removeChild(embedObject)
                    }
                }
                
                innerLinks[j].parentNode.insertBefore(theDiv, innerLinks[j].nextSibling)
                theDiv.addEventListener('click', clickFunc, true)
            }
            
            genClickFunc()
        }
    }
}

var mdElements = document.getElementsByClassName("md")

// Find all user created comment sections
for (var i in mdElements) {
    if (mdElements[i].tagName == 'DIV') {
        addButtons(mdElements[i]);
    }
}

// hasClass, stolen from the Reddit Enhancement Suite
function hasClass(ele,cls) {
  if ((typeof(ele) == 'undefined') || (ele == null)) {
    console.log(arguments.callee.caller);
    return false;
  }
  return ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)'));
}

// Add a listener for the DOMNodeInserted event so we can expand emotes in new comments
// created by either a reply or by clicking "load more comments" in large threads.
function handleInsertion( event ) {
    // The actual even we see will be the insertion of the outer "thing" div
    if ((event.target.tagName == 'DIV') && (hasClass(event.target, "thing"))) {
        var mdElements = event.target.getElementsByClassName("md")
        for (var i in mdElements) {
            if (mdElements[i].tagName == 'DIV') {
                addButtons(mdElements[i]);
            }
        }
    }
}

document.body.addEventListener('DOMNodeInserted', handleInsertion, false);