Greasy Fork is available in English.

YouTube Title Adder

Preloads any YouTube (and LiveLink!) links and appends the title of the video to the link in the referring page

  1. // ==UserScript==
  2. // @name YouTube Title Adder
  3. // @namespace Smiths
  4. // @description Preloads any YouTube (and LiveLink!) links and appends the title of the video to the link in the referring page
  5. // @include *
  6. // @exclude http://*.youtube.com/*
  7. // @exclude https://*.youtube.com/*
  8. // @exclude http://*.liveleak.com/*
  9. // @exclude http://youtube.com/*
  10. // @exclude http://liveleak.com/*
  11. // @exclude http://*.google.*/search?*
  12. // @exclude http://google.*/search?*
  13. // @exclude https://google.*/search?*
  14. // @exclude https://*.google.*/search?*
  15. // @version 3.4.2
  16. // @grant GM_getValue
  17. // @grant GM_setValue
  18. // @grant GM_addStyle
  19. // @grant GM_log
  20. // @grant GM_xmlhttpRequest
  21. // @grant GM_registerMenuCommand
  22. // @attribution changes [d:03.15.13][u:<ul><li>Finally fixed long-standing oversight on my part that did not even try to define the size of the expand/collapse icon. This led to some sites having some huge Plus/Minus pictures.</li><li>Per suggestion on script's forum (and something I made another script to do manually), this now will automatically append YT/LL titles to Twitter/Tweetdeck posts that use the "data-full/expanded" et al tags.</li><li>If tweets don't use those tags (some inline twitter things on certain websites always just use the URL shortener without any indication of what the real page is) I recommend <a href="http://userscripts.org/scripts/show/140411">My URL Unshortener</a> script</li></ul>]
  23. // ==/UserScript==
  24.  
  25. //note to self: gotta make sure to update the one in the metadata too!
  26. var v = "3.4.2";
  27.  
  28. var scriptNum = "12113";
  29. var scriptName = "YouTube Title Adder";
  30.  
  31. //<--Updater Stuff
  32. var isFireFox = navigator.userAgent.indexOf("Firefox") > -1 || navigator.userAgent.indexOf("Iceweasel") > -1;
  33. GM_addStyle("#smgm_bgdiv{ text-align: center;position:fixed;top:0px;left:0px;z-index:9991;width:100%;height:100%;background-color:black;opacity:0.7;display:block;visibility:visible;}");
  34. GM_addStyle("#smgm_dialogbox { vertical-align:middle;left:40px;top:15px;border:3px solid #000 !important;text-align:center !important;background-color:#fff !important;color:#000 !important;font-family:arial,verdana !important;z-Index:9999;position:fixed;width:18%;height:50%;margin-left:auto;margin-right:auto;display:block;visibility:visible;}");
  35. GM_addStyle(".smgm_buttons { color:#000 !important;font: 90% 'arial','trebuchet ms',helvetica,sans-serif !important;background-color:#B2CCFF !important;border:2px solid !important;border-color: #E0EBFF #000 #000 #E0EBFF !important;vertical-align: top !important;}");
  36. GM_addStyle(".smgm_table { margin-bottom:10px !important;border:0px !important;border-collapse:collapse !important;margin-left:auto;margin-right:auto; }");
  37. var remindLaterV = GM_getValue('remindLaterV', remindLaterV);
  38. if (!remindLaterV) { remindLaterV = 0; GM_setValue('remindLaterV',remindLaterV); }
  39.  
  40. var homepageURL = "http://userscripts.org/scripts/show/" + scriptNum ;
  41. var metaURL = "http://userscripts.org/scripts/source/" + scriptNum + ".meta.js";
  42. var scriptJSURL = "http://userscripts.org/scripts/source/" + scriptNum + ".user.js";
  43.  
  44. function doremindLater(clicked,span)
  45. {
  46. if (clicked)
  47. remindLaterV = span;
  48. else
  49. remindLaterV--;
  50. GM_setValue('remindLaterV',remindLaterV);
  51. }
  52.  
  53. function hideUpdate()
  54. {
  55. document.body.removeChild(document.getElementById('smgm_bgdiv'));
  56. document.body.removeChild(document.getElementById('smgm_dialogbox'));
  57. }
  58.  
  59. function checkNew(version)
  60. {
  61. var upgrade = 0;
  62. var verstring = "";
  63. var theHTML = "";
  64. GM_xmlhttpRequest({
  65. method:"GET",
  66. url:metaURL,
  67. onload:function(content){
  68. var aResponse = content.responseText;
  69. var USversion = aResponse.match(/@version.*?(\d[^<]+?)\n/);
  70. aResponse = aResponse.replace(/ \/>/g,'>');
  71. aResponse = aResponse.replace(/\n/g,'');
  72. var changeDate = aResponse.match(/\[d:([0-9]+?\.[0-9]+?\.[0-9]+?)\]/i)[1];
  73. var theChanges = aResponse.match(/\[u:(.*?)\]/i)[1];
  74. vSplit = version.split(".");
  75. vmain = Number(vSplit[0]);
  76. vvsub = Number(vSplit[1]);
  77. vrsub = Number(vSplit[2]);
  78. USsplit = USversion[1].split(".");
  79. USvmain = Number(USsplit[0]);
  80. USvsub = Number(USsplit[1]);
  81. USrsub = Number(USsplit[2]);
  82. verstring = "<div style='padding:5px;border-bottom:1px dotted #000;'>Latest Version on Userscripts: <a href='" + homepageURL + "' target='_new' title='Click to visit script's page'><b>" + USvmain + "." + USvsub + "." + USrsub + "</b></a><br>Your Installed Version: <b>" + vmain + "." + vvsub + "." + vrsub + "</b></div>";
  83. if (USvmain > vmain) upgrade = 1;
  84. if ( (USvsub > vvsub) && (USvmain >= vmain) ) upgrade = 1;
  85. if ( (USrsub > vrsub) && (USvsub == vvsub) && (USvmain >= vmain) ) upgrade = 1;
  86. if (upgrade == 1) //upgrade available, pop a box
  87. {
  88. theHTML += "<div style='padding:5px;border-bottom:1px dotted #000;'>New version of " + scriptName + " available.</div>";
  89. theHTML += verstring + "<p>";
  90. theHTML += "<table class='smgm_table'><tr><td><input type='button' class='smgm_buttons' id='smgm_installButton' onMouseUp=\"document.location.href=\'" + scriptJSURL + "\';\" value='Install'></td>";
  91. theHTML += "<td style='width:25px;'>&nbsp;</td><td><input style='' class='smgm_buttons' type='button' id='smgm_remindButton' value='Remind Me Later'></td>";
  92. theHTML += "</tr></table><div style='background-color:white !important;overflow:auto !important;height:50%;text-align:left;border-top:1px dotted #000;padding:7px;' colspan='5'>Changes (" + changeDate.replace(/\./g,"/") + "):<br><span style='font-style:italic;'>" + theChanges + "</span></div>";
  93. div1 = document.createElement('div');
  94. div1.id = 'smgm_dialogbox';
  95. div1.style.display = "none";
  96. div1.innerHTML = theHTML;
  97. document.body.appendChild(div1);
  98. div2 = document.createElement('div');
  99. div2.id = 'smgm_bgdiv';
  100. div2.style.display = "none";
  101. div2.addEventListener("click",function(){doremindLater(true,15);hideUpdate();},false);
  102. document.body.appendChild(div2);
  103. document.getElementById('smgm_bgdiv').style.display='block';
  104. document.getElementById('smgm_dialogbox').style.display='block';
  105. document.getElementById('smgm_remindButton').addEventListener("click", function(){doremindLater(true,60);hideUpdate();},false);
  106. document.getElementById('smgm_installButton').addEventListener("click", function(){hideUpdate();},false);
  107. }
  108. }
  109. })
  110. }
  111.  
  112. if (isFireFox) //only do update on FFox, Chrome/Tampermonkey are weird
  113. {
  114. doremindLater(false);
  115. if (remindLaterV < 1)
  116. checkNew(v);
  117. }
  118. //end updater stuff-->
  119.  
  120. var ytcollapseimg = "data:image/gif,GIF89a%0B%00%0B%00%A2%00%00%00%00%00%FF%FF%FF%5C%AD%E0%B6%E3%FF%FF%A5%A5%CE%CE%CE%FF%FF%FF%00%00%00!%F9%04%01%00%00%06%00%2C%00%00%00%00%0B%00%0B%00%00%03%24h%B0%CC%3A0%8E%10%96%94%15%5Ci%1B%1B%1DA%05%04Pt%9E%B9%08C%E1%BE'%20%B0%DB%3A%D7J%BA%18%09%00%3B";
  121. var ytexpandimg = "data:image/gif,GIF89a%0B%00%0B%00%A2%00%00%00%00%00%FF%FF%FF%5C%AD%E0%B6%E3%FF%FF%A5%A5%CE%CE%CE%FF%FF%FF%00%00%00!%F9%04%01%00%00%06%00%2C%00%00%00%00%0B%00%0B%00%00%03*h%B0%CC%3A0%8E%10Vd%B0%82K%40%81%16%A3m!A%05%5D%11.%A3%0A%08%60Z%B8%02%CC%7C%C3R%C33%0E(%8D%86!%01%00%3B";
  122. var ytdisabled = "data:image/gif,GIF89a%0B%00%0B%00%A2%00%00%00%00%00%FF%FF%FF%5C%AD%E0%B6%E3%FF%FF%A5%A5%CE%CE%CE%FF%FF%FF%00%00%00!%F9%04%01%00%00%06%00%2C%00%00%00%00%0B%00%0B%00%00%03-h%B0%CC%3A0%8E%10%16%04%11W%0C%08(%DDg%0D%40U%15%20v%9D%05%A9%96p%BB%08!%E8%A5%02%8D%92%E8%9C%B7%10%99%A2%D10%24%00%00%3B";
  123. var closeIcon = "data:image/gif;base64,R0lGODlhCgAKAIABAAAAAP///yH5BAEAAAEALAAAAAAKAAoAAAIWhI8WyxfA3oOyqnVno9piyElONCVJAQA7";
  124. var ytlinks = 1;
  125. var ytimage = 0;
  126. var ytembedimage = 1;
  127. var ytlowbw = 0;
  128. var ytsize = 1;
  129. var playerV=3;
  130. var playerAN=3;
  131. if (!GM_xmlhttpRequest) {
  132. alert('Please upgrade to the latest version of Greasemonkey to use the full features of this script.');
  133. return;
  134. } else {
  135. ytlinks = Number(GM_getValue('ytlinks', ytlinks));
  136. ytimage = Number(GM_getValue('ytimage', ytimage));
  137. ytembedimage = Number(GM_getValue('ytembedimage', ytembedimage));
  138. ytlowbw = Number(GM_getValue('ytlowbw', ytlowbw));
  139. ytsize = Number(GM_getValue('ytsize', ytsize));
  140. playerAN = Number(GM_getValue('playerAN', playerAN));
  141. GM_registerMenuCommand('YouTube Title Adder Options', smgm_yt_showOptions);
  142. }
  143. var dw = 425;
  144. var dh = 320;
  145. var vw,vh;
  146. //h/w * nw = nh
  147. if (ytsize==0)
  148. vw = dw;
  149. else if (ytsize==1)
  150. vw = 560;
  151. else if (ytsize==2)
  152. vw = 750;
  153. else
  154. vw = dw;
  155. vh = dh/dw * vw;
  156.  
  157. function checkNew2(version)
  158. {
  159. GM_xmlhttpRequest({
  160. method:"GET",
  161. url:metaURL,
  162. headers:{"User-Agent":"monkeyagent"},
  163. onload:function(content){
  164. var upgrade = 0;
  165. var USversion = content.responseText.match(/@version.*?(\d[^<]+?)\n/);
  166. content.responseText = content.responseText.replace(/ \/>/g,'>');
  167. content.responseText = content.responseText.replace(/\n/g,'');
  168. var changeDate = content.responseText.match(/\[d:([0-9]+?\.[0-9]+?\.[0-9]+?)\]/i)[1];
  169. var theChanges = content.responseText.match(/\[u:(.*?)\]/i)[1];
  170. vSplit = version.split(".");
  171. vmain = Number(vSplit[0]);
  172. vvsub = Number(vSplit[1]);
  173. vrsub = Number(vSplit[2]);
  174. USsplit = USversion[1].split(".");
  175. USvmain = Number(USsplit[0]);
  176. USvsub = Number(USsplit[1]);
  177. USrsub = Number(USsplit[2]);
  178. verstring = "<div style='padding:5px;border-bottom:1px dotted #000;'>Latest Version on Userscripts: <a href='" + homepageURL + "' target='_new' title='Click to visit script's page'><b>" + USvmain + "." + USvsub + "." + USrsub + "</b></a><br>Your Installed Version: <b>" + vmain + "." + vvsub + "." + vrsub + "</b></div>";
  179. if (USvmain > vmain) upgrade = 1;
  180. if ( (USvsub > vvsub) && (USvmain >= vmain) ) upgrade = 1;
  181. if ( (USrsub > vrsub) && (USvsub == vvsub) && (USvmain >= vmain) ) upgrade = 1;
  182. document.getElementById('versioncheck').innerHTML = "<br>" + verstring + "<br><b>" + (upgrade ? "<a href=\"" + homepageURL + "\" target=\"_blank\">UPGRADE AVAILABLE</a>" : "You have the latest release");
  183. }
  184. })
  185. }
  186.  
  187. function setOptions()
  188. {
  189. if (ytlinks) document.getElementById('linkon').checked = true;
  190. else document.getElementById('linkoff').checked = true;
  191. if (ytimage) document.getElementById('imageon').checked = true;
  192. else document.getElementById('imageoff').checked = true;
  193. if (ytembedimage) document.getElementById('embedon').checked = true;
  194. else document.getElementById('embedoff').checked = true;
  195. if (ytlowbw == 0) document.getElementById('lowbw0').checked = true;
  196. else if (ytlowbw == 1) document.getElementById('lowbw1').checked = true;
  197. else document.getElementById('lowbw2').checked = true;
  198. if (ytsize == 0) document.getElementById('vid0').checked = true;
  199. else if (ytsize == 1) document.getElementById('vid1').checked = true;
  200. else document.getElementById('vid2').checked = true;
  201. if (playerAN==1) document.getElementById('playerANon').checked = true;
  202. else document.getElementById('playerANoff').checked = true;
  203. }
  204.  
  205. function saveOptions()
  206. {
  207. if (document.getElementById('linkon').checked) GM_setValue('ytlinks', 1 );
  208. else GM_setValue('ytlinks', 0 );
  209. if (document.getElementById('imageon').checked) GM_setValue('ytimage', 1 );
  210. else GM_setValue('ytimage', 0 );
  211. if (document.getElementById('embedon').checked) GM_setValue('ytembedimage', 1 );
  212. else GM_setValue('ytembedimage', 0 );
  213. if (document.getElementById('lowbw1').checked)
  214. GM_setValue('ytlowbw', 1 );
  215. else if (document.getElementById('lowbw2').checked)
  216. GM_setValue('ytlowbw', 2 );
  217. else
  218. GM_setValue('ytlowbw', 0 );
  219. if (document.getElementById('vid1').checked)
  220. GM_setValue('ytsize', 1 );
  221. else if (document.getElementById('vid2').checked)
  222. GM_setValue('ytsize', 2 );
  223. else
  224. GM_setValue('ytsize', 0 );
  225. if (document.getElementById('playerANon').checked) GM_setValue('playerAN', 1 );
  226. else GM_setValue('playerAN', 3 );
  227. }
  228.  
  229. function hideOptions()
  230. {
  231. document.body.removeChild(document.getElementById("smgm_optionsDiv"));
  232. document.body.removeChild(document.getElementById("smgm_modalDiv"));
  233. }
  234.  
  235. //full thanks to "Google Anonymizer" code for visual options - http://userscripts.org/scripts/review/10448
  236. function smgm_yt_showOptions()
  237. {
  238. ytlinks = Number(GM_getValue('ytlinks', ytlinks));
  239. ytimage = Number(GM_getValue('ytimage', ytimage));
  240. ytembedimage = Number(GM_getValue('ytembedimage', ytembedimage));
  241. var div1=document.getElementById("smgm_modalDiv");
  242. if (div1==null)
  243. {
  244. GM_addStyle("#smgm_modalDiv{position:fixed; top:0px; left:0px; z-index:200; width:100%; height:100%; background-color:black; opacity:0.75;}");
  245. GM_addStyle(".smgm_hidden{display:none; visibility:hidden;}");
  246.  
  247. div1=document.createElement("DIV");
  248. div1.id="smgm_modalDiv";
  249. div1.className="smgm_hidden";
  250. div1.title="Click to cancel and close";
  251. document.body.appendChild(div1);
  252. div1.addEventListener("click",hideOptions,false);
  253. }
  254. var div2=document.getElementById("smgm_optionsDiv");
  255. if (div2==null)
  256. {
  257. GM_addStyle(".smgm_optionsTable{vertical-align:middle !important;border-spacing: 2px !important; border: 1px solid #000 !important; border-collapse: collapse !important;padding-left:10px !important;margin-bottom:3px !important;color:#000 !important;}");
  258. GM_addStyle("#smgm_optionsDiv{overflow:auto;position:fixed !important; top:3%; left:20%; z-index:210; width:50%; height:60%; background-color:white !important; border:solid 3px #0033CC !important;}");
  259. div2=document.createElement("DIV");
  260. div2.id="smgm_optionsDiv";
  261. div2.className="smgm_hidden";
  262. div2.setAttribute("style","text-align:justify !important;padding:10px !important;font-family:verdana,arial !important;font-size:10pt !important;");
  263. var text1="";
  264. text1+="<center><font size=\"+1\"><a href=\""+ homepageURL + "\" target=\"_blank\">YouTube Title Adder</a> Options</font><span id=\"versioncheck\" style=\"font-size:10px;\"><br><br>ver. " + v + " (Checking for updates...)</span></center>";
  265. text1+="<form id=\"YTTA\" name=\"titleform\"><ul>";
  266. text1+="<li>Names on YouTube/LiveLeak Text Links:<br><input type=\"radio\" id=\"linkon\" name=\"textlinks\" value=\"1\"/><label for=\"linkon\"> Enabled</label><br><input type=\"radio\" id=\"linkoff\" name=\"textlinks\" value=\"0\"/><label for=\"linkoff\"> Disabled</label><br>";
  267. text1+="<li>Names on YouTube/LiveLeak Image Links:<br><input type=\"radio\" id=\"imageon\" name=\"imglinks\" value=\"1\"/><label for=\"imageon\"> Enabled</label><br><input id=\"imageoff\" type=\"radio\" name=\"imglinks\" value=\"0\"/><label for=\"imageoff\"> Disabled</label><br>";
  268. text1+="<li>Embed Buttons for YouTube/LiveLeak Links:<br><input type=\"radio\" id=\"embedon\" name=\"embed\" value=\"1\"/><label for=\"embedon\"> Enabled</label><br><input type=\"radio\" id=\"embedoff\" name=\"embed\" value=\"0\"/><label for=\"embedoff\"> Disabled</label><br>";
  269. text1+="<li>Default Embedded Video Size:<br><input type=\"radio\" id=\"vid0\" name=\"vidsize\" value=\"0\"/><label for=\"vid0\"> Small (Default since script began)</label><br><input type=\"radio\" id=\"vid1\" name=\"vidsize\" value=\"1\"/><label for=\"vid1\"> Medium</label><br><input type=\"radio\" id=\"vid2\" name=\"vidsize\" value=\"2\"/><label for=\"vid2\"> Large</label><br>";
  270. text1+="<li>Bandwidth Version:<br><input type=\"radio\" id=\"lowbw0\" name=\"lowbw\" value=\"0\"/><label for=\"lowbw0\"> Full (Complete Error Descriptions)</label><br><input type=\"radio\" id=\"lowbw1\" name=\"lowbw\" value=\"1\"/><label for=\"lowbw1\"> Medium (Uses mobile site, less error descriptions)</label><br><input type=\"radio\" id=\"lowbw2\" name=\"lowbw\" value=\"2\"/><label for=\"lowbw2\"> Lowest (uses Meta, very minimal error messages)</label><br>";
  271. text1+="<li>Enable Video Annotations by Default:<br><input type=\"radio\" id=\"playerANon\" name=\"playerAN\" value=\"1\"/><label for=\"playerANon\"> Enabled</label><br><input type=\"radio\" id=\"playerANoff\" name=\"playerAN\" value=\"0\"/><label for=\"playerANoff\"> Disabled</label><br>";
  272. text1+="</ul><center><input type=\"button\" value=\"Ok\" id=\"okButton\" /><input type=\"button\" value=\"Cancel\" id=\"cancelButton\" /></center></form>";
  273. div2.innerHTML=text1;
  274. document.body.appendChild(div2);
  275. document.getElementById("okButton").addEventListener("click",function(){saveOptions();hideOptions();location.reload(true);},false);
  276. document.getElementById("cancelButton").addEventListener("click",function(){hideOptions();},false);
  277. }
  278. document.getElementById("smgm_optionsDiv").className="";
  279. document.getElementById("smgm_modalDiv").className="";
  280. setOptions();
  281. checkNew2(v);
  282. div1.className="";
  283. div2.className="";
  284. }
  285.  
  286. GM_addStyle(".smgm_ytTitle{border:none !important; padding:0px !important; margin:none !important; margin-left:2px !important;}");
  287. GM_addStyle(".smgm_ytButton{height:11px !important;width:11px !important;}");
  288.  
  289. function makeStart(time)
  290. {
  291. var h=0;var m=0;var s=0;
  292. if (time.match(/h/)) h=time.match(/(\d+)h/)[1];
  293. if (time.match(/m/)) m=time.match(/(\d+)m/)[1];
  294. if (time.match(/s/)) s=time.match(/(\d+)s/)[1];
  295. time = parseInt(h)*3600+parseInt(m)*60+parseInt(s);
  296. return time;
  297. }
  298.  
  299. var allLinks, thisLink, thetitle, tubelink;
  300. function addtitle(link, number,vidlink) {
  301. var requestURL;
  302. if (ytlowbw==0) requestURL = link.href;
  303. else if (ytlowbw==1) requestURL = "http://m.youtube.com/watch?v=" + vidlink;
  304. else if (ytlowbw==2) requestURL = "http://gdata.youtube.com/feeds/api/videos/" + vidlink;
  305. GM_xmlhttpRequest({
  306. method:"GET",
  307. url:requestURL,
  308. onload:function(content){
  309. var isAgeVerify;
  310. var verifyHTML = "";
  311. var ageString = "";
  312. var color1 = "0x000000";
  313. var color2 = "0x7c7c7c";
  314. var embedid, alink;
  315. var linkOK = "";
  316. var videoname = "";
  317. var extra = link.hash;
  318. var aResponse = content.responseText;
  319. if(extra.length>0)
  320. extra = makeStart(extra);
  321. if (ytlowbw==0)
  322. {
  323. var videoembedcode = aResponse.match(/(http:\/\/youtu\.be\/)([^<]+?)\"/);
  324. if (videoembedcode) { linkOK = videoembedcode[1]; var videoembed = unescapeHTML(videoembedcode[2].replace(/\\/g,"")); videoNumber = videoembed;}
  325. aResponse = aResponse.replace(/\\'/g,"'");
  326. videoname = aResponse.match(/meta property=\"og:title\" content=\"([^<]+?)\"/);
  327. if (!videoname) {
  328. videoname = aResponse.match(/<div id=\"vidTitle\">([^<]+)<\/div>/);
  329. }
  330. if (!videoname) {
  331. videoname = aResponse.match(/<meta name=\"title\" content=\"([^<]+)\">/);
  332. }
  333. if (!videoname) { //at this point it's an error page on YouTube (login page, etc)
  334. //let's see if its an age verification
  335. isAgeVerify = aResponse.match(/desktop_uri=%2Fverify_age%3Fnext_url%3Dhttp%253A%2F%2Fwww.youtube.com%2Fwatch%253Fv%253D([^<]+?)&amp;/);
  336. if (isAgeVerify) {
  337. var videoembed = unescapeHTML(isAgeVerify[1].replace(/\\/g,""));
  338. var videoNumber = videoembed;
  339. linkOK = "http"; //we know it's legit
  340. videoname = aResponse.match(/alt="Thumbnail" class="" title=\"([^<]+?)\"/);
  341. ageString = " [age restr]";
  342. var color1 = "0xFF9900";
  343. var color2 = "0xCC5200";
  344. GM_xmlhttpRequest({
  345. method: "GET",
  346. url: "http://www.youtube.com/watch?v=" + videoNumber,
  347. onload: function( response ) {
  348. verifyHTML = response.responseText;
  349. }
  350. });
  351. }
  352. else //who knows, video not found, whatever
  353. {
  354. if (aResponse.match(/<div id=\"unavailable-message\"/i))
  355. {
  356. theError = aResponse.match(/<div id=\"unavailable-message\".*?>[ \t]+(.*?)\n/i)[1]
  357. videoname = ["Error",theError.substr(0,theError.length-1).replace(/<.*?>/g,'')];
  358. }
  359. else
  360. videoname = ["Error","Video Not Found"];
  361. }
  362. }
  363. }else if (ytlowbw==1){
  364. if (aResponse.match(/<title>YouTube - Broadcast Yourself.<\/title>/)) //error
  365. {
  366. if (aResponse.match(/border-bottom:1px dashed #FF0000"><\/div>/)) //just a bunch of dashes
  367. videoname = ["Error","Removed by Youtube"];
  368. else if (aResponse.match(/border-bottom:1px dashed #FF0000">/)) //there an error on mobile site
  369. {
  370. theError = aResponse.match(/border-bottom:1px dashed #FF0000">(.*?)<\/div>/)[1];
  371. videoname = ["Error",theError.substr(0,theError.length-1).replace(/<.*?>/g,'')];
  372. }
  373. else
  374. videoname = ["Error","Other (age rest./etc.)"];
  375. }
  376. else
  377. {
  378. linkOK = "http";
  379. videoname = aResponse.match(/<title>(.*?)<\/title>/);
  380. videoNumber = vidlink;
  381. }
  382. }else if (ytlowbw==2){
  383. if (aResponse.match(/<media:title/) == null) //error
  384. {
  385. if (aResponse.match(/<error>/))
  386. videoname = ["Error",aResponse.match(/<code>(.*?)<\/code>/)[1]];
  387. else
  388. videoname = ["Error",aResponse];
  389. }
  390. else
  391. {
  392. linkOK = "http";
  393. videoname = aResponse.match(/<media:title.*?>(.*?)<\/media:title>/);
  394. videoNumber = vidlink;
  395. }
  396. }
  397. embeddedtag = document.createElement('div');
  398. embeddedtag.className = "smgm_ytTitle";
  399. btn = document.createElement('a');
  400. btn.className = "smgm_ytTitle";
  401. if (linkOK.substr(0,4).toLowerCase() == "http")
  402. {
  403. alink = vidlink + number;
  404. btn.id = alink; embedid = alink + "embedded";
  405. embeddedtag.id = embedid;
  406. embeddedtag.style.display = 'none';
  407. embeddedtag.setAttribute("align", "center");
  408. objectHTML = '<object><param name="movie" value="http://www.youtube.com/v/' +
  409. videoNumber + '?version='+playerV+'&amp;fs=1&amp;hl=en_US&amp;disablekb=1&amp;rel=0&amp;color1=' + color1 + '&amp;color2=' + color2 + '&amp;border=0&amp;iv_load_policy='+playerAN+'&amp;modestbranding=1&amp;autohide=1&amp;start='+extra+'"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param>' +
  410. '<embed id="'+embedid+'_v" src="http://www.youtube.com/v/' + videoNumber + '?version='+playerV+'&amp;fs=1&amp;hl=en_US&amp;disablekb=1&amp;rel=0&amp;color1=' + color1 + '&amp;color2=' + color2 + '&amp;modestbranding=1&amp;border=0&amp;iv_load_policy='+playerAN+'&amp;autohide=1&amp;start='+extra+'" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="'+vw+'" height="'+vh+'"></embed></object>' +
  411. '';
  412. embeddedtag.innerHTML = objectHTML;
  413. btn.innerHTML = '<img class="smgm_ytTitle smgm_ytButton" src="' + ytexpandimg + '" align="top" border="0" title="Click to Show Video">';
  414. btn.addEventListener('click', function(){toggleembed(this.id,1);drawvidoptions(this.id);}, true);
  415. }
  416. if ((link.innerHTML.indexOf('<img') < 0) && (ytlinks == 1))
  417. {
  418. link.innerHTML = (videoname[0] != "Error") ? '<i style="background:none !important;">' + link.innerHTML + " (<b>YT: " + unescapeHTML(videoname[1]) + ageString + "</b>)</i>" :
  419. '<i style="background:none !important;">' + link.innerHTML + " (<b>Error: " + unescapeHTML(videoname[1]) + "</b>)</i>";
  420. if (ytembedimage == 1)
  421. {
  422. link.parentNode.insertBefore(embeddedtag, link.nextSibling);
  423. link.parentNode.insertBefore(btn, link.nextSibling);
  424. }
  425. }
  426. if ((link.innerHTML.indexOf('<img') > -1) && (ytimage == 1))
  427. {
  428. link.innerHTML = (videoname[0] != "Error") ? '<i style="background:none !important;">' + link.innerHTML + " (<b>YT: " + unescapeHTML(videoname[1]) + ageString + "</b>)</i>" :
  429. '<i style="background:none !important;">' + link.innerHTML + " (<b>Error: " + unescapeHTML(videoname[1]) + "</b>)</i>";
  430. if (ytembedimage == 1)
  431. {
  432. link.parentNode.insertBefore(embeddedtag, link.nextSibling);
  433. link.parentNode.insertBefore(btn, link.nextSibling);
  434. }
  435. }
  436. else
  437. {
  438. if (link.innerHTML.indexOf('<img') > -1)
  439. {
  440. theimg = link.getElementsByTagName('img');
  441. if (videoname[0] != "Error")
  442. theimg[0].setAttribute('title', 'YouTube link: Video name = "' + unescapeHTML(videoname[1]) + ageString + '"');
  443. else
  444. theimg[0].setAttribute('title', 'YouTube Error: ' + unescapeHTML(videoname[1]));
  445. }
  446. if ((linkOK.substr(0,4) == "http") && (ytembedimage == 1))
  447. {
  448. link.parentNode.insertBefore(embeddedtag, link.nextSibling);
  449. link.parentNode.insertBefore(btn, link.nextSibling);
  450. }
  451. else
  452. {
  453. if (ytembedimage == 1)
  454. {
  455. objectHTML = '<object ><param name="movie" value="http://www.youtube.com/v/' +
  456. videoNumber + '?version='+playerV+'fs=1&amp;hl=en_US&amp;disablekb=1&amp;rel=0&amp;color1=' + color1 + '&amp;color2=' + color2 + '&amp;border=0&amp;iv_load_policy='+playerAN+'&amp;modestbranding=1&amp;autohide=1&amp;start='+extra+'"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param>' +
  457. '<embed src="http://www.youtube.com/v/' + videoNumber + '?version='+playerV+'fs=1&amp;hl=en_US&amp;disablekb=1&amp;rel=0&amp;color1=' + color1 + '&amp;color2=' + color2 + '&amp;border=0&amp;modestbranding=1&amp;iv_load_policy='+playerAN+'&amp;autohide=1&amp;start='+extra+'" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="'+vw+'" height="'+vh+'"></embed></object>';
  458. alink = vidlink + number;
  459. btn.id = alink; embedid = alink + "embedded";
  460. embeddedtag.id = embedid;
  461. embeddedtag.style.display = 'none';
  462. embeddedtag.setAttribute("align", "center");
  463. embeddedtag.innerHTML = objectHTML;
  464. if (videoname[0] != "Error")
  465. {
  466. btn.innerHTML = '<img src="' + ytdisabled + '" align="top" border="0" title="Embedding disabled for this video, click to see preview thumb">';
  467. btn.addEventListener('click', function(){toggleembed(this.id,0);drawvidoptions(this.id);}, true);
  468. }
  469. else
  470. btn.innerHTML = '<img src="' + ytdisabled + '" align="top" border="0" title="YouTube Error: ' + unescapeHTML(videoname[1]) + '">';
  471. link.parentNode.insertBefore(embeddedtag, link.nextSibling);
  472. link.parentNode.insertBefore(btn, link.nextSibling);
  473. }
  474. }
  475. }
  476. (videoname[0] != "Error") ? link.setAttribute('title', 'YouTube link: Video name = "' + unescapeHTML(videoname[1]) + ageString + '"') :
  477. link.setAttribute('title', 'YouTube Error: ' + unescapeHTML(videoname[1]));
  478. }
  479. })
  480. }
  481.  
  482. //LiveLeak
  483. function addtitleLL(link, number, vidlink) {
  484. GM_xmlhttpRequest({
  485. method:"GET",
  486. url:link.href,
  487. onload:function(content){
  488. var embedid, alink;
  489. var aResponse = content.responseText;
  490. var videoembedcode = aResponse.match(/<!--share_item_(.*?)_menu-->/);
  491. aResponse = aResponse.replace(/\\'/g,"'");
  492. var videoname = aResponse.match(/<span class="section_title" st.*?>([^<]+?)<\/span>/);
  493. embeddedtag = document.createElement('div');
  494. embeddedtag.className = "smgm_ytTitle";
  495. btn = document.createElement('a');
  496. btn.className = "smgm_ytTitle";
  497. if (!videoname) videoname = "Video Not Found";
  498. alink = vidlink + number;
  499. btn.id = alink; embedid = alink + "embedded";
  500. embeddedtag.id = embedid;
  501. embeddedtag.style.display = 'none';
  502. embeddedtag.setAttribute("align", "center");
  503. objectHTML = '<object width="425" height="373"><param name="movie" value="http://www.liveleak.com/e/' +
  504. videoembedcode[1] + '"></param><param name="wmode" value="transparent"></param><param name="allowscriptaccess" value="never">' +
  505. '</param><embed id="'+embedid+'_v" src="http://www.liveleak.com/e/' + videoembedcode[1] + '" type="application/x-shockwave-flash" wmode="transparent" allowscriptaccess="never" width="450" height="370"></embed></object>';
  506. embeddedtag.innerHTML = objectHTML;
  507. btn.innerHTML = '<img class="smgm_ytTitle smgm_ytButton" src="' + ytexpandimg + '" align="top" border="0" title="Click to Show Video">';
  508. btn.addEventListener('click', function(){toggleembed(this.id,1);drawvidoptions(this.id);}, true);
  509.  
  510. if ((link.innerHTML.indexOf('<img') < 0) && (ytlinks == 1))
  511. {
  512. link.innerHTML = '<i style="background:none !important;">' + link.innerHTML + " (<b>LL: " + unescapeHTML(videoname[1]) + "</b>)</i>";
  513. if (ytembedimage == 1)
  514. {
  515. link.parentNode.insertBefore(embeddedtag, link.nextSibling);
  516. link.parentNode.insertBefore(btn, link.nextSibling);
  517. }
  518. }
  519. if ((link.innerHTML.indexOf('<img') > -1) && (ytimage == 1))
  520. {
  521. link.innerHTML = '<i style="background:none !important;">' + link.innerHTML + " (<b>LL: " + unescapeHTML(videoname[1]) + "</b>)</i>";
  522. if (ytembedimage == 1)
  523. {
  524. link.parentNode.insertBefore(embeddedtag, link.nextSibling);
  525. link.parentNode.insertBefore(btn, link.nextSibling);
  526. }
  527. }
  528. else
  529. {
  530. if (link.innerHTML.indexOf('<img') > -1)
  531. {
  532. theimg = link.getElementsByTagName('img');
  533. theimg[0].setAttribute('title', 'LiveLeak link: Video name = "' + unescapeHTML(videoname[1]) + '"');
  534. }
  535. if (ytembedimage == 1)
  536. {
  537. link.parentNode.insertBefore(embeddedtag, link.nextSibling);
  538. link.parentNode.insertBefore(btn, link.nextSibling);
  539. }
  540. }
  541. link.setAttribute('title', 'Liveleak link: Video name = "' + unescapeHTML(videoname[1]) + '"');
  542. }
  543. })
  544. }
  545.  
  546. function toggleembed(id,embedable)
  547. {
  548. embeddedid = id + "embedded";
  549. embeddedDIV = document.getElementById(embeddedid);
  550. if (embeddedDIV.style.display != 'none')
  551. {
  552. if (embedable == 1) document.getElementById(id).innerHTML = '<img class="smgm_ytTitle smgm_ytButton" src="' + ytexpandimg + '" align="top" border="0" title="Click to Show Video">';
  553. if (embedable == 0) document.getElementById(id).innerHTML = '<img class="smgm_ytTitle smgm_ytButton" src="' + ytdisabled + '" align="top" border="0" title="Embedding disabled for this video, click to see preview thumb">';
  554. embeddedDIV.innerHTML = embeddedDIV.innerHTML;
  555. embeddedDIV.style.display = 'none';
  556. }
  557. else
  558. {
  559. document.getElementById(id).innerHTML = '<img class="smgm_ytTitle smgm_ytButton" src="' + ytcollapseimg + '" align="top" border="0" title="Click to Hide Video">';
  560. embeddedDIV.style.display = '';
  561. }
  562. }
  563.  
  564. function unescapeHTML(s)
  565. {
  566. return s.replace('&amp;', '&').replace('&lt;',"<").replace('&gt;','>').replace('&quot;','"').replace('&#39;','\'');
  567. }
  568.  
  569.  
  570. function drawvidoptions(id)
  571. {
  572. vid = id + "embedded_v";
  573. var pos = findPos(document.getElementById(id));
  574. if (document.getElementById("smgm_ytvidsize" + id))
  575. document.body.removeChild(document.getElementById("smgm_ytvidsize" + id));
  576. else
  577. {
  578. var highlighttag = document.createElement('div');
  579. highlighttag.id = "smgm_ytvidsize" + id;
  580. highlighttag.setAttribute('style','padding:0px !important;margin:2px !important;color:#000;text-align:center;border:1px solid #000;background-color:#B6E3FF;z-index:175;position:absolute;top:'+(pos[1]-30)+'px;left:'+(pos[0]+20)+'px;-moz-box-shadow:2px 2px 4px #333;-webkit-box-shadow:2px 2px 4px #333;box-shadow:2px 2px 4px #333;');
  581. var close = document.createElement('span');
  582. close.id = vid + "sizebox";
  583. close.addEventListener('click',function(){toggleembed(this.id.substr(0,this.id.length-17),1);drawvidoptions(this.id.substr(0,this.id.length-17));},false);
  584. close.setAttribute('style','margin-left:4px;vertical-align:middle;cursor:pointer;font-size:6pt;');
  585. close.setAttribute('title','Click to Hide Video');
  586. close.innerHTML = "<img alt='[x]' src='" + closeIcon + "'>";
  587. var ytsizetable = document.createElement('table');
  588. ytsizetable.setAttribute('style','font-family:verdana,arial !important;font-size:9pt !important;border-collapse:collapse;color:#000 !important;margin:0px !important; padding:2px !important;text-align:center !important;border:none !important;');
  589. aTR1 = document.createElement('tr');
  590. aTR1.setAttribute('style','background:#5CADE0;');
  591. headerTD = document.createElement('td');
  592. headerTD.setAttribute('colspan',3);
  593. headerTD.setAttribute('style','border-bottom:1px dotted #000;font-size:9pt;text-align:center;padding:1px !important;');
  594. headerTD.innerHTML = "Video Size";
  595. headerTD.appendChild(close);
  596. aTR1.appendChild(headerTD);
  597. ytsizetable.appendChild(aTR1);
  598. aTR2 = document.createElement('tr');
  599. aTR2.setAttribute('style','padding:2px !important;margin:0px !important;');
  600. var newTD = document.createElement('td');
  601. newTD.innerHTML = '<a style="text-decoration:none !important;color:#000 !important;" title="Small" onclick="javascript:(function(){document.getElementById(&quot;'+vid+'&quot;).width=&quot;425&quot;;document.getElementById(&quot;'+vid+'&quot;).height=&quot;320&quot;;})();" href="javascript:void(0);">S</a>';
  602. newTD.setAttribute('style','font-family:verdana,arial !important;font-size:9pt !important;text-align:center !important;padding:1px !important;margin:0px !important;border:none !important;');
  603. aTR2.appendChild(newTD);
  604. var newTD = document.createElement('td');
  605. newTD.innerHTML = '<a style="text-decoration:none !important;color:#000 !important;" title="Medium" onclick="javascript:(function(){document.getElementById(&quot;'+vid+'&quot;).width=&quot;560&quot;;document.getElementById(&quot;'+vid+'&quot;).height=&quot;420&quot;;})();" href="javascript:void(0);">M</a>';
  606. newTD.setAttribute('style','font-family:verdana,arial !important;font-size:9pt !important;text-align:center !important;padding:1px !important;margin:0px !important;border:none !important;');
  607. aTR2.appendChild(newTD);
  608. var newTD = document.createElement('td');
  609. newTD.innerHTML = '<a style="text-decoration:none !important;color:#000 !important;" title="Large" onclick="javascript:(function(){document.getElementById(&quot;'+vid+'&quot;).width=&quot;750&quot;;document.getElementById(&quot;'+vid+'&quot;).height=&quot;563&quot;;})();" href="javascript:void(0);">L</a>';
  610. newTD.setAttribute('style','font-family:verdana,arial !important;font-size:9pt !important;text-align:center !important;padding:1px !important;margin:0px !important;border:none !important;');
  611. aTR2.appendChild(newTD);
  612. ytsizetable.appendChild(aTR2);
  613. highlighttag.appendChild(ytsizetable);
  614. highlighttag.addEventListener('click',function(){var p=findPos(document.getElementById(this.id.substr(14)));document.getElementById(this.id).style.top=(p[1]-30)+"px";document.getElementById(this.id).style.left=(p[0]+20)+"px";},false);
  615. document.body.appendChild(highlighttag);
  616. }
  617. }
  618.  
  619. function findPos(obj){
  620. var curleft = curtop = 0;
  621. if (obj.offsetParent){
  622. do{
  623. curleft += obj.offsetLeft;
  624. curtop += obj.offsetTop;
  625. }while (obj = obj.offsetParent);
  626. }
  627. return [curleft,curtop];
  628. }
  629.  
  630. var vc=0;
  631. document.addEventListener('DOMNodeInserted',function(e){
  632. window.setTimeout(function(){
  633. var newLinks = document.querySelectorAll('a[data-full-url*="youtu.be/"],a[data-full-url*="youtube.com/watch"],a[data-expanded-url*="youtu.be/"],a[data-expanded-url*="youtube.com/watch"],a[href*="liveleak.com/view"],a[href*="youtu.be/"],a[href*="youtube.com/watch"]');
  634. if (newLinks.length > 0)
  635. {
  636. for (var i = 0; i < newLinks.length; i++) {
  637. if (newLinks[i].className.match(/\bsmgm_ytTitle\b/) == null)
  638. {
  639. vc++;
  640. var theURL;
  641. if (newLinks[i].href.match('/t.co/') && newLinks[i].getAttribute("data-expanded-url") != null)
  642. theURL = unescape(newLinks[i].getAttribute("data-expanded-url"));
  643. else if (newLinks[i].href.match('/t.co/') && newLinks[i].getAttribute("data-full-url") != null)
  644. theURL = unescape(newLinks[i].getAttribute("data-full-url"));
  645. else
  646. theURL = unescape(newLinks[i].href);
  647. (newLinks[i].className == "") ? newLinks[i].className = "smgm_ytTitle" : newLinks[i].className = newLinks[i].className + " smgm_ytTitle";
  648. if (!theURL.match(/liveleak/i))
  649. {
  650. vidlink = theURL.match(/youtube\.com\/watch/) ? theURL.match(/youtube\.com\/watch.*?\?.*v=([-_A-Za-z0-9]{11})/)[1] : theURL.match(/youtu\.be\/([-_A-Za-z0-9]{11})/)[1];
  651. youtubelink = "http://www.youtube.com/watch?v=" + vidlink;
  652. if (theURL.match(/#(.*?)$/)) youtubelink += '#' + theURL.match(/#(.*?)$/)[1];
  653. newLinks[i].href = youtubelink;
  654. addtitle(newLinks[i], vc, vidlink);
  655. }
  656. else //liveleak
  657. {
  658. vidlink = theURL.match(/view\?i=([-_A-Za-z0-9]{14})/)[1];
  659. addtitleLL(newLinks[i],vc,vidlink);
  660. }
  661. }
  662. }
  663. }
  664. }, 200);}
  665. , false);
  666.