🏠 Home 

Greasy Fork is available in English.

LinkTube

Replaces an embedded video with a link to the video page.

  1. // ==UserScript==
  2. // @name LinkTube
  3. // @version 2019.11.25
  4. // @description Replaces an embedded video with a link to the video page.
  5. // @author sebaro
  6. // @namespace http://sebaro.pro/linktube
  7. // @icon https://gitlab.com/sebaro/linktube/raw/master/linktube.png
  8. // @include *
  9. // ==/UserScript==
  10. /*
  11. Copyright (C) 2011 - 2019 Sebastian Luncan
  12. This program is free software: you can redistribute it and/or modify
  13. it under the terms of the GNU General Public License as published by
  14. the Free Software Foundation, either version 3 of the License, or
  15. (at your option) any later version.
  16. This program is distributed in the hope that it will be useful,
  17. but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. GNU General Public License for more details.
  20. You should have received a copy of the GNU General Public License
  21. along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. Website: http://sebaro.pro/linktube
  23. Contact: http://sebaro.pro/contact
  24. */
  25. (function() {
  26. // ==========Variables========== //
  27. // Userscript
  28. var userscript = 'LinkTube';
  29. // Page
  30. var page = {win: window, doc: window.document, url: window.location.href};
  31. // Contact
  32. var contact = 'http://sebaro.pro/contact';
  33. // Warning
  34. var warning = 'Couldn\'t get the video link. Please report it <a href="' + contact + '">here</a>.';
  35. // Options
  36. var option = {'secure': true};
  37. // ==========Fixes========== //
  38. // Don't run on frames or iframes
  39. if (window.top != window.self) return;
  40. // ==========Functions========== //
  41. function createMyElement(type, content) {
  42. var obj = document.createElement(type);
  43. if (type == 'div') {
  44. if (content) obj.innerHTML = content;
  45. }
  46. return obj;
  47. }
  48. function getMyElement(element, get, tag) {
  49. var obj;
  50. if (get == 'parent') obj = element.parentNode;
  51. else if (get == 'source') {
  52. obj = element.src;
  53. if (!obj) {
  54. for (var i = 0; i < element.attributes.length; i++) {
  55. if (element.attributes[i].name.match(/^data.*src$/)) {
  56. obj = element.attributes[i].value;
  57. break;
  58. }
  59. }
  60. }
  61. }
  62. else if (get == 'name') obj = element.name;
  63. else if (get == 'value') obj = element.value;
  64. else if (get == 'children') obj = element.getElementsByTagName(tag);
  65. return obj;
  66. }
  67. function modifyMyElement(obj, type, content, clear) {
  68. if (type == 'div') {
  69. if (content) obj.innerHTML = content;
  70. }
  71. if (clear) {
  72. if (obj.hasChildNodes()) {
  73. while (obj.childNodes.length >= 1) {
  74. obj.removeChild(obj.firstChild);
  75. }
  76. }
  77. }
  78. }
  79. function styleMyElement(obj, styles) {
  80. for (var property in styles) {
  81. if (styles.hasOwnProperty(property)) obj.style[property] = styles[property];
  82. }
  83. }
  84. function appendMyElement(parent, child) {
  85. if (parent == 'body') document.body.appendChild(child);
  86. else parent.appendChild(child);
  87. }
  88. function removeMyElement(parent, child) {
  89. if (parent == 'body') document.body.removeChild(child);
  90. else parent.removeChild(child);
  91. }
  92. function replaceMyElement(parent, orphan, child) {
  93. parent.replaceChild(orphan, child);
  94. }
  95. function embedMyLinks(element) {
  96. var elements;
  97. if (element == 'iframe') elements = iframeElements;
  98. else if (element == 'object') elements = objectElements;
  99. else if (element == 'embed') elements = embedElements;
  100. var child, parent, video, param, name;
  101. var foundSite;
  102. var linkID, videoID, videoLink, videoURL;
  103. var myScriptLogo = [];
  104. myScriptLogo[element] = [];
  105. var myScriptMess = [];
  106. myScriptMess[element] = [];
  107. var myLinkWindow = [];
  108. myLinkWindow[element] = [];
  109. for (var e = elements.length - 1; e >= 0; e--) {
  110. foundSite = false;
  111. child = elements[e];
  112. parent = getMyElement(child, 'parent', '');
  113. if (element == 'iframe' || element == 'embed') {
  114. video = getMyElement(child, 'source', '');
  115. }
  116. else if (element == 'object') {
  117. params = getMyElement(child, 'children', 'param');
  118. for (var p = 0; p < params.length; p++) {
  119. name = getMyElement(params[p], 'name', '');
  120. if (name == 'movie' || name == 'src' || name == 'flashvars') {
  121. video = getMyElement(params[p], 'value', '');
  122. if (!video) video = getMyElement(params[p], 'source', '');
  123. }
  124. }
  125. }
  126. if (video) {
  127. for (var l = 0; l < linkParsers.length; l++) {
  128. if (video.match(linkParsers[l]['source'])) {
  129. foundSite = true;
  130. linkID = l;
  131. break;
  132. }
  133. }
  134. }
  135. if (foundSite) {
  136. myScriptLogo[element][e] = createMyElement('div', userscript);
  137. styleMyElement(myScriptLogo[element][e], {margin: '0px auto', padding: '10px', color: '#FFFFFF', fontSize: '20px', textAlign: 'center', textShadow: '#000000 -1px 1px 1px'});
  138. myScriptMess[element][e] = createMyElement('div', '');
  139. myLinkWindow[element][e] = createMyElement('div', '');
  140. appendMyElement(myLinkWindow[element][e], myScriptLogo[element][e]);
  141. appendMyElement(myLinkWindow[element][e], myScriptMess[element][e]);
  142. var childStyles = child.getAttribute('style');
  143. if (childStyles) {
  144. childStyles = childStyles.replace('absolute', 'relative');
  145. myLinkWindow[element][e].setAttribute('style', childStyles);
  146. styleMyElement(myLinkWindow[element][e], {border: '3px solid #F4F4F4', backgroundColor: 'transparent'});
  147. }
  148. else styleMyElement(myLinkWindow[element][e], {width: '100%', height: '100%', border: '3px solid #F4F4F4', backgroundColor: 'transparent'});
  149. styleMyElement(parent, {padding: '0px', height: '100%'});
  150. replaceMyElement(parent, myLinkWindow[element][e], child);
  151. videoID = video.match(linkParsers[linkID]['pattern']);
  152. videoID = (videoID) ? videoID[1] : null;
  153. if (videoID) {
  154. videoURL = linkParsers[linkID]['link'] + videoID;
  155. if (!option['secure']) videoURL = videoURL.replace(/^https/, 'http');
  156. videoLink = '<a href="' + videoURL + '" style="color:#336699;text-decoration:none;">' + videoURL + '</a>';
  157. styleMyElement(myScriptMess[element][e], {border: '1px solid #F4F4F4', margin: '5px', padding: '5px', backgroundColor: '#FFFFFF', color: '#00C000', textAlign: 'center', fontSize: '16px'});
  158. modifyMyElement(myScriptMess[element][e], 'div', videoLink, false);
  159. }
  160. else {
  161. styleMyElement(myScriptMess[element][e], {border: '1px solid #F4F4F4', margin: '5px', padding: '5px', backgroundColor: '#FFFFFF', color: '#AD0000', textAlign: 'center', fontSize: '16px'});
  162. modifyMyElement(myScriptMess[element][e], 'div', warning, false);
  163. }
  164. }
  165. }
  166. }
  167. // ==========Websites========== //
  168. /* Parsers */
  169. var linkParsers = [
  170. {'source': 'youtube(.com|-nocookie.com)/embed/(videoseries|\\?list)', 'pattern': 'list=(.*?)(&|$)', 'link': 'https://www.youtube.com/playlist?list='},
  171. {'source': 'youtube(.com|-nocookie.com)/embed/', 'pattern': '/embed/(.*?)(\\?|&|$)', 'link': 'https://www.youtube.com/watch?v='},
  172. {'source': 'youtube(.com|-nocookie.com)/v/', 'pattern': '/v/(.*?)(\\?|&|$)', 'link': 'https://www.youtube.com/watch?v='},
  173. {'source': 'dailymotion.com/embed/', 'pattern': '/video/(.*?)$', 'link': 'https://www.dailymotion.com/video/'},
  174. {'source': 'dailymotion.com/swf/(?!video)', 'pattern': '/swf/(.*?)$', 'link': 'https://www.dailymotion.com/video/'},
  175. {'source': 'dailymotion.com/swf/(?=video)', 'pattern': '/video/(.*?)$', 'link': 'https://www.dailymotion.com/video/'},
  176. {'source': 'vimeo.com/video/', 'pattern': '/video/(.*?)(\\?|&|$)', 'link': 'https://vimeo.com/'},
  177. {'source': 'vimeo.com/moogaloop', 'pattern': '/moogaloop.swf\\?clip_id=(.*?)(&|$)', 'link': 'https://vimeo.com/'},
  178. {'source': 'metacafe.com/embed/', 'pattern': '/embed/(.*?)/', 'link': 'https://www.metacafe.com/watch/'},
  179. {'source': 'metacafe.com/fplayer/', 'pattern': '/fplayer/(.*?)/', 'link': 'https://www.metacafe.com/watch/'},
  180. {'source': 'funnyordie.com/embed/', 'pattern': '/embed/(.*?)$', 'link': 'https://www.funnyordie.com/videos/'},
  181. {'source': 'vk.com/video', 'pattern': 'video_ext.php\\?(.*?)$', 'link': 'http://vk.com/video_ext.php?'},
  182. {'source': 'hostname=www.twitch.tv', 'pattern': 'channel=(.*?)(&|$)', 'link': 'http://www.twitch.tv/'}
  183. ];
  184. var iframeElements;
  185. var objectElements;
  186. var embedElements;
  187. function LinkTube() {
  188. /* IFrame */
  189. iframeElements = getMyElement(document, 'children', 'iframe');
  190. if (iframeElements.length > 0 ) embedMyLinks('iframe');
  191. /* Object */
  192. objectElements = getMyElement(document, 'children', 'object');
  193. if (objectElements.length > 0 ) embedMyLinks('object');
  194. /* Embed */
  195. embedElements = getMyElement(document, 'children', 'embed');
  196. if (embedElements.length > 0 ) embedMyLinks('embed');
  197. }
  198. // ==========Run========== //
  199. LinkTube();
  200. page.win.setInterval(function() {
  201. if (page.url != page.win.location.href) {
  202. page.doc = page.win.document;
  203. page.url = page.win.location.href;
  204. LinkTube();
  205. }
  206. }, 500);
  207. })();