Youtube-filter(channel、comment、video)

block and highlight youtube video/comment by keyword、channel

当前为 2024-07-26 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Youtube-filter(channel、comment、video)
  3. // @namespace smallsupo
  4. // @version 1.3
  5. // @description block and highlight youtube video/comment by keyword、channel
  6. // @description:zh-TW 屏蔽/高亮 youtube影片/留評 (依頻道、關鍵字)
  7. // @author smallsupo (smallsupo@gmail.com)
  8. // @match https://www.youtube.com/*
  9. // @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com
  10. // @grant none
  11. // @license Copyright smallsupo
  12. // ==/UserScript==
  13.  
  14. let languages=[
  15. {language:"en",restore:'restore',backup:'backup',setting:'setting',show:'show',hide:'hide',
  16. block:'block',channel:'channel',video:'video',keyword:'keyword',comment:'comment',
  17. user:'user',highlight:'highlight',color:'color',curvature:'curvature',border:'border',
  18. regex:'regex',posttime:'post time',regex_post_time:'minute ,hour,^1\sday'},
  19. {language:"zh",restore:'還原',backup:'備份',setting:'設定',show:'顯示',hide:'隱藏',
  20. block:'屏蔽',channel:'頻道',video:'影片',keyword:'關鍵字',comment:'留言',
  21. user:'用戶',highlight:'高亮',color:'顏色',curvature:'弧度',border:'邊框',
  22. regex:'正規表示式',posttime:'發佈時間',regex_post_time:'分鐘,小時,^1\s天'},
  23. ];
  24. let autoDectectSystemLanguage=true;//set true to auto detect system language or set false to assign specify language below
  25. let language="en";
  26. let currentlanguageindex=0;
  27. //---add language by yourself -------------------------------------------------
  28. const BLOCK_CHANNEL=0;const BLOCK_VIDEO_KEYWORD=1;const BLOCK_VIDEO=2;const BLOCK_COMMENT_USER=3;const BLOCK_COMMENT_KEYWORD=4;
  29. const HIGHLIGHT_CHANNEL=5;const HIGHLIGHT_VIDEO_KEYWORD=6;const HIGHLIGHT_VIDEO=7;const HIGHLIGHT_COMMENT_USER=8;
  30. let narrowwidth=150;
  31. let block="block";let highlight="highlight";let setting="setting";let show='show';let hide='hide';
  32. let parametersArray=[
  33. {title:"channel",value:[],uiwidth:200,filter:"true",storageid:"small_array0"},
  34. {title:"video keyword",value:[],uiwidth:narrowwidth-40,filter:"true",storageid:"small_array1"},
  35. {title:"video",value:[],uiwidth:narrowwidth-50,filter:"true",storageid:"small_array2"},
  36. {title:"comment user",value:[],uiwidth:200,filter:"true",storageid:"small_array3"},
  37. {title:"comment keyword",value:[],uiwidth:narrowwidth,filter:"true",storageid:"small_array4"},
  38. {title:"channel",value:[],uiwidth:200,filter:"true",storageid:"small_array5"},
  39. {title:"video keyword",value:[],uiwidth:narrowwidth-40,filter:"true",storageid:"small_array6"},
  40. {title:"video",value:[],uiwidth:narrowwidth-50,filter:"true",storageid:"small_array7"},
  41. {title:"comment user",value:[],uiwidth:200,filter:"true",storageid:"small_array8"},
  42. ];
  43. const HIGHLIGHT_CHANNEL_BACKGROUND=0;const HIGHLIGHT_VIDEO_KEYWORD_ARC=1;const HIGHLIGHT_VIDEO_KEYWORD_BACKGROUND=2;
  44. const HIGHLIGHT_VIDEO_BACKGROUND=3;const HIGHLIGHT_COMMENT_USER_BACKGROUND=4;const HIGHTLIGHT_POSTTIME_BAKGROUND=5;
  45. const HIGHTLIGHT_POSTTIME_REGX=6;const HIGHTLIGHT_POSTTIME_TRUE=7;const HIDE_COMMENT=8;
  46. let parametersSingle=[
  47. {title:"highlight channel color",type:"color",value:'#ffffe6',storageid:"small_single0"},
  48. //highlight keyword border:
  49. {title:"curvature",type:"string",value:'12',valuer:'px',storageid:"small_single1"},
  50. {title:"color",type:"color",value:'#ff0000',valuep:'4px solid ',storageid:"small_single2"},
  51. {title:"highlight video color",type:"color",value:'#e6fffd',storageid:"small_single3"},
  52. {title:"hightlight comment user color",type:"color",value:'#ffffe6',storageid:"small_single4"},
  53. //highlight post time
  54. {title:"color",type:"color",value:'#ffd2dc',storageid:"small_single5"},
  55. {title:"regex",type:"string",value:'minute,hour,^1\sday',storageid:"small_single6"},
  56. {title:"highlight post time",type:"boolean",value:'true',storageid:"small_single7"},
  57. {title:"hide comment",type:"boolean",value:'false',storageid:"small_single8"},
  58. ];
  59. //----------------------------------------------------------------------------
  60. let title_restorefile="restore";let title_savefile="backup";
  61. class ParametersAgent{
  62. container;uniqueid;
  63. filename="parameters.txt";
  64. fontsize="14px";
  65. parametersUiHieght="200";
  66. splitmark=",";
  67. static checkid="_checked";
  68. static currentSelect=BLOCK_CHANNEL;
  69. constructor(container,filename,fontsize=this.fontsize){
  70. this.container=container;
  71. this.filename=filename;
  72. this.fontsize=fontsize;
  73. }
  74. static LT=0;static LB=1;static RT=2;static RB=3; //parameters ui position
  75. setPositionxy(mode){
  76. let edgex="left";let edgey="top";
  77. let edgegapx="2px",edgegapy="2px";
  78. if(mode==ParametersAgent.LT){edgex="left";edgey="top";}
  79. else if(mode==ParametersAgent.LB){edgex="left";edgey="bottom";edgegapy="20px";}
  80. else if(mode==ParametersAgent.RT){edgex="right";edgey="top";}
  81. else if(mode==ParametersAgent.RB){edgex="right";edgey="bottom";edgegapy="20px";}
  82. let xy=`${edgex}:${edgegapx};${edgey}:${edgegapy};`;
  83. return xy;
  84. }
  85. setPanel_Parameters(positionmode,dofunc_whenopen,dofunc_whenclose,lines=2){
  86. //let table=this.generateParametersArrayUI(lines);
  87. let table=this.generateParametersArrayUI_tabpane();
  88. this.createParametersControlPanel(positionmode,table,dofunc_whenopen,dofunc_whenclose);
  89. }
  90. static setTAshow(index){
  91. ParametersAgent.currentSelect=index;
  92. let backgroundcolor="#cce6ff";
  93. if(index==this.SETTING){
  94. let p=document.getElementById("smallsuposettings");
  95. let b=document.getElementById("smallbuttonsetting");
  96. if(p!=null&&b!=null){
  97. p.style.display="block";b.style.background = backgroundcolor;
  98. for(let i=0;i<parametersArray.length;i++){
  99. let p= parametersArray[i];
  100. let ta=document.getElementById(p.storageid);
  101. let button=document.getElementById("smallbutton"+p.storageid);
  102. ta.style.display="none";
  103. button.style.background = null;
  104. }
  105. }
  106. }else{
  107. for(let i=0;i<parametersArray.length;i++){
  108. let p= parametersArray[i];
  109. let ta=document.getElementById(p.storageid);
  110. let button=document.getElementById("smallbutton"+p.storageid);
  111. if(i==index){
  112. ta.style.display="block";
  113. button.style.background = backgroundcolor;
  114. }else{
  115. ta.style.display="none";
  116. button.style.background = null;
  117. }
  118. }
  119. let p=document.getElementById("smallsuposettings");let b=document.getElementById("smallbuttonsetting");
  120. if(p!=null&&b!=null){ p.style.display="none";b.style.background = null;}
  121. }
  122. }
  123. createParametersControlPanel(positionmode,mainpanel,dofunc_whenopen,dofunc_whenclose){
  124. const zindex=9999999;const position="fixed";
  125. const others="";//"transform: translate(0%, -100%);";
  126. const ui_border_color="#888888";
  127. //const id_uniq="youtubeP";
  128. const bgcolor="rgb(241, 242, 243)";const fcolor="black";
  129. const id_button="smallsupo_id_parametersControlPanel_button_"+this.uniqueid;
  130. const id_divpanel="smallsupo_id_parametersControlPanel_divpanel_"+this.uniqueid;
  131. const button_width="32px";
  132. const button_opacity="0.2";
  133. const ICON_SETTING='<svg id="i-settings" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32" fill="none" stroke="currentcolor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M13 2 L13 6 11 7 8 4 4 8 7 11 6 13 2 13 2 19 6 19 7 21 4 24 8 28 11 25 13 26 13 30 19 30 19 26 21 25 24 28 28 24 25 21 26 19 30 19 30 13 26 13 25 11 28 8 24 4 21 7 19 6 19 2 Z" /><circle cx="16" cy="16" r="4" /></svg>';
  134. const button_openicon=ICON_SETTING;
  135. let button_closeicon=ICON_SETTING;
  136. const button_fontsize="small";
  137. let SETTING=-1;
  138. let div=document.createElement("div");div.setAttribute("style","position:"+position+";z-Index:"+zindex+";"+this.setPositionxy(positionmode));
  139. let table=document.createElement("table");table.setAttribute("style","border:0px;");
  140. //---button--------------
  141. let tr0=document.createElement("tr");
  142. let td0=document.createElement("td");td0.setAttribute("style","vertical-align: top;");
  143. let button=document.createElement("div");button.setAttribute("id",id_button);
  144. button.setAttribute("style","text-align: center;cursor: pointer;width:"+button_width+";height:"+button_width+";background-color:"+bgcolor+";color:"+fcolor+";font-size: "+button_fontsize+";");
  145. button.innerHTML=button_closeicon;
  146. button.onmouseover= (e) => {
  147. let b=document.getElementById(id_button);let p=document.getElementById(id_divpanel);
  148. if(p.style.display=="none"){b.style.opacity=1;}
  149. };
  150. button.onmouseleave=(e) => {
  151. let b=document.getElementById(id_button);let p=document.getElementById(id_divpanel);
  152. if(p.style.display=="none"){b.style.opacity=button_opacity;}
  153. };
  154. button.onclick = ()=> {
  155. let b=document.getElementById(id_button);let p=document.getElementById(id_divpanel);
  156. if(p.style.display=="none"){
  157. b.innerHTML=button_openicon;b.style.opacity=1;button.style.border ="1px solid "+ui_border_color+";";
  158. p.style.display="block";
  159. this.openParametersUI(dofunc_whenopen);
  160. }else{
  161. b.innerHTML=button_closeicon;button.style.border ="none";p.style.display ="none";
  162. this.closeParametersUI(dofunc_whenclose);
  163. }
  164. };
  165. td0.appendChild(button);tr0.appendChild(td0);
  166. //-----
  167. let tr1=document.createElement("tr");let td1=document.createElement("td");td1.setAttribute("style","vertical-align: center;");
  168. let divpanel=document.createElement("div");divpanel.setAttribute("id",id_divpanel);
  169. divpanel.setAttribute("style","background-color:"+bgcolor+";color:"+fcolor+";display:none;");
  170. //-----main panel ui code here
  171. divpanel.appendChild(mainpanel);
  172. td1.appendChild(divpanel);tr1.appendChild(td1);
  173. //-----
  174. if(positionmode==ParametersAgent.LT||positionmode==ParametersAgent.RT){table.appendChild(tr0);table.appendChild(tr1);}
  175. else if(positionmode==ParametersAgent.LB||positionmode==ParametersAgent.RB){table.appendChild(tr1);table.appendChild(tr0);}
  176. div.appendChild(table);this.container.appendChild(div);
  177. //default hidden
  178. divpanel.style.display="none";
  179. setTimeout(()=>{
  180. if(document.getElementById(id_divpanel).style.display=="none")document.getElementById(id_button).style.opacity=button_opacity;
  181. },5000);
  182. }
  183. static setFilerValue(id,filter){
  184. for(let i=0;i<parametersArray.length;i++){
  185. if(parametersArray[i].storageid==id){
  186. parametersArray[i].filter=filter;
  187. ParametersAgent.saveLocalStorage1(parametersArray[i].storageid+ParametersAgent.checkid,parametersArray[i].filter);
  188. }
  189. }
  190. //console.log(id,filter);
  191. for(let i=0;i<parametersSingle.length;i++){
  192. if(parametersSingle[i].storageid==id){
  193. parametersSingle[i].value==filter;
  194. ParametersAgent.saveLocalStorage1(parametersSingle[i].storageid,filter);
  195. }
  196. }
  197. }
  198. generateSettingPanel(){
  199. let widthpx=290;
  200. let table=document.createElement("table");table.setAttribute("id","smallsuposettings");table.setAttribute("style","display:'none';");
  201. let tr=document.createElement("tr");
  202. let td=document.createElement("td");td.setAttribute("style","width:"+widthpx+"px;vertical-align: top;font-size:"+this.fontsize+";");
  203. td=this.generateParametersSingleUI(td);tr.appendChild(td);table.appendChild(tr);
  204. tr=document.createElement("tr");
  205. td=document.createElement("td");td.setAttribute("style","width:"+widthpx+"px;vertical-align: center;font-size:"+this.fontsize+";");
  206. td.innerText=" ";tr.appendChild(td);table.appendChild(tr);
  207. tr=document.createElement("tr");
  208. td=document.createElement("td");td.setAttribute("style","width:"+widthpx+"px;vertical-align: top;font-size:"+this.fontsize+";");
  209. this.loadLocalFile(td,title_restorefile,"font-size:"+this.fontsize+";",this.doAfterLoadFile.bind(this));
  210. tr.appendChild(td);table.appendChild(tr);
  211. tr=document.createElement("tr");
  212. td=document.createElement("td");td.setAttribute("style","width:"+widthpx+"px;vertical-align: top;font-size:"+this.fontsize+";");
  213. this.saveLocalFile(td,title_savefile,this.filename,"text","font-size:"+this.fontsize+";",this.doBeforeSaveFile.bind(this));
  214. tr.appendChild(td);table.appendChild(tr);
  215. return table;
  216. }
  217. generateParametersArrayUI_tabpane(){
  218. let table=document.createElement("table");
  219. table.style.border="1px solid #888888;";table.style.boxShadow = "10px 20px 30px gray";
  220. let trtop=document.createElement("tr");
  221. let tdtop=document.createElement("td");tdtop.setAttribute("colspan",3);tdtop.setAttribute("style","text-align:center;");
  222. tdtop.innerHTML="<h2>Youtube-filter by smallsupo@gmail.com 🐱</h2>";
  223. trtop.appendChild(tdtop);table.appendChild(trtop);
  224. let tr=document.createElement("tr");
  225. let tdleft=document.createElement("td");tdleft.setAttribute("style",
  226. "width:200px;vertical-align: top;font-size:"+this.fontsize+";");
  227. let menutable=document.createElement("table");
  228. for(let i=0;i<parametersArray.length;i++){
  229. if(i==0||i==5){
  230. let type=block;if(i==5)type=highlight;
  231. if(i==5){
  232. let tr=document.createElement("tr");
  233. let td=document.createElement("td");td.setAttribute("style","visibility: hidden;");td.innerText=" ";tr.appendChild(td);
  234. td=document.createElement("td");
  235. tr.appendChild(td);
  236. menutable.appendChild(tr);
  237. }
  238. let tr=document.createElement("tr");
  239. let td=document.createElement("td");td.setAttribute("colspan",2);
  240. td.setAttribute("style","color: red;font-weight: bold;width:200px;vertical-align: top;text-align:left;font-size:"+this.fontsize+";");
  241. td.innerText=type;
  242. tr.appendChild(td);menutable.appendChild(tr);
  243. }
  244. let menutr=document.createElement("tr");
  245. let p=parametersArray[i];
  246. let td=document.createElement("td");td.setAttribute("style",
  247. "vertical-align: top;font-size:"+this.fontsize+";");
  248. //let dtable=document.createElement("table");
  249. let dtdc=document.createElement("td");
  250. let dtdtitle=document.createElement("td");
  251. let c=document.createElement("input");c.setAttribute("id",p.storageid+ParametersAgent.checkid);c.setAttribute("type", "checkbox");
  252. let title=document.createElement("button");title.setAttribute("id","smallbutton"+p.storageid);
  253. title.setAttribute("style","width:180px;cursor: pointer;");title.innerText=p.title;
  254. p.filter=this.loadLocalStorage(p.storageid+ParametersAgent.checkid,p.filter);
  255. if(p.filter=="true"){c.checked=true;}else{c.checked=false;}
  256. c.onclick = function () {if(!c.checked){
  257. ParametersAgent.setFilerValue(p.storageid,"false");}else {ParametersAgent.setFilerValue(p.storageid,"true");}
  258. filter("from checkbox");
  259. };
  260. title.onclick = function (){
  261. ParametersAgent.setTAshow(i);
  262. };
  263. dtdc.appendChild(c);dtdtitle.appendChild(title);menutr.appendChild(dtdc);menutr.appendChild(dtdtitle);
  264. menutable.appendChild(menutr);
  265.  
  266. }
  267. //----------------------------------------------
  268. let menutr=document.createElement("tr");
  269. let td=document.createElement("td");td.setAttribute("style","visibility: hidden;");td.innerText=" ";menutr.appendChild(td);
  270. td=document.createElement("td");
  271. menutr.appendChild(td);
  272. menutable.appendChild(menutr);
  273. menutr=document.createElement("tr");
  274. td=document.createElement("td");menutr.appendChild(td);
  275. td=document.createElement("td");
  276. let settingbutton=document.createElement("button");settingbutton.setAttribute("style","width:180px;cursor: pointer;");
  277. settingbutton.innerText=setting;settingbutton.setAttribute("id","smallbuttonsetting");
  278. settingbutton.onclick = function (){ParametersAgent.setTAshow(this.SETTING);};
  279. td.appendChild(settingbutton);menutr.appendChild(td);
  280. menutable.appendChild(menutr);
  281. tdleft.appendChild(menutable);
  282. //----------------------------------------------
  283.  
  284. let tdcenter=document.createElement("td");tdcenter.setAttribute("style","width:300px;vertical-align: top;font-size:"+this.fontsize+";");
  285. for(let i=0;i<parametersArray.length;i++){
  286. let p=parametersArray[i];
  287. let ta=document.createElement("textarea")
  288. ta.setAttribute("id",p.storageid);ta.setAttribute("rows",20);
  289. ta.setAttribute("style","display:'none';width:98%;height:100%;white-space:pre;overflow:scroll;resize: general;font-size:"+this.fontsize+";");
  290. tdcenter.appendChild(ta);
  291. }
  292. tdcenter.appendChild(this.generateSettingPanel());
  293. //let tdright=document.createElement("td");tdright.setAttribute("style","width:200px;vertical-align: top;font-size:"+this.fontsize+";");
  294.  
  295. tr.appendChild(tdleft);tr.appendChild(tdcenter);//tr.appendChild(this.generateParametersSingleUI(tdright));
  296. table.appendChild(tr);
  297. tr=document.createElement("tr");
  298. //let td=document.createElement("td");td.setAttribute("style","vertical-align: center;font-size:"+this.fontsize+";");td.setAttribute("colspan",2);
  299. //this.loadLocalFile(td,title_restorefile,"font-size:"+this.fontsize+";",this.doAfterLoadFile.bind(this));tr.appendChild(td);
  300. //this.saveLocalFile(td,title_savefile,this.filename,"text","font-size:"+this.fontsize+";",this.doBeforeSaveFile.bind(this));tr.appendChild(td);
  301. td=document.createElement("td");td.setAttribute("style","text-align: right;");td.setAttribute("colspan",2);this.generateQuestionLink(td);tr.appendChild(td);
  302. table.appendChild(tr);
  303. return table;
  304. //--------------------
  305.  
  306. }
  307. generateParametersArrayUI(lines){
  308. let table=document.createElement("table");
  309. table.style.border="1px solid #888888;";table.style.boxShadow = "10px 20px 30px gray";
  310. let startindex=0;
  311. let onelinecount=Math.ceil(parametersArray.length/lines);
  312. for(let j=0;j<lines;j++){
  313. let tr=document.createElement("tr");
  314. for(let i=0;i<onelinecount;i++){
  315. //console.log("index:"+(startindex+i));
  316. if((startindex+i)<parametersArray.length){
  317. let p=parametersArray[startindex+i];
  318. let w=p.uiwidth;
  319. let td=document.createElement("td");td.setAttribute("style","width:"+w+"px;word-wrap: break-word;vertical-align: bottom;font-size:"+
  320. this.fontsize+";");
  321. let d=document.createElement("div");d.innerText=p.title;//+'('+p.value.length+')';
  322. let c=document.createElement("input");c.setAttribute("id",p.storageid+ParametersAgent.checkid);c.setAttribute("type", "checkbox");
  323. p.filter=this.loadLocalStorage(p.storageid+ParametersAgent.checkid,p.filter);
  324. if(p.filter=="true"){c.checked=true;}else{c.checked=false;}
  325. c.onclick = function () {if(!c.checked){
  326. ParametersAgent.setFilerValue(p.storageid,"false");}else {ParametersAgent.setFilerValue(p.storageid,"true");}
  327. filter("from checkbox");
  328. };
  329. d.appendChild(c);td.appendChild(d);
  330. tr.appendChild(td);
  331. }
  332. }
  333. if(j==0){
  334. let td=document.createElement("td");td.setAttribute("style","vertical-align: top;font-size:"+this.fontsize+";");
  335. td.setAttribute("rowspan",lines*2);
  336. tr.appendChild(this.generateParametersSingleUI(td));
  337. }
  338. table.appendChild(tr);
  339. tr=document.createElement("tr");
  340. for(let i=0;i<onelinecount;i++){
  341. if((startindex+i)<parametersArray.length){
  342. let p=parametersArray[startindex+i];
  343. if(Array.isArray(p.value)){
  344. let td=document.createElement("td");td.setAttribute("style","vertical-align: top;font-size:"+this.fontsize+";");
  345. let w=p.uiwidth;
  346. let h=this.parametersUiHieght;
  347. let ta=document.createElement("textarea")
  348. ta.setAttribute("id",p.storageid);
  349. ta.setAttribute("style","width:"+w+"px;height:"+h+"px;white-space:pre;overflow:scroll;resize: general;font-size:"+this.fontsize+";");
  350. td.appendChild(ta);tr.appendChild(td);
  351. }
  352. }
  353. }
  354. table.appendChild(tr);
  355. startindex+=onelinecount;
  356. }
  357. //-------
  358. let tr=document.createElement("tr");
  359. let td=document.createElement("td");td.setAttribute("style","vertical-align: center;font-size:"+this.fontsize+";");td.setAttribute("colspan",onelinecount);
  360. this.loadLocalFile(td,title_restorefile,"font-size:"+this.fontsize+";",this.doAfterLoadFile.bind(this));tr.appendChild(td);
  361. //td=document.createElement("td");td.setAttribute("style","vertical-align: center;text-align:right;font-size:"+this.fontsize+";");
  362. this.saveLocalFile(td,title_savefile,this.filename,"text","font-size:"+this.fontsize+";",this.doBeforeSaveFile.bind(this));tr.appendChild(td);
  363. td=document.createElement("td");td.setAttribute("style","text-align: right;");this.generateQuestionLink(td);tr.appendChild(td);
  364. table.appendChild(tr);
  365. return table;
  366. }
  367. generateParametersSingleUI(container){
  368. let innerhtml="";let bodersytle="border-style: ridge;border-width: 2px;margin:2px";
  369. let colorwidth="70px;";
  370. let p=parametersSingle[0];
  371. let div=document.createElement("div");div.setAttribute("style","vertical-align: top;font-size:"+this.fontsize+";"+bodersytle);
  372. innerhtml='<div><b>'+languages[currentlanguageindex].highlight+' '+languages[currentlanguageindex].channel+
  373. ':</b> '+languages[currentlanguageindex].color+'<input type="text" id="'+p.storageid+'" style="width:'+colorwidth+'">';
  374. innerhtml+='<input type="color" value="'+p.value+'" id="color-picker'+p.storageid+'"/></div>';
  375. div.innerHTML=innerhtml;container.appendChild(div);
  376.  
  377. div=document.createElement("div");div.setAttribute("style","vertical-align: top;font-size:"+this.fontsize+";"+bodersytle);
  378. innerhtml='<div><b>'+languages[currentlanguageindex].highlight+' '+languages[currentlanguageindex].channel+' '+
  379. languages[currentlanguageindex].border+':</b></div>';
  380. p=parametersSingle[1];
  381. innerhtml+='<div>'+p.title+':<input type="text" id="'+p.storageid+'" style="width:40px;">';
  382. p=parametersSingle[2];
  383. innerhtml+=' '+p.title+':<input type="text" id="'+p.storageid+'" style="width:'+colorwidth+'">';
  384. innerhtml+='<input type="color" value="'+p.value+'" id="color-picker'+p.storageid+'"/></div>';
  385. div.innerHTML=innerhtml;container.appendChild(div);
  386.  
  387. p=parametersSingle[3];
  388. div=document.createElement("div");div.setAttribute("style","vertical-align: top;font-size:"+this.fontsize+";"+bodersytle);
  389. innerhtml='<div><b>'+languages[currentlanguageindex].highlight+' '+languages[currentlanguageindex].video+
  390. ':</b> '+languages[currentlanguageindex].color+'<input type="text" id="'+p.storageid+'" style="width:'+colorwidth+'">';
  391. innerhtml+='<input type="color" value="'+p.value+'" id="color-picker'+p.storageid+'"/></div>';
  392. div.innerHTML=innerhtml;container.appendChild(div);
  393.  
  394. p=parametersSingle[4];
  395. div=document.createElement("div");div.setAttribute("style","vertical-align: top;font-size:"+this.fontsize+";"+bodersytle);
  396. innerhtml='<div><b>'+languages[currentlanguageindex].highlight+' '+languages[currentlanguageindex].comment+' '+
  397. languages[currentlanguageindex].user+':</b> '+languages[currentlanguageindex].color+'<input type="text" id="'+p.storageid+'" style="width:'+colorwidth+'">';
  398. innerhtml+='<input type="color" value="'+p.value+'" id="color-picker'+p.storageid+'"/></div>';
  399. div.innerHTML=innerhtml;container.appendChild(div);
  400.  
  401. div=document.createElement("div");div.setAttribute("style","vertical-align: top;font-size:"+this.fontsize+";"+bodersytle);
  402. //innerhtml='<div><b>'+languages[currentlanguageindex].highlight+' '+languages[currentlanguageindex].posttime+':</b></div>';
  403.  
  404. p=parametersSingle[5];
  405. innerhtml='<div>'+p.title+':<input type="text" id="'+p.storageid+'" style="width:'+colorwidth+'">';
  406. innerhtml+='<input type="color" value="'+p.value+'" id="color-picker'+p.storageid+'"/></div>';
  407. p=parametersSingle[6];
  408. innerhtml+='<div>'+p.title+':</div><div><input type="text" id="'+p.storageid+'" style="width:96%;"></div>';
  409. div.innerHTML=innerhtml;container.appendChild(div);
  410.  
  411. p=parametersSingle[7];
  412. let div1=document.createElement("div");div1.setAttribute("style","vertical-align: top;font-weight: bold;font-size:"+this.fontsize+";");
  413. let c=document.createElement("input");c.setAttribute("id",p.storageid);c.setAttribute("type", "checkbox");
  414. if((""+p.value).localeCompare("true")==0){c.checked=true;}else{c.checked=false;}
  415. c.onclick = function () {if(c.checked==false){
  416. p.value="false";//ParametersAgent.setFilerValue(p.storageid,"false");
  417. }else {p.value="true";//ParametersAgent.setFilerValue(p.storageid,"true");
  418. }
  419. filter("from checkbox post time");
  420. };
  421. div1.innerText=p.title;
  422. div1.appendChild(c);
  423. div.insertBefore(div1,div.firstChild);
  424.  
  425. let p1=parametersSingle[8];
  426. div=document.createElement("div");div.setAttribute("style","vertical-align: top;font-weight: bold;font-size:"+this.fontsize+";"+bodersytle);
  427. let c1=document.createElement("input");c1.setAttribute("id",p1.storageid);c1.setAttribute("type", "checkbox");
  428. if((""+p1.value).localeCompare("true")==0){c1.checked=true;}else{c1.checked=false;}
  429. c1.onclick = function () {if(!c1.checked){
  430. p1.value="false";}else {p1.value="true";}
  431. filter("from checkbox");
  432. };
  433. div.innerText=p1.title;
  434. div.appendChild(c1);
  435. container.appendChild(div);
  436.  
  437. return container;
  438. }
  439. generateParametersSingleUI1(container){
  440. let innerhtml="";
  441. for(let i=0;i<parametersSingle.length;i++){
  442. let p=parametersSingle[i];
  443. if(p.type.localeCompare("boolean")==0){
  444. let div=document.createElement("div");div.setAttribute("style","vertical-align: top;font-size:"+this.fontsize+";");
  445. let c=document.createElement("input");c.setAttribute("id",p.storageid);c.setAttribute("type", "checkbox");
  446. if((""+p.value).localeCompare("true")==0){c.checked=true;}else{c.checked=false;}
  447. c.onclick = function () {if(!c.checked){
  448. p.value="false";}else {p.value="true";}
  449. filter("from checkbox");
  450. };
  451. div.innerText=p.title;
  452. div.appendChild(c);
  453. container.appendChild(div);
  454. }else if(p.type.localeCompare("color")==0){
  455. let div=document.createElement("div");div.setAttribute("style","vertical-align: top;font-size:"+this.fontsize+";");
  456. innerhtml='<div>'+p.title+':</div><div><input type="text" id="'+p.storageid+'" style="width:150px;">';
  457. innerhtml+='<input type="color" value="'+p.value+'" id="color-picker'+p.storageid+'"/></div>';
  458. div.innerHTML=innerhtml;
  459. container.appendChild(div);
  460.  
  461. }else{
  462. let div=document.createElement("div");div.setAttribute("style","vertical-align: top;font-size:"+this.fontsize+";");
  463. innerhtml='<div>'+p.title+':</div><div><input type="text" id="'+p.storageid+'" style="width:96%;"></div>';
  464. div.innerHTML=innerhtml;
  465. container.appendChild(div);
  466. }
  467. }
  468. return container;
  469. }
  470. generateQuestionLink(container){
  471. let icon='<svg width="30" height="30" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="none" /><text x="50%" y="50%" font-size="50" text-anchor="middle" fill="black" dy=".3em">?</text></svg>';
  472. let div=document.createElement("div");div.setAttribute("style","align:right;vertical-align: bottom;font-size:"+this.fontsize+";cursor: pointer;");
  473. div.onclick = function () {
  474. window.location.href = "https://greasyfork.org/scripts/500798";
  475. };
  476. div.innerHTML=icon;
  477. container.appendChild(div);
  478. }
  479. saveLocalFile(element,uistring,filename,filetype,style,doBeforeSave){
  480. let div=document.createElement("div");
  481. let l=document.createElement("label");l.innerText=uistring+": ";
  482. let b=document.createElement("button");b.setAttribute("style","border: 1px solid #888888;cursor: pointer;"+style);
  483. b.innerText=".txt";
  484. b.onclick = function () {
  485. let s="";
  486. s=doBeforeSave();
  487. ParametersAgent.download(s, filename, filetype);
  488. };
  489. div.appendChild(l);div.appendChild(b);
  490. element.appendChild(div);
  491. }
  492. static download(data, filename, type) {
  493. var file = new Blob([data], {type: type});
  494. if (window.navigator.msSaveOrOpenBlob){
  495. window.navigator.msSaveOrOpenBlob(file, filename);
  496. }else {
  497. var a = document.createElement("a"),
  498. url = URL.createObjectURL(file);
  499. a.href = url;
  500. a.download = filename;
  501. document.body.appendChild(a);
  502. console.log(a);
  503. a.click();
  504. setTimeout(function() {
  505. document.body.removeChild(a);
  506. window.URL.revokeObjectURL(url);
  507. }, 0);
  508. }
  509. }
  510. loadLocalFile(element,uistring,style,doAfterLoad){
  511. let b=document.createElement("label");b.setAttribute("style",style);b.innerText=uistring+": ";element.appendChild(b);
  512. b=document.createElement("input");b.setAttribute("style",style);b.setAttribute("type", "file");
  513. b.addEventListener('change', function () {
  514. let fr = new FileReader();
  515. fr.onload = function () {
  516. doAfterLoad(fr.result);
  517. }
  518. fr.readAsText(this.files[0]);
  519. });
  520. element.appendChild(b);
  521. }
  522. doAfterLoadFile(s){
  523. let lines=s.split("\n");
  524. for(let i=0;i<lines.length;i++){
  525. if(lines[i].indexOf!=-1){
  526. let storageid=lines[i].substring(0,lines[i].indexOf(":"));
  527. let value=lines[i].substring(lines[i].indexOf(":")+1,lines[i].length);
  528. for(let j=0;j<parametersArray.length;j++){
  529. let p=parametersArray[j];
  530. if(p.storageid==storageid)p.value=JSON.parse(value);
  531. }
  532. for(let j=0;j<parametersSingle.length;j++){
  533. let p=parametersSingle[j];
  534. if(p.storageid==storageid)p.value=JSON.parse(value);
  535. }
  536. }
  537. }
  538. this.parametersToUi();
  539. this.save_parameters_toStorage();
  540. }
  541. doBeforeSaveFile(){
  542. this.uiToParameters();
  543. let s="";
  544. for(let i=0;i<parametersArray.length;i++){
  545. let p=parametersArray[i];
  546. s+=p.storageid+":"+JSON.stringify(p.value)+"\n";
  547. }
  548. for(let i=0;i<parametersSingle.length;i++){
  549. let p=parametersSingle[i];
  550. s+=p.storageid+":"+JSON.stringify(p.value)+"\n";
  551. }
  552. return s;
  553. }
  554. setColorPickerEvent(){
  555. for(let i=0;i<parametersSingle.length;i++){
  556. let p=parametersSingle[i];
  557. if(p.type.localeCompare("color")==0){
  558. let colorPicker = document.getElementById("color-picker"+p.storageid);
  559. let colortext = document.getElementById(p.storageid);
  560. if(colorPicker!=null&&colortext!=null){
  561. colorPicker.value=p.value;
  562. colorPicker.addEventListener("input", (event)=>{
  563. p.value=event.target.value;
  564. colortext.value=p.value;}, false);
  565. colorPicker.addEventListener("change",(event)=>{
  566. p.value=event.target.value;colortext.value=p.value;
  567. filterDelay(3000);}, false);
  568. }
  569. }
  570. }
  571. }
  572. openParametersUI(dofunc_whenopen){
  573. ParametersAgent.setTAshow(ParametersAgent.currentSelect);
  574. this.setColorPickerEvent();
  575. dofunc_whenopen();
  576. this.load_parameters_fromStorage();
  577. this.parametersToUi();
  578. }
  579. closeParametersUI(dofunc_whenclose){
  580. this.uiToParameters();
  581. this.save_parameters_toStorage();
  582. dofunc_whenclose("from parameter ui button closed");
  583. }
  584. load_parameters_fromStorage(){
  585. for(let i=0;i<parametersArray.length;i++){
  586. let p=parametersArray[i];
  587. p.value=JSON.parse(this.loadLocalStorage(p.storageid,JSON.stringify(p.value)));
  588. }
  589. for(let i=0;i<parametersSingle.length;i++){
  590. let p=parametersSingle[i];
  591. p.value=JSON.parse(this.loadLocalStorage(p.storageid,JSON.stringify(p.value)));
  592. }
  593. }
  594. save_parameters_toStorage(){
  595. for(let i=0;i<parametersArray.length;i++){
  596. let p=parametersArray[i];
  597. this.saveLocalStorage(p.storageid,JSON.stringify(p.value));
  598. }
  599. for(let i=0;i<parametersSingle.length;i++){
  600. let p=parametersSingle[i];
  601. this.saveLocalStorage(p.storageid,JSON.stringify(p.value));
  602. }
  603. }
  604. parametersToUi(){
  605. for(let i=0;i<parametersArray.length;i++){
  606. let p=parametersArray[i];
  607. let ta=document.getElementById(p.storageid);ta.value=p.value.join("\n")+"\n";
  608. let l=ta.value.length;ta.focus();ta.setSelectionRange(l, l);
  609. }
  610. for(let i=0;i<parametersSingle.length;i++){
  611. let p=parametersSingle[i];
  612. document.getElementById(p.storageid).value=p.value;
  613. }
  614. }
  615. uiToParameters(){
  616. for(let i=0;i<parametersArray.length;i++){
  617. let p=parametersArray[i];
  618. p.value=document.getElementById(p.storageid).value.split('\n');
  619. p.value=p.value.filter((str) => str !=="");
  620. }
  621. for(let i=0;i<parametersSingle.length;i++){
  622. let p=parametersSingle[i];
  623. let d=document.getElementById(p.storageid);
  624. if(d.type=="checkbox"){
  625. p.value=d.checked;
  626. }else{
  627. p.value=document.getElementById(p.storageid).value;
  628. }
  629. }
  630. }
  631. static saveLocalStorage1(ls_id,value){
  632. localStorage.setItem(ls_id,value);
  633. }
  634. saveLocalStorage(ls_id,value){
  635. localStorage.setItem(ls_id, value);
  636. }
  637. loadLocalStorage(ls_id,parameter){
  638. if(!localStorage.getItem(ls_id))localStorage.setItem(ls_id, parameter);
  639. return localStorage.getItem(ls_id);
  640. }
  641. saveArrayLocalStorage(ls_id,ary){
  642. localStorage.setItem(ls_id, ary.toString());
  643. }
  644. loadArrayLocalStorage(ls_id,splitmark){
  645. let r=null;
  646. if(!localStorage.getItem(ls_id)){localStorage.setItem(ls_id, "");}
  647. r=localStorage.getItem(ls_id).split(splitmark);
  648. r=r.filter((str) => str !=="");
  649. return r;
  650. }
  651. }
  652. //----------------------------------------------------------------
  653. // STG -----------------------------------------------------------------------------
  654. class STG{ //smallsupo tools - general
  655. constructor(){}
  656. static delayRun(func,miliseconds=3000){setTimeout(function(){func();},miliseconds);}
  657. static COMPARE=0;static INDEXOF=1;static REGX=2;static INDEXOFREVERSE=3;
  658. static isEnglish(text){
  659. return /^[a-z]+$/i.test(text);
  660. }
  661. static stringToRegArray(s,splitmark){
  662. //s = s.replace("\\", "\\\\");
  663. let arr=s.split(splitmark);
  664. for(let i=0;i<arr.length;i++){
  665. arr[i]=new RegExp(arr[i]);
  666. }
  667. return arr;
  668. }
  669. static findInArray(text,ary,mode=this.COMPARE){
  670. let find=false;
  671. if(text==null)return false;
  672. ary.forEach((word) => {
  673. if(mode==this.COMPARE){if (text.localeCompare(word) == 0 ){find=true;}}
  674. else if(mode==this.INDEXOF){if(text.toLowerCase().indexOf(word.toLowerCase()) != -1 ){find=true;}}
  675. else if(mode==this.REGX){
  676. if(this.isEnglish(word)){
  677. if(new RegExp("\\b("+word+")\\b", "gi").test(text)){find=true;}
  678. }else{
  679. if(new RegExp(word,"g").test(text)){find=true;}
  680. }
  681.  
  682. }
  683. else if(mode==this.INDEXOFREVERSE){if(word.toLowerCase().indexOf(text.toLowerCase()) != -1 ){find=true;}}
  684. });
  685. return find;
  686. }
  687. static findInArrayText(text,ary,mode=this.COMPARE){
  688. let find=null;
  689. if(text==null)return null;
  690. ary.forEach((word) => {
  691. if(mode==this.COMPARE){if (text.localeCompare(word) == 0 ){find=word;}}
  692. else if(mode==this.INDEXOF){if(text.toLowerCase().indexOf(word.toLowerCase()) != -1 ){find=word;}}
  693. else if(mode==this.REGX){if(word.test(text)){find=word;}}
  694. else if(mode==this.INDEXOFREVERSE){if(word.toLowerCase().indexOf(text.toLowerCase()) != -1 ){find=word;}}
  695. });
  696. return find;
  697. }
  698. static removeInArray(value,ary,mode=this.COMPARE){
  699. if(mode==this.COMPARE){return ary.filter((str) => str !==value);}
  700. else if(mode==this.INDEXOF){return ary.filter((str) => value.toLowerCase().indexOf(str.toLowerCase()) == -1);}
  701. else if(mode==this.INDEXOFREVERSE){return ary.filter((str) => str.toLowerCase().indexOf(value.toLowerCase()) == -1);}
  702. }
  703. static addRemoveInArray(value,addvalue,ary,mode=this.COMPARE){
  704. if(STG.findInArray(value,ary,mode)){ary=STG.removeInArray(value,ary,mode);}else{ary.push(addvalue);}
  705. return ary;
  706. }
  707. }
  708. //end STG ----------------------------------------------------
  709. //----------------------------------------------------------------
  710. class STD{ //smallsupo tools - dom ui
  711. static DISPLAY_NONE=0;static VISIBILITY_HIDDEN=1;
  712. constructor(){}
  713. static createEL(htmltag,id,style){
  714. let e=document.createElement(htmltag);if(id!=null)e.setAttribute("id",id);if(style!=null)e.setAttribute("style",style);
  715. return e;
  716. }
  717. //--------------------------------------------------------------------------------------------------
  718. static isHiddenEL(element,mode=this.DISPLAY_NONE){
  719. if(mode==this.DISPLAY_NONE){if(element.style.display==="none")return true;else return false;}
  720. else if(mode==this.VISIBILITY_HIDDEN){if(element.style.visibility==="hidden")return true;else return false;}
  721. }
  722. static hiddenEL(element,mode=this.DISPLAY_NONE){
  723. if(mode==this.DISPLAY_NONE){element.style.display="none";}
  724. else if(mode==this.VISIBILITY_HIDDEN){element.style.width="0px";element.style.height="0px";element.style.visibility="hidden";}
  725. }
  726. static visibleEL(element,mode=this.DISPLAY_NONE){
  727. if(mode==this.DISPLAY_NONE){element.style.display="block";}
  728. else if(mode==this.VISIBILITY_HIDDEN){element.style.width="100%";element.style.height="100%";element.style.visibility="visible";}
  729. }
  730. //-------------------------------------------------------------------------------------------------
  731. static eventStopBubbling(e) {
  732. e = window.event || e;if (e.stopPropagation) {e.stopPropagation();} else {e.cancelBubble = true;}
  733. }
  734. static setMouseEnterLeaveBgColor(el,enterColor="#eee",leaveColor="white"){
  735. el.addEventListener("mouseenter", () => {el.style.backgroundColor=enterColor;});
  736. el.addEventListener("mouseleave", () => {el.style.backgroundColor=leaveColor;});
  737. }
  738. static setMouseEnterLeaveColor(el,enterColor="#aaa",leaveColor="#eee"){
  739. el.addEventListener("mouseenter", () => {el.style.color=enterColor;});
  740. el.addEventListener("mouseleave", () => {el.style.color=leaveColor;});
  741. }
  742. //-------------------------------------------------------------------------------------------------
  743. static arrayToTextarea(ary,ta){if(ta!=null){ta.value = ary.join("\n")+"\n";}}
  744. static textareaToArray(ta){
  745. let ary=[];ary=ta.value.split('\n');ary=ary.filter((str) => str !=="");
  746. return ary;
  747. }
  748. static cursor_scrollToBottom(element){
  749. let l=element.value.length;element.focus();element.setSelectionRange(l, l);
  750. }
  751. static adjustELnotOutofScreen(dome,useParent,defaultTranslateX=0,defaultTranslateY=0){
  752. let body=document.getElementsByTagName('body')[0];
  753. if(useParent)body=dome.parentElement;
  754. let bodyRect = body.getBoundingClientRect();
  755. let domeRect = dome.getBoundingClientRect();
  756. //out right
  757. if(domeRect.right>bodyRect.right){
  758. dome.style.transform=`translate(${defaultTranslateX+parseInt(bodyRect.right-domeRect.right)}px,${defaultTranslateY}px)`;
  759. }
  760. //out left、top、bottom...
  761. //TBD
  762.  
  763. }
  764. //-------------------------------------------------------------------------------------------------
  765. static getDomNode(root,queryArray){
  766. let node=root;
  767. if(queryArray.length>0){
  768. node=root.querySelector(queryArray[0]);
  769. for(let i=1;i<queryArray.length;i++){if(node!=null){node=node.querySelector(queryArray[i]);}}
  770. }
  771. return node;
  772. }
  773. static getDomNodes(root,queryArray){
  774. let nodes=null;
  775. let endquery=queryArray.pop();
  776. let node=STD.getDomNode(root,queryArray);
  777. if(node!=null){nodes=node.querySelectorAll(endquery);}
  778. return nodes;
  779. }
  780. static getDomAttribute(root,queryArray,attribute){
  781. let value=null;let node=this.getDomNode(root,queryArray);
  782. if(node!=null){if(node.hasAttribute(attribute))value=node.getAttribute(attribute);}
  783. return value;
  784. }
  785. static getDomInnerText(root,queryArray){
  786. let value=null;let node=this.getDomNode(root,queryArray);
  787. if(node!=null){value=node.innerText;}
  788. return value;
  789. }
  790. //-------------------------------------------------------------------------------------------------
  791. static ABSOLUTE_RIGHT=0;static COVERALL=1;
  792. static setELPosition(el,mode){
  793. if(mode==STD.ABSOLUTE_RIGHT){
  794. el.style.position="absolute";
  795. el.style.left="100%";
  796. el.style.transform="translateX(-100%)";
  797. }
  798. if(mode==STD.COVERALL){
  799. el.style.position="absolute";
  800. //el.width="100%";el.height="100%";
  801. let parentnode=el.parentElement;let rect = parentnode.getBoundingClientRect();
  802. el.style.width=parseInt(rect.right-rect.left)+"px";
  803. el.style.height=parseInt(rect.bottom-rect.top)+"px";
  804. el.style.textAlign="center";
  805. el.style.left=parentnode.offsetLeft; el.style.top=parentnode.offsetTop;
  806. }
  807. }
  808. //-------special---------------------------------------------------------------------------------------
  809. static ISCOVER=true;static UNCOVER=false
  810. static setCoverEL(becoverdEl,uniqueId,show,zindex=999,inner=SVGICON.CLOSERED,bgcolor="transparent"){ //show cover, hind cover
  811. if(becoverdEl==null)return;
  812. let id="smallsupo_coverel_id"+uniqueId;
  813. let temp=becoverdEl.querySelectorAll('span[id="'+id+'"]');
  814. if(temp.length>1){
  815. for(let i=1;i<temp.length;i++)temp[i].remove();
  816. }else if(temp.length==1){
  817. }else{
  818. let cover=STD.createEL("span",id,"zindex:"+zindex+";background-color:"+bgcolor+";");
  819. //cover.style.backgroundColor="blue";
  820. cover.innerHTML=SVGICON.getIcon(inner,32,32);
  821. becoverdEl.appendChild(cover);
  822. STD.setELPosition(cover,STD.COVERALL);
  823. STD.hiddenEL(cover);
  824. }
  825. let cover=document.getElementById(id);
  826. if(cover!=null){
  827. if(show)STD.visibleEL(cover);
  828. else STD.hiddenEL(cover);
  829. }
  830. }
  831. }
  832. //--------------------------------------------------------------
  833. class SVGICON{
  834. constructor(){}
  835. static SETTING='<svg id="i-settings" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="WWWWWW" height="HHHHHH" fill="none" stroke="currentcolor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M13 2 L13 6 11 7 8 4 4 8 7 11 6 13 2 13 2 19 6 19 7 21 4 24 8 28 11 25 13 26 13 30 19 30 19 26 21 25 24 28 28 24 25 21 26 19 30 19 30 13 26 13 25 11 28 8 24 4 21 7 19 6 19 2 Z" /><circle cx="16" cy="16" r="4" /></svg>';
  836. static CLOSERED='<svg id="i-close" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="WWWWWW" height="HHHHHH" fill="none" stroke="red" stroke-linecap="round" stroke-linejoin="round" stroke-width="4"><path d="M2 30 L30 2 M30 30 L2 2" /></svg>';
  837. static getIcon(icontype,width=32,height=32){
  838. return icontype.replace("WWWWWW",width).replace("HHHHHH",height);
  839. }
  840. }
  841. //--下拉選單--------------------------------------------------------------
  842. let currentMenu=null;
  843. function whenPopup(p){
  844. if(currentMenu!=null){
  845. STD.hiddenEL(currentMenu);
  846. }
  847. currentMenu=p;
  848. }
  849. class SFAC_DropDownMenu{
  850. //lines[{title:"",func}]
  851. static IDPRE="smallsupo_dropdown_id";
  852. static removeUnFIndPopupMenu(containerEL,uniqueId,index){
  853. let ns=containerEL.querySelectorAll('span[id^="'+SFAC_DropDownMenu.IDPRE+uniqueId+'"]');
  854. if(ns!=null){
  855. if(ns.length==1){
  856. let x=containerEL.querySelector('span[id="'+SFAC_DropDownMenu.IDPRE+uniqueId+index+'"]');
  857. if(x==null){
  858. containerEL.removeChild(ns[0]);
  859. }
  860. }else{
  861. for(let i=0;i<ns.length;i++){
  862. containerEL.removeChild(ns[i]);
  863. }
  864. }
  865. }
  866. }
  867. static setPopupMenu(containerEL,uniqueId,items,attributes,positionMode,whenPopup,endPopup,useParent,zindex=999){
  868. if(containerEL==null)return;
  869. let dropdown_id=SFAC_DropDownMenu.IDPRE+uniqueId;
  870. let dropdown_button_id="smallsupo_dropdown_button_id"+uniqueId;
  871. let dropdown_panel_id="smallsupo_dropdown_panel_id"+uniqueId;
  872. let temp=containerEL.querySelectorAll('span[id="'+dropdown_id+'"]');
  873. if(temp.length>1){
  874. for(let i=1;i<temp.length;i++)temp[i].remove();
  875. }else if(temp.length==1){
  876. }else{
  877. let span=STD.createEL("span",dropdown_id,"z-index:"+zindex+";align:left;");
  878. if(positionMode!=null)STD.setELPosition(span,positionMode);
  879. let button=STD.createEL("button",dropdown_button_id,'color:#eeeeee;padding:0px 10px 4px 10px;background-color:transparent;border:none;cursor: pointer;');button.innerText="⁝";span.appendChild(button);
  880. STD.setMouseEnterLeaveColor(button);
  881. let panel=STD.createEL("div",dropdown_panel_id,"display: none;padding:6px;position: absolute;z-index:99999;background-color: #ffffff;box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);transform: translateX(-20px);");
  882. for(let i=0;i<items.length;i++){
  883. let item=STD.createEL("div",null,"cursor: pointer;padding:2px;white-space: nowrap;");
  884. item.innerHTML=items[i].title(attributes);
  885. STD.setMouseEnterLeaveBgColor(item);
  886. item.onclick=()=>{
  887. let panel=document.getElementById(dropdown_panel_id);panel.style.display="none";
  888. items[i].func(attributes);
  889. STD.eventStopBubbling(event);
  890. };
  891. panel.appendChild(item);
  892. }
  893. span.appendChild(panel);
  894. containerEL.appendChild(span);
  895. //-------------------------------------------
  896. button.onclick = ()=> {
  897. let b=document.getElementById(dropdown_button_id);
  898. let p=document.getElementById(dropdown_panel_id);
  899. if(STD.isHiddenEL(p)){
  900. whenPopup(p);
  901. STD.visibleEL(p);STD.adjustELnotOutofScreen(p,useParent,-22);
  902. }else{
  903. STD.hiddenEL(p);
  904. }
  905. STD.eventStopBubbling(event);
  906. };
  907. }
  908. }
  909. }
  910.  
  911. //----------------------------------------------------------------
  912. //--- 文字選取popup選單 ---------------------------------------------------------
  913. let selecttextpopupshow=false;
  914. class SFAC_SelectTextPopup{
  915. constructor(){}
  916. static setPopupEvent(triggerEL,containerEL,lines,uniqueId,whenPopup,endPopup){
  917. triggerEL.onmouseup = ()=>{
  918. let selecttext = window.getSelection().toString();document.execCommand('copy');
  919. if(selecttext!=null&&selecttext.length>0){
  920. //window.getSelection().empty();
  921. let x=event.clientX;let y=event.clientY;
  922. if(!selecttextpopupshow)SFAC_SelectTextPopup.setPopup(containerEL,x,y,uniqueId,selecttext,lines,whenPopup,endPopup);
  923. }
  924. STD.eventStopBubbling(event);
  925. };
  926. }
  927. static setPopup(containerEL,x,y,uniqueId,selecttext,lines,whenPopup,endPopup,useParent=false){
  928. let container=document.getElementsByTagName('body')[0];if(containerEL!=null)container=containerEL;
  929. let left=0;if(x!=null)left=x;let top=0;if(y!=null)top=y;
  930. let popup_id="smallsupo_selecttextpopup_id"+uniqueId;
  931. let temp=container.querySelectorAll('div[id="'+popup_id+'"]');
  932. if(temp.length>1){
  933. for(let i=1;i<temp.length;i++)temp[i].remove();
  934. }else if(temp.length==1){
  935. }else{
  936. let popup=STD.createEL("div",popup_id,'left:'+left+'px;top:'+top+'px;padding:6px;border:1px black;'+
  937. 'position: fixed;z-index:999999;cursor: pointer;background-color: #ffffff;'+
  938. 'box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);white-space: nowrap;'+
  939. 'transform: translate(-50px, -30px);');
  940. for(let i=0;i<lines.length;i++){
  941. let item=STD.createEL("div",popup_id+"_item"+i,"cursor: pointer;padding:2px;white-space: nowrap;");
  942. STD.setMouseEnterLeaveBgColor(item);
  943. popup.appendChild(item);
  944. }
  945. container.appendChild(popup);
  946. popup.onmouseleave= (e) => {popup.style.display="none";};
  947. }
  948. //-- do --
  949. let p=document.getElementById(popup_id);
  950. //whenPopup(p);
  951. p.style.left=left+"px";p.style.top=top+"px";
  952. p.style.display="block";
  953. p.style.transform="translate(-30px,-20px)";STD.adjustELnotOutofScreen(p,useParent,-32,-20);
  954. for(let i=0;i<lines.length;i++){
  955. let item=document.getElementById(popup_id+"_item"+i);
  956. item.innerHTML=lines[i].title+"<font color=#ff0000>"+selecttext+"</font>";
  957. item.onclick = function () {
  958. p.style.display="none";
  959. lines[i].func(selecttext);
  960. };
  961. }
  962.  
  963. }
  964. }
  965.  
  966. // end 文字選取popup選單 -------------------------------------------------
  967. class YoutubeHandler{
  968. static findNewDayNode(e){
  969. let nodes=STD.getDomNodes(e,['div[id="content"]','div[id="details"]','div[id="meta"]','ytd-video-meta-block','div[id="metadata"]','div[id="metadata-line"]','span']);
  970. let node=null;
  971. if(nodes!=null&&nodes.length>=2)node=nodes[1];
  972. return node;
  973. }
  974. static find_video_channel_id_youtube_homepage(e){
  975. let id=null;
  976. let node=STD.getDomNode(e,['div[id="content"]','div[id="details"]','a[id="avatar-link"]']);
  977. if(node!=null){
  978. id=node.getAttribute("href");
  979. if(id!=null){id=id.substring(1,id.length)+"|"+node.getAttribute("title");}
  980. //console.log(id);
  981. }
  982. return id;
  983. }
  984. static find_comment_channel_id_youtube_watchpage(e){
  985. let r=null;let r1=null;
  986. let as=['div[id="header-author"]','a[id="author-text"]'];
  987. let as1=['div[id="header-author"]','a[id="author-text"]','span'];
  988. r=STD.getDomAttribute(e,as,"href");
  989. r1=STD.getDomInnerText(e,as1);
  990. //if(r!=null)r=r.replace("/channel/","")+"|"+r.replace("/","");
  991. if(r!=null){r=r.replace("/channel/","");r=r.replace("/","");}
  992. return r;
  993. }
  994. static get_channel_id_in_comment_replay_watchpage(e,queryArray){
  995. let id=null;
  996. let node=STD.getDomNode(e,queryArray);
  997. if(node!=null){
  998. //id=node.getAttribute("href");id=id.replace("/channel/","")+"|"+id.replace("/","");
  999. id=node.getAttribute("href");id=id.replace("/channel/","");id=id.replace("/","");
  1000. }
  1001. return id;
  1002. }
  1003. static find_video_channel_id_watchpage(e){
  1004. let id=null;
  1005. let node=STD.getDomNode(e,['div[id="upload-info"]','div[id="container"]','yt-formatted-string']);
  1006. if(node!=null){
  1007. id=node.querySelector('a').getAttribute("href");
  1008. if(id!=null)id=id.substring(1,id.length)+"|"+node.innerText;
  1009. //console.log(id);
  1010. }
  1011. return id;
  1012. }
  1013. static find_video_channel_id_youtube_searchpage(e){
  1014. let id=null;
  1015. let node=STD.getDomNode(e,['div[id="channel-info"]','ytd-channel-name','yt-formatted-string','a']);
  1016. if(node!=null){
  1017. id=node.getAttribute("href");
  1018. if(id!=null){id=id.substring(1,id.length)+"|"+node.innerText;}
  1019. //console.log(id);
  1020. }
  1021. return id;
  1022. }
  1023. static cutid(id){
  1024. let result=id;
  1025. if(id.indexOf("|")!=-1){result=id.substring(0,id.indexOf("|"));}
  1026. return result;
  1027. }
  1028. static setUnlink_HomePage(rootn){
  1029. function handleClick(event) {
  1030. return false;
  1031. }
  1032. let n=STD.getDomNode(rootn,['div[id="content"]','div[id="details"]','div[id="meta"]','h3']);
  1033. if(n!=null)n.style.cursor = "text";
  1034. YoutubeHandler.removeALink(rootn,['div[id="content"]','div[id="details"]','div[id="meta"]','h3','a[id="video-title-link"]']);
  1035. }
  1036. static setUnlinkSearchPage(rootn){
  1037. function handleClick(event) {
  1038. event.preventDefault();
  1039. event.stopPropagation();
  1040. return false;
  1041. }
  1042. let n=STD.getDomNode(rootn,['div[id="dismissible"]','div[class="text-wrapper style-scope ytd-video-renderer"]','div[id="meta"]','h3']);
  1043. if(n!=null)n.style.cursor = "default";
  1044. YoutubeHandler.removeALink(n,['a']);
  1045. }
  1046. static setUnlinkRightSideWatchPage(rootn,queryArray){
  1047. //let n=STD.getDomNode(rootn,queryArray);
  1048. //if(n!=null)n=STD.getDomNode(n,['h3']);
  1049. if(rootn!=null)rootn.style.cursor = "text";
  1050. YoutubeHandler.removeALink(rootn,queryArray);
  1051. }
  1052. static removeALink(rootn,queryArray){
  1053. function handleClick1(event) {
  1054. //event.preventDefault();
  1055. //event.stopPropagation();
  1056. return false;
  1057. }
  1058. let n1=STD.getDomNode(rootn,queryArray);
  1059. if(n1!=null){
  1060. n1.style.display = "inline-block";
  1061. n1.style.pointerEvents = "none";
  1062. n1.onclick=handleClick1;
  1063. }
  1064. }
  1065. static elementSetToDefault(e,newDayNode){
  1066. e.style.display="block";
  1067. e.style.background =null;
  1068. e.style.border = null;
  1069. if(newDayNode!=null){
  1070. newDayNode.style.background =null;
  1071. newDayNode.style.border = null;
  1072. }
  1073. }
  1074. static removeHighLightTag(e,uniqueid){
  1075. let id="smallsupo_"+uniqueid
  1076. let c=document.querySelectorAll('span[id^="'+id+'"]');
  1077. for(let i=0;i<c.length;i++){
  1078. if(e.contains(c[i])){
  1079. e.removeChild(c[i]);
  1080. }
  1081. }
  1082. }
  1083. static setHighLightTag(e,uniqueid,text,show,bordercolor,borderradius){
  1084. let id="smallsupo_"+uniqueid;
  1085. //console.log(id);
  1086. let n=document.getElementById(id);
  1087. if(n==null){
  1088. let x=STD.createEL("span",id,"position:absolute;right:0px;bottom:0px;padding:4px 4px 0px 4px;color:white;background-color:"+bordercolor+";");
  1089. x.style.transform="translateXY(-96%,-96%)";
  1090. x.style.borderRadius=borderradius+" 0px 2px 0px";x.innerText=text;
  1091. e.appendChild(x);
  1092. }else{
  1093. if(show){n.style.display="block";n.innerText=text;
  1094. }else {n.style.display="none";}
  1095. }
  1096. }
  1097. static setHighLightTagforWatchPage(e,uniqueid,text,show,bordercolor,borderradius){
  1098. let id="smallsupo_"+uniqueid;
  1099. //console.log(id);
  1100. let n=document.getElementById(id);
  1101. if(n==null){
  1102. let x=STD.createEL("span",id,"position:relative;left:0px;top:0px;padding:2px 2px 2px 2px;color:white;background-color:"+bordercolor+";");
  1103. //x.style.transform="translateXY(-96%,-96%)";
  1104. x.style.borderRadius="4px 4px 4px 4px";x.innerText=text;
  1105. e.insertBefore(x,e.firstChild);
  1106. }else{
  1107. if(show){n.style.display="block";n.innerText=text;
  1108. }else {n.style.display="none";}
  1109. }
  1110. }
  1111. static findIdInArray(text,ary){
  1112. let find=false;
  1113. if(text==null)return false;
  1114. if(text.indexOf("|")!=-1)text=text.substring(0,text.indexOf("|"));
  1115. ary.forEach((word) => {
  1116. if(word.indexOf("|")!=-1)word=word.substring(0,word.indexOf("|"));
  1117. if (text.localeCompare(word) == 0 ){find=true;}
  1118. });
  1119. return find;
  1120. }
  1121. static findChannelIdareadyhave(idtitle){
  1122. let find=false;
  1123. for(let i=0;i<tempchannelArray.length;i++){
  1124. let cid=tempchannelArray[i];
  1125. if(cid.title==idtitle){
  1126. find=true;
  1127. }
  1128. }
  1129. return find;
  1130. }
  1131. static getChannelId(idtitle){
  1132. let id=null;
  1133. for(let i=0;i<tempchannelArray.length;i++){
  1134. let cid=tempchannelArray[i];
  1135. if(cid.title==idtitle){
  1136. id=cid.id;
  1137. }
  1138. }
  1139. return id;
  1140. }
  1141. static moveChannelcontainerToUPLayer(rootn){
  1142. let dn=rootn.querySelector('div#dismissible div[class="metadata style-scope ytd-compact-video-renderer"]');
  1143. if(dn!=null){
  1144. let sn=dn.querySelector('a').querySelector('div');
  1145. if(sn!=null){
  1146. dn.appendChild(sn);
  1147. //dn.querySelector('a').querySelector('div').inner;
  1148. }
  1149. }
  1150.  
  1151. }
  1152. static getChannelIDformURL(rootn,link,videoid,channelcontainer,channeltitle){
  1153. $.ajax({
  1154. url: link,type: 'get',dataType: "text",
  1155. success: (data) => {
  1156. let serchstartstring='<link itemprop="url" href="http://www.youtube.com/';
  1157. let startindex=data.indexOf(serchstartstring);
  1158. if(startindex<0)return;
  1159. let r=data.substring(startindex+serchstartstring.length,data.indexOf('"',startindex+serchstartstring.length));
  1160.  
  1161. if(channelcontainer==null)return;
  1162. let id=r;
  1163. //console.log(id);
  1164. let o={title:channeltitle,id:id}
  1165. tempchannelArray.push(o);
  1166. id=id+"|"+channeltitle;
  1167. SFAC_DropDownMenu.removeUnFIndPopupMenu(channelcontainer,"runchannel_watch",videoid);
  1168. SFAC_DropDownMenu.setPopupMenu(channelcontainer,"runchannel_watch"+videoid,dropdownitems_homepage,[id,videoid],null,whenPopup,null,false);
  1169. //moveChannelcontainerToUPLayer(rootn);
  1170. },
  1171. complete: (data) => {
  1172.  
  1173. },
  1174. error: (data) => {
  1175.  
  1176. }
  1177. });
  1178. }
  1179. static drawUI(tag,cid,vid,text,e,arr){
  1180. let keeprun=true;
  1181. for(let i=0;i<arr.length;i++){
  1182. if(keeprun){
  1183. if(arr[i]==HIGHLIGHT_VIDEO&&parametersArray[HIGHLIGHT_VIDEO].filter=="true"){
  1184. if(STG.findInArray(vid,parametersArray[HIGHLIGHT_VIDEO].value,STG.COMPARE)){e.style.background=parametersSingle[HIGHLIGHT_VIDEO_BACKGROUND].value;keeprun=false;}
  1185. }else if(arr[i]==BLOCK_VIDEO&&parametersArray[BLOCK_VIDEO].filter=="true"){
  1186. if(STG.findInArray(vid,parametersArray[BLOCK_VIDEO].value,STG.COMPARE)){STD.hiddenEL(e);keeprun=false;}
  1187. }else if(arr[i]==HIGHLIGHT_VIDEO_KEYWORD&&parametersArray[HIGHLIGHT_VIDEO_KEYWORD].filter=="true"){
  1188. if(STG.findInArray(text,parametersArray[HIGHLIGHT_VIDEO_KEYWORD].value,STG.REGX)){
  1189. let s=STG.findInArrayText(text,parametersArray[HIGHLIGHT_VIDEO_KEYWORD].value,STG.INDEXOF);
  1190. e.style.border = parametersSingle[HIGHLIGHT_VIDEO_KEYWORD_BACKGROUND].valuep+parametersSingle[HIGHLIGHT_VIDEO_KEYWORD_BACKGROUND].value;
  1191. e.style.borderRadius =parametersSingle[HIGHLIGHT_VIDEO_KEYWORD_ARC].value+parametersSingle[HIGHLIGHT_VIDEO_KEYWORD_ARC].valuer;
  1192. YoutubeHandler.setHighLightTag(e,tag+vid,s,true,parametersSingle[HIGHLIGHT_VIDEO_KEYWORD_BACKGROUND].value,e.style.borderRadius);
  1193. keeprun=true;
  1194. }
  1195. }else if(arr[i]==HIGHLIGHT_CHANNEL&&parametersArray[HIGHLIGHT_CHANNEL].filter=="true"){
  1196. if(YoutubeHandler.findIdInArray(cid,parametersArray[HIGHLIGHT_CHANNEL].value)){e.style.background=parametersSingle[HIGHLIGHT_CHANNEL_BACKGROUND].value;keeprun=false;}
  1197. }else if(arr[i]==BLOCK_CHANNEL&&parametersArray[BLOCK_CHANNEL].filter=="true"){
  1198. if(YoutubeHandler.findIdInArray(cid,parametersArray[BLOCK_CHANNEL].value)){STD.hiddenEL(e);keeprun=false;}
  1199. }else if(arr[i]==BLOCK_VIDEO_KEYWORD&&parametersArray[BLOCK_VIDEO_KEYWORD].filter=="true"){
  1200. if(STG.findInArray(text,parametersArray[BLOCK_VIDEO_KEYWORD].value,STG.INDEXOF)){STD.hiddenEL(e);keeprun=false;}
  1201. }
  1202. else if(arr[i]==HIGHLIGHT_COMMENT_USER&&parametersArray[HIGHLIGHT_COMMENT_USER].filter=="true"){
  1203. if(STG.findInArray(cid,parametersArray[HIGHLIGHT_COMMENT_USER].value,STG.COMPARE)){e.style.background=parametersSingle[HIGHLIGHT_COMMENT_USER_BACKGROUND].value;keeprun=false;}
  1204. }else if(arr[i]==BLOCK_COMMENT_USER&&parametersArray[BLOCK_COMMENT_USER].filter=="true"){
  1205. if(YoutubeHandler.findIdInArray(cid,parametersArray[BLOCK_COMMENT_USER].value)){STD.hiddenEL(e);keeprun=false;}
  1206. }else if(arr[i]==BLOCK_COMMENT_KEYWORD&&parametersArray[BLOCK_COMMENT_KEYWORD].filter=="true"){
  1207. //if(STG.findInArray(text,parametersArray[BLOCK_COMMENT_KEYWORD].value,STG.INDEXOF)){STD.hiddenEL(e);}
  1208. if(STG.findInArray(text,parametersArray[BLOCK_COMMENT_KEYWORD].value,STG.REGX)){STD.hiddenEL(e);}
  1209. }
  1210. }
  1211. }
  1212. return keeprun;
  1213. }
  1214. }
  1215. //----------------------------------------------------------------
  1216. function removeClickEvent(){
  1217. window.addEventListener('click', event => {
  1218. //console.log(event.target);
  1219. if (event.target.tagName=="H3") {
  1220. event.stopPropagation();
  1221. //event.preventDefault();
  1222. }
  1223. }, true);
  1224. }
  1225. //---------------------------------------------------------------
  1226. let CHANNELID=0,VIDEOID=1;
  1227. let dropdownitems_homepage_title=['block channel','block video','highlight channel','highlight video'];
  1228. let dropdownitems_homepage=[
  1229. {title:(attributes)=>{return `${dropdownitems_homepage_title[0]} <font color=#ff0000>${attributes[CHANNELID].split("|")[1]}</font>`},
  1230. func:(attributes)=>{let value=attributes[CHANNELID];if(value.indexOf("|")!=-1)value=value.substring(0,value.indexOf("|"));
  1231. parametersArray[BLOCK_CHANNEL].value=STG.addRemoveInArray(value,attributes[CHANNELID],parametersArray[BLOCK_CHANNEL].value,STG.INDEXOFREVERSE);
  1232.  
  1233. sp.save_parameters_toStorage();filter("from dropdownmenu_homepage");}},
  1234. {title:(attributes)=>{return dropdownitems_homepage_title[1]},
  1235. func:(attributes)=>{parametersArray[BLOCK_VIDEO].value=STG.addRemoveInArray(attributes[VIDEOID],attributes[VIDEOID],parametersArray[BLOCK_VIDEO].value);sp.save_parameters_toStorage();filter("from dropdownmenu_homepage");}},
  1236. {title:(attributes)=>{return dropdownitems_homepage_title[2]},
  1237. func:(attributes)=>{let value=attributes[CHANNELID];if(value.indexOf("|")!=-1)value=value.substring(0,value.indexOf("|"));
  1238. parametersArray[HIGHLIGHT_CHANNEL].value=STG.addRemoveInArray(value,attributes[CHANNELID],parametersArray[HIGHLIGHT_CHANNEL].value,STG.INDEXOFREVERSE);
  1239.  
  1240. sp.save_parameters_toStorage();filter("from dropdownmenu_homepage");}},
  1241. {title:(attributes)=>{return dropdownitems_homepage_title[3]},
  1242. func:(attributes)=>{parametersArray[HIGHLIGHT_VIDEO].value=STG.addRemoveInArray(attributes[VIDEOID],attributes[VIDEOID],parametersArray[HIGHLIGHT_VIDEO].value);sp.save_parameters_toStorage();filter("from dropdownmenu_homepage");}}
  1243. ];
  1244. let selecttext_popupitems_homepage_title=['block','highlight'];
  1245. let selecttext_popupitems_homepage=[
  1246. {title:selecttext_popupitems_homepage_title[0]+" ",func:(selecttext)=>{parametersArray[BLOCK_VIDEO_KEYWORD].value.push(selecttext.trim());sp.save_parameters_toStorage();filter("from selecttext_popupitems_homepage");}},
  1247. {title:selecttext_popupitems_homepage_title[1]+" ",func:(selecttext)=>{parametersArray[HIGHLIGHT_VIDEO_KEYWORD].value=STG.addRemoveInArray(selecttext.trim(),selecttext.trim(),parametersArray[HIGHLIGHT_VIDEO_KEYWORD].value);sp.save_parameters_toStorage();filter("from selecttext_popupitems_homepage");}}]
  1248.  
  1249. function filter_homepage_newVersion(){
  1250. let videoPanels=document.querySelectorAll('ytd-rich-item-renderer[class="style-scope ytd-rich-grid-renderer"]');
  1251. for(let i=0;i<videoPanels.length;i++){
  1252. let newDayNode=YoutubeHandler.findNewDayNode(videoPanels[i]);
  1253. YoutubeHandler.elementSetToDefault(videoPanels[i],newDayNode);
  1254. let id=YoutubeHandler.find_video_channel_id_youtube_homepage(videoPanels[i]);
  1255. let text=null;
  1256. YoutubeHandler.setUnlink_HomePage(videoPanels[i]);
  1257. let videoid=STD.getDomAttribute(videoPanels[i],['div#content div#details div#meta a#video-title-link'],"href");
  1258. if(videoid!=null){
  1259. videoid=videoid.replace("/watch?v=","");
  1260. if(videoid.indexOf("&")!=-1)videoid=videoid.substring(0,videoid.indexOf("&"));
  1261. }
  1262. let channelcontainer=STD.getDomNode(videoPanels[i],['div#content div#details div#meta ytd-video-meta-block div#metadata div#byline-container']);
  1263. let titlecontainer=STD.getDomNode(videoPanels[i],['div#content div#details div#meta h3 yt-formatted-string#video-title']);
  1264. if(titlecontainer!=null){text=titlecontainer.innerText;}
  1265. //-------------------
  1266. let keeprun=false;
  1267. if(id!=null&&videoid!=null&&channelcontainer!=null&&titlecontainer!=null&&text!=null){
  1268. keeprun=true;
  1269. SFAC_DropDownMenu.removeUnFIndPopupMenu(channelcontainer,"",videoid);
  1270. SFAC_DropDownMenu.setPopupMenu(channelcontainer,videoid,dropdownitems_homepage,[id,videoid],STD.ABSOLUTE_RIGHT,whenPopup,null,false);
  1271. let textcontainer=STD.getDomNode(videoPanels[i],['div#content div#details div#meta']);
  1272. SFAC_SelectTextPopup.setPopupEvent(textcontainer,null,selecttext_popupitems_homepage,"homepage",whenPopup,null);
  1273. if(newDayNode!=null&&((""+parametersSingle[HIGHTLIGHT_POSTTIME_TRUE].value).localeCompare("true")==0)){
  1274. let arr = STG.stringToRegArray(parametersSingle[HIGHTLIGHT_POSTTIME_REGX].value,",");
  1275. if(STG.findInArray(newDayNode.innerText,arr,STG.REGX)){
  1276. newDayNode.style.background=parametersSingle[HIGHTLIGHT_POSTTIME_BAKGROUND].value;
  1277. }
  1278. }
  1279. if(keeprun){YoutubeHandler.removeHighLightTag(videoPanels[i],"homehightag_");}
  1280. if(keeprun){
  1281. YoutubeHandler.drawUI("homehightag_",id,videoid,text,videoPanels[i],[HIGHLIGHT_VIDEO,BLOCK_VIDEO,HIGHLIGHT_VIDEO_KEYWORD,HIGHLIGHT_CHANNEL,BLOCK_CHANNEL,BLOCK_VIDEO_KEYWORD]);
  1282. }
  1283. }
  1284. }
  1285. }
  1286. function filter_homepage(){
  1287. let videoPanels=document.querySelectorAll('ytd-rich-item-renderer[class="style-scope ytd-rich-grid-row"]');
  1288. for(let i=0;i<videoPanels.length;i++){
  1289. let newDayNode=YoutubeHandler.findNewDayNode(videoPanels[i]);
  1290. YoutubeHandler.elementSetToDefault(videoPanels[i],newDayNode);
  1291. let id=YoutubeHandler.find_video_channel_id_youtube_homepage(videoPanels[i]);
  1292. let text=null;
  1293. YoutubeHandler.setUnlink_HomePage(videoPanels[i]);
  1294. let videoid=STD.getDomAttribute(videoPanels[i],['div#content div#details div#meta a#video-title-link'],"href");
  1295. if(videoid!=null){
  1296. videoid=videoid.replace("/watch?v=","");
  1297. if(videoid.indexOf("&")!=-1)videoid=videoid.substring(0,videoid.indexOf("&"));
  1298. }
  1299. let channelcontainer=STD.getDomNode(videoPanels[i],['div#content div#details div#meta ytd-video-meta-block div#metadata div#byline-container']);
  1300. let titlecontainer=STD.getDomNode(videoPanels[i],['div#content div#details div#meta h3 yt-formatted-string#video-title']);
  1301. if(titlecontainer!=null){text=titlecontainer.innerText;}
  1302. //-------------------
  1303. let keeprun=false;
  1304. if(id!=null&&videoid!=null&&channelcontainer!=null&&titlecontainer!=null&&text!=null){
  1305. keeprun=true;
  1306. SFAC_DropDownMenu.removeUnFIndPopupMenu(channelcontainer,"",videoid);
  1307. SFAC_DropDownMenu.setPopupMenu(channelcontainer,videoid,dropdownitems_homepage,[id,videoid],STD.ABSOLUTE_RIGHT,whenPopup,null,false);
  1308. let textcontainer=STD.getDomNode(videoPanels[i],['div#content div#details div#meta']);
  1309. SFAC_SelectTextPopup.setPopupEvent(textcontainer,null,selecttext_popupitems_homepage,"homepage",whenPopup,null);
  1310. if(newDayNode!=null&&((""+parametersSingle[HIGHTLIGHT_POSTTIME_TRUE].value).localeCompare("true")==0)){
  1311. let arr = STG.stringToRegArray(parametersSingle[HIGHTLIGHT_POSTTIME_REGX].value,",");
  1312. if(STG.findInArray(newDayNode.innerText,arr,STG.REGX)){
  1313. newDayNode.style.background=parametersSingle[HIGHTLIGHT_POSTTIME_BAKGROUND].value;
  1314. }
  1315. }
  1316. if(keeprun){YoutubeHandler.removeHighLightTag(videoPanels[i],"homehightag_");}
  1317. if(keeprun){
  1318. YoutubeHandler.drawUI("homehightag_",id,videoid,text,videoPanels[i],[HIGHLIGHT_VIDEO,BLOCK_VIDEO,HIGHLIGHT_VIDEO_KEYWORD,HIGHLIGHT_CHANNEL,BLOCK_CHANNEL,BLOCK_VIDEO_KEYWORD]);
  1319. }
  1320. }
  1321. }
  1322. }
  1323. let rowcount=0;
  1324. function getItemRowCount(content){
  1325. if(rowcount==0)rowcount=content.parentElement.children.length;
  1326. return rowcount;
  1327. }
  1328. function filter_homepage_reorder(){
  1329. let videoPanels=document.querySelectorAll('ytd-rich-item-renderer[class="style-scope ytd-rich-grid-row"]');
  1330. if(videoPanels.length==0)return;
  1331. let content=videoPanels[0].parentElement.parentElement.parentElement;
  1332. if(content==null)return;
  1333. //let itemperrow=parseInt(videoPanels[0].getAttribute("items-per-row"));
  1334. let itemperrow=getItemRowCount(videoPanels[0]);//console.log(itemperrow);
  1335.  
  1336. let rows=content.querySelectorAll('ytd-rich-grid-row[class="style-scope ytd-rich-grid-renderer"]');
  1337. //console.log(videoPanels.length, rows.length,videoPanels.length/3);
  1338. //remove all video
  1339. for(let i=0;i<rows.length;i++){
  1340. let container=rows[i].querySelector('div[id="contents"]');
  1341. let c=container.querySelectorAll('ytd-rich-item-renderer[class="style-scope ytd-rich-grid-row"]');
  1342. // console.log(c.length);
  1343. for(let k=0;k<c.length;k++){
  1344. container.removeChild(c[k]);
  1345. }
  1346. }
  1347. //add all video
  1348. let index=0;let counter=0;
  1349. for(let i=0;i<videoPanels.length;i++){
  1350. if(index<rows.length){
  1351. let container=rows[index].querySelector('div[id="contents"]');
  1352. if(videoPanels[i].querySelector('ytd-ad-slot-renderer')!=null){
  1353. //console.log("find ad "+index+" "+i);
  1354. }else{
  1355. container.appendChild(videoPanels[i]);
  1356. if(videoPanels[i].style.display=='none'){}else{counter++;}
  1357. }
  1358. if(counter==itemperrow){index++;counter=0;}
  1359. }
  1360. }
  1361. }
  1362. //---------------------------------------------------------------
  1363. let dropdownitemscomment_watchpage_title=['block user','highlight user'];
  1364. let dropdownitemscomment_watchpage=[
  1365. {title:(attributes)=>{return `${dropdownitemscomment_watchpage_title[0]} <font color=#ff0000>${attributes[CHANNELID]}</font>`},
  1366. func:(attributes)=>{let value=attributes[CHANNELID];if(value.indexOf("|")!=-1)value=value.substring(0,value.indexOf("|"));
  1367. parametersArray[BLOCK_COMMENT_USER].value=STG.addRemoveInArray(value,attributes[CHANNELID],parametersArray[BLOCK_COMMENT_USER].value,STG.INDEXOFREVERSE);sp.save_parameters_toStorage();filter("from dropdownitemscomment_watchpage");}},
  1368. {title:(attributes)=>{return dropdownitemscomment_watchpage_title[1]},
  1369. func:(attributes)=>{let value=attributes[CHANNELID];if(value.indexOf("|")!=-1)value=value.substring(0,value.indexOf("|"));
  1370. parametersArray[HIGHLIGHT_COMMENT_USER].value=STG.addRemoveInArray(value,attributes[CHANNELID],parametersArray[HIGHLIGHT_COMMENT_USER].value,STG.INDEXOFREVERSE);sp.save_parameters_toStorage();filter("from dropdownitemscomment_watchpage");}}
  1371. ];
  1372. let selecttext_popupitems_comment_watchpage_title=['block'];
  1373. let selecttext_popupitems_comment_watchpage=[{title:selecttext_popupitems_comment_watchpage_title[0]+" ",
  1374. func:(selecttext)=>{parametersArray[BLOCK_COMMENT_KEYWORD].value.push(selecttext.trim());sp.save_parameters_toStorage();filter("from selecttext_popupitems_comment_watchpage");}}]
  1375. function filter_watchpage(){
  1376. let commentPanels=document.querySelectorAll('ytd-comment-thread-renderer[class="style-scope ytd-item-section-renderer"]');
  1377. let index=0;
  1378. for(let i=0;i<commentPanels.length;i++){
  1379. YoutubeHandler.elementSetToDefault(commentPanels[i]);
  1380. let id=YoutubeHandler.find_comment_channel_id_youtube_watchpage(commentPanels[i]);
  1381. let text=STD.getDomInnerText(commentPanels[i],['div[id="content"]','yt-attributed-string[id="content-text"]']);
  1382. let channelcontainer=STD.getDomNode(commentPanels[i],['div[id="header-author"]']);
  1383. let commentcontainer=STD.getDomNode(commentPanels[i],['div[id="content"]']);
  1384. let keeprun=false;
  1385. if(id!=null&&text!=null&&channelcontainer!=null&&commentcontainer!=null){
  1386. let cc=STD.getDomNode(commentPanels[i],['div[id="header-author"]']);
  1387. SFAC_DropDownMenu.removeUnFIndPopupMenu(cc,"comment",YoutubeHandler.cutid(id)+index);
  1388. SFAC_DropDownMenu.setPopupMenu(cc,"comment"+YoutubeHandler.cutid(id)+index,dropdownitemscomment_watchpage,[id],null,whenPopup,null,false);
  1389. //setDropdownMenuComment(cc,id,index,commentPanels[i]);
  1390. index+=1;
  1391. SFAC_SelectTextPopup.setPopupEvent(commentcontainer,null,selecttext_popupitems_comment_watchpage,"watchpage",whenPopup,null);
  1392. keeprun=true;
  1393. keeprun=YoutubeHandler.drawUI("",id,null,text,commentPanels[i],[HIGHLIGHT_COMMENT_USER,BLOCK_COMMENT_USER,BLOCK_COMMENT_KEYWORD]);
  1394. if(keeprun){
  1395. index=filter_comment_replay_watchpage(commentPanels[i],index,false);
  1396. }
  1397. }
  1398. }
  1399. if((""+parametersSingle[HIDE_COMMENT].value).localeCompare("true")==0){
  1400. hidden_comment_watchpage();
  1401. }else{
  1402. let hiddennode=document.getElementById("smallsupo_hiddennode");
  1403. if(hiddennode!=null)hiddennode.remove();
  1404. let comment=document.getElementById("sections");if(comment!=null)comment.style.display="block";
  1405. }
  1406. //right side video
  1407. filter_rightside_video_watchpage();
  1408. //video self
  1409. filter_videoself_watchpage();
  1410. }
  1411. function hidden_comment_watchpage(){
  1412. let p=document.querySelector('ytd-comments[id="comments"]');
  1413. if(p==null)return;
  1414. let hiddennode=document.getElementById("smallsupo_hiddennode");
  1415. if(hiddennode==null){
  1416. let hiddennode=STD.createEL("div","smallsupo_hiddennode",'cursor: pointer;');
  1417. let index=getCurrentLanguageIndex(language);
  1418. hiddennode.innerText=languages[index].show+"/"+languages[index].hide+" "+languages[index].comment;
  1419. p.insertBefore(hiddennode, p.children[1]);
  1420. let comment=document.getElementById("sections");comment.style.display="none";
  1421. }else{
  1422. hiddennode.onclick=(evnt)=>{
  1423. let commentnode=document.getElementById("sections");
  1424. //console.log("hi"+comment);
  1425. if(commentnode!=null){
  1426. if(commentnode.style.display=="none"){commentnode.style.display="block";}else{
  1427. commentnode.style.display="none";
  1428. }
  1429. }
  1430. };
  1431. }
  1432. }
  1433. function filter_comment_replay_watchpage(comment,index){
  1434. let replies=comment.querySelector('div[id="replies"]').querySelectorAll('ytd-comment-view-model');
  1435. //console.log(replies.length);
  1436. for(let i=0;i<replies.length;i++){
  1437. YoutubeHandler.elementSetToDefault(replies[i]);
  1438. let id=YoutubeHandler.get_channel_id_in_comment_replay_watchpage(replies[i],['div[id="header-author"]','a[id="author-text"]']);
  1439. let text=STD.getDomInnerText(replies[i],['div[id="content"]','yt-attributed-string[id="content-text"]']);
  1440. //console.log(text);
  1441. let channelcontainer=STD.getDomNode(replies[i],['div[id="header-author"]']);//,'a[id="author-text"]','yt-formatted-string']);
  1442. let commentcontainer=STD.getDomNode(replies[i],['div[id="content"]','yt-attributed-string[id="content-text"]']);
  1443. if(id!=null&&channelcontainer!=null){
  1444. //console.log(id," ",cutid(id));
  1445. SFAC_DropDownMenu.removeUnFIndPopupMenu(channelcontainer,"comment",YoutubeHandler.cutid(id)+index);
  1446. SFAC_DropDownMenu.setPopupMenu(channelcontainer,"comment"+YoutubeHandler.cutid(id)+index,dropdownitemscomment_watchpage,[id],null,whenPopup,null,false);
  1447. index+=1;
  1448. }
  1449. if(commentcontainer!=null){
  1450. SFAC_SelectTextPopup.setPopupEvent(commentcontainer,null,selecttext_popupitems_comment_watchpage,"watchpage",whenPopup,null);
  1451. }
  1452. let keeprun=true;
  1453. YoutubeHandler.drawUI("",id,null,text,replies[i],[HIGHLIGHT_COMMENT_USER,BLOCK_COMMENT_USER,BLOCK_COMMENT_KEYWORD]);
  1454. }
  1455. return index;
  1456. }
  1457. function filter_rightside_video_watchpage(){
  1458. let videoP=document.querySelectorAll('ytd-compact-video-renderer');
  1459. for(let i=0;i<videoP.length;i++){
  1460. YoutubeHandler.elementSetToDefault(videoP[i]);
  1461. let tc=STD.getDomNode(videoP[i],['div[class="details style-scope ytd-compact-video-renderer"]','h3','span[id="video-title"]']);
  1462. let text=null;
  1463. let id=null;
  1464. let videoid=videoP[i].querySelector('#thumbnail').getAttribute("href");
  1465. videoid=videoid.replace("/watch?v=","");if(videoid.indexOf("&")!=-1){videoid.substring(0,videoid.indexOf("&"));}
  1466. let videourl="https://www.youtube.com/watch?v="+videoid;
  1467. let channelcontainer=videoP[i].querySelector('div#dismissible div#metadata div#byline-container');
  1468. let channeltitle=channelcontainer.querySelector('div#container yt-formatted-string').getAttribute("title");
  1469. //if(i==0){
  1470. if(YoutubeHandler.findChannelIdareadyhave(channeltitle)){
  1471. id=YoutubeHandler.getChannelId(channeltitle);
  1472. //console.log(channeltitle,"aready has",id);
  1473. id=id+"|"+channeltitle;
  1474. SFAC_DropDownMenu.removeUnFIndPopupMenu(channelcontainer,"runchannel_watch",videoid);
  1475. SFAC_DropDownMenu.setPopupMenu(channelcontainer,"runchannel_watch"+videoid,dropdownitems_homepage,[id,videoid],STD.ABSOLUTE_RIGHT,whenPopup,null,false);
  1476.  
  1477. YoutubeHandler.moveChannelcontainerToUPLayer(videoP[i]);
  1478. }else{
  1479. YoutubeHandler.getChannelIDformURL(videoid[i],videourl,videoid,channelcontainer,channeltitle);
  1480. }
  1481. //}
  1482. let keeprun=false;
  1483. if(tc!=null){
  1484. text=tc.innerText;
  1485. YoutubeHandler.setUnlinkRightSideWatchPage(videoP[i],['div[class="details style-scope ytd-compact-video-renderer"]','a']);
  1486. SFAC_SelectTextPopup.setPopupEvent(STD.getDomNode(videoP[i],['div[class="details style-scope ytd-compact-video-renderer"]'])
  1487. ,null,selecttext_popupitems_homepage,"runchannel_watch",whenPopup,null);
  1488. keeprun=true;
  1489. }
  1490. if(keeprun){YoutubeHandler.removeHighLightTag(videoP[i],"videohightag_");}
  1491. if(keeprun){
  1492. YoutubeHandler.drawUI("videohightag_",id,videoid,text,videoP[i],[HIGHLIGHT_VIDEO,BLOCK_VIDEO,HIGHLIGHT_VIDEO_KEYWORD,HIGHLIGHT_CHANNEL,BLOCK_CHANNEL,BLOCK_VIDEO_KEYWORD]);
  1493. }
  1494. }
  1495. }
  1496.  
  1497. function filter_videoself_watchpage(){
  1498. let r=document.querySelector('div[id="columns"]');
  1499. if (r==null)return;
  1500. let id=null;
  1501. let videoid=STD.getDomAttribute(r,['div[id="primary"]','div[id="below"]','ytd-watch-metadata'],"video-id");
  1502. let videocontainer=STD.getDomNode(r,['div[id="primary"]','div[id="below"]','ytd-watch-metadata','div[id="above-the-fold"]','div[id="title"]']);
  1503. let titlecontainer=STD.getDomNode(videocontainer,['h1']);
  1504. let channelcontainer=STD.getDomNode(r,['div[id="primary"]','div[id="below"]','div[id="above-the-fold"]','div[id="top-row"]','ytd-video-owner-renderer']);
  1505. let coveredEL=null;if(channelcontainer!=null)coveredEL=STD.getDomNode(channelcontainer,['div[id="upload-info"]']);
  1506. let text=null;
  1507. if(channelcontainer!=null&&coveredEL!=null&&videoid!=null&&channelcontainer!=null){
  1508. channelcontainer.style.background=null;
  1509. STD.setCoverEL(coveredEL,"channel",STD.UNCOVER);
  1510. STD.setCoverEL(videocontainer,"video",STD.UNCOVER);
  1511. id=YoutubeHandler.find_video_channel_id_watchpage(channelcontainer);
  1512. }
  1513. if(titlecontainer!=null){YoutubeHandler.removeHighLightTag(titlecontainer,"watchhightag_");}
  1514. let keeprun=false;
  1515. if(id!=null&&channelcontainer!=null){
  1516. SFAC_DropDownMenu.removeUnFIndPopupMenu(channelcontainer,"runchannelw",id);
  1517. SFAC_DropDownMenu.setPopupMenu(channelcontainer,"runchannelw"+id,dropdownitems_homepage,[id,videoid],null,whenPopup,null,false);
  1518. //setDropdownMenuVideoWatchPage(channelcontainer,id,"watchpage",channelcontainer);
  1519. if(videocontainer!=null){
  1520. SFAC_SelectTextPopup.setPopupEvent(videocontainer,null,selecttext_popupitems_homepage,"runchannelw",whenPopup,null);
  1521. //text=STD.getDomInnerText(videocontainer,['div[id="title"]','yt-formatted-string']);
  1522. text=videocontainer.innerText;
  1523. }
  1524. keeprun=true;
  1525. }
  1526. if(keeprun){
  1527. if(YoutubeHandler.findIdInArray(id,parametersArray[HIGHLIGHT_CHANNEL].value)&&parametersArray[HIGHLIGHT_CHANNEL].filter=="true"){
  1528. channelcontainer.style.background=parametersSingle[HIGHLIGHT_CHANNEL_BACKGROUND].value;
  1529. //keeprun=false;
  1530. }
  1531. }
  1532. if(keeprun){
  1533. if(YoutubeHandler.findIdInArray(id,parametersArray[BLOCK_CHANNEL].value)&&parametersArray[BLOCK_CHANNEL].filter=="true"){
  1534. STD.setCoverEL(coveredEL,"channel",STD.ISCOVER);
  1535. //keeprun=false;
  1536. }
  1537. }
  1538. if(keeprun){
  1539. videocontainer.style.background=null;
  1540. if(STG.findInArray(videoid,parametersArray[HIGHLIGHT_VIDEO].value,STG.INDEXOF)&&parametersArray[HIGHLIGHT_VIDEO].filter=="true"){
  1541. videocontainer.style.background=parametersSingle[HIGHLIGHT_VIDEO_BACKGROUND].value;
  1542. //keeprun=false;
  1543. }
  1544. }
  1545. if(keeprun){
  1546. if(STG.findInArray(videoid,parametersArray[BLOCK_VIDEO].value,STG.INDEXOF)&&parametersArray[BLOCK_VIDEO].filter=="true"){
  1547. STD.setCoverEL(videocontainer,"video",STD.ISCOVER);
  1548. //keeprun=false;
  1549. }
  1550. }
  1551. if(keeprun){
  1552. if(parametersArray[HIGHLIGHT_VIDEO_KEYWORD].filter=="true"){
  1553. if(STG.findInArray(text,parametersArray[HIGHLIGHT_VIDEO_KEYWORD].value,STG.REGX)){
  1554. let s=STG.findInArrayText(text,parametersArray[HIGHLIGHT_VIDEO_KEYWORD].value,STG.INDEXOF);
  1555. //videocontainer.style.border = parametersSingle[HIGHLIGHT_VIDEO_KEYWORD_BACKGROUND].valuep+parametersSingle[HIGHLIGHT_VIDEO_KEYWORD_BACKGROUND].value;
  1556. videocontainer.style.borderRadius =parametersSingle[HIGHLIGHT_VIDEO_KEYWORD_ARC].value+parametersSingle[HIGHLIGHT_VIDEO_KEYWORD_ARC].valuer;
  1557. if(titlecontainer!=null){
  1558. YoutubeHandler.setHighLightTagforWatchPage(titlecontainer,"watchhightag_"+videoid,s,true,parametersSingle[HIGHLIGHT_VIDEO_KEYWORD_BACKGROUND].value,videocontainer.style.borderRadius);
  1559. }
  1560. }
  1561. }
  1562. }
  1563. }
  1564. //---------------------------------------------------------
  1565. function filter_searchpage(){
  1566. let videoPanels=document.querySelectorAll('ytd-video-renderer');
  1567. for(let i=0;i<videoPanels.length;i++){
  1568. //let newDayNode=findNewDayNode(videoPanels[i]);
  1569. YoutubeHandler.elementSetToDefault(videoPanels[i],null);
  1570. let id=YoutubeHandler.find_video_channel_id_youtube_searchpage(videoPanels[i]);
  1571. let text=null;
  1572.  
  1573. YoutubeHandler.setUnlinkSearchPage(videoPanels[i]);
  1574.  
  1575. let videoid=STD.getDomAttribute(videoPanels[i],['div[id="dismissible"]','ytd-thumbnail','a'],"href");
  1576. if(videoid!=null){
  1577. videoid=videoid.replace("/watch?v=","");
  1578. if(videoid.indexOf("&")!=-1)videoid=videoid.substring(0,videoid.indexOf("&"));
  1579. //console.log(videoid);
  1580. }
  1581.  
  1582. let channelcontainer=STD.getDomNode(videoPanels[i],['div[id="channel-info"]']);
  1583. //console.log(id,videoid);)
  1584. let titlecontainer=STD.getDomNode(videoPanels[i],['div[id="dismissible"]','div[class="text-wrapper style-scope ytd-video-renderer"]','div[id="meta"]','h3']);
  1585. if(titlecontainer!=null){text=titlecontainer.innerText;}
  1586. let keeprun=false;
  1587.  
  1588. if(id!=null&&videoid!=null&&channelcontainer!=null&&titlecontainer!=null&&text!=null){
  1589. keeprun=true;
  1590. SFAC_DropDownMenu.removeUnFIndPopupMenu(channelcontainer,"research",videoid);
  1591. SFAC_DropDownMenu.setPopupMenu(channelcontainer,"research"+videoid,dropdownitems_homepage,[id,videoid],STD.ABSOLUTE_RIGHT,whenPopup,null,false);
  1592. // let textcontainer=STD.getDomNode(videoPanels[i],['div[id="content"]','div[id="details"]','div[id="meta"]']);
  1593.  
  1594. SFAC_SelectTextPopup.setPopupEvent(titlecontainer,null,selecttext_popupitems_homepage,"researchpage",whenPopup,null);
  1595. }
  1596. if(keeprun){ YoutubeHandler.removeHighLightTag(videoPanels[i],"searchhightag_");}
  1597. if(keeprun){
  1598. YoutubeHandler.drawUI("searchhightag_",id,videoid,text,videoPanels[i],[HIGHLIGHT_VIDEO,BLOCK_VIDEO,HIGHLIGHT_VIDEO_KEYWORD,HIGHLIGHT_CHANNEL,BLOCK_CHANNEL,BLOCK_VIDEO_KEYWORD]);
  1599. }
  1600. }
  1601. }
  1602. //---------------------------------------------------------
  1603. function filter_shortpage(){
  1604. let root=document.querySelector('div[id="shorts-inner-container"]');
  1605. let comments=root.querySelectorAll('ytd-reel-video-renderer[class="reel-video-in-sequence style-scope ytd-shorts"]');
  1606. let index=0;
  1607. let currentindex=-1;
  1608. for(let i=0;i<comments.length;i++){
  1609. YoutubeHandler.elementSetToDefault(comments[i]);
  1610. let videolink=STD.getDomAttribute(comments[i],['a[class="ytp-title-link yt-uix-sessionlink"]'],"href");
  1611. //console.log("link "+i+":"+videolink);
  1612. if(videolink!=null&&videolink.localeCompare(window.location.href)==0){
  1613. currentindex=i;
  1614. }
  1615. }
  1616. //console.log("match:"+currentindex);
  1617. if(currentindex==-1)return;
  1618. //----
  1619. let commentPanels=comments[currentindex].querySelectorAll('ytd-comment-thread-renderer[class="style-scope ytd-item-section-renderer"]');
  1620. //console.log(commentPanels.length);
  1621. for(let i=0;i<commentPanels.length;i++){
  1622. YoutubeHandler.elementSetToDefault(commentPanels[i]);
  1623. let usercontainer=STD.getDomNode(commentPanels[i],['#header-author']);
  1624. let userid=STD.getDomAttribute(usercontainer,['h3','a'],"href");
  1625. if(userid!=null){userid=userid.replace("/","");}
  1626. let commentcontainer=commentPanels[i].querySelector("#content");
  1627. let comment=STD.getDomInnerText(commentcontainer,["#content-text > span"]);
  1628. let keeprun=false;
  1629. if(userid!=null&&comment!=null&&usercontainer!=null&&commentcontainer!=null){
  1630. SFAC_DropDownMenu.removeUnFIndPopupMenu(usercontainer,"short",YoutubeHandler.cutid(userid)+i);
  1631. SFAC_DropDownMenu.setPopupMenu(usercontainer,"short"+YoutubeHandler.cutid(userid)+i,dropdownitemscomment_watchpage,[userid],null,whenPopup,null,true);
  1632. SFAC_SelectTextPopup.setPopupEvent(commentcontainer,null,selecttext_popupitems_comment_watchpage,"short",whenPopup,null);
  1633. keeprun=true;
  1634. }
  1635. if(keeprun){
  1636. keeprun=YoutubeHandler.drawUI("",userid,null,comment,commentPanels[i],[HIGHLIGHT_COMMENT_USER,BLOCK_COMMENT_USER,BLOCK_COMMENT_KEYWORD]);
  1637. }
  1638. if(keeprun){
  1639. filter_short_reply(commentPanels[i],i);
  1640. }
  1641.  
  1642. }// end for(let i=0;i<commentPanels.length;i++)
  1643.  
  1644. }//end filter_shortpage
  1645. function filter_short_reply(comment,index){
  1646. let replies=comment.querySelector('div[id="replies"]').querySelectorAll('ytd-comment-view-model');
  1647. for(let i=0;i<replies.length;i++){
  1648. YoutubeHandler.elementSetToDefault(replies[i]);
  1649. let id=STD.getDomAttribute(replies[i],['div[id="header-author"]','a[id="author-text"]'],"href");
  1650. id=id+"|"+id.replace("/","");
  1651. let text=STD.getDomInnerText(replies[i],['div[id="content"]','yt-attributed-string[id="content-text"]']);
  1652. //console.log(text);
  1653. let channelcontainer=STD.getDomNode(replies[i],['div[id="header-author"]']);//,'a[id="author-text"]','yt-formatted-string']);
  1654. let commentcontainer=STD.getDomNode(replies[i],['div[id="content"]','yt-attributed-string[id="content-text"]']);
  1655. if(id!=null&&channelcontainer!=null){
  1656. //console.log(id," ",cutid(id));
  1657. SFAC_DropDownMenu.removeUnFIndPopupMenu(channelcontainer,"shortreply",YoutubeHandler.cutid(id)+index+i);
  1658. SFAC_DropDownMenu.setPopupMenu(channelcontainer,"shortreply"+YoutubeHandler.cutid(id)+index+i,dropdownitemscomment_watchpage,[id],null,whenPopup,null,true);
  1659. //setDropdownMenuComment(commentcontainer,id,index,replies[i]);
  1660. index+=1;
  1661. }
  1662. if(commentcontainer!=null){
  1663. SFAC_SelectTextPopup.setPopupEvent(commentcontainer,null,selecttext_popupitems_comment_watchpage,"shortreply",whenPopup,null);
  1664. }
  1665. let keeprun=true;
  1666. if(keeprun){
  1667. YoutubeHandler.drawUI("",id,null,text,replies[i],[HIGHLIGHT_COMMENT_USER,BLOCK_COMMENT_USER,BLOCK_COMMENT_KEYWORD]);
  1668. }
  1669. }
  1670. }//end filter_short_reply(commetPanels,index)
  1671. //------------------------------------------------------------------------------------------------------------------
  1672. let is_observer=false;let page_observer=null;
  1673. function stop_page_observer(){
  1674. is_observer=false;
  1675. //if(debug)console.log("stop_page_observer");
  1676. if(page_observer!=null){page_observer.disconnect();page_observer=null;}
  1677. }
  1678. let isfiltering=false;
  1679. function detectYoutubeVersion(){
  1680. let newV=false;
  1681. let videoPanels=document.querySelectorAll('ytd-rich-item-renderer[class="style-scope ytd-rich-grid-row"]');
  1682. if(videoPanels.length==0)newV=true;
  1683. return newV;
  1684. }
  1685. function filter(from){
  1686. //do something here
  1687. console.log("filter-run..."+from);
  1688. stop_page_observer();
  1689. let url=window.location.href;
  1690. if(url.localeCompare("https://www.youtube.com/")==0){
  1691. rowcount=0;
  1692. if(detectYoutubeVersion()==true){
  1693. filter_homepage_newVersion();
  1694. }else{
  1695. filter_homepage();
  1696. filter_homepage_reorder();
  1697. }
  1698. removeClickEvent();
  1699. start_page_observer(document.querySelector('ytd-rich-grid-renderer'));
  1700. }else if(/youtube.com\/watch/.test(url)){
  1701. filter_watchpage();
  1702. start_page_observer(document.querySelector('div[id="columns"]'));
  1703. }else if(/youtube.com\/results/.test(url)){
  1704. filter_searchpage();
  1705. removeClickEvent();
  1706. start_page_observer(document.querySelector('div[id="columns"]'));
  1707. }else if(/youtube.com\/shorts/.test(url)){
  1708. filter_shortpage();
  1709. start_page_observer(document.querySelector('div[id="shorts-inner-container"]'));
  1710. }
  1711. isfiltering=false;
  1712. }
  1713. let pre=0;let filtertimer;
  1714. function filterDelay(milis){
  1715. let now= new Date();
  1716. if(now-pre>milis){
  1717. clearTimeout(filtertimer);
  1718. filtertimer=setTimeout(()=>{
  1719. if(isfiltering!=true){isfiltering=true;filter("filterDelay:"+milis/1000);}pre=now;}, 500);
  1720. }
  1721. }
  1722. function start_page_observer(dome){
  1723. is_observer=true;
  1724. if(dome==null){dome=document.getElementsByTagName('body')[0];}
  1725. //if(debug)console.log("start_page_observer");
  1726. if(page_observer==null){
  1727. page_observer = new MutationObserver(mutationRecords => {filterDelay(3000);});
  1728. page_observer.observe(dome, {
  1729. attributes:false,childList: true,characterData:false,attributeOldValue:false,
  1730. subtree: true,characterDataOldValue: false});
  1731. }
  1732. }
  1733. //----------------------------------------------------------------
  1734. let currentUrl = location.href;
  1735. let page_interval=null;
  1736. function start_page_interval(milis){
  1737. //console.log("start_page_interval");
  1738. page_interval=setInterval(()=>{
  1739. if (location.href !== currentUrl) {
  1740. stop_page_interval();
  1741. setTimeout(function() {
  1742. currentUrl = location.href;
  1743. filter("from interval");
  1744. start_page_interval();
  1745. }, milis);
  1746. }
  1747. }, 3000);
  1748. }
  1749. function stop_page_interval(){
  1750. //console.log("stop_page_interval");
  1751. if(page_interval!=null){clearInterval(page_interval);}
  1752. }
  1753. //----------------------------------------------------------------
  1754. let tempchannelArray=[];let ttcasid="tempchannelArray_storage";
  1755. function transfertempchannelarrytostring(){
  1756. let s="";
  1757. for(let i=0;i<tempchannelArray.length-1;i++){
  1758. s+=tempchannelArray[i].title+'YYYYY'+tempchannelArray[i].id+'XXXXX';
  1759. }
  1760. if(tempchannelArray.length>0){
  1761. s+=tempchannelArray[tempchannelArray.length-1].title+'YYYYY'+tempchannelArray[tempchannelArray.length-1].id;
  1762. }
  1763. return s;
  1764. }
  1765. function save_tempchannelarray(){
  1766. let s=transfertempchannelarrytostring();
  1767. localStorage.setItem(ttcasid, s);
  1768. }
  1769. function load_tempchannelarray(){
  1770. let r=null;
  1771. if(!localStorage.getItem(ttcasid)){localStorage.setItem(ttcasid, "");}
  1772. let s=localStorage.getItem(ttcasid);
  1773. if(s==""){tempchannelArray.length=0;return;}
  1774. let sa=s.split("XXXXX");
  1775. tempchannelArray.length=0;
  1776. for(let i=0;i<sa.length;i++){
  1777. let temp=sa[i].split("YYYYY");
  1778. let o={title:temp[0],id:temp[1]}
  1779. tempchannelArray.push(o);
  1780. }
  1781. }
  1782. //----------------------------------------------------------------
  1783. function do_before_openSetting(){
  1784. stop_page_observer();
  1785. }
  1786. function do_after_closeSetting(){
  1787. filter("from parameter ui button closed");
  1788. }
  1789. function getCurrentLanguageIndex(language){
  1790. let index=0;
  1791. for(let i=0;i<languages.length;i++){
  1792. let l=languages[i];
  1793. if(l.language==language){
  1794. index=i;
  1795. }
  1796. }
  1797. return index;
  1798.  
  1799. }
  1800. function setLanguage(){
  1801. if(autoDectectSystemLanguage){
  1802. let systemLanguage = navigator.language;
  1803. language=systemLanguage.substring(0,2);
  1804.  
  1805. }
  1806. for(let i=0;i<languages.length;i++){
  1807. let l=languages[i];
  1808. if(l.language==language){
  1809. block=l.block;highlight=l.highlight;setting=l.setting;show=l.show;hide=l.hide;
  1810. parametersArray[BLOCK_CHANNEL].title=l.channel;
  1811. parametersArray[BLOCK_VIDEO_KEYWORD].title=l.video+" "+l.keyword;
  1812. parametersArray[BLOCK_VIDEO].title=l.video;
  1813. parametersArray[BLOCK_COMMENT_USER].title=l.comment+" "+l.user;
  1814. parametersArray[BLOCK_COMMENT_KEYWORD].title=l.comment+" "+l.keyword;
  1815. parametersArray[HIGHLIGHT_CHANNEL].title=l.channel;
  1816. parametersArray[HIGHLIGHT_VIDEO_KEYWORD].title=l.video+" "+l.keyword;
  1817. parametersArray[HIGHLIGHT_VIDEO].title=l.video;
  1818. parametersArray[HIGHLIGHT_COMMENT_USER].title=l.comment+" "+l.user;
  1819. parametersSingle[HIGHLIGHT_CHANNEL_BACKGROUND].title=l.highlight+" "+l.channel+" "+l.color;
  1820. parametersSingle[HIGHLIGHT_VIDEO_KEYWORD_ARC].title=l.curvature;
  1821. parametersSingle[HIGHLIGHT_VIDEO_KEYWORD_BACKGROUND].title=l.color;
  1822. parametersSingle[HIGHLIGHT_VIDEO_BACKGROUND].title=l.highlight+" "+l.video+" "+l.color;
  1823. parametersSingle[HIGHLIGHT_COMMENT_USER_BACKGROUND].title=l.highlight+" "+l.comment+" "+l.user+" "+l.color;
  1824. parametersSingle[HIGHTLIGHT_POSTTIME_BAKGROUND].title=l.color;
  1825. parametersSingle[HIGHTLIGHT_POSTTIME_REGX].title=l.regex;
  1826. parametersSingle[HIGHTLIGHT_POSTTIME_TRUE].title=l.highlight+" "+l.posttime;
  1827. parametersSingle[HIDE_COMMENT].title=l.hide+" "+l.comment;
  1828. dropdownitems_homepage_title[0]=l.block+" "+l.channel;
  1829. dropdownitems_homepage_title[1]=l.block+" "+l.video;
  1830. dropdownitems_homepage_title[2]=l.highlight+" "+l.channel;
  1831. dropdownitems_homepage_title[3]=l.highlight+" "+l.video;
  1832. selecttext_popupitems_homepage_title[0]=l.block;
  1833. selecttext_popupitems_homepage_title[1]=l.highlight;
  1834. dropdownitemscomment_watchpage_title[0]=l.block+" "+l.user;
  1835. dropdownitemscomment_watchpage_title[1]=l.highlight+" "+l.user;
  1836. selecttext_popupitems_comment_watchpage_title[0]=l.block;
  1837. selecttext_popupitems_homepage[0].title=selecttext_popupitems_homepage_title[0]+" ";
  1838. selecttext_popupitems_homepage[1].title=selecttext_popupitems_homepage_title[1]+" ";
  1839. selecttext_popupitems_comment_watchpage[0].title=selecttext_popupitems_comment_watchpage_title[0]+" ";
  1840. title_restorefile=l.restore;
  1841. title_savefile=l.backup;
  1842. currentlanguageindex=i;
  1843. }
  1844. }
  1845. }
  1846. let sp;
  1847. function init(){
  1848. sp=new ParametersAgent(document.getElementsByTagName('body')[0],"Youtube-filter(channel、comment、video).txt");
  1849. sp.load_parameters_fromStorage();
  1850. let lines=2;sp.setPanel_Parameters(ParametersAgent.LB,do_before_openSetting,do_after_closeSetting,lines);
  1851. load_tempchannelarray();
  1852. }
  1853. //-----------------------------------------------------------------
  1854. function debounce(func, wait) {
  1855. let timeout;
  1856. return function(...args) {
  1857. clearTimeout(timeout);
  1858. timeout = setTimeout(() => func.apply(this, args), wait);
  1859. };
  1860. }
  1861. setTimeout(function() {
  1862. (function() {
  1863. console.log("Youtube Filter...啟動");
  1864. setLanguage();
  1865. init();
  1866. start_page_observer(document.getElementsByTagName('body')[0]);
  1867. start_page_interval(3000);
  1868. document.onclick=(evnt)=>{if(currentMenu!=null){
  1869. STD.hiddenEL(currentMenu);currentMenu=null;
  1870. }};
  1871. window.addEventListener('beforeunload', function (e) { //用來避免重復爬video channel id
  1872. console.log("beforeunload");save_tempchannelarray();
  1873. });
  1874.  
  1875. window.addEventListener('resize', debounce(function() {
  1876. rowcount=0;
  1877. }, 50));
  1878. })();
  1879. }, 3000);