YouTube Embedded Popupper

You can pop up embeded videos by right click. (It may require permission for pop up blocker at the first pop)

目前為 2019-03-16 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name YouTube Embedded Popupper
  3. // @name:ja YouTube Embedded Popupper
  4. // @namespace knoa.jp
  5. // @description You can pop up embeded videos by right click. (It may require permission for pop up blocker at the first pop)
  6. // @description:ja YouTubeの埋め込み動画を、右クリックからポップアップで開けるようにします。(初回のみポップアップブロックの許可が必要かもしれません)
  7. // @include https://www.youtube.com/embed/*
  8. // @include https://www.youtube-nocookie.com/embed/*
  9. // @version 2.1.0
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. (function (){
  14. const SCRIPTNAME = 'YouTubeEmbeddedPopupper';
  15. const DEBUG = false;
  16. console.time(SCRIPTNAME);
  17. const POPUPWIDTH = 960;/* width of popup window (height depends on the width) */
  18. const POPUPTOP = 'CENTER';/* position top of popup window (DEFAULT,TOP,CENTER,BOTTOM) */
  19. const POPUPLEFT = 'CENTER';/* position left of popup window (DEFAULT,LEFT,CENTER,RIGHT) */
  20. const INDICATORDURATION = 1000;/* duration for indicator animation (ms) */
  21. const PAUSEDELAY = 1000;/* delay video pause for popuping window (ms) */
  22. const POPUPTITLE = 'Right Click to Popup';/* shown on mouse hover */
  23. const PARAMS = [/* overwrite YouTube parameters via https://developers.google.com/youtube/player_parameters */
  24. 'autoplay=1',/* autoplay */
  25. 'controls=2',/* show controls */
  26. 'disablekb=0',/* enable keyboard control */
  27. 'fs=1',/* enable fullscreen */
  28. 'rel=0',/* not to show relative videos */
  29. 'popped=1',/* (original) prevent grandchild popup */
  30. ];
  31. let core = {
  32. initialize: function(){
  33. /* Prevent grandchild popup and enables shortcut keys on popupped window */
  34. if(location.href.includes('popped=1')) return setTimeout(function(){document.querySelector('video').focus();}, 100);
  35. /* Title for Indicator */
  36. document.body.title = POPUPTITLE;
  37. /* Right Click to Popup */
  38. document.body.addEventListener('contextmenu', function(e){
  39. /* Define elements */
  40. let video = document.querySelector('video');
  41. /* Stop playing */
  42. core.showAnimation();
  43. setTimeout(video.pause.bind(video), PAUSEDELAY);
  44. /* Get current time */
  45. let params = PARAMS.concat('start=' + Math.floor(video.currentTime + (PAUSEDELAY / 1000)));/* use params at local scope */
  46. /* Build URL */
  47. /* (Duplicated params are overwritten by former) */
  48. let l = location.href.split('?');
  49. let url = l[0] + '?' + params.join('&');
  50. if(l.length === 2) url += ('&' + l[1]);
  51. /* Open popup window */
  52. /* (Use URL for window name to prevent popupping the same videos) */
  53. window.open(url, location.href, core.setOptions());
  54. e.preventDefault();
  55. e.stopPropagation();
  56. }, {capture: true});
  57. },
  58. setOptions: function(){
  59. let parameters = [], screen = window.screen, body = document.body, width = POPUPWIDTH, height = (width / body.offsetWidth) * body.offsetHeight;
  60. parameters.push('width=' + width);
  61. parameters.push('height=' + height);
  62. switch(POPUPTOP){
  63. case 'TOP': parameters.push('top=' + 0); break;
  64. case 'CENTER': parameters.push('top=' + (screen.availTop + (screen.availHeight / 2) - (height / 2))); break;
  65. case 'BOTTOM': parameters.push('top=' + (screen.availTop + (screen.availHeight) - (height))); break;
  66. case 'DEFAULT': break;
  67. default: break;
  68. }
  69. switch(POPUPLEFT){
  70. case 'LEFT': parameters.push('left=' + 0); break;
  71. case 'CENTER': parameters.push('left=' + (screen.availLeft + (screen.availWidth / 2) - (width / 2))); break;
  72. case 'RIGHT': parameters.push('left=' + (screen.availLeft + (screen.availWidth) - (width))); break;
  73. case 'DEFAULT': break;
  74. default: break;
  75. }
  76. return parameters.join(',');
  77. },
  78. showAnimation: function(e){
  79. let ready = document.createElement('div');
  80. ready.style.position = 'absolute';
  81. ready.style.margin = 'auto';
  82. ready.style.top = ready.style.bottom = ready.style.left = ready.style.right = '-100%';
  83. ready.style.width = ready.style.height = '0px';
  84. ready.style.borderRadius = '0px';
  85. ready.style.background = 'rgba(255,255,255,1.0)';
  86. ready.style.transitionDuration = INDICATORDURATION + 'ms';
  87. ready.addEventListener('transitionend', function(){
  88. document.body.removeChild(ready);
  89. });
  90. document.body.appendChild(ready);
  91. requestAnimationFrame(function(){
  92. let size = Math.hypot(document.body.clientWidth, document.body.clientHeight);
  93. ready.style.width = ready.style.height = size + 'px';
  94. ready.style.borderRadius = size + 'px';
  95. ready.style.background = 'rgba(255,255,255,0.0)'
  96. });
  97. },
  98. };
  99. let log = (DEBUG) ? console.log.bind(null, SCRIPTNAME + ':') : function(){};
  100. core.initialize();
  101. console.timeEnd(SCRIPTNAME);
  102. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址