Advertisement
Guest User

Untitled

a guest
Jul 1st, 2021
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.67 KB | None | 0 0
  1. The script is (has been) using plain JavaScript, with the exception of unsafeWindow mapped to window which in reality means the window in the userscript is the same window as the page (as would be the case for userscripts injected into page context).
  2.  
  3. At the moment ...
  4. In case of GM & FM, userscript is injected into page context
  5. In case of TM, it is injected into content context and then mapped to page window via unsafeWindow
  6. In case of VM, since VM by default injects into page context, the script works but can break if VM default is changed to content`
  7.  
  8. Considering all above, the userscript developer could have opted to inject into page context all the time and there would have been no need for @grant unsafeWindow and it would have worked the same way on all userscript managers.
  9.  
  10. UserScript Injection into Page Context:
  11. TM automatically injects into page context if @grant none
  12. FM automatically injects into page context if @inject-into page
  13. VM automatically injects into page context if @inject-into page
  14. GM is the only one that needs manual injection via <script> tag
  15.  
  16. Therefore, the following would simply take care of FM|TM|VM
  17. Using the built-in feature would make the code slightly simpler.
  18. There is also a slight improvement in performance/memory-use.
  19.  
  20. The original code:
  21. Code is injected into content context and evaluated
  22. Then a copy of the code is injected into page context and evaluated in page context
  23.  
  24. Using Built-in Feature:
  25. Code is injected into page context and evaluated in page context
  26. As you can see above, in the first method, 2 sets/copies of the code will exist and be evaluated/parsed, once in context and once in page, while in the second method, only one set.
  27.  
  28. Note: It is also recommended to use the more robust @match instead of @include
  29.  
  30. Actually, the GM compatibility of the script is only for legacy GM3 since there is no GM_info in GM4 (someone might want to mention it to the dev).
  31. GM_Info is no longer supported by GM (since 2017).
  32.  
  33. // ==UserScript==
  34. // @name Disable YouTube Video Ads
  35. // @namespace DisableYouTubeVideoAds
  36. // @version 1.2.27
  37. // @license AGPLv3
  38. // @author jcunews
  39. // @website https://greasyfork.org/en/users/85671-jcunews
  40. // @description Disable YouTube video & screen based ads at home page, and right before or in the middle of the main video playback. For new YouTube layout (Polymer) only.
  41. // @match https://www.youtube.com/*
  42. // @grant none
  43. // @run-at document-start
  44. // @inject-into page
  45. // ==/UserScript==
  46.  
  47. (() => {
  48.  
  49. let fn = (a, ipse, haia, hca, rpo, et) => {
  50.  
  51. if ((a = document.scripts[document.scripts.length - 1]) && (a.id === "dyvaUjs")) a.remove();
  52.  
  53. et = window.InstallTrigger ? "beforescriptexecute" : "message"; //Firefox workaround
  54.  
  55. JSON.parse_dyva = JSON.parse;
  56. JSON.parse = function(a) {
  57. var m, z;
  58. if (rpo) {
  59. a = rpo; //JSON.parse_dyva(a); //from xhr/fetch
  60. try {
  61. if (a.forEach) {
  62. a.forEach((p, a) => {
  63. if (p.player && p.player.args && p.player.args.player_response) {
  64. a = p.player_response_; //JSON.parse_dyva(p.player_response);
  65. patchPlayerResponse(a);
  66. p.player_response = JSON.stringify(a);
  67. } else if (p.playerResponse) {
  68. patchPlayerResponse(p.playerResponse);
  69. }
  70. });
  71. } else patchPlayerResponse(a);
  72. } catch(z) {}
  73. rpo = null;
  74. } else {
  75. a = JSON.parse_dyva(a);
  76. if (a.playerResponse) patchPlayerResponse(a.playerResponse);
  77. }
  78. return a;
  79. };
  80.  
  81. var ftc = window.fetch_dyva = window.fetch;
  82. window.fetch = function(u) {
  83. if (u) {
  84. if (u.substr && /\/v1\/player\/ad_break/.test(u)) return new Promise(() => {});
  85. if (u.url && u.url.substr && /\/v1\/player\/ad_break/.test(u.url)) return new Promise(() => {});
  86. }
  87. return ftc.apply(this, arguments);
  88. };
  89.  
  90. var rj = Response.prototype.json_dyva = Response.prototype.json;
  91. Response.prototype.json = function() {
  92. var rs = this, p = rj.apply(this, arguments), pt = p.then;
  93. p.then = function(fn) {
  94. var fn_ = fn;
  95. fn = function(j) {
  96. if (/\/v1\/player\?/.test(rs.url)) rpo = j;
  97. if ("function" === typeof fn_) return fn_.apply(this, arguments);
  98. };
  99. return pt.apply(this, arguments);
  100. };
  101. return p;
  102. };
  103. var rt = Response.prototype.text;
  104. Response.prototype.text = function() {
  105. var rs = this, p = rt.apply(this, arguments), pt = p.then;
  106. p.then = function(fn) {
  107. var fn_ = fn;
  108. fn = function(t) {
  109. if (/\/v1\/player\?/.test(rs.url)) rpo = JSON.parse_dyva(t);
  110. if ("function" === typeof fn_) return fn_.apply(this, arguments);
  111. };
  112. return pt.apply(this, arguments);
  113. };
  114. return p;
  115. };
  116.  
  117. window.XMLHttpRequest.prototype.open_dyva = window.XMLHttpRequest.prototype.open;
  118. window.XMLHttpRequest.prototype.open = function(mtd, url) {
  119. if (!(/get_midroll_info/).test(url) && !((/^\/watch/).test(location.pathname) && (/get_video_info/).test(url))) {
  120. this.url_dyva = url;
  121. return this.open_dyva.apply(this, arguments);
  122. }
  123. };
  124. window.XMLHttpRequest.prototype.addEventListener_dyva = window.XMLHttpRequest.prototype.addEventListener;
  125. window.XMLHttpRequest.prototype.addEventListener = function(typ, fn) {
  126. if (typ === "readystatechange") {
  127. var f = fn;
  128. fn = function() {
  129. var z;
  130. if ((this.readyState === 4) && (/\/watch\?|get_video_info/).test(this.url_dyva)) {
  131. rpo = JSON.parse_dyva(this.responseText);
  132. try {
  133. rpo.forEach(p => {
  134. if (p.player && p.player.args && p.player.args.player_response) {
  135. p.playerResponse_ = JSON.parse_dyva(p.player_response);
  136. if (p.playerResponse_.playabilityStatus && (p.playerResponse_.playabilityStatus.status === "LOGIN_REQUIRED")) {
  137. nav.navigate({commandMetadata: {webCommandMetadata: {url: location.href, webPageType: "WEB_PAGE_TYPE_BROWSE"}}}, false);
  138. return;
  139. }
  140. patchPlayerResponse(p.playerResponse_);
  141. p.player_response = JSON.stringify(p.playerResponse_);
  142. } else if (p.playerResponse) {
  143. patchPlayerResponse(p.playerResponse);
  144. }
  145. });
  146. } catch(z) {}
  147. }
  148. return f.apply(this, arguments);
  149. };
  150. }
  151. return this.addEventListener_dyva.apply(this, arguments);
  152. };
  153.  
  154. var img = window.Image, imgsrc = Object.getOwnPropertyDescriptor(HTMLImageElement.prototype, "src");
  155. window.Imageq = function() {
  156. var r = new img();
  157. Object.defineProperty(r, "src", {
  158. get: function() {
  159. return imgsrc.get.apply(this, arguments);
  160. },
  161. set: function(v) {
  162. if (/\/pagead\/|\/ads\?/.test(v)) return v;
  163. return imgsrc.set.apply(this, arguments);
  164. }
  165. });
  166. return r;
  167. };
  168.  
  169. window.Node.prototype.appendChild_dyva = window.Node.prototype.appendChild;
  170. window.Node.prototype.appendChild = function(node) {
  171. var a;
  172. if (!ipse && (a = document.querySelector('ytd-watch-flexy')) && (a = a.constructor.prototype) && a.isPlaShelfEnabled_) {
  173. a.isPlaShelfEnabled_ = () => false;
  174. ipse = true;
  175. }
  176. if ((!hca || !haia) && (a = document.querySelector('ytd-watch-next-secondary-results-renderer')) && (a = a.constructor.prototype)) {
  177. if (a.hasAllowedInstreamAd_ && !haia) {
  178. a.hasAllowedInstreamAd_ = () => false;
  179. haia = true;
  180. }
  181. if (a.hasCompanionAds_ && !hca) {
  182. a.hasCompanionAds_ = () => false;
  183. hca = true;
  184. }
  185. }
  186. if ((node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) && Array.from(node.childNodes).some((n, i) => {
  187. if (n.id === "masthead-ad") {
  188. n.remove();
  189. return true;
  190. }
  191. })); //window.Node.prototype.appendChild = window.Node.prototype.appendChild_dyva;
  192. if (node.querySelector && (a = node.querySelector('.ytp-ad-skip-button'))) a.click();
  193. return this.appendChild_dyva.apply(this, arguments);
  194. };
  195.  
  196. function patchPlayerResponse(playerResponse) {
  197. if (playerResponse.adPlacements) playerResponse.adPlacements = [];
  198. if (playerResponse.playerAds) playerResponse.playerAds = [];
  199. }
  200.  
  201. function patchPlayerArgs(args, a) {
  202. if (args.ad_device) args.ad_device = "0";
  203. if (args.ad_flags) args.ad_flags = 0;
  204. if (args.ad_logging_flag) args.ad_logging_flag = "0";
  205. if (args.ad_preroll) args.ad_preroll = "0";
  206. if (args.ad_slots) delete args.ad_slots;
  207. if (args.ad_tag) delete args.ad_tag;
  208. if (args.ad3_module) args.ad3_module = "0";
  209. if (args.adsense_video_doc_id) delete args.adsense_video_doc_id;
  210. if (args.afv) args.afv = false;
  211. if (args.afv_ad_tag) delete args.afv_ad_tag;
  212. if (args.allow_html5_ads) args.allow_html5_ads = 0;
  213. if (args.csi_page_type) args.csi_page_type = args.csi_page_type.replace(/watch7ad/, "watch7");
  214. if (args.enable_csi) args.enable_csi = "0";
  215. if (args.pyv_ad_channel) delete args.pyv_ad_channel;
  216. if (args.show_pyv_in_related) args.show_pyv_in_related = false;
  217. if (args.vmap) delete args.vmap;
  218. if (args.player_response) {
  219. a = JSON.parse_dyva(args.player_response);
  220. patchPlayerResponse(a);
  221. args.player_response = JSON.stringify(a);
  222. }
  223. }
  224.  
  225. function patchSpf() {
  226. if (window.spf && !spf.request_dyva) {
  227. spf.request_dyva = spf.request;
  228. spf.request = function(a, b) {
  229. if (b && b.onDone) {
  230. var onDone_ = b.onDone;
  231. b.onDone = function(response) {
  232. var a = response;
  233. if (a && (/\/watch\?/).test(a.url) && (a = a.response) && (a = a.parts)) {
  234. a.forEach((p, a) => {
  235. if (p.player && p.player.args && p.player.args.player_response) {
  236. a = JSON.parse_dyva((p = p.player.args).player_response);
  237. patchPlayerResponse(a);
  238. p.player_response = JSON.stringify(a);
  239. } else if (p.playerResponse) {
  240. patchPlayerResponse(p.playerResponse);
  241. }
  242. });
  243. }
  244. return onDone_.apply(this, arguments);
  245. };
  246. }
  247. return this.request_dyva.apply(this, arguments);
  248. };
  249. return;
  250. }
  251. }
  252.  
  253. var ldh;
  254.  
  255. function do1(ev, a) {
  256.  
  257. if ((a = document.scripts[document.scripts.length - 1]) && /"adPlacements"/.test(a.text)) {
  258. a.text = a.text.replace(/"adPlacements"/, '"adPlacements":[],"zadPlacements"');
  259. }
  260. if (window.loadDataHook) {
  261. if (!window.loadDataHook.dyva) {
  262. ldh = window.loadDataHook;
  263. window.loadDataHook = function(ep, dt) {
  264. if (dt.playabilityStatus && (dt.playabilityStatus === "LOGIN_REQUIRED")) {
  265. location.href = location.href;
  266. throw "Ain't gonna login";
  267. }
  268. patchPlayerResponse(dt);
  269. return ldh.apply(this, arguments);
  270. };
  271. window.loadDataHook.dyva = true;
  272. }
  273. }
  274. if (window.ytcfg && window.ytcfg.set) {
  275. if (!window.ytcfg.set.dyva) {
  276. var ytcfgSet = window.ytcfg.set;
  277. window.ytcfg.set = function(ytConfig, ytValue){
  278. if (window.ytInitialPlayerResponse) {
  279. if (ytInitialPlayerResponse.playabilityStatus && (ytInitialPlayerResponse.playabilityStatus === "LOGIN_REQUIRED")) {
  280. location.href = location.href;
  281. throw "Ain't gonna login";
  282. }
  283. patchPlayerResponse(window.ytInitialPlayerResponse);
  284. }
  285. patchSpf();
  286. if (ytConfig) {
  287. var a;
  288. if (a = ytConfig.EXPERIMENT_FLAGS) {
  289. if (a.enable_auto_play_param_fix_for_masthead_ad) a.enable_auto_play_param_fix_for_masthead_ad = false;
  290. if (a.html5_check_both_ad_active_and_ad_info) a.html5_check_both_ad_active_and_ad_info = false;
  291. if (a.web_enable_ad_signals_in_it_context) a.web_enable_ad_signals_in_it_context = false;
  292. }
  293. if (ytConfig.SKIP_RELATED_ADS === false) ytConfig.SKIP_RELATED_ADS = true;
  294. if (ytConfig.TIMING_ACTION) ytConfig.TIMING_ACTION = ytConfig.TIMING_ACTION.replace(/watch7ad/, "watch7");
  295. if (a = ytConfig.TIMING_INFO) {
  296. if (a.yt_ad) a.yt_ad = 0;
  297. if (a.yt_ad_an) delete a.yt_ad_an;
  298. if (a.yt_ad_pr) a.yt_ad_pr = 0;
  299. }
  300. if (
  301. (a = ytConfig.WEB_PLAYER_CONTEXT_CONFIGS) && (a = a.WEB_PLAYER_CONTEXT_CONFIG_ID_KEVLAR_WATCH) &&
  302. a.serializedExperimentFlags && a.serializedExperimentFlags.replace
  303. ) {
  304. a.serializedExperimentFlags = a.serializedExperimentFlags.replace(
  305. /([a-z][^=]+)=([^&]+)/g, (s, a, b) => {
  306. switch (a) {
  307. case "enable_ad_break_end_time_on_pacf_tvhtml5":
  308. case "enable_auto_play_param_fix_for_masthead_ad":
  309. case "html5_check_both_ad_active_and_ad_info": b = false; break;
  310. case "web_enable_ad_signals_in_it_context":
  311. case "web_player_gvi_wexit_adunit": b = false; break;
  312. }
  313. return a + "=" + b;
  314. }
  315. );
  316. }
  317. }
  318. return ytcfgSet.apply(this, arguments);
  319. };
  320. window.ytcfg.set.dyva = true;
  321. }
  322. }
  323. if (window.yt) {
  324. if (window.yt.player && window.yt.player.Application) {
  325. if (window.yt.player.Application.create) {
  326. if (!window.yt.player.Application.create.dyva) {
  327. var ytPlayerApplicationCreate = window.yt.player.Application.create;
  328. window.yt.player.Application.create = function(id, ytPlayerConfig) {
  329. if ((id === "player-api") && ytPlayerConfig && ytPlayerConfig.args) {
  330. if (ytPlayerConfig.args.raw_player_response) patchPlayerResponse(ytPlayerConfig.args.raw_player_response);
  331. if (ytPlayerConfig.args.vmap) delete ytPlayerConfig.args.vmap;
  332. }
  333. return ytPlayerApplicationCreate.apply(this, arguments);
  334. };
  335. window.yt.player.Application.create.dyva = true;
  336. }
  337. }
  338. if (window.yt.player.Application.createAlternate) {
  339. if (!window.yt.player.Application.createAlternate.dyva) {
  340. var ytPlayerApplicationCreateAlternate = window.yt.player.Application.createAlternate;
  341. window.yt.player.Application.createAlternate = function(id, ytPlayerConfig) {
  342. if ((id === "player-api") && ytPlayerConfig && ytPlayerConfig.args) {
  343. if (ytPlayerConfig.args.raw_player_response) patchPlayerResponse(ytPlayerConfig.args.raw_player_response);
  344. if (ytPlayerConfig.args.vmap) delete ytPlayerConfig.args.vmap;
  345. }
  346. return ytPlayerApplicationCreateAlternate.apply(this, arguments);
  347. };
  348. window.yt.player.Application.createAlternate.dyva = true;
  349. }
  350. }
  351. }
  352. if (window.yt.setConfig) {
  353. if (!window.yt.setConfig.dyva) {
  354. var ytSetConfig = window.yt.setConfig;
  355. window.yt.setConfig = function(ytConfig){
  356. if (ytConfig && ytConfig.ADS_DATA) delete ytConfig.ADS_DATA;
  357. return ytSetConfig.apply(this, arguments);
  358. };
  359. window.yt.setConfig.dyva = true;
  360. }
  361. }
  362. }
  363. if (window.ytplayer && window.ytplayer.config && window.ytplayer.config.args) {
  364. if (!window.ytplayer.config.args.dvya) {
  365. patchPlayerArgs(window.ytplayer.config.args);
  366. window.ytplayer.config.args.dvya = true;
  367. }
  368. }
  369. }
  370. addEventListener(et, do1);
  371. if (et === "message") postMessage({});
  372. do1();
  373.  
  374. addEventListener("spfpartprocess", function(ev) { //old youtube
  375. if (ev.detail && ev.detail.part && ev.detail.part.data &&
  376. ev.detail.part.data.swfcfg && ev.detail.part.data.swfcfg.args) {
  377. patchPlayerArgs(ev.detail.part.data.swfcfg.args);
  378. }
  379. }, true);
  380.  
  381. addEventListener("load", a => {
  382. if (!(a = window.ayvp_cssOverride)) {
  383. a = document.createElement("STYLE");
  384. a.id = "ayvp_cssOverride";
  385. a.innerHTML = `\/*
  386. .video-ads{display:none!important}
  387. .ytp-ad-overlay-open .caption-window.ytp-caption-window-bottom{margin-bottom:4em}
  388. .ytp-autohide .caption-window.ytp-caption-window-bottom, .ytp-hide-controls .caption-window.ytp-caption-window-bottom{margin-bottom:0!important}`;
  389. document.documentElement.appendChild(a);
  390. }
  391. if (et === "message") {
  392. if (document.readyState !== "complete") {
  393. postMessage({});
  394. } else removeEventListener(et, do1);
  395. }
  396. });
  397. };
  398. if ((GM_info || GM?.info)?.scriptHandler === 'Greasemonkey') { // Optional chaining FF74+, Chrome 80+
  399. // Greasemonkey workaround for compatibility with the original (unrestricted) Greasemonkey version.
  400. const e = document.createElement("SCRIPT");
  401. e.id = "dyvaUjs";
  402. e.text = "(" + fn + ")()";
  403. document.documentElement.appendChild(e);
  404. } else fn();
  405.  
  406. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement