// ==UserScript== // @name 手机浏览器触摸手势 // @name:en Mobile browser touch gestures // @description 为手机浏览器添加触摸手势,即装即用,无需配置。除了通用手势外,还有针对文字、图片、视频的特殊手势。还嫌不够?支持添加属于你的个性化手势。推荐使用狐猴浏览器、Edge浏览器和Yandex浏览器。 // @description:en Add touch gestures to your mobile browser, ready to use and no configuration required. In addition to general gestures, there are also special gestures for text, images, and videos. Do you still think it's not enough? Support adding personalized gestures that belong to you. We recommend using Lemur browser, Edge browser and Yandex browser. // @version 9.6.3 // @author L.Xavier // @namespace https://greasyfork.org/zh-CN/users/128493 // @match *://*/* // @license MIT // @grant window.close // @grant GM_setValue // @grant GM_getValue // @grant GM_openInTab // @grant GM_setClipboard // @grant GM_addValueChangeListener // @run-at document-start // @downloadURL none // ==/UserScript== // v9.6.3 2024-12-12 - 更新需要重置手势数据。高版本内核(>121),当evel方法无法使用后,向外部传递数据的方法失效,更新将调整新的传递方法。 /*手势数据模块*/ const gestureData={}; gestureData.gesture={ '↑→↓←':{name:'打开设置',code:'/*ONLY TOP*/gestureData.openSet();'}, '◆◆':{name:'视频全屏',code:'gestureData.videoFullScreen();'}, '●':{name:'手势穿透',code:'if(/^[TIV]/.test(gestureData.path)){gestureData.path=(gestureData.path.indexOf("I")>-1) ? "I" : "";}if(gestureData.path!=="I" && gestureData.settings["图片手势"]){if(gestureData.touchEle.nodeName!=="IMG"){let imgs=[...document.querySelectorAll("[_imgShow_=\'1\']")];if(gestureData.shadowList){for(let Ti=0,len=gestureData.shadowList.length;TiimgRect.x && gestureData.touchStart.clientX<(imgRect.x+imgRect.width) && gestureData.touchStart.clientY>imgRect.y && gestureData.touchStart.clientY<(imgRect.y+imgRect.height)){gestureData.touchEle=imgs[Ti];break;}}}if(gestureData.path || !(gestureData.touchEle.compareDocumentPosition(gestureData.videoPlayer) & Node.DOCUMENT_POSITION_FOLLOWING)){if(gestureData.touchEle.nodeName==="IMG"){gestureData.path="I";}else{let bgImg=getComputedStyle(gestureData.touchEle).backgroundImage;if(bgImg!=="none"){gestureData.touchEle.src=bgImg.split(\'"\')[1];gestureData.path="I";}}}}'}, '→←':{name:'后退',code:'/*ONLY TOP*/function pageBack(){if(gestureData.backTimer){history.go(-1);setTimeout(pageBack,20);}}gestureData.backTimer=setTimeout(()=>{gestureData.backTimer=0;window.close();},200);pageBack();'}, '←→':{name:'前进',code:'/*ONLY TOP*/history.go(1);'}, '↓↑':{name:'回到顶部',code:'/*WITH TOP*/let boxNode=gestureData.touchEle.parentNode;while(boxNode.nodeName!=="#document"){boxNode.scrollIntoView(true);if(boxNode.scrollTop){boxNode.scrollTo(0,0);}boxNode=boxNode.parentNode;}'}, '↑↓':{name:'回到底部',code:'/*WITH TOP*/let boxNode=gestureData.touchEle.parentNode;while(boxNode.nodeName!=="#document"){if(getComputedStyle(boxNode).overflowY!=="hidden"){boxNode.scrollTo(0,boxNode.scrollHeight+999999);}boxNode=boxNode.parentNode;}'}, '←↓':{name:'刷新页面',code:'/*ONLY TOP*/document.documentElement.style.cssText="filter:grayscale(100%)";history.go(0);'}, '←↑':{name:'新建页面',code:'/*ONLY TOP*/gestureData.GM_openInTab("//limestart.cn");'}, '→↓':{name:'关闭页面',code:'/*ONLY TOP*/window.close();'}, '→↑':{name:'恢复页面',code:'/*ONLY TOP*/gestureData.GM_openInTab("chrome-native://recent-tabs");'}, '↓↑●':{name:'新页面打开',code:'let linkNode=gestureData.touchEle;while(true){if(linkNode.href){gestureData.GM_openInTab(linkNode.href);break;}linkNode=linkNode.parentNode;if(linkNode.nodeName==="BODY"){gestureData.touchEle.click();break;}}'}, '↑↓●':{name:'隐藏元素',code:'let boxNode=gestureData.touchEle,area=boxNode.offsetWidth*boxNode.offsetHeight,area_p=boxNode.parentNode.offsetWidth*boxNode.parentNode.offsetHeight,area_s=screen.width*screen.height;while(boxNode.parentNode.nodeName!=="BODY" && area/area_p>0.2 && area_p/area_s<0.9){boxNode=boxNode.parentNode;area_p=boxNode.parentNode.offsetWidth*boxNode.parentNode.offsetHeight;}if(boxNode.nodeName!=="HTML"){boxNode.remove();}'}, '↓→':{name:'复制页面',code:'/*ONLY TOP*/gestureData.GM_openInTab(location.href);'}, '→←→':{name:'半屏模式',code:'/*ONLY TOP*/if(gestureData.halfScreen){setTimeout(()=>{gestureData.halfScreen.remove();halfClose.remove();gestureData.halfScreen=null;document.documentElement.scrollTop=gestureData.scrollTop;},500);gestureData.scrollTop=document.body.scrollTop;let halfClose=gestureData.addStyle("html{transform:translateY(0) !important;}");}else{gestureData.scrollTop=document.documentElement.scrollTop;gestureData.halfScreen=gestureData.addStyle("html,body{height:43vh !important;overflow-y:auto !important;}html{transform:translateY(50vh) !important;transition:0.5s !important;overflow:hidden !important;}");document.body.scrollTop=gestureData.scrollTop;}'}, '→↓↑←':{name:'视频解析',code:'/*ONLY TOP*/gestureData.GM_openInTab("https://jx.xmflv.com/?url="+location.href);'}, 'T→↑':{name:'百度翻译',code:'gestureData.GM_openInTab("//fanyi.baidu.com/#auto/auto/"+encodeURIComponent(gestureData.selectWords));'}, 'T←↑':{name:'有道翻译',code:'gestureData.GM_openInTab("//dict.youdao.com/w/eng/"+encodeURIComponent(gestureData.selectWords));'}, 'T◆◆':{name:'双击搜索',code:'gestureData.GM_setClipboard(gestureData.selectWords);if(!regURL.test(gestureData.selectWords.trim())){gestureData.selectWords="//bing.com/search?q="+encodeURIComponent(gestureData.selectWords);}else if(!/^(https?:)?\\/\\//.test(gestureData.selectWords.trim())){gestureData.selectWords="//"+gestureData.selectWords.trim();}gestureData.GM_openInTab(gestureData.selectWords.trim());'}, 'I↓↑●':{name:'打开图片',code:'gestureData.GM_openInTab(gestureData.touchEle.src);'}, 'I→↑●':{name:'百度搜图',code:'gestureData.GM_openInTab("//graph.baidu.com/details?isfromtusoupc=1&tn=pc&carousel=0&promotion_name=pc_image_shituindex&extUiData%5bisLogoShow%5d=1&image="+gestureData.touchEle.src);'}, 'V→':{name:'前进10s',code:'gestureData.videoPlayer.currentTime+=10;gestureData.tipBox.textContent="+10s ";gestureData.tipBox.style.display="block";setTimeout(()=>{gestureData.tipBox.style.display="none";},500);'}, 'V←':{name:'后退10s',code:'gestureData.videoPlayer.currentTime-=10;gestureData.tipBox.textContent="-10s ";gestureData.tipBox.style.display="block";setTimeout(()=>{gestureData.tipBox.style.display="none";},500);'}, 'V↑':{name:'增加倍速',code:'if(document.fullscreen){let playSpeed=gestureData.videoPlayer.playbackRate;playSpeed+=(playSpeed<1.5) ? 0.25 : 0.5;gestureData.tipBox.textContent="×"+playSpeed+" ∞ ";gestureData.tipBox.style.display="block";gestureData.videoPlayer.playbackRate=playSpeed;setTimeout(()=>{gestureData.tipBox.style.display="none";},500)}'}, 'V↓':{name:'减小倍速',code:'if(document.fullscreen){let playSpeed=gestureData.videoPlayer.playbackRate;playSpeed-=(playSpeed>1.5) ? 0.5 : (playSpeed>0.25 && 0.25);gestureData.tipBox.textContent="×"+playSpeed+" ∞ ";gestureData.tipBox.style.display="block";gestureData.videoPlayer.playbackRate=playSpeed;setTimeout(()=>{gestureData.tipBox.style.display="none";},500)}'}, 'V→●':{name:'快进播放',code:'gestureData.playSpeed=gestureData.videoPlayer.playbackRate;gestureData.videoPlayer.playbackRate=10;gestureData.tipBox.textContent="×10 ";gestureData.tipBox.style.display="block";'}, 'V→○':{name:'停止快进',code:'gestureData.videoPlayer.playbackRate=gestureData.playSpeed;gestureData.tipBox.style.display="none";'}, 'V←●':{name:'快退播放',code:'gestureData.videoTimer=setInterval(()=>{--gestureData.videoPlayer.currentTime;},100);gestureData.tipBox.textContent="- ×10 ";gestureData.tipBox.style.display="block";'}, 'V←○':{name:'停止快退',code:'clearInterval(gestureData.videoTimer);gestureData.tipBox.style.display="none";'}, 'V↑●':{name:'增加音量',code:'if(document.fullscreen){gestureData.videoPlayer.muted=false;gestureData.tipBox.textContent=(gestureData.videoPlayer.volume*100|0)+"%";gestureData.tipBox.style.display="block";let lastY=gestureData.touchEnd.screenY;gestureData.videoTimer=setInterval(()=>{if(lastY-gestureData.touchEnd.screenY){let tempVolume=gestureData.videoPlayer.volume+(lastY-gestureData.touchEnd.screenY)/100;gestureData.videoPlayer.volume=+(tempVolume>1) || (+(tempVolume>0) && tempVolume);gestureData.tipBox.textContent=(gestureData.videoPlayer.volume*100|0)+"%";lastY=gestureData.touchEnd.screenY;}},50);}'}, 'V↑○':{name:'关闭增加音量',code:'clearInterval(gestureData.videoTimer);gestureData.tipBox.style.display="none";'}, 'V↓●':{name:'减少音量',code:'if(document.fullscreen){gestureData.videoPlayer.muted=false;gestureData.tipBox.textContent=(gestureData.videoPlayer.volume*100|0)+"%";gestureData.tipBox.style.display="block";let lastY=gestureData.touchEnd.screenY;gestureData.videoTimer=setInterval(()=>{if(lastY-gestureData.touchEnd.screenY){let tempVolume=gestureData.videoPlayer.volume+(lastY-gestureData.touchEnd.screenY)/100;gestureData.videoPlayer.volume=+(tempVolume>1) || (+(tempVolume>0) && tempVolume);gestureData.tipBox.textContent=(gestureData.videoPlayer.volume*100|0)+"%";lastY=gestureData.touchEnd.screenY;}},50);}'}, 'V↓○':{name:'关闭减少音量',code:'clearInterval(gestureData.videoTimer);gestureData.tipBox.style.display="none";'}, 'V→▼':{name:'右滑进度',code:'let lastX=gestureData.touchEnd.screenX,hour,minu,sec;function showTip(){minu=gestureData.videoPlayer.currentTime/60;sec=gestureData.videoPlayer.currentTime%60;hour=minu/60;minu%=60;gestureData.tipBox.textContent=(hour|0)+":"+((minu<10) ? "0":"")+(minu|0)+":"+((sec<10) ? "0" : "")+(sec|0);}showTip();gestureData.tipBox.style.display="block";gestureData.videoTimer=setInterval(()=>{let len=gestureData.touchEnd.screenX-lastX;if(len){gestureData.videoPlayer.currentTime+=len*(1+Math.abs(len)*gestureData.videoPlayer.duration/10800).toFixed(2);lastX=gestureData.touchEnd.screenX;}showTip();},50);'}, 'V→▽':{name:'关闭右滑进度',code:'clearInterval(gestureData.videoTimer);gestureData.tipBox.style.display="none";'}, 'V←▼':{name:'左滑进度',code:'let lastX=gestureData.touchEnd.screenX,hour,minu,sec;function showTip(){minu=gestureData.videoPlayer.currentTime/60;sec=gestureData.videoPlayer.currentTime%60;hour=minu/60;minu%=60;gestureData.tipBox.textContent=(hour|0)+":"+((minu<10) ? "0":"")+(minu|0)+":"+((sec<10) ? "0" : "")+(sec|0);}showTip();gestureData.tipBox.style.display="block";gestureData.videoTimer=setInterval(()=>{let len=gestureData.touchEnd.screenX-lastX;if(len){gestureData.videoPlayer.currentTime+=len*(1+Math.abs(len)*gestureData.videoPlayer.duration/10800).toFixed(2);lastX=gestureData.touchEnd.screenX;}showTip();},50);'}, 'V←▽':{name:'关闭左滑进度',code:'clearInterval(gestureData.videoTimer);gestureData.tipBox.style.display="none";'} } gestureData.settings={ '滑动系数':[0.2,0,0.5,2],//[当前值,最小值,最大值,取值精度] '文字手势':true, '图片手势':true, '视频手势':true, '网页加速':true, '视频下载':false, '避免断触':false }; //GM方法写入 gestureData.GM_setValue=GM_setValue; gestureData.GM_getValue=GM_getValue; gestureData.GM_openInTab=GM_openInTab; gestureData.GM_setClipboard=GM_setClipboard; //存储数据读取 gestureData.gesture=gestureData.GM_getValue('gesture',gestureData.gesture); gestureData.settings=gestureData.GM_getValue('settings',gestureData.settings); //脚本常量 const minSide=(screen.width>screen.height) ? screen.height : screen.width,limit=(minSide*gestureData.settings['滑动系数'][0])**2,attachShadow=Element.prototype.attachShadow,regURL=/^((https?:)?\/\/)?([\w\-]+\.)+\w{2,4}(:\d{1,5})?(\/\S*)?$/, mObserver=new MutationObserver(()=>{if(!checkTimer){checkTimer=setTimeout(loadCheck,200);}}), iObserver=new IntersectionObserver((entries)=>{for(let Ti=0,len=entries.length;Ti{for(let Ti=0,len=entries.length;Ti300000){link._prefetch_=nowTime;document.head.insertAdjacentHTML('beforeend','');}}else{link.setAttribute('_linkShow_','0');}}},{rootMargin:'50%'}); /*手势功能模块*/ //手指功能变量 let startPoint={},timeSpan=0,pressTime=0,raiseTime=0,slideTime=0,slideClock=0,slideLimit=0,fingersNum=0,gestureTimer=0,clickTimer=0,isAllow=0,isClick=0; //手势执行 gestureData.runCode=(code)=>{ try{eval(code);}catch(error){ if((error+'').indexOf('unsafe-eval')>-1){ if(!window._eval_){ window._eval_=(()=>{ let script=document.createElement('script'); (function(){this.gestureData=gestureData;this.close=window.close;})()//将数据传递给外部 return (js)=>{ script.remove();script=document.createElement('script'); script.textContent='try{'+js+'}catch(error){alert("“"+gestureData.path+"” 手势执行脚本错误:\\n"+error+" !");}'; document.body.insertAdjacentElement('beforeend',script); } })(); if(top===self){window._eval_('window.addEventListener("popstate",()=>{clearTimeout(gestureData.backTimer);gestureData.backTimer=0;},true);window.addEventListener("beforeunload",()=>{clearTimeout(gestureData.backTimer);gestureData.backTimer=0;},true);');} } window._eval_(code); } else{alert('“'+gestureData.path+'” 手势执行脚本错误:\n'+error+' !');} } } gestureData.runFrame=(runPath)=>{ let code=gestureData.gesture[runPath].code; if(top===self || /^[TIV]/.test(runPath)){gestureData.runCode(code);} else{ if(code.indexOf('/*ONLY TOP*/')<0){gestureData.runCode(code);} if(/\/\*(ONLY|WITH) TOP\*\//.test(code)){ if(/[●▼]$/.test(runPath)){window._isPushing_=()=>{let _gestureData={};_gestureData.touchEnd=copyTouch(gestureData.touchEnd);top.postMessage({'type':'pushTouch','gestureData':_gestureData},'*');}} let _gestureData={}; _gestureData.touchStart=copyTouch(gestureData.touchStart); _gestureData.touchEnd=copyTouch(gestureData.touchEnd); top.postMessage({'type':'runPath','runPath':gestureData.path,'gestureData':_gestureData},'*'); } } } gestureData.runGesture=(newPath)=>{ if(gestureData.gesture[gestureData.path]){ gestureData.runFrame(gestureData.path); if(gestureData.gesture[newPath]){gestureData.path=newPath;} }else if(gestureData.gesture[gestureData.path.slice(1)] && /^[TIV]/.test(gestureData.path)){ gestureData.runFrame(gestureData.path.slice(1)); if(gestureData.gesture[newPath?.slice(1)]){gestureData.path=newPath;} } raiseTime=0; } //长按执行 function longPress(){ if(isAllow && !/[●○▽]$/.test(gestureData.path)){ isAllow=isClick=0; startPoint=gestureData.touchEnd; let newPath=gestureData.path+'○';gestureData.path+='●'; gestureData.runGesture(newPath); } } //持续滑动执行 function slidingRun(){ slideClock=0; let newPath=gestureData.path+'▽';gestureData.path+='▼'; gestureData.runGesture(newPath); gestureData.path=gestureData.path.replace('▼',''); } //手指按下 function touchStart(e){ clearTimeout(gestureTimer); if((fingersNum=e.touches.length)>1){return;} pressTime=Date.now();timeSpan=pressTime-raiseTime; let lineLen=raiseTime && (e.changedTouches[0].screenX-gestureData.touchEnd.screenX)**2+(e.changedTouches[0].screenY-gestureData.touchEnd.screenY)**2; if(timeSpan>50 || lineLen>limit){//断触判断 startPoint=e.changedTouches[0]; if(timeSpan>200 || lineLen>limit*4){ gestureData.path='';slideLimit=limit; gestureData.touchEle=e.target; gestureData.touchEnd=gestureData.touchStart=startPoint; gestureData.selectWords=window.getSelection()+''; if(gestureData.selectWords && gestureData.settings['文字手势']){gestureData.path='T';} else if(document.contains(gestureData.videoPlayer) && gestureData.settings['视频手势']){ let videoRect=gestureData.findVideoBox().getBoundingClientRect(); if(fullsState>0 && gestureData.touchStart.clientY<(videoRect.y+videoRect.height/8)){gestureData.path='!';} else if(gestureData.touchStart.clientX>videoRect.x && gestureData.touchStart.clientX<(videoRect.x+videoRect.width) && gestureData.touchStart.clientY>videoRect.y && gestureData.touchStart.clientY<(videoRect.y+videoRect.height)){gestureData.path='V';} } }else if(isClick){e.preventDefault();} slideTime=pressTime;isAllow=isClick=1; }else if(isClick){clearTimeout(clickTimer);gestureData.path=gestureData.path.slice(0,-1);} gestureTimer=setTimeout(longPress,300+slideTime-pressTime); } //手指滑动 function touchMove(e){ clearTimeout(gestureTimer); gestureData.touchEnd=e.changedTouches ? e.changedTouches[0] : e; if(window._isPushing_){setTimeout(window._isPushing_);} if(/[○▽]$/.test(gestureData.path) || fingersNum>1){return;} let xLen=(gestureData.touchEnd.screenX-startPoint.screenX)**2,yLen=(gestureData.touchEnd.screenY-startPoint.screenY)**2, direction=(xLen>yLen*1.42) ? ((gestureData.touchEnd.screenX>startPoint.screenX) ? '→' : '←') : ((gestureData.touchEnd.screenY>startPoint.screenY) ? '↓' : '↑'), nowTime=Date.now(),pathLen=xLen+yLen,lastIcon=gestureData.path.slice(-1); if(pathLen>limit/576){ slideTime=nowTime;isClick=0; if(lastIcon===direction || pathLen>slideLimit){ if(lastIcon!==direction && (timeSpan<50 || 'TIV◆'.indexOf(lastIcon)>-1)){gestureData.path+=direction;slideLimit*=(slideLimit300){setTimeout(slidingRun);} }else if(pathLen>limit/100){slideClock=isAllow=0;} } gestureTimer=setTimeout(longPress,300+slideTime-nowTime); } //手指抬起 function touchEnd(e){ clearTimeout(gestureTimer); if(--fingersNum>0){if(!/[○▽]$/.test(gestureData.path)){gestureData.path='!';}return;} if(window._isPushing_){window._isPushing_=null;} gestureData.touchEnd=e.changedTouches[0]; raiseTime=Date.now();setTimeout(iframeLock); if(/[○▽]$/.test(gestureData.path)){setTimeout(gestureData.runGesture);return;} if(isClick){gestureData.path+='◆';if(/^V◆◆$|^T/.test(gestureData.path)){e.stopPropagation();e.preventDefault();window.getSelection().empty();}} if(isAllow){gestureTimer=setTimeout(gestureData.runGesture,199);} } //延迟点击,避免断触触发点击 function delayClick(e){ if(e.isTrusted){ e.stopImmediatePropagation();e.stopPropagation();e.preventDefault(); if(timeSpan<50){return;} let ev=new PointerEvent('click',{bubbles:true,cancelable:true,clientX:e.clientX,clientY:e.clientY,composed:true,detail:1,layerX:e.layerX,layerY:e.layerY,offsetX:e.offsetX,offsetY:e.offsetY,pageX:e.pageX,pageY:e.pageY,pointerId:e.pointerId,pointerType:e.pointerType,screenX:e.screenX,screenY:e.screenY,sourceCapabilities:e.sourceCapabilities,view:e.view,x:e.x,y:e.y}); clickTimer=setTimeout(()=>{e.target.dispatchEvent(ev);},50); } } /*视频功能模块*/ //视频功能变量 let oriLock=0,resizeTimer=0,fullsState=0; //videoPlayer赋值 async function setVideo(player){ let _videoPlayer=player.target || player; if(gestureData.videoPlayer?.paused===false && _videoPlayer.muted===true){return;} gestureData.videoPlayer=_videoPlayer; videoOriLock(); gestureData.videoPlayer.parentNode.insertAdjacentElement('beforeend',gestureData.tipBox); if(gestureData.settings['视频下载']){ await gestureData.findVideoBox()?.insertAdjacentElement('beforeend',gestureData.videoPlayer._downloadTip_); if(window._urlObjects_[gestureData.videoPlayer.src]){ gestureData.videoPlayer._downloadTip_.textContent='正在捕获'; gestureData.videoPlayer._downloadTip_.buffers=window._urlObjects_[gestureData.videoPlayer.src].sourceBuffers; window._urlObjects_[gestureData.videoPlayer.src]._downloadTip_=gestureData.videoPlayer._downloadTip_; delete window._urlObjects_[gestureData.videoPlayer.src]; }else if(gestureData.videoPlayer._downloadTip_.textContent==='未加载'){ if(!gestureData.videoPlayer.src && gestureData.videoPlayer.children.length){gestureData.videoPlayer.src=gestureData.videoPlayer.firstChild.src;} if(gestureData.videoPlayer.src.indexOf('blob:') && gestureData.videoPlayer.src){gestureData.videoPlayer._downloadTip_.textContent='可下载';} } } } //video方向锁定 function videoOriLock(){ if(!gestureData.videoPlayer.videoWidth){if(!gestureData.videoPlayer.error && document.contains(gestureData.videoPlayer)){setTimeout(videoOriLock,100);}oriLock=0;return;} oriLock=+(gestureData.videoPlayer.videoWidth>gestureData.videoPlayer.videoHeight); if(fullsState>0 && oriLock){top.postMessage({'type':'GYRO'},'*');} else{screen.orientation.unlock();} } //video框架锁定 function iframeLock(){ if(top!==self && !window._isShow_){gestureData.GM_setValue('isShow',Date.now());} } //video全屏/退出全屏 gestureData.videoFullScreen=async ()=>{ if(resizeTimer){return;} if(document.fullscreen){await document.exitFullscreen()?.catch(Date);} else if(gestureData.videoPlayer){await gestureData.findVideoBox()?.requestFullscreen()?.catch(Date);} else if(iframeEles.length){gestureData.GM_setValue('fullscreen',Date.now());} } //获取video全屏样式容器 gestureData.findVideoBox=(player=gestureData.videoPlayer)=>{ if(!document.contains(player)){return null;} if(player._videoBox_?.contains(player) && (document.fullscreen || player._boxHeight_>=player._videoBox_.clientHeight)){return player._videoBox_;} player._videoBox_=player.parentNode;player.setAttribute('_videobox_',''); let parentEle=player._videoBox_.parentNode,videoStyle=getComputedStyle(player),childStyle=getComputedStyle(player._videoBox_),childWidth=0,childHeight=0,_childWidth=0,_childHeight=0; if(player._videoBox_.offsetParent===parentEle){ childWidth=Math.round(player.offsetWidth+(+videoStyle.marginLeft.slice(0,-2))+(+videoStyle.marginRight.slice(0,-2))); childHeight=Math.round(player.offsetHeight+(+videoStyle.marginTop.slice(0,-2))+(+videoStyle.marginBottom.slice(0,-2))); _childWidth=Math.round(player._videoBox_.offsetWidth+(+childStyle.marginLeft.slice(0,-2))+(+childStyle.marginRight.slice(0,-2))); _childHeight=Math.round(player._videoBox_.offsetHeight+(+childStyle.marginTop.slice(0,-2))+(+childStyle.marginBottom.slice(0,-2))); }else{ childWidth=Math.round(player.offsetWidth+(+videoStyle.left.slice(0,-2) || 0)+(+videoStyle.marginLeft.slice(0,-2))+(+videoStyle.marginRight.slice(0,-2))+(+videoStyle.right.slice(0,-2) || 0)); childHeight=Math.round(player.offsetHeight+(+videoStyle.top.slice(0,-2) || 0)+(+videoStyle.marginTop.slice(0,-2))+(+videoStyle.marginBottom.slice(0,-2))+(+videoStyle.bottom.slice(0,-2) || 0)); _childWidth=Math.round(player._videoBox_.offsetWidth+(+childStyle.left.slice(0,-2) || 0)+(+childStyle.marginLeft.slice(0,-2))+(+childStyle.marginRight.slice(0,-2))+(+childStyle.right.slice(0,-2) || 0)); _childHeight=Math.round(player._videoBox_.offsetHeight+(+childStyle.top.slice(0,-2) || 0)+(+childStyle.marginTop.slice(0,-2))+(+childStyle.marginBottom.slice(0,-2))+(+childStyle.bottom.slice(0,-2) || 0)); } childWidth=(childWidth>_childWidth) ? childWidth : _childWidth; childHeight=(childHeight>_childHeight) ? childHeight : _childHeight; while(childWidth>=parentEle.clientWidth && parentEle.nodeName!=='BODY'){ if(childHeight=0.85*parentEle.clientHeight){isBreak=0;break;} } if(isBreak){break;} } if(parentEle.clientHeight){ player._videoBox_.setAttribute('_videobox_',''); player._videoBox_=parentEle;player._boxHeight_=childHeight; childStyle=getComputedStyle(parentEle); if(parentEle.offsetParent===parentEle.parentNode){ _childWidth=Math.round(parentEle.offsetWidth+(+childStyle.marginLeft.slice(0,-2))+(+childStyle.marginRight.slice(0,-2))); _childHeight=Math.round(parentEle.offsetHeight+(+childStyle.marginTop.slice(0,-2))+(+childStyle.marginBottom.slice(0,-2))); }else{ _childWidth=Math.round(parentEle.offsetWidth+(+childStyle.left.slice(0,-2) || 0)+(+childStyle.marginLeft.slice(0,-2))+(+childStyle.marginRight.slice(0,-2))+(+childStyle.right.slice(0,-2) || 0)); _childHeight=Math.round(parentEle.offsetHeight+(+childStyle.top.slice(0,-2) || 0)+(+childStyle.marginTop.slice(0,-2))+(+childStyle.marginBottom.slice(0,-2))+(+childStyle.bottom.slice(0,-2) || 0)); } childWidth=(childWidth>_childWidth) ? childWidth : _childWidth; childHeight=(childHeight>_childHeight) ? childHeight : _childHeight; } parentEle=parentEle.parentNode; } player._videoBox_.setAttribute('_videobox_','outer'); return player._videoBox_; } //全屏检测事件 function regRESIZE(){ let videoCss=gestureData.addStyle(''),stopResize=()=>{resizeTimer=0;}; window.addEventListener('resize',()=>{ clearTimeout(resizeTimer);resizeTimer=setTimeout(stopResize,200); if(document.fullscreen && !fullsState){ fullsState=document.fullscreenElement; if(fullsState.nodeName==='IFRAME'){fullsState=-1;return;} let srcFindVideo=fullsState.getElementsByTagName('video'),srcVideo=(fullsState.nodeName==='VIDEO') ? fullsState : srcFindVideo[0]; if(!fullsState.hasAttribute('_videobox_') && (!srcVideo || srcFindVideo.length>1 || (srcVideo._videoBox_.offsetWidth*srcVideo._videoBox_.offsetHeight/fullsState.offsetWidth/fullsState.offsetHeight)<0.9)){fullsState=-1;videoCss.textContent='';return;} if(srcVideo!==gestureData.videoPlayer){gestureData.videoPlayer?.pause();setVideo(srcVideo);} fullsState=1;if(oriLock){top.postMessage({'type':'GYRO'},'*');} videoCss.textContent='*[_videobox_]{inset:0 !important;margin:0 !important;padding:0 !important;transform:none !important;}*[_videobox_=""]{width:100% !important;height:100% !important;max-width:100% !important;max-height:100% !important;}video{position:fixed !important;object-fit:contain !important;}'; }else if(fullsState && !document.fullscreen){fullsState=0;videoCss.textContent='';} },true); } /*视频下载模块*/ if(gestureData.settings['视频下载']){ //原始方法存储 const createObjectURL=URL.createObjectURL,addSourceBuffer=MediaSource.prototype.addSourceBuffer,appendBuffer=SourceBuffer.prototype.appendBuffer,endOfStream=MediaSource.prototype.endOfStream; //初始化视频下载 window._initDownload_=(player)=>{ player._downloadTip_=document.createElement('div'); player._downloadTip_.style.cssText='position:absolute;right:0;top:20px;background:#3498db;border-radius:20px 0 0 20px;text-align:center;padding:20px;line-height:0px;color:#fff;min-width:60px;font-size:16px;font-family:system-ui;z-index:2147483647;'; player._downloadTip_.target=player; player._downloadTip_.textContent='未加载'; if(window._urlObjects_[player.src]){ player._downloadTip_.textContent='正在捕获'; player._downloadTip_.buffers=window._urlObjects_[player.src].sourceBuffers; window._urlObjects_[player.src]._downloadTip_=player._downloadTip_; delete window._urlObjects_[player.src]; }else{ if(!player.src && player.children.length){player.src=player.firstChild.src;} if(player.src.indexOf('blob:') && player.src){player._downloadTip_.textContent='可下载';} } player._downloadTip_.onclick=window._downloadVideo_; player._videoBox_.insertAdjacentElement('beforeend',player._downloadTip_); } //下载视频 window._downloadVideo_=function(data){ if(this.textContent==='未加载'){return;} if(data.target){data=this;data.src=this.target.src;} let buffers=data.buffers; if(top!==self){ let _buffers=[]; for(let Ti=0,len=buffers.length;Ti{ let url=createObjectURL(obj); if(obj.sourceBuffers){window._urlObjects_[url]=obj;} return url; } //添加捕获 MediaSource.prototype.addSourceBuffer=function(mime){ let sourceBuffer=addSourceBuffer.call(this,mime); sourceBuffer._bufferList_=[]; sourceBuffer._mime_=mime; sourceBuffer._mediaSource_=this; return sourceBuffer; } //捕获片段 SourceBuffer.prototype.appendBuffer=function(buffer){ this._bufferList_.push(buffer); if(this._mime_.indexOf('video')>-1 && this._mediaSource_._downloadTip_){this._mediaSource_._downloadTip_.textContent='已捕获'+this._bufferList_.length+'个片段';} appendBuffer.call(this,buffer); } //捕获完成 MediaSource.prototype.endOfStream=function(){ if(this._downloadTip_){this._downloadTip_.textContent='可下载';} endOfStream.call(this); } } /*功能补充模块*/ //功能补充变量 let videoEles=[],imgEles=[],aEles=[],iframeEles=document.getElementsByTagName('iframe'),checkTimer=0; //修改Trusted-Types策略 window.trustedTypes?.createPolicy('default',{createHTML:string=>string,createScript:string=>string,createScriptURL:string=>string}); //设置shadow-root (open) Element.prototype.attachShadow=function(){ if(!gestureData.shadowList){gestureData.shadowList=[];} let shadowRoot=attachShadow.call(this,arguments[0]); gestureData.shadowList.push(shadowRoot); mObserver.observe(shadowRoot,{childList:true,subtree:true}); return shadowRoot; } //页面加载检测 async function loadCheck(){ videoEles=[...document.querySelectorAll('video:not([_videoBox_])')]; imgEles=[...document.querySelectorAll('img:not([_imgShow_])'),...document.querySelectorAll('[style*="url("]:not([_imgShow_])')]; aEles=[...document.querySelectorAll('a:not([_linkShow_])')]; //检测shadow-root if(gestureData.shadowList){ for(let Ti=0,len=gestureData.shadowList.length;Ti-1){ link._prefetch_=0; aObserver.observe(link); link.addEventListener('click',()=>{link._prefetch_=0;},true); } } } checkTimer=0; } //添加样式表 gestureData.addStyle=(css)=>{ let style=document.createElement('style'); style.textContent=css; if(document.head){ document.head.insertAdjacentElement('beforeend',style); return style; }else{setTimeout(()=>{gestureData.addStyle(css)});} } //复制坐标对象 function copyTouch(oldObj){ let newObj={}; for(let Ti in oldObj){ if(Ti==='target'){continue;} newObj[Ti]=oldObj[Ti]; } return newObj; } //手势功能设置UI gestureData.openSet=()=>{ let gestureName='',gesturePath='',gestureBox=document.createElement('div'),pathEle=null,_clickTimer=0; //页面生成 gestureData.addStyle('*{overflow:hidden !important;}'+ '#_gestureBox_{background-color:#fff;width:100%;height:100%;position:fixed;padding:0;margin:0;inset:0;overflow-y:auto !important;z-index:2147483647;}'+ '#_gestureBox_ *{font-family:system-ui;margin:0;padding:0;text-align:center;font-size:5vmin;line-height:12vmin;user-select:none !important;transform:none;text-indent:0;}'+ '#_gestureBox_ ::placeholder{color:#999;font-size:2.5vmin;line-height:6vmin;}'+ '#_gestureBox_ h1{width:60%;height:12vmin;color:#0074d9;background-color:#dee6ef;margin:3vmin auto;border-radius:12vmin;box-shadow:0.9vmin 0.9vmin 3vmin #dfdfdf;}'+ '#_gestureBox_ #_addGesture_{width:14vmin;height:14vmin;margin:3vmin auto;line-height:14vmin;background-color:#dee6ef;color:#032e58;font-size:7.5vmin;border-radius:15vmin;box-shadow:0.3vmin 0.3vmin 1.5vmin #dfdfdf;}'+ '#_gestureBox_ ._gestureLi_{height:18vmin;width:100%;border-bottom:0.3vmin solid #dfdfdf;}'+ '#_gestureBox_ ._gestureLi_ p{margin:3vmin 0 0 1%;width:38%;height:12vmin;border-left:1.8vmin solid;color:#ffb400;background-color:#fff1cf;float:left;white-space:nowrap;text-overflow:ellipsis;text-shadow:0.3vmin 0.3vmin 3vmin #ffcb56;}'+ '#_gestureBox_ ._gestureLi_ ._gesturePath_{margin:3vmin 0 0 3%;float:left;width:38%;height:12vmin;background-color:#f3f3f3;color:#000;box-shadow:0.3vmin 0.3vmin 1.5vmin #ccc9c9;border-radius:3vmin;white-space:nowrap;text-overflow:ellipsis;}'+ '#_gestureBox_ ._gestureLi_ ._delGesture_{margin:3vmin 2% 0 0;width:15vmin;height:12vmin;float:right;color:#f00;text-decoration:line-through;}'+ '#_gestureBox_ #_revisePath_{background-color:rgba(0,0,0,0.7);width:100%;height:100%;position:fixed;inset:0;display:none;color:#000;}'+ '#_gestureBox_ #_revisePath_ span{width:15vmin;height:15vmin;font-size:12.5vmin;line-height:15vmin;position:absolute;}'+ '#_gestureBox_ #_revisePath_ div{color:#3339f9;position:absolute;width:30%;height:12vmin;font-size:10vmin;bottom:15%;}'+ '#_gestureBox_ #_revisePath_ p{color:#3ba5d8;position:absolute;top:15%;font-size:10vmin;height:12vmin;width:100%;}'+ '#_gestureBox_ #_revisePath_ #_path_{top:40%;color:#ffee03;height:100%;word-wrap:break-word;font-size:15vmin;line-height:18vmin;}'+ '#_gestureBox_ #_editGesture_{overflow-y:auto !important;background-color:#fff;width:100%;height:100%;position:fixed;inset:0;display:none;color:#000;}'+ '#_gestureBox_ #_editGesture_ p{color:#3339f9;font-size:7.5vmin;text-align:left;margin:6vmin 0 0 9vmin;width:100%;height:9vmin;line-height:9vmin;}'+ '#_gestureBox_ #_editGesture_ #_gestureName_{margin-top:6vmin;width:80%;height:12vmin;color:#000;border:0.3vmin solid #dadada;border-radius:3vmin;text-align:left;padding:0 3vmin;}'+ '#_gestureBox_ #_editGesture_ ._label_box_>label{display:inline-block;margin-top:6vmin;position:relative;}'+ '#_gestureBox_ #_editGesture_ ._label_box_>label>input{position:absolute;top:0;left:-6vmin;}'+ '#_gestureBox_ #_editGesture_ ._label_box_>label>div{width:20vw;border:#ddd solid 0.3vmin;height:12vmin;color:#666;position:relative;}'+ '#_gestureBox_ #_editGesture_ ._label_box_>label>input:checked + div{border:#d51917 solid 0.3vmin;color:#d51917;}'+ '#_gestureBox_ #_editGesture_ ._label_box_>label>input + div:after{top:auto;left:auto;bottom:-3vmin;right:0;transition:none;}'+ '#_gestureBox_ #_editGesture_ ._label_box_>label>input:checked + div:after{content:"";display:block;border:none;width:6vmin;height:6vmin;background-color:#d51917;transform:skewY(-45deg);position:absolute;}'+ '#_gestureBox_ #_editGesture_ ._label_box_>label>input:checked + div:before{content:"";display:block;width:0.9vmin;height:2.4vmin;border-right:#fff solid 0.6vmin;border-bottom:#fff solid 0.6vmin;transform:rotate(35deg);position:absolute;bottom:0.6vmin;right:1.2vmin;z-index:1;}'+ '#_gestureBox_ #_editGesture_ #_gestureCode_{overflow-y:auto !important;width:80%;margin-top:6vmin;height:40%;text-align:left;line-height:6vmin;padding:3vmin;border:0.3vmin solid #dadada;border-radius:3vmin;}'+ '#_gestureBox_ #_editGesture_ button{width:30vmin;height:15vmin;font-size:7.5vmin;line-height:15vmin;display:inline-block;color:#fff;background-color:#2866bd;margin:6vmin 3vmin 0 3vmin;border:none;}'+ '#_gestureBox_ #_settingsBox_{overflow-y:auto !important;background-color:#fff;width:100%;height:100%;position:fixed;inset:0;display:none;color:#000;}'+ '#_gestureBox_ #_settingsBox_ p{color:#3339f9;text-align:left;margin:9vmin 0 0 9vmin;float:left;height:6vmin;line-height:6vmin;clear:both;}'+ '#_gestureBox_ #_settingsBox_ ._slideRail_{overflow:initial !important;width:55%;background-color:#a8a8a8;float:left;margin:12vmin 0 0 3vmin;height:0.6vmin;position:relative;}'+ '#_gestureBox_ #_settingsBox_ ._slideRail_ ._slideButton_{line-height:9vmin;color:#fff;background-color:#2196f3;min-width:9vmin;height:9vmin;border-radius:9vmin;font-size:4vmin;position:absolute;top:-4.5vmin;box-shadow:0.3vmin 0.3vmin 1.8vmin #5e8aee;padding:0 1vmin;}'+ '#_gestureBox_ #_settingsBox_ ._switch_{position:relative;display:inline-block;width:18vmin;height:9vmin;float:left;margin:7.5vmin 42% 0 3vmin;}'+ '#_gestureBox_ #_settingsBox_ ._switch_ input{display:none;}'+ '#_gestureBox_ #_settingsBox_ ._slider_{border-radius:9vmin;position:absolute;cursor:pointer;inset:0;background-color:#ccc;transition:0.4s;}'+ '#_gestureBox_ #_settingsBox_ ._slider_:before{border-radius:50%;position:absolute;content:"";height:7.5vmin;width:7.5vmin;left:0.6vmin;bottom:0.6vmin;background-color:white;transition:0.4s;}'+ '#_gestureBox_ #_settingsBox_ input:checked + ._slider_{background-color:#2196F3;}'+ '#_gestureBox_ #_settingsBox_ input:checked + ._slider_:before{transform:translateX(9vmin);}'+ '#_gestureBox_ #_settingsBox_ #_saveSettings_{display:block;clear:both;width:30vmin;height:15vmin;font-size:7.5vmin;line-height:15vmin;color:#fff;background-color:#2866bd;border:none;margin:12vmin 0 0 calc(50% - 15vmin);float:left;}'); gestureBox.id='_gestureBox_'; document.body.insertAdjacentElement('beforeend',gestureBox); gestureBox.innerHTML='

手势轨迹设置

+
'+ '
'+ '

请滑动手指

清除
保存
'+ '

手势名称:

'+ '

手势类型:

'+ '

手势执行脚本:

'+ '
'+ '

功能开关设置

'; pathEle=document.getElementById('_path_'); //编辑手势 function editGesture(){ gestureName=this.parentNode.getAttribute('name'); if(['打开设置','视频全屏','手势穿透'].indexOf(gestureName)>-1){alert('该手势脚本无法修改!');return;} gesturePath=this.parentNode.getAttribute('path'); let selectType=(/^[TIV]/.test(gesturePath)) ? '_'+gesturePath.slice(0,1)+'_' : '_G_'; document.getElementById(selectType).click(); document.getElementById('_gestureName_').value=gestureName; document.getElementById('_gestureCode_').value=gestureData.gesture[gesturePath].code; document.getElementById('_editGesture_').style.display='block'; } //修改路径 function revisePath(){ gestureName=this.parentNode.getAttribute('name'); gesturePath=this.parentNode.getAttribute('path'); pathEle.textContent=''; window.removeEventListener('touchmove',touchMove,true); window.removeEventListener('pointermove',touchMove,true); document.getElementById('_revisePath_').style.display='block'; } //删除手势 function delGesture(){ gestureName=this.parentNode.getAttribute('name'); if(['打开设置','视频全屏','手势穿透'].indexOf(gestureName)>-1){alert('该手势无法删除!');return;} if(!confirm('确定删除"'+gestureName+'"手势')){return;} gesturePath=this.parentNode.getAttribute('path'); delete gestureData.gesture[gesturePath]; gestureData.GM_setValue('gesture',gestureData.gesture); init(); } //滑动条 function silideBar(e){ e.preventDefault();fingersNum=2; let diffX=e.changedTouches[0].clientX-gestureData.touchStart.clientX, leftPX=(+this.style.left.slice(0,-2))+diffX,vmin=this.offsetWidth/2,setArr=gestureData.settings[this.id]; leftPX=(leftPX<-vmin) ? -vmin : ((leftPX>(diffX=this.parentNode.offsetWidth-vmin)) ? diffX : leftPX); this.style.left=leftPX+'px'; this.textContent=((leftPX+vmin)/this.parentNode.offsetWidth*(setArr[2]-setArr[1])+setArr[1]).toFixed(setArr[3]); gestureData.touchStart=e.changedTouches[0]; } //长按执行 function _longPress(){if(isClick || !/^$|[●○▼▽]$/.test(pathEle.textContent)){isClick=0;startPoint=gestureData.touchEnd;pathEle.textContent+='●';}} //持续滑动执行 function _slidingRun(){slideClock=0;pathEle.textContent+='▼';} //点击执行 function _clickRun(){if(!/[○▼▽]$/.test(pathEle.textContent)){pathEle.textContent+='◆';}} //界面初始化 function init(){ let gestureUL=document.getElementById('_gestureUL_'); gestureUL.textContent=''; for(let Ti in gestureData.gesture){ let gestureLi=document.createElement('div'),nameEle=document.createElement('p'),pathEle=document.createElement('div'),delEle=document.createElement('div'); gestureLi.className='_gestureLi_';gestureLi.setAttribute('name',gestureData.gesture[Ti].name);gestureLi.setAttribute('path',Ti); nameEle.textContent=gestureData.gesture[Ti].name;nameEle.addEventListener('click',editGesture,true); pathEle.className='_gesturePath_';pathEle.textContent=Ti;pathEle.addEventListener('click',revisePath,true); delEle.className='_delGesture_';delEle.textContent='删除';delEle.addEventListener('click',delGesture,true); gestureLi.insertAdjacentElement('beforeend',nameEle); gestureLi.insertAdjacentElement('beforeend',pathEle); gestureLi.insertAdjacentElement('beforeend',delEle); gestureUL.insertAdjacentElement('beforeend',gestureLi); } } init(); //.新建手势 document.getElementById('_addGesture_').addEventListener('click',()=>{ gestureName=gesturePath=''; document.getElementById('_G_').click(); document.getElementById('_gestureName_').value=''; document.getElementById('_gestureCode_').value=''; document.getElementById('_editGesture_').style.display='block'; },true); //保存手势 document.getElementById('_saveGesture_').addEventListener('click',()=>{ let name=document.getElementById('_gestureName_').value; if(!name){alert('请输入手势名称!');return;} if(document.querySelector('#_gestureBox_ ._gestureLi_[name="'+name+'"]:not([path="'+gesturePath+'"])')){alert('存在同名手势!');return;} let typeEle=document.getElementsByName('_gestureType_'); for(let Ti=0,len=typeEle.length;Ti{ document.getElementById('_editGesture_').style.display='none'; },true); //路径修改事件 document.getElementById('_revisePath_').addEventListener('touchstart',()=>{ if(fingersNum>1){return;} clearTimeout(gestureTimer);clearTimeout(_clickTimer); gestureTimer=setTimeout(_longPress,300+slideTime-pressTime); },true); document.getElementById('_revisePath_').addEventListener('touchmove',(e)=>{ e.preventDefault();clearTimeout(gestureTimer); gestureData.touchEnd=e.changedTouches[0]; if(/[○▼▽]$/.test(pathEle.textContent) || fingersNum>1){return;} let xLen=(gestureData.touchEnd.screenX-startPoint.screenX)**2,yLen=(gestureData.touchEnd.screenY-startPoint.screenY)**2, direction=(xLen>yLen) ? ((gestureData.touchEnd.screenX>startPoint.screenX) ? '→' : '←') : ((gestureData.touchEnd.screenY>startPoint.screenY) ? '↓' : '↑'), nowTime=Date.now(),pathLen=xLen+yLen,lastIcon=pathEle.textContent.slice(-1); if(pathLen>limit/576){ slideTime=nowTime;isClick=0; if(lastIcon===direction || pathLen>limit){ if(lastIcon!==direction){pathEle.textContent+=direction;slideClock=nowTime;} startPoint=gestureData.touchEnd; if(slideClock && nowTime-slideClock>300){_slidingRun();} }else if(pathLen>limit/100){slideClock=0;} } gestureTimer=setTimeout(_longPress,300+slideTime-nowTime); },true); document.getElementById('_revisePath_').addEventListener('touchend',(e)=>{ if(!isClick || fingersNum>0){return;} if(gestureData.path.indexOf('◆◆')>-1){gestureData.path=''; switch(pathEle.textContent.slice(-1)){ case '●':{pathEle.textContent=pathEle.textContent.slice(0,-1)+'○';break;} case '○':{pathEle.textContent=pathEle.textContent.slice(0,-1)+'●';break;} case '▼':{pathEle.textContent=pathEle.textContent.slice(0,-1)+'▽';break;} case '▽':{pathEle.textContent=pathEle.textContent.slice(0,-1)+'▼';break;} default:{pathEle.textContent+='◆';setTimeout(_clickRun,100);break;} } }else{_clickTimer=setTimeout(_clickRun,200);} }); //清除路径 document.getElementById('_clearPath_').addEventListener('touchend',(e)=>{ e.stopPropagation(); if(!isClick || fingersNum>0){return;} if(gestureData.path.indexOf('◆◆')>-1){gestureData.path='';pathEle.textContent='';} else{pathEle.textContent=pathEle.textContent.slice(0,-1);} }); //保存修改路径 document.getElementById('_cancleRevise_').addEventListener('touchend',(e)=>{ e.stopPropagation();e.preventDefault(); if(!isClick || fingersNum>0){return;} if(pathEle.textContent){ if(gestureName==='视频全屏' && pathEle.textContent.slice(-1)!=='◆'){alert('视频全屏需要以◆结尾!');return;} if(gestureData.gesture[pathEle.textContent]?.name==='手势穿透'){alert('路径与"手势穿透"功能冲突!');return;} if(/^[TIV]/.test(gesturePath)){pathEle.textContent=gesturePath.slice(0,1)+pathEle.textContent;} if(gestureData.gesture[pathEle.textContent]){ let pathTXT=((/^[TIV]/.test(gesturePath)) ? gesturePath.slice(0,1) : '')+'['+gestureData.gesture[pathEle.textContent].name+']'; gestureData.gesture[pathTXT]=gestureData.gesture[pathEle.textContent]; } gestureData.gesture[pathEle.textContent]=gestureData.gesture[gesturePath]; delete gestureData.gesture[gesturePath]; gestureData.GM_setValue('gesture',gestureData.gesture); init(); } window.addEventListener('touchmove',touchMove,{capture:true,passive:true}); window.addEventListener('pointermove',touchMove,{capture:true,passive:true}); document.getElementById('_revisePath_').style.display='none'; }); //打开功能开关设置 document.getElementById('_openSettings_').addEventListener('click',()=>{ gestureBox.style.cssText='overflow-y:hidden !important'; document.getElementById('_settingsBox_').style.display='block'; let settingList=document.getElementById('_settingList_'); settingList.textContent=''; for(let Ti in gestureData.settings){ settingList.innerHTML+='

'+Ti+':

'; if(typeof(gestureData.settings[Ti])==='boolean'){ settingList.innerHTML+=''; }else if(typeof(gestureData.settings[Ti])==='object'){ settingList.innerHTML+='
'; let slideButton=document.getElementById(Ti), leftPX=slideButton.parentNode.offsetWidth*(gestureData.settings[Ti][0]-gestureData.settings[Ti][1])/(gestureData.settings[Ti][2]-gestureData.settings[Ti][1])-slideButton.offsetWidth/2; slideButton.style.left=leftPX+'px'; slideButton.textContent=gestureData.settings[Ti][0].toFixed(gestureData.settings[Ti][3]); } } let slideList=document.getElementsByClassName('_slideButton_'); for(let Ti=0,len=slideList.length;Ti{ gestureBox.style.cssText=''; for(let Ti in gestureData.settings){ if(typeof(gestureData.settings[Ti])==='boolean'){ gestureData.settings[Ti]=document.getElementById(Ti).checked; }else if(typeof(gestureData.settings[Ti])==='object'){ gestureData.settings[Ti][0]=+document.getElementById(Ti).textContent; } } gestureData.GM_setValue('settings',gestureData.settings); document.getElementById('_settingsBox_').style.display='none'; },true); } /*事件注册模块*/ (function(){ if(top===self){ //清除后退定时器 window.addEventListener('popstate',()=>{clearTimeout(gestureData.backTimer);gestureData.backTimer=0;},true); window.addEventListener('beforeunload',()=>{clearTimeout(gestureData.backTimer);gestureData.backTimer=0;},true); //接收iframe数据 window.addEventListener('message',async (e)=>{ let data=e.data; switch(data.type){ case 'GYRO':{//锁定横屏模式 await screen.orientation.lock('landscape')?.catch(Date); break;} case 'forceFullScreen':{//iframe强制可全屏 for(let Ti=0,len=iframeEles.length;Ti{ if(!document.hidden && window._isShow_){ await gestureData.findVideoBox()?.requestFullscreen()?.catch(Date); } }); //iframe锁定 GM_addValueChangeListener('isShow',(name,old_value,new_value,remote)=>{ if(!document.hidden){window._isShow_=!remote;} }); } //加载检测 checkTimer=setTimeout(loadCheck,200); mObserver.observe(document,{childList:true,subtree:true}); //手势事件注册 window.addEventListener('touchstart',touchStart,{capture:true,passive:false}); window.addEventListener('touchmove',touchMove,{capture:true,passive:true}); window.addEventListener('pointermove',touchMove,{capture:true,passive:true}); window.addEventListener('touchend',touchEnd,{capture:true,passive:false}); window.addEventListener('touchcancel',touchEnd,{capture:true,passive:false}); if(gestureData.settings['图片手势']){window.addEventListener('contextmenu',(e)=>{if((gestureData.path.indexOf("I")>-1 || e.target.nodeName==='IMG') && gestureData.touchEle.src!==location.href){e.preventDefault();}},true);}//长按图片时禁止弹出菜单 if(gestureData.settings['避免断触']){window.addEventListener('click',delayClick,true);} //禁止网页检测焦点 window.addEventListener('visibilitychange',(e)=>{e.stopImmediatePropagation();//禁止页面切换检测 if(document.hidden){//视频后台播放 let playState=gestureData.videoPlayer?.paused,playTime=gestureData.videoPlayer?.currentTime+0.2,playSpeed=gestureData.videoPlayer?.playbackRate,playVolume=gestureData.videoPlayer?.volume; setTimeout(()=>{if(playState!==gestureData.videoPlayer?.paused){ gestureData.videoPlayer.load();gestureData.videoPlayer.currentTime=playTime; gestureData.videoPlayer.onloadstart=()=>{gestureData.videoPlayer.play();gestureData.videoPlayer.playbackRate=playSpeed;gestureData.videoPlayer.volume=playVolume;} }}); }else if(gestureData.settings['网页加速']){//更新预加载链接 let links=[...document.querySelectorAll('a[_linkShow_="1"]')],nowTime=Date.now(); if(gestureData.shadowList){ for(let Ti=0,len=gestureData.shadowList.length;Ti300000){ links[Ti]._prefetch_=Date.now(); document.head.insertAdjacentHTML('beforeend',''); } } } },true); window.addEventListener('pagehide',(e)=>{e.stopImmediatePropagation();},true); window.addEventListener('blur',(e)=>{e.stopImmediatePropagation();}); //禁止修改复制内容 window.addEventListener('copy',(e)=>{ if(gestureData.selectWords){return;} e.stopImmediatePropagation();e.stopPropagation(); },true); //禁止网页写入剪切板 document.execCommand=()=>{}; if(navigator.clipboard){navigator.clipboard.writeText=()=>{};navigator.clipboard.write=()=>{};} //解除选中限制 gestureData.addStyle('*{user-select:auto !important;touch-action:manipulation;overscroll-behavior-x:none;}'); window.addEventListener('selectstart',(e)=>{e.stopImmediatePropagation();},true); //预取+预渲染,高版本内核才支持speculationrules推测规则api if(gestureData.settings['网页加速'] && HTMLScriptElement.supports && HTMLScriptElement.supports('speculationrules')){ let specScript=document.createElement('script'), specRules={ 'prerender':[{ 'source':'document', 'where':{'and':[{'selector_matches':'a[_linkShow_="1"]'}]}, 'referrer_policy':'strict-origin-when-cross-origin', 'eagerness':'immediate' }], 'prefetch':[{ 'source':'document', 'where':{'and':[{'selector_matches':'a[_linkShow_="1"]'}]}, 'referrer_policy':'strict-origin-when-cross-origin', 'eagerness':'immediate' }], 'prefetch_with_subresources':[{ 'source':'document', 'where':{'and':[{'selector_matches':'a[_linkShow_="1"]'}]}, 'referrer_policy':'strict-origin-when-cross-origin', 'eagerness':'immediate' }] }; specScript.type='speculationrules'; specScript.textContent=JSON.stringify(specRules); document.head?.insertAdjacentElement('beforeend',specScript); } })();