Youtube Repeat button

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

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

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