AutoPagerize_Console

AutoPagerizeの操作系を拡張します。

当前为 2018-05-23 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name AutoPagerize_Console
  3. // @name:en AutoPagerize_Console
  4. // @description AutoPagerizeの操作系を拡張します。
  5. // @description:en Expansion Autopagerize operation.
  6. // @namespace phodra
  7. // @include *
  8. // @exclude https://www.youtube.com/*
  9. // @version 5.02
  10. // @noframes
  11. // @grant GM_getValue
  12. // @grant GM_setValue
  13. // @grant GM.getValue
  14. // @grant GM.setValue
  15. // ==/UserScript==
  16.  
  17. (()=>{
  18. // Greasemonkey 4.0未満バージョン対応
  19. if( this.GM == null ){
  20. this.GM = {};
  21. this.GM.getValue = async (name, defaultValue) => {
  22. return GM_getValue(name, defaultValue);
  23. };
  24. this.GM.setValue = async (name, value) => {
  25. return GM_setValue(name, value);
  26. };
  27. }
  28. // 拡張
  29. Array.prototype.first = function(){ return this[0]; };
  30. Array.prototype.last = function(){ return this[this.length-1]; };
  31. Array.prototype.round = function(i){ return this[i<0? 0: i>=this.length? this.length-1: i]; };
  32. Node.prototype.prependChild = function(elm){ this.insertBefore(elm,this.firstChild); };
  33. Element.prototype.css = function(arg1, arg2){
  34. if( arg2 == null){
  35. for( let key in arg1 ){
  36. this.style[key] = arg1[key];
  37. }
  38. }else{
  39. this.style[arg1] = arg2;
  40. }
  41. };
  42. Element.prototype.attr = function(arg1, arg2){
  43. if( arg2 == null){
  44. for( let key in arg1 ){
  45. this.setAttribute(key, arg1[key]);
  46. }
  47. }else{
  48. this.setAttribute(arg1, arg2);
  49. }
  50. };
  51. // 任意のイベントを発火
  52. const FireEvent = ename => {
  53. const e = document.createEvent('Event');
  54. e.initEvent( ename, true, false);
  55. return document.dispatchEvent(e);
  56. };
  57.  
  58.  
  59. // 画像をひとまとめにしておく
  60. const RES = {
  61. 'config': "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAC5SURBVCiRrZI9DsIwDIVfKsQIxyjlBNwC7lFWBq4AKyMrB0C9AGzcBlDFAAh9DE2rNKQoSDzJcvxsyz+x9C8ACTBy7AxIYhILKuRWAAo/rhfIHVi9CXANjK1iJO0lDSVNJPW9uIekk6SrpKkxhrq9MW3cgDWwBV6eL/Nnyx3nwuF3Dp/XfNe27h3vNgKtnoElsAKeoVZ/Xc5F0qxZjlf9wCeOflxoxtLquRWp+obvsCeXOnYadXKxeAMXu9O375dXpAAAAABJRU5ErkJggg==",
  62. 'scrAll': "data:image/png;base64,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6LY0xzroyiAbWQ7nyDd+ePiDFuKl3SBW3f8B8fP2P2is2c4AAABielRYdFJhdyBwcm9maWxlIHR5cGUgaXB0YwAAeNo9icENwDAMAv+eoiPY4KrpOrU//eXR/VUnUgJCAk7e/oUcUw5hc/jtqV7esrRQ8KraCCqNZwUkbZIo8tS28YwIck1V+QEwdRTPIeQRVwAACWppVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+Cjx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDQuNC4wLUV4aXYyIj4KIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgZGM6Rm9ybWF0PSJpbWFnZS9wbmciLz4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/PgD/gEAAAAAGYktHRAD/AP8A/6C9p5MAAAAJcEhZcwAADdcAAA3XAUIom3gAAAAHdElNRQffDB8MHyAdGHmgAAABB0lEQVQ4y72VLUuEQRRGz6wLKot/QBDNIghazDZBMAsGs2AxWv0V/gPDVvOCxaprsoomYVGLCMKxDDIOr/N+oPvALZd7mDv3YyYgndSDKYP93CFuARetQWAOWP63VENeVXEFOGwNdi5OncQBcATS2NQZ9VK1LXhuVBvo1ERNoQN/6q0JtK1+ZKB10Jr6YoVK0KL6kMQ+1YLqgnqTxD2qJynYq2hwHxgC69H1CuwAk7rJWQVG0QBGgXAnbhbBQBgD48q57rhW+/mlmvTyuFUfI7SrfuZgcR/FDeAKGETXBHgupqouZU0ffh8klAbgNoGu1fk05rcX4AyYBe5jenuB8P4nb870v4AvLySHS1xd+RoAAAAASUVORK5CYII=",
  63. 'scrPage': "data:image/png;base64,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CiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIGRjOkZvcm1hdD0iaW1hZ2UvcG5nIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgCjw/eHBhY2tldCBlbmQ9InciPz4A/4BAAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH3wwfDB8brBOQhAAAAPhJREFUOMvl1LEuREEUh/FvNisiSCRCIqGytQdR06oUFAqF91Do0NJrvIBaK6p9AZWEhGx8miXHdWfvzHbiJNPcO7/8586cuQmZqnrwV2C/FoibwC5I1VCvVGvRQB1NAy8cVw3aUN+/YM2ungAzcZtK0lbVV0OVJh4Dc82D6UpbUp9tVEniEbDY1gqT0ubVJ1uqK/EAWG57kXL3UZwFhsDa+NElcNa5VPUwrOxFXfkxJ4P66jDA01/zMnAvoDd1vROqPfUhwPPWz2mBOwGN1EEpvA/wOnvODbQd0Ie6VQrvAryZ1FXfDSAuAPuhB24T6THXUukf/Mk/Ac1knVlDqEQOAAAAAElFTkSuQmCC",
  64. 'disabled': "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADpSURBVCiRnZIxCsJAEEXfBo0IilhYWIgogo1W1mLnHTyFjVXOEkif1kKvYGsr2NhoaaVo8S2WsGoikiwss/NnHjvsfiMhCqxSctjvYbNxBd+HTgdmM2i1MkgJSSgMEaDBAE0mqN22ue+j1Qo9n7Yv2SlwvXbFywUtFlYPghyghB4P1O+jahVdr073/j1CuQzzOdxusNs5/S8I0O3aeD7nBI2xsVLJCR6PNg6HOcD7HbZb6PVgPHZ66TcChwMsl3A6QRyD935NlgFGI9Ro2LzZRFH0+UUSMolXvy1Xr9vxplOo1dLTmKImfwFplKHHjazaRQAAAABJRU5ErkJggg==",
  65. 'enabled': "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAACESURBVCiRzdIxDkFREIXh74lWh9BolBagYhU2o1CrWYtF2IyK/mokzPPmvRCFmWpOzp+592QqRfFF9cN0xDVxrrDOwD1uWDSA4zbQAzp3vlSv2/JjsAqpTnHBqOba4BCl9z/OsKtp86ad5aUnimVQ0v6HcLIDGOL0HGM4W/nJDdo2flB3ti8tcnms5h0AAAAASUVORK5CYII=",
  66. };
  67.  
  68.  
  69.  
  70. // スタイル
  71. const $style = document.createElement("style");
  72. $style.setAttribute("type", "text/css");
  73. $style.textContent = `
  74. #apc-panel *,
  75. #apc-config * {
  76. color: #eee;
  77. border-color: #666;
  78. }
  79. .apc-box,
  80. #apc-pageList,
  81. #apc-config {
  82. background-color: #1c1c1c !important;
  83. }
  84. .apc-button {
  85. filter: brightness(100%) contrast(150%);
  86. }
  87. #apc-enabler {
  88. filter: grayscale(100%);
  89. }
  90. #apc-panel[valid] #apc-enabler {
  91. filter: grayscale(60%);
  92. }
  93.  
  94.  
  95. /* コンソールパネル */
  96. #apc-panel {
  97. opacity: 0.6;
  98. background-color: transparent !important;
  99.  
  100. position: fixed;
  101. z-index: 9999999990;
  102. right: 0;
  103. /*top: 48px;*/
  104. margin: 0;
  105.  
  106. display: inline-flex;
  107. flex-direction: column;
  108. align-items: flex-end;
  109.  
  110. }
  111. #apc-panel[display_rule=valid]:not([valid]) {
  112. visibility: hidden;
  113. }
  114.  
  115. #apc-panel *,
  116. #apc-config * {
  117. font-family: arial, sans-serif;
  118. font-size: 14px;
  119. font-weight: normal;
  120. letter-spacing: normal;
  121. vertical-align: baseline;
  122. line-height: normal;
  123. }
  124. .apc-box {
  125. padding: 1px;
  126. box-sizing: content-box;
  127. min-width: 18px;
  128. /*position: relative;*/
  129. pointer-events: auto;
  130. }
  131. #apc-panel[non_hover='transparent']:not(:hover):not([config]) .apc-box {
  132. background-color: transparent !important;
  133. }
  134. #apc-panel[non_hover='stealth']:not(:hover):not([config]) .apc-box {
  135. visibility: hidden;
  136. }
  137.  
  138. /* ボタンのスタイル */
  139. .apc-button {
  140. border: solid 1px;
  141. box-sizing: border-box;
  142. cursor: pointer;
  143. margin: 1px;
  144. padding: 0;
  145. position: relative;
  146. opacity: 0.5;
  147. width: 16px;
  148. }
  149. .apc-button:hover {
  150. opacity: 0.8;
  151. }
  152. .apc-button:active {
  153. opacity: 0.3;
  154. }
  155. /* ボタンの大きさ */
  156. #apc-optionBox .apc-button {
  157. height: 16px;
  158. }
  159. #apc-scrollerBox .apc-button {
  160. height: 32px;
  161. }
  162.  
  163.  
  164. /* オプションボックス */
  165. #apc-optionBox {
  166. display: flex;
  167. z-index: 9999999991;
  168. }
  169. #apc-enabler[state="enable"] {
  170. background-image: url(${RES.enabled});
  171. }
  172. #apc-enabler[state="disable"] {
  173. background-image: url(${RES.disabled});
  174. }
  175. #apc-setting {
  176. background-image: url(${RES.config});
  177. }
  178. /* optionBox配置形状: */
  179. #apc-panel[valid] #apc-optionBox[option_dir_valid='Left'],
  180. #apc-panel:not([valid]) #apc-optionBox[option_dir_invalid='Left'] {
  181. flex-direction: row-reverse;
  182. }
  183. #apc-panel[valid] #apc-optionBox[option_dir_valid='Right'],
  184. #apc-panel:not([valid]) #apc-optionBox[option_dir_invalid='Right'] {
  185. flex-direction: row;
  186. }
  187. #apc-panel[valid] #apc-optionBox[option_dir_valid^='Up'],
  188. #apc-panel:not([valid]) #apc-optionBox[option_dir_invalid^='Up'] {
  189. flex-direction: column-reverse;
  190. }
  191. #apc-panel[valid] #apc-optionBox[option_dir_valid^='Down'],
  192. #apc-panel:not([valid]) #apc-optionBox[option_dir_invalid^='Down'] {
  193. flex-direction: column;
  194. }
  195. #apc-panel[valid] #apc-optionBox[option_dir_valid='Up_protrude'],
  196. #apc-panel:not([valid]) #apc-optionBox[option_dir_invalid='Up_protrude'] {
  197. margin-top: -18px;
  198. }
  199. #apc-panel[valid] #apc-optionBox[option_dir_valid='Down_protrude'],
  200. #apc-panel:not([valid]) #apc-optionBox[option_dir_invalid='Down_protrude'] {
  201. margin-bottom: -18px;
  202. }
  203.  
  204.  
  205. /* スクローラーボックス */
  206. #apc-scrollerBox {
  207. z-index: 9999999992;
  208. }
  209. #apc-scrollTop,
  210. #apc-scrollBottom {
  211. background-image: url(${RES.scrAll});
  212. }
  213. #apc-scrollPrev,
  214. #apc-scrollNext {
  215. background-image: url(${RES.scrPage});
  216. }
  217. /* scrollerBox配置形状:スリム */
  218. #apc-scrollerBox[scroller_form='Slim'] {
  219. display: flex;
  220. flex-flow: column wrap-reverse;
  221. }
  222. #apc-scrollerBox[scroller_form='Slim'] #apc-scrollTop {
  223. order: 1;
  224. }
  225. #apc-scrollerBox[scroller_form='Slim'] #apc-scrollPrev {
  226. order: 2;
  227. }
  228. #apc-scrollerBox[scroller_form='Slim'] #apc-scrollNext {
  229. order: 3;
  230. transform: scale(1, -1);
  231. }
  232. #apc-scrollerBox[scroller_form='Slim'] #apc-scrollBottom,
  233. #apc-panel:not([valid]) #apc-scrollBottom {
  234. order: 4;
  235. transform: scale(1, -1);
  236. }
  237. /* scrollerBox配置形状:スクエア */
  238. #apc-panel[valid] #apc-scrollerBox[scroller_form='Square'] {
  239. display: grid;
  240. }
  241. #apc-panel[valid] #apc-scrollerBox[scroller_form='Square'] #apc-scrollTop {
  242. grid-row: 1/2;
  243. grid-column: 2/3;
  244. transform: scale(-1, 1);
  245. }
  246. #apc-panel[valid] #apc-scrollerBox[scroller_form='Square'] #apc-scrollBottom {
  247. grid-row: 2/3;
  248. grid-column: 2/3;
  249. transform: scale(-1, -1);
  250. }
  251. #apc-panel[valid] #apc-scrollerBox[scroller_form='Square'] #apc-scrollNext {
  252. grid-row: 2/3;
  253. grid-column: 1/2;
  254. transform: scale(1, -1);
  255. }
  256. #apc-panel[valid] #apc-scrollerBox[scroller_form='Square'] #apc-scrollPrev {
  257. grid-row: 1/2;
  258. grid-column: 1/2;
  259. }
  260.  
  261.  
  262. /* ページボックス */
  263. #apc-pageIndexBox {
  264. cursor: pointer;
  265. z-index: 9999999993;
  266. min-height: 17px;
  267. position: relative;
  268. }
  269. /* ページ表示 */
  270. #apc-sequencer {
  271. margin: 0px 1px;
  272. padding: 0px;
  273. text-align: center;
  274. }
  275. /* pageIndexBox配置形状:縦置き */
  276. #apc-pageIndexBox[page_index_form$='Pile'] #apc-sequencer {
  277. display: flex;
  278. flex-direction: column;
  279. }
  280. #apc-pageIndexBox[page_index_form$='Pile'] span:first-child{
  281. border-bottom: solid 1px #eee !important;
  282. }
  283. /* pageIndexBox配置形状:横置き */
  284. #apc-pageIndexBox[page_index_form='Strip'],
  285. #apc-pageIndexBox[page_index_form='Growed Pile']{
  286. box-sizing: border-box;
  287. width: 100%;
  288. }
  289. #apc-pageIndexBox[page_index_form$='Strip'] span:first-child::after{
  290. content: " / ";
  291. }
  292.  
  293. /* ページ一覧 */
  294. #apc-pageList {
  295. position: absolute;
  296. min-width: 38px;
  297. margin: 0;
  298. padding: 0px;
  299. list-style-type: none;
  300.  
  301. display: none;
  302. flex-flow: column wrap-reverse;
  303. max-height: 50vh;
  304. }
  305. #apc-pageIndexBox:hover #apc-pageList {
  306. display: flex;
  307. }
  308. #apc-pageIndexBox[page_list_expand^="Left"] #apc-pageList {
  309. right: 100%;
  310. }
  311. #apc-pageIndexBox[page_list_expand^="Right"] #apc-pageList {
  312. left: 100%;
  313. flex-wrap: wrap;
  314. }
  315. #apc-pageIndexBox[page_list_expand$="upper"] #apc-pageList {
  316. bottom: 0;
  317. }
  318. #apc-pageIndexBox[page_list_expand$="lower"] #apc-pageList {
  319. top: 0;
  320. }
  321. #apc-pageIndexBox[page_list_expand="Upper"] #apc-pageList {
  322. right: 0;
  323. bottom: 100%;
  324. }
  325. #apc-pageIndexBox[page_list_expand="Lower"] #apc-pageList {
  326. right: 0;
  327. top: 100%;
  328. }
  329. .apc-pageListItem {
  330. border-style: outset;
  331. border-width: 1px;
  332. box-sizing: border-box;
  333. cursor: pointer;
  334. margin: 1px;
  335. padding: 0px;
  336. text-align: center;
  337. }
  338.  
  339. #apc-panel:not([valid]) #apc-scrollPrev,
  340. #apc-panel:not([valid]) #apc-scrollNext,
  341. #apc-panel:not([valid]) #apc-pageIndexBox {
  342. display: none;
  343. }
  344.  
  345. #apc-panel[config]+#apc-configDialog {
  346. display: flex;
  347. }
  348. /* コンフィグメニューダイアログ */
  349. #apc-configDialog {
  350. background-color: transparent !important;
  351. position: fixed;
  352. z-index: 9999999999;
  353. top: 0px;
  354. left: 0px;
  355. width: 100%;
  356. height: 100%;
  357. display: none;
  358. flex-direction: column;
  359. justify-content: center;
  360. align-items: center;
  361. }
  362. #apc-config {
  363. opacity: 1.0;
  364. border: outset 3px white;
  365. display: inline-block;
  366.  
  367. text-align: left;
  368. padding: 5px 15px;
  369. max-height: 90vh;
  370. overflow: scroll;
  371.  
  372. user-select: none;
  373. -moz-user-select: none;
  374. -webkit-user-select: none;
  375. -ms-user-select: none;
  376. }
  377. #apc-config h4 {
  378. display: block;
  379. background-color: transparent;
  380. padding: 0;
  381. padding-bottom: 1px;
  382. margin: 5px 0 2px -5px;
  383. border: solid 0;
  384. border-bottom-width: 1px;
  385. font-weight: bold !important;
  386. }
  387. #apc-config .apc-group {
  388. border: solid 1px;
  389. /*position: relative;*/
  390. margin: 0;
  391. margin-top: 10px;
  392. padding: 5px;
  393. font-size: 0;
  394. }
  395. #apc-config .apc-group h5 {
  396. /*position: relative;*/
  397. display: inline-block;
  398. margin: 0;
  399. margin-top: -1em;
  400. padding: 0 3px;
  401. background-color: #1c1c1c;
  402. font-weight: bold !important;
  403. }
  404. #apc-config .apc-mItem {
  405. display: block;
  406. margin: 5px 2px 0 2px;
  407. }
  408. #apc-config label {
  409. display: block;
  410. margin: 2px;
  411. cursor: pointer;
  412. }
  413. #apc-config input,
  414. #apc-config select {
  415. /*color: white;*/
  416. background-image: none;
  417. background-color: #000;
  418. border: 2px inset #666;
  419. margin: auto 2px;
  420. cursor: pointer;
  421. border-radius: initial;
  422. padding: initial;
  423. }
  424. #apc-config option {
  425. color: black;
  426. background-color: white;
  427. }
  428. #apc-config input {
  429. width: auto;
  430. height: auto;
  431. padding: 0;
  432. cursor: pointer;
  433. }
  434. #apc-config select,
  435. #apc-config input[type='number'] {
  436. box-sizing: content-box;
  437. height: 19px;
  438. }
  439. #apc-config input[type='number'] {
  440. max-width: 60px;
  441. -webkit-appearance: ;
  442. }
  443. #apc-config select {
  444. max-width: 80px;
  445. }
  446. #apc-config input[type='checkbox'] {
  447. vertical-align: middle;
  448. }
  449. #apc-config #apc-mButtons {
  450. display: flex;
  451. justify-content: stretch;
  452. margin: 10px 0 5px 0;
  453. }
  454. #apc-config .apc-config_button {
  455. border: outset 2px;
  456. margin: 0 5px;
  457. width: 100%;
  458. }
  459. #apc-config .apc-config_button:first-child {
  460. margin-left: 0;
  461. }
  462. #apc-config .apc-config_button:last-child {
  463. margin-right: 0;
  464. }
  465. `;
  466. document.head.appendChild($style);
  467.  
  468.  
  469.  
  470. // APが有効なページであるのか
  471. const apValid = {
  472. name: "valid",
  473. flag: null,
  474. };
  475. /// APメッセージバー(アドオン版)かAPアイコン(スクリプト版)が
  476. /// 挿入されると、APが有効なページであるとみなす。
  477. const checkApValid = $elm => {
  478. if( apValid.flag == null ){
  479. // AutoPagerize有効なページでのみ行う処理
  480. if( $elm.id == "autopagerize_message_bar" ||
  481. $elm.id == "autopagerize_icon" )
  482. {
  483. apValid.flag = $elm.id;
  484. $panel.attr( apValid.name, true);
  485. return true;
  486. }
  487. }
  488. return false;
  489. };
  490. const apObject = document.getElementById("autopagerize_message_bar") ||
  491. document.getElementById("autopagerize_icon");
  492. if( apObject != null ){
  493. checkApValid(apObject);
  494. }else{
  495. const mo = new MutationObserver(
  496. mRecs => {
  497. for( let rec of mRecs ){
  498. for( let added of rec.addedNodes ){
  499. if( checkApValid(added) ){
  500. mo.disconnect();
  501. }
  502. }
  503. }
  504. }
  505. );
  506. mo.observe( document.body, {'childList': true});
  507. document.addEventListener(
  508. 'GM_AutoPagerizeNextPageLoaded',
  509. () => mo.disconnect()
  510. );
  511. }
  512.  
  513. let scrTop = document.documentElement.scrollTop;
  514. let oldPage = null;
  515. // ウィンドウのスクロールが発生した時
  516. window.addEventListener(
  517. 'scroll',
  518. () => {
  519. scrTop = document.documentElement.scrollTop;
  520. // 現在のページを更新
  521. const np = getNowPage();
  522. if( np != oldPage ){
  523. $sequencerNow.textContent = np+1;
  524. oldPage = np;
  525. }
  526. }
  527. );
  528. // 各ページを管理する配列
  529. let pageBounds = [0];
  530. // 現在のページを取得(境界線上を前ページとみなす場合false)
  531. const getNowPage = (notLess=true) => {
  532. const breakOver = notLess ?
  533. (st, bound) => st >= bound :
  534. (st, bound) => st > bound ;
  535. let i;
  536. for( i = pageBounds.length-1; i >= 0; i-- ){
  537. if( breakOver( scrTop, pageBounds[i]) ) break;
  538. }
  539. return i;
  540. };
  541. const getBottomPos = () => {
  542. return Math.max(
  543. document.body.clientHeight,
  544. document.body.scrollHeight,
  545. document.documentElement.scrollHeight,
  546. document.documentElement.clientHeight) -
  547. window.innerHeight;
  548. };
  549.  
  550. // ページを継ぎ足した時、継ぎ目の位置を記録する
  551. const apPageAppended = () => {
  552. // セパレーターの絶対位置を取得
  553. const $apSep = document.getElementsByClassName("autopagerize_page_separator");
  554. const len = $apSep.length;
  555.  
  556. let sepPos = $apSep.item(len-1).getBoundingClientRect().top + window.pageYOffset;
  557. sepPos = Math.round(sepPos);
  558. if( !pageBounds.includes(sepPos) ){
  559. pageBounds.push(sepPos);
  560. }
  561. $sequencerMax.textContent = len+1;
  562.  
  563. // ページリストアイテムを追加
  564. $pageList.appendChild( $createPageListItem(len+1) );
  565. };
  566.  
  567. document.addEventListener(
  568. 'GM_AutoPagerizeNextPageLoaded',
  569. () => apPageAppended()
  570. );
  571.  
  572. let scrTick = null;
  573. // 任意の位置にスクロール
  574. const smoothScrollTo = targetY => {
  575. // 続けてスクロールさせるとキャンセルして新たなスクロール
  576. if( scrTick != null ){
  577. clearTimeout(scrTick);
  578. scrTick = null;
  579. }
  580. // 再帰処理部分
  581. const smoothScrollTick = (_targetY) => {
  582. // 常に最新の位置をターゲットにしたい場合、引数に関数を渡す
  583. // (最下部へのスクロール用。
  584. //  なぜかスクロール途中にページの高さが変わる場合がある)
  585. let targetY = (typeof(_targetY) == "function" ?
  586. _targetY() :
  587. _targetY);
  588. // 移動量
  589. let moveY = (targetY-scrTop)/10;
  590. // 終了条件
  591. let endOver;
  592. // 下方向の移動量調整と終了条件
  593. if( moveY>0 ){
  594. moveY = Math.ceil(moveY); //切り上げ
  595. endOver = scrTop+moveY>=targetY; //ターゲットを越えていれば
  596. }
  597. // 上方向の移動量調整と終了条件
  598. else{
  599. moveY = Math.floor(moveY); //切り下げ
  600. endOver = scrTop+moveY<=targetY; //ターゲットを下回っていれば
  601. }
  602. // 条件を満たしていれば終了
  603. if( endOver ){
  604. window.scrollTo( 0, targetY);
  605. clearTimeout(scrTick);
  606. scrTick = null;
  607. }else{
  608. window.scrollBy( 0, moveY);
  609. scrTick = setTimeout(
  610. () => smoothScrollTick(targetY),
  611. 10
  612. );
  613. }
  614. };
  615. smoothScrollTick(targetY);
  616. };
  617.  
  618.  
  619.  
  620. // コントロール配置
  621. /// パネル(最親)
  622. const $panel = document.createElement("div");
  623. $panel.id = "apc-panel";
  624. document.body.appendChild($panel);
  625.  
  626. // ボックスを作成
  627. const $createBox = () => {
  628. const $box = document.createElement("div");
  629. $box.className = "apc-box";
  630. return $box;
  631. };
  632. // ボタンを作成
  633. const $createButton = (attr) => {
  634. const $button = document.createElement("div");
  635. $button.className = "apc-button";
  636. $button.attr(attr);
  637. return $button;
  638. };
  639.  
  640. ///panel/ オプションボックス
  641. const $optionBox = $createBox();
  642. $optionBox.id = "apc-optionBox";
  643. $panel.appendChild($optionBox);
  644.  
  645. ///panel/optionBox/ オンオフボタン (enable/disable)
  646. const $enabler = $createButton(
  647. { 'id': "apc-enabler" }
  648. );
  649. const apEnable = {
  650. name: "enable",
  651. state: true,
  652. };
  653. const changeToggle = (toggle = null) => {
  654. apEnable.state = toggle != null ? toggle : !apEnable.state;
  655. $enabler.attr(
  656. apEnable.state ?
  657. {
  658. 'state': "enable",
  659. 'alt': "E",
  660. 'title': "AutePagerize OFF (Now:Enable)"
  661. } :
  662. {
  663. 'state': "disable",
  664. 'alt': "D",
  665. 'title': "AutePagerize ON (Now:Disable)"
  666. }
  667. );
  668. GM.setValue( apEnable.name, apEnable.state);
  669. };
  670. ///panel/optionBox// APイベントをキャプチャー
  671. document.addEventListener(
  672. 'AutoPagerizeToggleRequest', () => changeToggle()
  673. );
  674. document.addEventListener(
  675. 'AutoPagerizeEnableRequest', () => changeToggle(true)
  676. );
  677. document.addEventListener(
  678. 'AutoPagerizeDisableRequest', () => changeToggle(false)
  679. );
  680. ///panel/optionBox// トグルボタン クリックでリクエストイベント発火
  681. $enabler.addEventListener(
  682. 'click', () => FireEvent('AutoPagerizeToggleRequest')
  683. );
  684. $optionBox.appendChild($enabler);
  685.  
  686. // コンフィグメニューを開いているか
  687. ///panel/optionBox/ 設定ボタン
  688. const $setting = $createButton(
  689. {
  690. 'id': "apc-setting",
  691. 'title': "Open Config",
  692. 'alt': "c",
  693. }
  694. );
  695. $optionBox.appendChild($setting);
  696. $setting.addEventListener(
  697. 'click', () => config.open()
  698. );
  699. /// ボタンが見えなくなった時のため、ショートカットで開けるようにする。
  700. /// Alt + Ctrl + p
  701. document.addEventListener(
  702. 'keydown', e => {
  703. if( e.altKey && e.ctrlKey && e.keyCode == 80 ){
  704. config.open();
  705. }
  706. }
  707. );
  708.  
  709. const $spacingBox12 = document.createElement("div");
  710. $spacingBox12.className = "apc-spacing";
  711. $spacingBox12.style.order = 2;
  712. $panel.appendChild($spacingBox12);
  713.  
  714. ///panel/ スクロールボックス
  715. const $scrollerBox = $createBox();
  716. $scrollerBox.id = "apc-scrollerBox";
  717. $panel.appendChild($scrollerBox);
  718.  
  719. ///panel/scr/ 最上部へ移動
  720. const $scrollTop = $createButton(
  721. {
  722. 'id': "apc-scrollTop",
  723. 'alt': "↑",
  724. 'title': "Move to Top",
  725. }
  726. );
  727. $scrollerBox.appendChild($scrollTop);
  728. ///panel/scr/ 最下部へ移動
  729. const $scrollBottom = $createButton(
  730. {
  731. 'id': "apc-scrollBottom",
  732. 'alt': "↓",
  733. 'title': "Move to Bottom",
  734. }
  735. );
  736. $scrollerBox.appendChild($scrollBottom);
  737. ///panel/scr/ 前のページ
  738. const $scrollPrev = $createButton(
  739. {
  740. 'id': "apc-scrollPrev",
  741. 'alt': "△",
  742. 'title': "Move to Previous",
  743. }
  744. );
  745. $scrollerBox.appendChild($scrollPrev);
  746. ///panel/scr/ 次のページ
  747. const $scrollNext = $createButton(
  748. {
  749. 'id': "apc-scrollNext",
  750. 'alt': "▽",
  751. 'title': "Move to Next",
  752. }
  753. );
  754. $scrollerBox.appendChild($scrollNext);
  755.  
  756. ///panel/scr/ 最上部へ移動
  757. $scrollTop.addEventListener(
  758. 'click', () => smoothScrollTo(0)
  759. );
  760. ///panel/scr/ 最下部へ移動
  761. $scrollBottom.addEventListener(
  762. 'click', () => smoothScrollTo(getBottomPos)
  763. );
  764. ///panel/scr/ 前のページ
  765. $scrollPrev.addEventListener(
  766. 'click', () => {
  767. smoothScrollTo( pageBounds.round( getNowPage(false) ) );
  768. }
  769. );
  770. ///panel/scr/ 次のページ
  771. $scrollNext.addEventListener(
  772. 'click', () => {
  773. const targetPage = getNowPage()+1;
  774. smoothScrollTo(
  775. targetPage < pageBounds.length ?
  776. pageBounds.round(targetPage) :
  777. getBottomPos
  778. );
  779. }
  780. );
  781.  
  782. const $spacingBox23 = document.createElement("div");
  783. $spacingBox23.className = "apc-spacing"
  784. $spacingBox23.style.order = 4;
  785. $panel.appendChild($spacingBox23);
  786.  
  787. ///panel/ ページボックス
  788. const $pageIndexBox = $createBox();
  789. $pageIndexBox.id = "apc-pageIndexBox";
  790.  
  791. ///panel/pageIndexBox/ ページ数表示
  792. const $sequencer = document.createElement("div");
  793. $sequencer.id = "apc-sequencer";
  794. const $sequencerNow = document.createElement("span");
  795. const $sequencerMax = document.createElement("span");
  796. $sequencerNow.textContent = $sequencerMax.textContent = "1";
  797. $sequencer.appendChild($sequencerNow);
  798. $sequencer.appendChild($sequencerMax);
  799. $pageIndexBox.appendChild($sequencer);
  800. $panel.appendChild($pageIndexBox);
  801.  
  802. ///panel/pageIndexBox/ ページリスト
  803. const $pageList = document.createElement("ol");
  804. $pageList.id = "apc-pageList";
  805. $pageIndexBox.appendChild($pageList);
  806. // 新しいページリストアイテムにイベントを追加
  807. const $createPageListItem = num => {
  808. const $elm = document.createElement("li");
  809. $elm.className = "apc-pageListItem";
  810. $elm.textContent = num;
  811. // クリックでそのページにスクロール
  812. $elm.addEventListener(
  813. 'click', function(){
  814. const targetNum = this.textContent-1;
  815. smoothScrollTo( pageBounds.round(targetNum) );
  816. }
  817. );
  818. // // ダブルクリックでページ移動
  819. // $elm.addEventListener(
  820. // 'dblclick', function(){
  821. // const num = this.textContent-2;
  822. // if( num >= 0 )
  823. // document.getElementsByClassName("autopagerize_link")[num].href;
  824. // }
  825. // );
  826. return $elm;
  827. };
  828. $pageList.appendChild( $createPageListItem(1) );
  829.  
  830.  
  831.  
  832.  
  833.  
  834.  
  835. /// コンフィグメニューを作成
  836. // コンフィグコントロール管理クラス
  837. // 基底クラス
  838. class ConfigControl {
  839. constructor(name, options){
  840. this.name = name;
  841. this.defaultValue = options.defaultValue || 0;
  842. this.onchange_ = options.onchange || null;
  843. }
  844.  
  845. get state(){
  846. return this.value;
  847. }
  848. set state(val){
  849. this.value = val;
  850. this.onchange();
  851. }
  852. onchange(){
  853. if( typeof(this.onchange_) == "function" ) this.onchange_();
  854. }
  855. getInitial(){
  856. return this.defaultValue || 0;
  857. }
  858. setDefault(){
  859. this.state = this.defaultValue;
  860. }
  861. restoreState(params){
  862. const val = params[this.name];
  863. if( val == null ){
  864. this.setDefault();
  865. }else{
  866. this.state = val;
  867. }
  868. }
  869. /* 仮想関数
  870. * 継承先のクラスでこれらをオーバーライドする
  871. * オーバーライドされていなければバグなのでwarn
  872. */
  873. /* virtual */get value(){
  874. console.warn("virtual get value", this.name);
  875. return null;
  876. }
  877. /* virtual */set value(val){
  878. console.warn("virtual set value", this.name);
  879. }
  880. /* virtual */appendTo($to){
  881. console.warn("virtual appendTo", this.name);
  882. }
  883. }
  884. // NumericUpDown管理クラス
  885. class NumericSet extends ConfigControl {
  886. constructor(name, options, attr){
  887. super(name, options);
  888.  
  889. this.$numeric = document.createElement("input");
  890. this.$numeric.type = 'number';
  891. this.$numeric.name = name;
  892. this.$numeric.value = this.getInitial();
  893. this.$numeric.attr(attr);
  894. this.$numeric.addEventListener(
  895. 'change', () => this.onchange()
  896. );
  897. }
  898. get value(){
  899. if( isNaN(this.$numeric.value) ){
  900. this.$numeric.value = this.defaultValue;
  901. }
  902. return this.$numeric.value;
  903. }
  904. set value(val){
  905. this.$numeric.value = parseInt(val, 10) || this.defaultValue;
  906. }
  907. appendTo($to){
  908. $to.appendChild(this.$numeric);
  909. }
  910. }
  911. // コンボボックス管理クラス
  912. class ComboSet extends ConfigControl{
  913. constructor(name, options){
  914. super(name, options);
  915.  
  916. this.$combo = document.createElement("select");
  917. this.$combo.attr("name", name);
  918. this.$combo.addEventListener(
  919. 'change', () => this.onchange()
  920. );
  921.  
  922. if( options.items != null ){
  923. this.addItems(options.items, this.getInitial());
  924. }
  925.  
  926. }
  927. get value(){
  928. return this.$combo.value;
  929. }
  930. set value(val){
  931. this.selectItem(val);
  932. }
  933. addItems(itemParams, sel = null){
  934. itemParams.forEach(
  935. (elm, i) => {
  936. let value, text;
  937. if( typeof(elm) == "string" ){
  938. value = text = elm;
  939. }else{
  940. value = elm.value;
  941. text = elm.text || value;
  942. }
  943. const $item = document.createElement("option");
  944. $item.value = value || "option"+i;
  945. $item.textContent = text || $item.value;
  946. this.$combo.appendChild($item);
  947. }
  948. );
  949. if( sel != null ) this.selectItem(sel);
  950. }
  951. selectItem(target){
  952. if( typeof target == "number" ){
  953. this.$combo.selectedIndex = target;
  954. }else if( typeof target == "string" ){
  955. this.$combo.value = target;
  956. }
  957. }
  958. appendTo($to){
  959. $to.appendChild(this.$combo);
  960. }
  961. // isDefault(){
  962. // if( typeof this.defaultValue == "number" ){
  963. // return this.$combo.selectedIndex == this.defaultValue;
  964. // }else if( typeof this.defaultValue == "string" ){
  965. // return this.$combo.value == this.defaultValue;
  966. // }
  967. // return false;
  968. // }
  969. }
  970. // ラジオボタン管理クラス
  971. class RadioSet extends ConfigControl {
  972. constructor(name, options){
  973. super(name, options);
  974. this.selected_ = null;
  975. this.items = [];
  976.  
  977. if( options.items != null ){
  978. this.addItems( options.items, this.getInitial() );
  979. }
  980. }
  981. get state(){
  982. return this.selected_;
  983. }
  984. set state(val){
  985. if( val >= 0 && val < this.items.length ){
  986. this.selected_ = val;
  987. this.items[val].$radio.checked = true;
  988. this.onchange();
  989. }
  990. }
  991. selectedIndex(){
  992. return this.selected_;
  993. }
  994. selectedItem(){
  995. let i = this.selectedIndex();
  996. if( i < 0 || i >= this.items.length ){
  997. i = this.defaultValue;
  998. }
  999. return this.items[i];
  1000. }
  1001. // isDefault(){
  1002. // return this.selectedIndex() == this.defaultValue;
  1003. // }
  1004.  
  1005. addItems(itemParams, sel = null){
  1006. itemParams.forEach(
  1007. (elm, i) => {
  1008. const nameItem = `${this.name}-item-${i}`;
  1009. const forId = elm.id || nameItem;
  1010. const value = elm.value || nameItem;
  1011. const title = elm.title || nameItem;
  1012. const text = elm.text || nameItem;
  1013.  
  1014. const $label = document.createElement("label");
  1015. $label.attr(
  1016. {
  1017. 'for': forId,
  1018. 'title': title,
  1019. }
  1020. );
  1021. const $radio = document.createElement("input");
  1022. $radio.attr(
  1023. {
  1024. 'type': "radio",
  1025. 'name': this.name,
  1026. 'id': forId,
  1027. }
  1028. );
  1029. $radio.addEventListener(
  1030. 'change', () => {
  1031. this.selected_ = i;
  1032. this.onchange();
  1033. }
  1034. );
  1035. $label.appendChild( $radio );
  1036. $label.appendChild( document.createTextNode(text) );
  1037.  
  1038. this.items.push(
  1039. {
  1040. 'value': value,
  1041. '$radio': $radio,
  1042. '$label': $label
  1043. }
  1044. );
  1045. }
  1046. );
  1047.  
  1048. if( sel != null ) this.state = sel;
  1049. }
  1050. appendTo($to){
  1051. this.items.forEach(
  1052. elm => $to.appendChild( elm.$label )
  1053. );
  1054. }
  1055. }
  1056.  
  1057. // コンフィグダイアログ
  1058. const $configDialog = document.createElement("div");
  1059. $configDialog.id = "apc-configDialog";
  1060. $configDialog.addEventListener(
  1061. 'click', () => config.close()
  1062. );
  1063. document.body.appendChild($configDialog);
  1064.  
  1065. /// コンフィグメニュー
  1066. const $config = document.createElement("div");
  1067. $config.id = "apc-config";
  1068. // バブリングストップ
  1069. $config.addEventListener(
  1070. 'click', e => e.stopPropagation()
  1071. );
  1072. $configDialog.appendChild($config);
  1073.  
  1074.  
  1075. const $createH4 = (title, text) => {
  1076. const $h4 = document.createElement("h4");
  1077. $h4.title = title;
  1078. $h4.textContent = text;
  1079. return $h4;
  1080. };
  1081. ///config/ 表示する条件
  1082. $config.appendChild( $createH4(
  1083. "APCが表示されるページ",
  1084. "The page on which Autopagerize_Console is display")
  1085. );
  1086. const radioDisplayRule = new RadioSet(
  1087. "display_rule",
  1088. {
  1089. 'onchange': function(){
  1090. $panel.attr(this.name, this.selectedItem().value);
  1091. },
  1092. 'items': [
  1093. {
  1094. 'id': "apc-mdAlways",
  1095. 'value': "always",
  1096. 'text': "always",
  1097. 'title': "常に表示",
  1098. },
  1099. {
  1100. 'id': "apc-mdValid",
  1101. 'value': "valid",
  1102. 'text': "only when \"AutoPagerize\" is valid",
  1103. 'title': "AutoPagerizeが有効なページであれば表示\n(Alt+Ctrl+pで設定画面を表示)",
  1104. }
  1105. ]
  1106. }
  1107. );
  1108. // radioDisplayRule.isAlways = function(){
  1109. // return this.selectedItem() == 0;
  1110. // };
  1111. // radioDisplayRule.isValid = function(){
  1112. // return this.selectedItem() == 1;
  1113. // };
  1114. radioDisplayRule.appendTo($config);
  1115.  
  1116. ///config/position/ マウスが外れている時の表示
  1117. $config.appendChild(
  1118. $createH4(
  1119. "マウスが外れている時の表示",
  1120. "Appearance when non-hover"
  1121. )
  1122. );
  1123. const radioNonHover = new RadioSet(
  1124. "non_hover",
  1125. {
  1126. 'onchange': function(){
  1127. $panel.attr(this.name, this.selectedItem().value);
  1128. },
  1129. 'items': [
  1130. {
  1131. 'id': "apc-no_change",
  1132. 'value': "no_change",
  1133. 'text': "No change",
  1134. 'title': "変更しない",
  1135. },
  1136. {
  1137. 'id': "apc-transparent",
  1138. 'value': "transparent",
  1139. 'text': "Transparent",
  1140. 'title': "背景を透過",
  1141. },
  1142. {
  1143. 'id': "apc-stealth",
  1144. 'value': "stealth",
  1145. 'text': "Stealth",
  1146. 'title': "隠れる",
  1147. }
  1148. ]
  1149. }
  1150. );
  1151. radioNonHover.appendTo($config);
  1152.  
  1153. const $createInputRow = (title, text) => {
  1154. const $row = document.createElement("div");
  1155. $row.className = "apc-mItem";
  1156. $row.title = title;
  1157. $row.textContent = text;
  1158. return $row;
  1159. };
  1160. const $createGroupBox = subject => {
  1161. const $box = document.createElement("div");
  1162. $box.className = "apc-group";
  1163. const $subject = document.createElement("h5");
  1164. $subject.textContent = subject;
  1165. $box.appendChild($subject);
  1166. return $box;
  1167. };
  1168. /// 位置設定
  1169. const UpdatePanelPos = () => {
  1170. $panel.style[comboPanelPosY.value] =
  1171. numericPanelPosValue.value + comboPanelPosUnit.value;
  1172. };
  1173. const UpdateBoxPos = ($elm, val) => {
  1174. $elm.style.height = val+"px";
  1175. };
  1176. const UpdateAllPositon = () => {
  1177. UpdatePanelPos();
  1178. UpdateBoxPos( $spacingBox12, numericSpecing12.value);
  1179. UpdateBoxPos( $spacingBox23, numericSpecing23.value);
  1180. };
  1181. ///config/ 位置
  1182. $config.appendChild( $createH4( "位置設定", "Expression style") );
  1183.  
  1184. //config/position/ パネル位置
  1185. const $panelPos = $createInputRow(
  1186. "パネル位置",
  1187. "panel position Y:"
  1188. );
  1189. $config.appendChild($panelPos);
  1190.  
  1191. ///config/position/panelPos/ 使用単位
  1192. const comboPanelPosY = new ComboSet(
  1193. "panel_position_y", {
  1194. 'items': [ "top", "bottom"],
  1195. 'onchange': () => {
  1196. $panel.style.removeProperty("top");
  1197. $panel.style.removeProperty("bottom");
  1198. UpdatePanelPos();
  1199. }
  1200. }
  1201. );
  1202. comboPanelPosY.appendTo($panelPos);
  1203. ///config/position/panelPos/ 座標
  1204. const numericPanelPosValue = new NumericSet(
  1205. "panel_position_value", {
  1206. 'defaultValue': 48,
  1207. 'onchange': UpdatePanelPos,
  1208. }
  1209. );
  1210. numericPanelPosValue.appendTo($panelPos);
  1211. ///config/position/panelPos/ 使用単位
  1212. const comboPanelPosUnit = new ComboSet(
  1213. "panel_position_unit", {
  1214. 'items': ["px","%"],
  1215. 'onchange': UpdatePanelPos,
  1216. }
  1217. );
  1218. comboPanelPosUnit.appendTo($panelPos);
  1219. ///config/position/ オプションボックス
  1220. const $optionGroup = $createGroupBox("Option box");
  1221. $config.appendChild($optionGroup);
  1222. ///config/position/optionBox/ 並び順
  1223. const $optionOrder = $createInputRow( "並び順", "Order:");
  1224. $config.appendChild($optionOrder);
  1225. const numericOptionOrder = new NumericSet(
  1226. "option_order",
  1227. {
  1228. 'defaultValue': 1,
  1229. 'onchange': function(){
  1230. $optionBox.style.order = this.value*2-1;
  1231. },
  1232. },
  1233. { 'min': 1, 'max': 3}
  1234. );
  1235. numericOptionOrder.appendTo($optionOrder);
  1236. $optionGroup.appendChild($optionOrder);
  1237. /// 展開方向
  1238. const optionDirOptions = {
  1239. 'items':
  1240. [ "Left", "Right", "Up", "Down",
  1241. {value: "Up_protrude", text: "Up (protrude)"},
  1242. {value: "Down_protrude", text: "Down (protrude)"} ],
  1243. 'defaultValue': "Up",
  1244. 'onchange': function(){
  1245. $optionBox.attr(this.name, this.value);
  1246. }
  1247. };
  1248. ///config/position/optionBox/ 有効ページでの展開方向
  1249. const $optionValidForm = $createInputRow(
  1250. "Autopagerizeが有効なページでの展開方向",
  1251. "Direction when AP is valid:"
  1252. );
  1253. const comboOptionDirValid = new ComboSet(
  1254. "option_dir_valid", optionDirOptions
  1255. );
  1256. comboOptionDirValid.appendTo($optionValidForm);
  1257. $optionGroup.appendChild($optionValidForm);
  1258. ///config/position/optionBox/ 対象外ページの展開方向
  1259. const $optionInvalidForm = $createInputRow(
  1260. "Autopagerizeが有効でないページでの展開方向",
  1261. "Direction when AP is invalid:"
  1262. );
  1263. const comboOptionDirInvalid = new ComboSet(
  1264. "option_dir_invalid", optionDirOptions
  1265. );
  1266. comboOptionDirInvalid.appendTo($optionInvalidForm);
  1267. $optionGroup.appendChild($optionInvalidForm);
  1268.  
  1269. ///config/position/scrollerBox/ BOX1とBOX2の間隔
  1270. const $specing12 = $createInputRow(
  1271. "BOX1とBOX2の間隔",
  1272. "Specing between to BOX1 and BOX2:"
  1273. );
  1274. const numericSpecing12 = new NumericSet(
  1275. "spacing_12",
  1276. {
  1277. 'onchange': function(){
  1278. UpdateBoxPos( $spacingBox12, this.value);
  1279. }
  1280. }
  1281. );
  1282. numericSpecing12.appendTo($specing12);
  1283. $specing12.appendChild(document.createTextNode(" px"));
  1284. $config.appendChild($specing12);
  1285.  
  1286. ///config/position/ スクローラーボックス
  1287. const $scrollerGroup = $createGroupBox("Scroller box");
  1288. $config.appendChild($scrollerGroup);
  1289. ///config/position/scrollerBox/ 並び順
  1290. const $scrollerOrder = $createInputRow( "並び順", "Order:");
  1291. $config.appendChild($scrollerOrder);
  1292. const numericScrollerOrder = new NumericSet(
  1293. "scroller_order",
  1294. {
  1295. 'defaultValue': 2,
  1296. 'onchange': function(){
  1297. $scrollerBox.style.order = this.value*2-1;
  1298. }
  1299. },
  1300. { 'min': 1, 'max': 3}
  1301. );
  1302. numericScrollerOrder.appendTo($scrollerOrder);
  1303. $scrollerGroup.appendChild($scrollerOrder);
  1304. ///config/position/scrollerBox/ 配置形状
  1305. const $scrollerForm = $createInputRow(
  1306. "配置形状\n(AP対象外ページでは自動的にボタンが2つになるので無視される)",
  1307. "Form when AP is valid:"
  1308. );
  1309. const comboScrollerForm = new ComboSet(
  1310. "scroller_form", {
  1311. 'items': ["Slim","Square"],
  1312. 'onchange': function(){
  1313. $scrollerBox.attr( this.name, this.value);
  1314. }
  1315. }
  1316. );
  1317. comboScrollerForm.appendTo($scrollerForm);
  1318. $scrollerGroup.appendChild($scrollerForm);
  1319.  
  1320. ///config/position/pageIndexBox/ BOX2とBOX3の間隔
  1321. const $specing23 = $createInputRow(
  1322. " BOX2とBOX3の間隔",
  1323. "Specing between to BOX2 and BOX3:"
  1324. );
  1325. const numericSpecing23 = new NumericSet(
  1326. "spacing_23",
  1327. {
  1328. 'onchange': function(){
  1329. UpdateBoxPos( $spacingBox23, this.value);
  1330. }
  1331. }
  1332. );
  1333. numericSpecing23.appendTo($specing23);
  1334. $specing23.appendChild(document.createTextNode(" px"));
  1335. $config.appendChild($specing23);
  1336. ///config/position/ ページインデックスボックス
  1337. const $pageIndexGroup = $createGroupBox("PageIndex box");
  1338. $config.appendChild($pageIndexGroup);
  1339. ///config/position/pageIndexBox/ 並び順
  1340. const $pageIndexOrder = $createInputRow( "並び順", "Order:");
  1341. $config.appendChild($pageIndexOrder);
  1342. const numericPageIndexOrder = new NumericSet(
  1343. "pageindex_order",
  1344. {
  1345. 'defaultValue': 3,
  1346. 'onchange': function(){
  1347. $pageIndexBox.style.order = this.value*2-1;
  1348. }
  1349. },
  1350. { 'min': 1, 'max': 3}
  1351. );
  1352. numericPageIndexOrder.appendTo($pageIndexOrder);
  1353. $pageIndexGroup.appendChild($pageIndexOrder);
  1354. ///config/position/pageIndexBox/ 配置形状
  1355. const $pageIndexForm = $createInputRow(
  1356. "配置形状\n(AP対象外ページでは自動的に非表示となるので無視される)",
  1357. "Form when AP is valid:"
  1358. );
  1359. const comboPageIndexForm = new ComboSet(
  1360. "page_index_form",
  1361. {
  1362. 'items': ["Pile", "Strip", "Growed Pile"],
  1363. 'onchange': function(){
  1364. $pageIndexBox.attr( this.name, this.value);
  1365. }
  1366. }
  1367. );
  1368. comboPageIndexForm.appendTo($pageIndexForm);
  1369. $pageIndexGroup.appendChild($pageIndexForm);
  1370. ///config/position/pageIndexBox/ 展開方向
  1371. const $pageListExpand = $createInputRow(
  1372. "展開方向",
  1373. "Page-list expand direction:"
  1374. );
  1375. const comboPageListExpand = new ComboSet(
  1376. "page_list_expand",
  1377. {
  1378. 'items': [
  1379. "Upper", "Lower",
  1380. "Left-upper", "Left-lower",
  1381. "Right-upper", "Right-lower"
  1382. ],
  1383. 'defaultValue': "Lower",
  1384. 'onchange': function(){
  1385. $pageIndexBox.attr( this.name, this.value);
  1386. }
  1387. }
  1388. );
  1389. comboPageListExpand.appendTo($pageListExpand);
  1390. $pageIndexGroup.appendChild($pageListExpand);
  1391.  
  1392.  
  1393.  
  1394. const $mButtons = document.createElement("div");
  1395. $mButtons.id = "apc-mButtons";
  1396. $config.appendChild($mButtons);
  1397.  
  1398. ///config/ 閉じるボタン
  1399. const $mCloseDecision = document.createElement("input");
  1400. $mCloseDecision.attr(
  1401. {
  1402. 'id': "apc-mCloseDecision",
  1403. 'class': "apc-config_button",
  1404. 'type': "button",
  1405. 'value': "OK",
  1406. }
  1407. );
  1408. $mCloseDecision.addEventListener(
  1409. 'click', () => config.close()
  1410. );
  1411. $mButtons.appendChild($mCloseDecision);
  1412. const $mCloseCancel = document.createElement("input");
  1413. $mCloseCancel.attr(
  1414. {
  1415. 'id': "apc-mCloseCancel",
  1416. 'class': "apc-config_button",
  1417. 'type': "button",
  1418. 'value': "Cancel",
  1419. }
  1420. );
  1421. $mCloseCancel.addEventListener(
  1422. 'click', () => config.close(false)
  1423. );
  1424. $mButtons.appendChild($mCloseCancel);
  1425.  
  1426.  
  1427. class Config {
  1428. constructor(name, options = null){
  1429. this.name = name;
  1430. this.tempParams = null;
  1431. this.init(options);
  1432. }
  1433. init(options){
  1434. if( options == null ) return;
  1435. if( options.items != null ) this.items = options.items;
  1436. if( options.onopen != null ) this.onopen_ = options.onopen;
  1437. if( options.onclose != null ) this.onclose_ = options.onclose;
  1438. }
  1439. open(){
  1440. this.tempParams = this.getParams();
  1441. if( typeof this.onopen_ == "function" ){ this.onopen_(); }
  1442. }
  1443. close(decision = true){
  1444. if( decision ) this.save();
  1445. else this.restore(this.tempParams);
  1446. this.tempParams = null;
  1447.  
  1448. if( typeof this.onclose_ == "function" ){ this.onclose_(); }
  1449. }
  1450. restore(params){
  1451. if( params == null ){
  1452. this.items.forEach( elm => elm.setDefault() );
  1453. }else{
  1454. this.items.forEach( elm => elm.restoreState(params) );
  1455. }
  1456. }
  1457. getParams(){
  1458. const params = {};
  1459. this.items.forEach(
  1460. elm => params[elm.name] = elm.state
  1461. );
  1462. return params;
  1463. }
  1464. save(){
  1465. GM.setValue( this.name, this.getParams() );
  1466. }
  1467. load(){
  1468. GM.getValue( this.name, null).then(
  1469. result => this.restore(result)
  1470. );
  1471. }
  1472. }
  1473. const config = new Config(
  1474. "config",
  1475. {
  1476. 'onopen': () => $panel.setAttribute("config", true),
  1477. 'onclose': () => {
  1478. $panel.removeAttribute("config");
  1479. UpdateAllPositon();
  1480. },
  1481. 'items': [
  1482. radioDisplayRule, radioNonHover,
  1483. comboPanelPosY,
  1484. numericPanelPosValue, comboPanelPosUnit,
  1485. numericOptionOrder,
  1486. comboOptionDirValid, comboOptionDirInvalid,
  1487. numericSpecing12,
  1488. numericScrollerOrder,
  1489. comboScrollerForm,
  1490. numericSpecing23,
  1491. numericPageIndexOrder,
  1492. comboPageIndexForm,
  1493. comboPageListExpand
  1494. ]
  1495. }
  1496. );
  1497. const loadState = () => {
  1498. GM.getValue( apEnable.name, true).then(
  1499. result => {
  1500. FireEvent(
  1501. result?
  1502. 'AutoPagerizeEnableRequest':
  1503. 'AutoPagerizeDisableRequest'
  1504. );
  1505. }
  1506. );
  1507. config.load();
  1508. UpdateAllPositon();
  1509. };
  1510. loadState();
  1511.  
  1512. // タブを切り替えた時にステータスを最新に同期する
  1513. window.document.addEventListener(
  1514. 'visibilitychange',
  1515. () => {
  1516. if( window.document.visibilityState == 'visible' ){
  1517. loadState();
  1518. }
  1519. }
  1520. );
  1521. })();

QingJ © 2025

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