ExtendPornHub

Remove ads, enlarges video, stops autoplay keeping buffering & block pop-ups

  1. // ==UserScript==
  2. // @author Jack_mustang
  3. // @version 3.0
  4. // @name ExtendPornHub
  5. // @description Remove ads, enlarges video, stops autoplay keeping buffering & block pop-ups
  6. // @date 2017 October 3
  7. // @include *pornhub.com/*
  8. // @include *pornhubpremium.com/*
  9. // @run-at document-start
  10. // @grant none
  11. // @license Public Domain
  12. // @icon https://gmgmla.dm2301.livefilestore.com/y2pAKJYeZAp4tG23hG68x1mRuEUQXqb1MxdLbuqVnyyuHFxC7ra5Fc-tfq6hD-r9cNnVufT3egUHaimL547xDlESrOVmQsqNSJ5gzaiSccLYzo/ExtendPornHub-logo.png
  13. // @namespace 649b97180995e878e7e91b2957ef3bbee0f840a0
  14. // ==/UserScript==
  15.  
  16. if (!!window.location.hostname.match(/premium/)) {
  17. (function ExtendPornHubPremium(){
  18. changePlayer();
  19. window.addEventListener("DOMContentLoaded", function(){
  20. if(document.querySelector("#player")) {
  21. videoFunctions();
  22. }
  23. }, false);
  24. })();
  25. return;
  26. }
  27.  
  28. // Block popups fallback
  29. function NoOpen() { return 1; }
  30. parent.open = NoOpen;
  31. this.open = NoOpen;
  32. window.open = NoOpen;
  33. open = NoOpen;
  34. window.open = function () { return; };
  35. open = function () { return; };
  36. this.open = function () { return; };
  37. parent.open = function () { return; };
  38.  
  39. function fnull() {
  40. return null;
  41. }
  42.  
  43. // Block ads
  44. Object.defineProperty(window, "adDelivery", {
  45. get: fnull,
  46. set: fnull
  47. });
  48. Object.defineProperty(window, "tj_ads", {
  49. get: fnull,
  50. set: fnull
  51. });
  52. Object.defineProperty(window, "tj_channels", {
  53. get: fnull,
  54. set: fnull
  55. });
  56.  
  57. window.EYP = {};
  58. // stop autoplay
  59. Object.defineProperty(window, "videoTimeTracking", {
  60. set: function (e) {
  61. // window.EYP.flashvars = ;
  62. Object.defineProperty(window, "flashvars_" + e.match(/\d+/)[0], {
  63. set: function (e) {
  64. e.autoplay = false;
  65. e.autoload = true;
  66. window.EYP.flashvars = e;
  67. },
  68. get: function () {
  69. return window.EYP.flashvars;
  70. }
  71. });
  72. window.EYP.videoTimeTracking = e;
  73. },
  74. get: function () {
  75. return window.EYP.videoTimeTracking;
  76. }
  77. });
  78.  
  79. (function addStyle() {
  80. // While <head> is not loaded we keep trying
  81. if (!document.querySelector("head")) {
  82. return setTimeout(addStyle, 50);
  83. }
  84.  
  85. // We create an object and start including its content to include in DOM at the end
  86. var ephcss =
  87. // Hide ads while we can't remove them
  88. "iframe, aside, figure," +
  89. // Ad area in gifs page
  90. // ".gifsWrapper > div:first-child," +
  91. // Video being watched in one line
  92. ".videos-being-watched.logInHotContainer li:last-child," +
  93. // Ad Block Message
  94. ".abAlertShown," +
  95. // Change language notice
  96. "#countryRedirectMessage {" +
  97. "display: none !important;" +
  98. "}" +
  99. // Pornstars page
  100. "ul.top_trending_pornstar {" +
  101. "display: table !important;" +
  102. "margin: auto !important;" +
  103. "}" +
  104. "ul.top_trending_pornstar li {" +
  105. "display: table-cell !important;" +
  106. "}" +
  107. ".sectionWrapper .pornstarVideosCounter {" +
  108. "width: 100% !important;" +
  109. "}" +
  110. // Gifs page
  111. ".gifsWrapper ul.gifs li.first {" +
  112. "margin-right: 12px !important;" +
  113. "margin-top: 0 !important;" +
  114. "height: 353px !important;" +
  115. "margin-bottom: 12px !important;" +
  116. "}" +
  117. "@media only screen and (min-width: 1350px) {" +
  118. ".gifsWrapper ul.gifs li.first {" +
  119. "height: 381px !important;" +
  120. "}" +
  121. ".gifsWrapper ul.gifs li:nth-child(8) {" +
  122. "display: none !important;" +
  123. "}" +
  124. "}" +
  125. ".gifColumnLeft.float-left {" +
  126. "width: 100% !important;" +
  127. "}";
  128.  
  129. // Inject created CSS
  130. var ephnode = document.createElement("style");
  131. ephnode.type = "text/css";
  132. ephnode.id = "EPH-style";
  133. ephnode.appendChild(document.createTextNode(ephcss));
  134. document.head.appendChild(ephnode);
  135. }());
  136.  
  137. (function ExtendPornHub() {
  138. // Scroll, keyboard shortcut
  139. function videoStuff() {
  140. // Scroll video to middle of page
  141. function scrollthere() {
  142. var player = document.getElementById("player");
  143. var vh = player.offsetHeight;
  144. var vd = document.querySelector(".container").offsetTop + document.querySelector(".container").parentNode.offsetTop + document.querySelector(".video-wrapper").offsetTop;
  145. var fh = window.innerHeight;
  146. var sc = vd - ((fh - vh) / 2);
  147. window.scrollTo(0, sc);
  148. // console.info("** ExtendPornHub **\ntop: " + vd + ", height: " + vh + ", scrolled: " + sc + ", window: " + fh);
  149. }
  150. // Inject this function to page
  151. var script = document.createElement("script");
  152. script.setAttribute("type", "text/javascript");
  153. script.innerHTML = scrollthere.toString();
  154. script.id = "EPH-scrollVid";
  155. document.body.appendChild(script);
  156. scrollthere();
  157.  
  158. // Keyboard Shortcut for centring
  159. window.addEventListener("keyup", function(e) {
  160. if (e.ctrlKey && e.altKey && (e.code === "KeyC" || (e.code === undefined && e.keyCode === 67))) {
  161. scrollthere();
  162. }
  163. }, false);
  164.  
  165. // Include button in right corner to center video on screen
  166. var node = document.createElement("div");
  167. node.setAttribute("style","position: fixed;" +
  168. "bottom: 0;" +
  169. "right: 0;" +
  170. "cursor: pointer;" +
  171. "border: 1px solid #313131;" +
  172. "border-top-left-radius: 5px;" +
  173. "color: #acacac;" +
  174. "font-weight: 700;" +
  175. "background: #2f2f2f;" +
  176. "text-align: center;" +
  177. "font-size: 12px;" +
  178. "padding: 7px 15px;" +
  179. "z-index: 999999;");
  180. node.setAttribute("onclick", "scrollthere();");
  181. node.setAttribute("title", "Use the keyboard shortcut Ctrl+Alt+C (For other keyboard layouts use the key where C should be on the QWERTY layout)");
  182. node.innerHTML = "Centre";
  183. node.id = "EPH-scroll";
  184. document.body.appendChild(node);
  185.  
  186. // Add video download when not logged
  187. if( document.body.classList[0].search("logged-in") < 0 ) {
  188. var tab = document.querySelector(".download-tab");
  189. var dwlinks = "";
  190.  
  191. for (var key in window.EYP.flashvars) {
  192. var quality = key.match(/quality_(\d+)p/);
  193. if (!!quality) {
  194. dwlinks += "<a class='downloadBtn greyButton' target='_blank' href='" + EYP.flashvars[key] + "'><i></i>" + (quality[1] > 700 ? "<span>HD</span> " : "") + quality[1] + "</a>"
  195. }
  196. }
  197.  
  198. tab.innerHTML = dwlinks;
  199. }
  200. }
  201.  
  202. var observer = new MutationObserver(function (changes) {
  203. changes.forEach(function (chg) {
  204. if (!!chg.target.className) {
  205. // remove ad spaces
  206. if (!!chg.target.className.match(/removeAdsStyle/)) {
  207. var node = chg.target.parentNode;
  208. if (!!node.parentNode.className.match(node.className.substr(0, node.className.length - 1))) {
  209. node = node.parentNode;
  210. }
  211. node.parentNode.removeChild(node);
  212. return;
  213. }
  214. // wide player
  215. if (!!chg.target.id.match(/\bplayer\b/)) {
  216. chg.target.className = "wide";
  217. return;
  218. }
  219. if (!!chg.target.id.match(/main-container/) && !!chg.previousSibling && !!chg.previousSibling.id && !!chg.previousSibling.id.match(/rightColVideoPage/)) {
  220. chg.previousSibling.className = "wide";
  221. return;
  222. }
  223. // update wide player button / HTML5 only
  224. if (!!chg.target.className.match(/mhp1138_front/)) {
  225. chg.target.childNodes.forEach(function (node) {
  226. if (!!node.className.match(/mhp1138_cinema/)) {
  227. node.className = "mhp1138_cinema mhp1138_cinemaState";
  228. return;
  229. }
  230. });
  231. return;
  232. }
  233. // centre video
  234. if (!!chg.target.className.match(/playerFlvContainer/)) {
  235. chg.addedNodes.forEach(function (element) {
  236. if (!!element && element.id === "pb_template") {
  237. var node = document.createElement("div");
  238. node.className = "mhp1138_playerStateIcon";
  239. node.setAttribute("style", "opacity: 1");
  240. node.innerHTML =
  241. "<div class='mhp1138_play' style='display: block'>" +
  242. " <div class='mhp1138_icon mhp1138_icon-play'></div>" +
  243. "</div>" +
  244. "<div class='mhp1138_background'></div>";
  245. element.appendChild(node);
  246.  
  247. videoStuff();
  248. return;
  249. }
  250. });
  251. }
  252. return;
  253. }
  254. });
  255. });
  256.  
  257. observer.observe(document, {childList: true, subtree: true});
  258. }());