Youtube Repeat button

Youtube動画プレイヤーにリピートボタンをつける(html5プレイヤーのみ動作)

当前为 2015-11-16 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Youtube Repeat button
  3. // @namespace
  4. // @version 0.1
  5. // @description Youtube動画プレイヤーにリピートボタンをつける(html5プレイヤーのみ動作)
  6. // @author Nobby
  7. // @match https://www.youtube.com/watch*
  8. // @grant GM_setValue
  9. // @grant GM_getValue
  10. // ==/UserScript==
  11.  
  12. (function(){
  13. var video = document.querySelector('video');
  14. var repeat = GM_getValue('rpt',false);
  15. var control = document.getElementsByClassName('ytp-chrome-controls')[0];
  16. var yrb = document.createElement('button');
  17. var title = 'リピート';
  18. yrb.setAttribute('class', 'ytp-button ytp-repeat-button');
  19. yrb.setAttribute('style', 'float:right;');
  20.  
  21. var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
  22. svg.setAttribute('width', '100%');
  23. svg.setAttribute('height', '100%');
  24. svg.setAttribute('viewBox', '-128 -128 768 768');
  25. svg.setAttribute('version', '1.1');
  26. svg.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
  27. svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
  28.  
  29. var defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
  30.  
  31. var from = 'M363 363v0h0v0h0v0l0-0 0-0v0h0zM149 149v0h0v0h0v0l0 0-0 0v0h0zM469 256l-85 85v-64H64v-42h320v-64l85 85z';
  32. var to = 'M363 363v-86h42v128H149v64l-85-85 85-85v64h214zM149 149v86h-42V107h256V43l85 85-85 85v-64H149zM256 256l-0 0v-0H256v-0h0v-0l0 0z';
  33.  
  34. if(repeat){
  35. from = [to, to = from][0];
  36. video.setAttribute('loop', '');
  37. title = 'リピート解除';
  38. }
  39. yrb.setAttribute('title', title);
  40.  
  41. var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
  42. path.setAttribute('id', 'ytp-repeat');
  43. path.setAttribute('d', from);
  44.  
  45. var animate = document.createElementNS('http://www.w3.org/2000/svg', 'animate');
  46. animate.setAttribute('attributeType', 'XML');
  47. animate.setAttribute('attributeName', 'd');
  48. animate.setAttribute('fill', 'freeze');
  49. animate.setAttribute('dur', '0.2s');
  50. animate.setAttribute('keySplines', '.4 0 1 1');
  51. animate.setAttribute('repeatCount', '1');
  52. animate.setAttribute('begin', 'indefinite');
  53.  
  54. var use1 = document.createElementNS('http://www.w3.org/2000/svg', 'use');
  55. use1.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#ytp-repeat');
  56. use1.setAttribute('class', 'ytp-svg-shadow');
  57.  
  58. var use2 = document.createElementNS('http://www.w3.org/2000/svg', 'use');
  59. use2.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#ytp-repeat');
  60. use2.setAttribute('class', 'ytp-svg-fill');
  61.  
  62. path.appendChild(animate);
  63. defs.appendChild(path);
  64. svg.appendChild(defs);
  65. svg.appendChild(use1);
  66. svg.appendChild(use2);
  67. yrb.appendChild(svg);
  68.  
  69. control.appendChild(yrb);
  70.  
  71. var tooltext = document.getElementsByClassName('ytp-tooltip-text')[0];
  72. var tooltip = tooltext.parentNode.parentNode;
  73. var delay = null;
  74. yrb.addEventListener('mouseover', function(){
  75. yrb.removeAttribute('title');
  76. tooltip.setAttribute('aria-hidden', 'true');
  77. tooltip.setAttribute('class', 'ytp-tooltip ytp-bottom');
  78. delay = setTimeout(function() {
  79. tooltip.style.display = '';
  80. tooltext.textContent = title;
  81. var parentRect = video.getBoundingClientRect();
  82. var childRect = yrb.getBoundingClientRect();
  83. var tipRect = tooltip.getBoundingClientRect();
  84. var x_left = childRect.left - parentRect.left + (childRect.width - tipRect.width)/2;
  85. tooltip.setAttribute('style', 'left:'+x_left+'px');
  86. tooltip.removeAttribute('aria-hidden');
  87. }, 500);
  88. }, false);
  89. yrb.addEventListener('mouseleave', function(){
  90. clearTimeout(delay);
  91. tooltip.style.display = 'none';
  92. tooltip.setAttribute('aria-hidden', 'true');
  93. yrb.setAttribute('title', title);
  94. }, false);
  95. yrb.addEventListener('click', function(){
  96. if(repeat){
  97. video.removeAttribute('loop');
  98. title = 'リピート';
  99. }else{
  100. video.setAttribute('loop', '');
  101. title = 'リピート解除';
  102. }
  103. repeat = !repeat;
  104. tooltext.textContent = title;
  105. var parentRect = video.getBoundingClientRect();
  106. var childRect = yrb.getBoundingClientRect();
  107. var tipRect = tooltip.getBoundingClientRect();
  108. var x_left = childRect.left - parentRect.left + (childRect.width - tipRect.width)/2;
  109. tooltip.setAttribute('style', 'left:'+x_left+'px');
  110. setTimeout(function() {
  111. animate.setAttribute('from', from);
  112. animate.setAttribute('to', to);
  113. animate.beginElement();
  114. from = [to, to = from][0];
  115. }, 50);
  116. }, false);
  117. window.onbeforeunload = function(){
  118. GM_setValue('rpt',repeat);
  119. };
  120. })();