您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
鼠标手势脚本,就是这么拽:支持右键轨迹手势和左键拖拽功能.可以拖拽[文本],[链接]和[图片],支持自定义设置:鼠标画➡⬅(右左)路径,进入设置
当前为
// ==UserScript== // @name MouseGesture--HY // @name:zh-CN 鼠标手势--就是这么拽! // @namespace http://greasyfork.icu/users/104201 // @description HY's mouse gesture script,supports ringt-key draw track functions and left-key drag functions.Drag target can be [Text] & [Links] & [Image] Customizenable → Right click to draw ⇄(left,right) to setting // @description:zh-CN 鼠标手势脚本,就是这么拽:支持右键轨迹手势和左键拖拽功能.可以拖拽[文本],[链接]和[图片],支持自定义设置:鼠标画➡⬅(右左)路径,进入设置 // @version 1.6 // @include * // @noframes // @run-at document-end // @grant GM_openInTab // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // @grant GM_setClipboard // @grant GM_download // @grant GM_addValueChangeListener // @grant GM_notification // @grant window.close // @grant GM_getResourceText // @grant GM_xmlhttpRequest // Thanks to: Peer Zeng's script: http://greasyfork.icu/zh-CN/scripts/4776-my-mouse-gestures [no License] [for right click gesture handle] // Thanks to: crxMouse Chrome™ Gestures [chrome crxID:jlgkpaicikihijadgifklkbpdajbkhjo] [for: drag processing] // Thanks to: Robbendebiene's project Gesturefy [https://github.com/Robbendebiene/Gesturefy] [for canvas line style] // Thanks to: Jim Lin's userscript 有道划词翻译 [http://greasyfork.icu/zh-CN/scripts/15844] [License MIT][for 划词翻译] // ==/UserScript== /* jshint esversion: 6 */ const MouseGesture = (function() { let arrowCss = `@font-face { font-family: 'MParrow'; src: url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAAQdAAoAAAAABPAAAQAAAAAAAAAAAAAAAAAAAAAECAAAABVPUy8yAAABYAAAAEQAAABgUc1dNGNtYXAAAAHEAAAARgAAAGAAcgFDZ2x5ZgAAAiAAAADwAAABNKukdSxoZWFkAAAA9AAAADQAAAA2DKcEFmhoZWEAAAEoAAAAHQAAACQEKQIaaG10eAAAAaQAAAAfAAAAJBGtAZVsb2NhAAACDAAAABQAAAAUATIBfm1heHAAAAFIAAAAFQAAACAACwAKbmFtZQAAAxAAAADnAAABe0DXvWtwb3N0AAAD+AAAABAAAAAgAAMAAXjaY2BkYGAA4gfLE97F89t8ZeBkYgCBq07amiD6mu+MRAaB/3cZXzFuAnI5GMDSAEgbC5142mNgZGBgYgACPSApwCDA+IqBkQEVcAIAGeEBSQAAAHjaY2BkYGDgBEIQzQAlkQAAAjsAFgAAAHjaY2Bm/MY4gYGVgYPRhzGNgYHBHUp/ZZBkaGFgYGJg5WSAAUYGJBCQ5poCpAwZLBkf/H/AoMeEpIaRAcpjAAAVNgmoeNpjYmBgYPzCYAbE3lBagImBQQzM/srgA6IBjAwITgB42i2KywmAQBQD57l+e9gCvAoieLd/7ShmnwZCmDBA4WslaLlMkdyzekdv0LFzSuaNQ9Kj+/ebUfNf0iv2YfA7Mb+pBQmvAAAAAAAAABQAJgA6AEwAXgByAIYAmnjaVY8hT8NAGIa/N0tzLJlgbY4LYmI0zekvTTmBuHomcGT9DXMkpD8Bwd+AhIo1wa8CVYfF4DCgm8wV7m6Gqc+8eZ7nI9AlRejwSCdERvAkYqHEQxljarv6zWIau0sEuv79xAtewy4tjJLpPH2q2rZqvtH3GAc6YiWaswlroQfPKLsaVzYe93ZXu90pneML94ElWRuWS/nhILO7qt2uG/K+M7f5OWxQsBJcLAtc9P04YLHeOu2xL1McJayMAtlx74W34YngW7n25tCe5VLoIp/nuAnxzz4eMwrO/zzDScZGG2xK393V74G7q/8AczlNtXjadY7BasJAEIb/mKgVSumh3ucBoiQetHjpod6K4MlLi7CROSzEBDaB0EfoC/hEvoLv0990G0Rwhtn99p9/hwHwiCMCXCLAsD0v0eP94DnEuNMjjDruY8rOHw/ofqcziEZUnvDhuccfn55D+v/1CC8d9/GFb88DPOO83hjnykbetuoqWxaSTpPkmmWlez1k6mQeyyxJF7HYwtbW5OI0V1OpHzHBGhsYOGaJBrJ7/TlhiS2USgVLtYAg5WoJ854uWLGzZx2QtR7BHDHPGbspFi1b/rGoWQY5347OnGU4UW82mfwCMzM4HQB42mNgZkAGjAxoAAAAjgAFSExQRAEARkMJAAAAUGF3J1oAAAAA) format('woff'); } #MPcanvas{position:fixed;top:0;left:0;z-index:9999999;} #MPtips{all:initial!important;position:fixed!important;z-index:9999998!important;top:50%!important;left:50%!important;transform:translate(-50%,-50%)!important;font-family:MParrow,"Arial",sans-serif!important;color:white!important;white-space:nowrap!important;line-height:normal!important;text-shadow:1px 1px 5px rgba(0,0,0,0.8)!important;text-align:center!important;padding:25px 20px 20px 20px!important;border-radius:5px!important;font-weight:bold!important; } `; GM_addStyle(arrowCss); let dObj = {};// the Object Element being draged let x, y, startX, startY, screenX, screenY, canvas, tips, ctx, direction = '', track = ''; //_*: default cfg values let _cfg = { t2n:{ // t2n: track <==> function name "2": {name:"toTop", arg:[]}, "8": {name:"toBottom", arg:[]}, "4": {name:"back", arg:[]}, "6": {name:"forward", arg:[]}, "86": {name:"close", arg:[]}, "42": {name:"reopenTab",arg:[]}, "64": {name:"setting", arg:[]} }, dt2n: { //dt2n: dragText <==> function name "8": {name:"copyText", arg:[]}, "6": { name:"searchText", arg:["http://www.baidu.com/s?wd=", true, true] } }, dl2n: { //dl2n: drag link <==> function name "6": {name:"openLink", arg:[]}, "8": {name:"copyLink", arg:[]} }, di2n: { //li2n: drag image <==> function "8": {name:"saveImg", arg:[]}, "6": { name:"searchImg", arg:['https://image.baidu.com/n/pc_search?queryImageUrl=%URL&uptype=urlsearch', true, true] }, "2": {name:"copyImgURL", arg:[]}, "4": {name:"selectImg", arg:[]} }, directions: 4, // 4 or 8 directions minLineWidth: 1, //canvas setting lineGrowth: 0.6, maxLineWidth: 10, lineColor: '00AAA0', fontSize: 50, //tips font size tipsBackground: "00000055", //div background funNotDefine: " (◔ ‸◔)?", //function not define tips language: 1, //language 0:Chinese 1:English sensitivity: 10, // minLength translateTo: 'zh-CHS', translateTimeout: 5, zoom: 2, dragType: "", dragtext: true, draginput: true, draglink: true, dragimage: true, imgfirst: false, imgfirstcheck: true, setdragurl: true }; //function name <==> tips let fn = { t2n: { stopLoading: ['停止加载', 'StopLoading'], reload: ['刷新', 'Refresh'], reloadNoCache: ['清缓存刷新', 'Refresh Without Cache'], close: ['关闭', 'Close'], back: ['后退', 'Back'], forward: ['前进', 'Forward'], toTop: ['到顶部', 'Scroll to Top'], toBottom: ['到底部', 'Scroll to Bottom'], reopenTab: ['打开最近关闭窗口', 'Reopen Latest Closed Window'], setting: ['设置', 'Settings'], URLLevelUp: ['网址向上一层', 'URL hierarchy up'], cloneTab: ['克隆标签页', 'Duplicate This Tab'], openBlankTab: ['打开空白页', 'Open New Blank Tab'], translate: ['翻译网页', 'Translate This Page'], fkVip: ['破解VIP视频', 'Crack to Watch VIP Video'], closeOtherTabs: ['关闭其他标签', 'Close Other Tabs'], translateSelect: ['开启划词翻译', 'Turn on Select And Translate'], //开发者功能 contentEditable: ['元素内容可编辑', 'Element Content Editable'] }, dt2n: { searchText: ['搜索选中文本', 'Search Selected Text'], copyText: ['复制选中文本', 'Copy Selected Text'] }, dl2n: { openLink: ['打开链接', 'Open Link'], copyLink: ['复制链接', 'Copy Link'], copyLinkText: ['复制链接文字', 'Copy Link Text'] }, di2n: { saveImg: ['保存图片', 'Save Image'], searchImg: ['搜索图片', 'Search Image'], copyImage: ['复制图片', 'Copy Image to ClickBoard'], copyImgURL: ['复制图片链接', 'Copy ImageURL'], openImgNewTab: ['新标签打开图片', 'Open Image in New Tab'], image2DataURL: ['复制图片为DataURL','Copy Image as DataURL'], selectImg: ['选中图片', 'Select This Image'] } }; //function name <==> function declaration ==> execute it let Fn = { stopLoading: function() { window.stop(); }, reload: function(arr) { history.go(0); //window.location.reload(); }, reloadNoCache: function() { window.location.reload(true); }, close: function() { window.close(); }, back: function() { history.back(); }, forward: function() { history.forward(); }, toTop: function() { document.documentElement.scrollTo(0, 0); }, toBottom: function() { document.documentElement.scrollTo(0, 9999999); }, reopenTab: function() { //GreasyMonkdy: // GM_openInTab(GM_getValue('latestTab'),false); //TamperMonkey: GM_openInTab(GM_getValue('latestTab', 'about:blank'), { active: true }); }, URLLevelUp: function() { //当前网址的层次结构向上一层 if (window.location.href[window.location.href.length - 1] === "/") window.location.href = "../"; else window.location.href = "./"; }, //clone curren tab ,background cloneTab: function() { GM_openInTab(location.href, { active: false }); }, //open new blank tab openBlankTab: function() { window.open('about:blank'); }, //use MicrosoftTranslator to translate the page translate: function(arr) { if (typeof Microsoft === 'undefined' || typeof Microsoft.Translator === 'undefined') { let d = document.createElement('div'); d.id = "MicrosoftTranslatorWidget"; d.style.cssText = 'visibility:hidden;'; d.setAttribute('class', 'Lignt'); let s = document.createElement('script'); s.type = 'text/javascript'; s.charset = 'UTF-8'; s.src = ((location && location.href && location.href.indexOf('https') == 0) ? 'https://ssl.microsofttranslator.com' : 'http://www.microsofttranslator.com') + '/ajax/v3/WidgetV3.ashx?siteData=ueOIGRSKkd965FeEGM5JtQ**&ctf=False&ui=true&settings=Manual&from='; let p = document.getElementsByTagName('head')[0] || document.documentElement; p.insertBefore(s, p.firstChild); document.body.appendChild(d); } let onComplete, onProgress, onError; onError = function(){ GM_notification({ title: 'MouseGesture:', text: cfg.language ? "出了问题,无法完成翻译" : "Oops,Something wrong Hapend...", timoeout: 2000 }); tips.parentNode.removeChild(tips); }; onComplete = function() { tips.parentNode.removeChild(tips); }; onProgress = function() { document.documentElement.appendChild(tips); tips.innerHTML = cfg.language ? "翻译中..." : "Translating..."; }; let doTranslate = function() { if (typeof Microsoft === 'undefined' || typeof Microsoft.Translator === 'undefined') return; clearInterval(loadTranslatorTimer); Microsoft.Translator.Widget.Translate('', arr[0], onProgress, onError, onComplete, () => {}, (cfg.translateTimeout) * 1000); }; loadTranslatorTimer = setInterval(doTranslate, 200); setTimeout(() => clearTimeout(loadTranslatorTimer), (cfg.translateTimeout) * 1000); }, fkVip: function() { GM_openInTab((cfg.vipApi)+location.href, {active:true}); }, closeOtherTabs: function() { GM_setValue('closeAll', Date()); }, translateSelect: function() { window.document.body.addEventListener('mouseup', translate, false); var context = new AudioContext(); function translate(e) { var previous = document.querySelector('.youdaoPopup'); if (previous) { document.body.removeChild(previous); } var selectObj = document.getSelection(); if (selectObj.anchorNode.nodeType == 3) { var word = selectObj.toString(); if (word == '') { return; } word = word.replace('-\n', ''); word = word.replace('\n', ' '); var ts = new Date().getTime(); var x = e.clientX; var y = e.clientY; translate(word, ts); } function popup(x, y, result) { var youdaoWindow = document.createElement('div'); youdaoWindow.classList.toggle('youdaoPopup'); var dict = JSON.parse(result); var query = dict.query; var errorCode = dict.errorCode; if (dict.basic) { word(); } else { sentence(); } youdaoWindow.style.cssText = `z-index:999999;display:block;position:fixed;color:black;text-align:left;word-wrap:break-word;background:lightBlue;border-radius:5px;box-shadow:0 0 5px 0;opacity:1;width:200px;left:${x+10}px;padding:5px`; if (x + 200 + 10 >= window.innerWidth) { youdaoWindow.style.left = parseInt(youdaoWindow.style.left) - 200 + 'px'; } if (y + youdaoWindow.offsetHeight + 10 >= window.innerHeight) { youdaoWindow.style.bottom = '20px'; } else { youdaoWindow.style.top = y + 10 + 'px'; } document.body.appendChild(youdaoWindow); function word() { var basic = dict.basic; var header = document.createElement('p'); var span = document.createElement('span'); span.innerHTML = query; header.appendChild(span); var phonetic = basic.phonetic; if (phonetic) { var phoneticNode = document.createElement('span'); phoneticNode.innerHTML = '[' + phonetic + ']'; phoneticNode.style.cursor = 'pointer'; header.appendChild(phoneticNode); phoneticNode.addEventListener('mouseup', function(e) { e.stopPropagation(); }, false); var soundUrl = 'https://dict.youdao.com/dictvoice?type=2&audio={}'.replace('{}', query); var promise = new Promise(function() { GM_xmlhttpRequest({ method: 'GET', url: soundUrl, responseType: 'arraybuffer', onload: function(res) { try { context.decodeAudioData(res.response, function(buffer) { phoneticNode.addEventListener('mouseup', function() { var source = context.createBufferSource(); source.buffer = buffer; source.connect(context.destination); source.start(0); }, false); header.appendChild(document.createTextNode('✓')); }); } catch (e) {} } }); }); promise.then(); } header.style.color = 'darkBlue'; header.style.margin = '0'; header.style.padding = '0'; span.style.color = 'black'; youdaoWindow.appendChild(header); var hr = document.createElement('hr'); hr.style.margin = '0'; hr.style.padding = '0'; youdaoWindow.appendChild(hr); var ul = document.createElement('ul'); ul.style.margin = '0'; ul.style.padding = '0'; basic.explains.map(function(trans) { var li = document.createElement('li'); li.style.listStyle = 'none'; li.style.margin = '0'; li.style.padding = '0'; li.appendChild(document.createTextNode(trans)); ul.appendChild(li); }); youdaoWindow.appendChild(ul); } function sentence() { var ul = document.createElement('ul'); ul.style.margin = '0'; ul.style.padding = '0'; dict.translation.map(function(trans) { var li = document.createElement('li'); li.style.listStyle = 'none'; li.style.margin = '0'; li.style.padding = '0'; li.appendChild(document.createTextNode(trans)); ul.appendChild(li); }); youdaoWindow.appendChild(ul); } } function translate(word, ts) { var reqUrl = 'http://fanyi.youdao.com/openapi.do?type=data&doctype=json&version=1.1&relatedUrl=' + escape('http://fanyi.youdao.com/#') + '&keyfrom=fanyiweb&key=null&translate=on' + '&q={}'.replace('{}', word) + '&ts={}'.replace('{}', ts); GM_xmlhttpRequest({ method: 'GET', url: reqUrl, onload: function(res) { popup(x, y, res.response); } }); } } }, contentEditable: function(){ console.log('x:'+startX+' y:'+startY); document.elementFromPoint(startX, startY).setAttribute('contenteditable', 'true'); document.elementFromPoint(startX, startY).setAttribute('data-mp', '1'); }, /* //not torking zoomIn: function(){ setTimeout(zoomer, 200); function zoomer(evt){ let a, b,isZoom = true; a = document.elementFromPoint(evt.clientX,evt.clientY).style.zoom=cfg.zoom; a.setAttribute('data-zoom', 'true'); [].every.forEach(document.querySelectorAll('*[data-zoom=true]'), function(item){ if (item !== a) item.style.zoom = null; }); } },*/ searchText: function(arr) { //get text let txt = window.getSelection().toString(); txt = encodeURIComponent(txt); //get search enging openURL = arr[0] + txt; GM_openInTab(openURL, { active: arr[1], insert: arr[2], setParent: true //makes the browser re-focus the current tab on close. }); }, copyText: function() { GM_setClipboard(dObj.text, "text"); }, openLink: function() { //TamperMonkey GM_openInTab(dObj.link, { active: true }); }, copyLink: function() { GM_setClipboard(dObj.link, "text"); }, copyLinkText: function() { GM_setClipboard(dObj.text, "text"); }, saveImg: function() { //TamperMonkey let arr = dObj.img.split('/'); let name = arr[arr.length - 1]; GM_download(dObj.img, name); //method 2 /* let a = document.createElement('a'); a.href = dObj.img; a.setAttribute('download', dObj.img.split('/').pop()); document.documentElement.appendChild(a); a.click(); a.parentElement.remove(a); */ /* //jQuery: $("<a>").attr("href", actionFn.request.selimg).attr("download", actionFn.request.selimg.split('/').pop()).appendTo("body"); a[0].click(); a.remove(); */ }, searchImg: function(event,arr) { //TamperMonkey GM_openInTab(arr[0].replace(/%URL/, dObj.img), { active: arr[1], insert: arr[2], setParent: true //not working }); }, selectImg: function() { // it may not working on some browsers [develping standard] //TamperMonkey document.execCommand('selectAll'); let sel = document.getSelection(); sel.collapse(dObj.target, 0); sel.modify("extend", "forward", "character"); }, //not working: copyImage: function(e) { let canvas = canvasDrawTheImage(e); // get image as blob canvas.canvas.toBlob((blob) => { GM_setClipboard(blob, { type: canvas.type, mimetype: canvas.mime }); }, canvas.mime); }, image2DataURL: function(e) { //canvas绘制图片,由于浏览器的安全考虑: //如果在使用canvas绘图的过程中,使用到了外域的图片资源,那么在toDataURL()时会抛出安全异常: let canvas = canvasDrawTheImage(e).canvas; let dataURL = canvas.toDataURL(); GM_setClipboard(dataURL, "text"); }, copyImgURL: function() { //TamperMonkey GM_setClipboard(dObj.img, "text"); }, openImgNewTab: function() { //TamperMonkey GM_openInTab(dObj.img, { active: true }); }, setting: function() { if (document.getElementById('HYetting')) { return; } makeSettingUi(); } }; let flag = { actionType:'', isDrag: false, //if drag ,isDrag = true isPress: false, //if mouse right key is press,ispress = true hascanvas: false, //if document has <canvas> hascanvas = true isZoom: false //zoom mode }; //============ supportive functions ==> used by Fn{}'s function //check if string is an url function isURL(string) { try { new URL(string); } catch (e) { return false; } return true; } function isObject (item) { return (item && typeof item === 'object' && !Array.isArray(item) && item !== null); } /** * deep merge two objects into a new one * from https://stackoverflow.com/a/37164538/3771196 **/ function mergeDeep (target, source) { let output = Object.assign({}, target); if (isObject(target) && isObject(source)) { Object.keys(source).forEach(key => { if (isObject(source[key])) { if (!(key in target)) Object.assign(output, { [key]: source[key] }); else output[key] = mergeDeep(target[key], source[key]); } else Object.assign(output, { [key]: source[key] }); }); } return output; } let cfg = mergeDeep(_cfg,GM_getValue('cfg', _cfg)); //return: {canvas:canvas,type:fileType,mime:mimeType} function canvasDrawTheImage(e) { // let img = e.target, let img = dObj.target, fileType = img.src.split('/').pop().split('.').pop().toLowerCase(), mimeType = 'image/' + fileType, canvas = document.createElement('canvas'); canvas.width = getNaturalSize(img).width; canvas.height = getNaturalSize(img).height; canvas.getContext('2d', { alpha: true }).drawImage(img, 0, 0); return { canvas: canvas, type: fileType, mime: mimeType }; } // function canvasDrawTheImage(e) { // // let img = e.target, // var img=new Image; // img.onload=function(){ // var canvas=document.createElement("canvas"); // canvas.width = getNaturalSize(img).width; // canvas.height = getNaturalSize(img).height; // var g=canvas.getContext("2d",{alpha:true}); // g.drawImage(img,0,0); // console.log(canvas.toDataURL()); // }; // img.crossOrigin="anonymous"; //关键 // img.src=dObj.img; // return { // canvas: canvas, // type: 'png', // // type: fileType, // mime: 'image/png' // // mime: mimeType // }; // } // get image natural width and height function getNaturalSize(ele) { let i, w, h; if (typeof ele.naturalWidth == 'undefined') { // IE 6/7/8 i = new Image(); i.src = ele.src; w = i.width; h = i.height; } else { // HTML5 browsers w = ele.naturalWidth; h = ele.naturalHeight; } return { width: w, height: h }; } //============ function for all //show Tips function showTips(){ if (cfg[cfg.dragType][track] !== undefined) { tips.innerHTML = track + '<br/>' + fn[cfg.dragType][cfg[cfg.dragType][track].name][cfg.language]; } else { tips.innerHTML = track + '<br/>' + (cfg.funNotDefine); } } function drawTrack(e){ if (flag.hascanvas) { ctx.lineWidth = Math.min(cfg.maxLineWidth, ctx.lineWidth += cfg.lineGrowth); ctx.beginPath(); ctx.moveTo(x, y); ctx.lineTo(e.clientX, e.clientY); ctx.stroke(); ctx.closePath(); } } function getDirection(cx, cy){ /*================= | | | 1↖ 2↑ 3↗ | | | | 4← 5 6→ | | | | 7↙ 8↓ 9↘ | | | |=================*/ let d, t; if(cfg.directions === 4){ //4 directions if (dx < dy) { d = cy > y ? "8" : "2"; } else { d = cx > x ? "6" : "4"; } }else{ //8 directions t = (cy-y)/(cx-x); if(-0.4142<= t && t < 0.4142) d = cx > x ? '6' : "4"; else if(2.4142 <= t || t< -2.4142) d = cy > y ? '8' : '2'; else if(0.4142 <= t && t < 2.4142) d= cx > x ? '9' : '1'; else d = cy > y ? '7' : '3'; } return d; } //draw track & show tips function tracer(e) { // const tracer = function(e) { let cx = e.clientX, cy = e.clientY; dx = Math.abs(cx - x), dy = Math.abs(cy - y); distance = dx * dx + dy * dy; if (distance < cfg.sensitivity * cfg.sensitivity) { return; } //if mouse right key is press and document has no <canvas>,then creaet <canvas> and append it //到里面才添加元素是为了避免 鼠标一按下,还没有移动就已经图层了 //这个图层有两方面作用,①画出轨迹 ②支持拖拽功能, 因为作用②,所以不能移到 drawTrack 函数里面 if (flag.isPress && !flag.hascanvas) addCanvas(e); let direction = getDirection(cx,cy); if (track.charAt(track.length - 1) !== direction) { track += direction; showTips(); //show action tips } drawTrack(e); //draw track on canvas // update (x,y) x = cx; y = cy; } //<canvas> & tips<div> is ready, when mousemove or drag, append to show track & tips function addCanvas(e) { document.documentElement.appendChild(tips); //append tips <div> document.documentElement.appendChild(canvas); //append <canvas> canvas.width = window.innerWidth; //set canvas attribute to clear content canvas.height = window.innerHeight; ctx.lineCap = "round"; ctx.lineJoin = "round"; if(cfg.lineColor.length>6)canvas.style.opacity = parseInt(cfg.lineColor.slice(6),16)/255; ctx.lineWidth = cfg.minLineWidth; ctx.strokeStyle = '#' + cfg.lineColor.slice(0,6); //like delicious link color//line color flag.hascanvas = true; } //remove <canvas> and tips<div>,set flags to false function reset() { if (flag.hascanvas) { document.documentElement.removeChild(canvas); document.documentElement.removeChild(tips); } flag.isPress = false; flag.hascanvas = false; } function createCanvaTips(){ //create <canvas> canvas = document.createElement("canvas"); canvas.id = 'MPcanvas'; ctx = canvas.getContext("2d"); //create tips<div> tips = document.createElement('div'); tips.id = 'MPtips'; tips.style.cssText = `background:#${cfg.tipsBackground} !important; font-size: ${cfg.fontSize}px !important;`; } createCanvaTips(); //=========== event processing //right click ==> gesture window.addEventListener('mousedown', function(e) { // 3 : mouse.right ; 1:mouse.left if (e.which === 3) { startX = x = e.clientX; startY = y = e.clientY; track = ""; flag.isPress = true; // flag.actionType = "common"; cfg.dragType = "t2n"; window.addEventListener('mousemove', tracer, false); } }, false); window.addEventListener('contextmenu', function(e) { reset(); window.removeEventListener('mousemove', tracer, false); if (track !== "") { e.preventDefault(); if (cfg.t2n.hasOwnProperty(track)) { Fn[cfg.t2n[track].name](cfg.t2n[track].arg); } } }, false); //left click ==> drag window.addEventListener('dragstart', function(e) { startX = x = e.clientX; startY = y = e.clientY; track = ''; flag.isPress = true; flag.isDrag = true; flag.actionType = "drag"; processDrag(e); window.addEventListener('drag', tracer, false); //避免释放鼠标时候,坐标跑到(0,0) window.allowDrop this.allowDrop = function(event) { event.preventDefault(); }; tips.addEventListener("dragover", allowDrop, false); canvas.addEventListener("dragover", allowDrop, false); }, false); window.addEventListener('dragend', function(e) { window.removeEventListener('drag', tracer, false); tips.removeEventListener("dragover", allowDrop, false); canvas.removeEventListener("dragover", allowDrop, false); reset(); isDrag = false; if (track !== "" && cfg[cfg.dragType].hasOwnProperty(track)) { // dragType + track => function Fn[cfg[cfg.dragType][track].name](event,cfg[cfg.dragType][track].arg); } }, false); function processDrag(e) { //========这部分借鉴 crxMouse Chrome™ Gestures, crxID:jlgkpaicikihijadgifklkbpdajbkhjo=========== dObj.target = e.target; let nodetype = e.target.nodeType; //confirm dragType if (nodetype === 3) { let isLink = e.target.parentNode.href; if (cfg.dragtext && !isLink) { // cfg.dragType = "text"; cfg.dragType = "dt2n"; } else if (isLink) { //use regular express to match? e = e.target.parentNode; cfg.dragType = "dl2n"; // cfg.dragType = "link"; } } if (nodetype === 1) { if (e.target.value && cfg.dragtext && cfg.draginput) { cfg.dragType = "dt2n"; // cfg.dragType = "text"; } else if (e.target.href) { if (window.getSelection().toString() == "" || e.target.textContent.length > window.getSelection().toString().lenght) { if (cfg.draglink) { cfg.dragType = "dl2n"; // cfg.dragType = "link"; } } else { if (cfg.dragtext) { cfg.dragType = "dt2n"; // cfg.dragType = "text"; } } if (!cfg.dragtext && cfg.draglink) { cfg.dragType = "dl2n"; // cfg.dragType = "link"; } } else if (e.target.src) { if (e.target.parentNode.href) { if (cfg.dragimage && (e[cfg.imgfirst + "Key"] || cfg.imgfirstcheck)) { cfg.dragType = "di2n"; // cfg.dragType = "image"; } else if (cfg.draglink) { cfg.dragType = "dl2n"; // cfg.dragType = "link"; e = e.target.parentNode; } } else if (cfg.dragimage) { cfg.dragType = "di2n"; // cfg.dragType = "image"; } } } if (!cfg.dragType) { flag.isDrag = false; return; } dObj.text = window.getSelection().toString() || e.target.innerHTML; dObj.link = e.href || e.target.href; dObj.img = e.target.src; if (cfg.setdragurl && cfg.dragType == "dt2n") { var tolink; if (dObj.text.indexOf("http://") != 0 && dObj.text.indexOf("https://") != 0 && dObj.text.indexOf("ftp://") != 0 && dObj.text.indexOf("rtsp://") != 0 && dObj.text.indexOf("mms://") != 0 && dObj.text.indexOf("chrome-extension://") != 0 && dObj.text.indexOf("chrome://") != 0) { tolink = "http://" + dObj.text; } else { tolink = dObj.text; } var urlreg = /^((chrome|chrome-extension|ftp|http(s)?):\/\/)([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/; if (urlreg.test(tolink)) { cfg.dragType = "dl2n"; dObj.link = tolink; } } //========== crxID:jlgkpaicikihijadgifklkbpdajbkhjo END=========== return dObj; } //when close a tab, save it's url, in order to reopen it: reopenTab window.addEventListener('unload', function() { GM_setValue('latestTab', window.location.href); }, false); //used in func: closeOtherTabs if(!GM_getValue('closeAll','')) GM_setValue('closeAll', Date()); GM_addValueChangeListener('closeAll',function(name, old_value, new_value, remote){if(remote)window.close();}); //update all tabs MG's config if(!GM_getValue('configChanged','')) GM_setValue('configChanged', Date()); GM_addValueChangeListener('configChanged',function(name, old_value, new_value, remote){ if(remote) cfg = GM_getValue('cfg', _cfg); createCanvaTips(); }); //========== Setting UI let makeSettingUi = function(){ let CSS = ` #MPsetting{z-index:999997!important;background:white!important;width:100%!important;height:100%!important;font-family:"微软雅黑"!important;position:fixed!important;top:0!important;left:0!important;} #MPmenu *, .MPcontent *{border-radius:5px!important;font-size:16px!important;} #MPlogo{background:white!important;box-shadow:inset 0 0 25px 15px yellowgreen!important;width:80px!important;height:80px!important;padding:0 10px 30px 10px!important;display:block!important;font-size:80px!important;color:cyan!important;text-shadow:6px 5px 15px black!important;} #MPmenu{z-index:999999!important;height:100%!important;width:100px!important;background:yellowgreen!important;color:white!important;text-align:center!important;} #MPmenu li{list-style-type:none!important;border-top:1px dashed white!important;margin:10px 15px!important;} .MPselected{box-shadow:inset 2px 2px 1px 4px rgba(16,12,12,0.6)!important;} #MPmenu li:hover{background:#05FDE7!important;color:#FF841D!important;} #MPmenu li span{display:block!important;width:40px!important;height:40px!important;font-size:35px!important;font-weight:bold!important;padding:0 15px!important;} #MPmenu b{display:block!important;width:70px!important;text-align:center!important;margin-top:10px!important;} .MPcontent{height:94%!important;width:100%!important;overflow-y:scroll!important;position:absolute!important;left:100px!important;top:0!important;z-index:999998!important;padding:20px!important;} .MPcontent h1, #FunsList legend{display:block!important;width:800px!important;font-size:30px!important;float:left!important;top:0!important;left:90px!important;padding:5px 12px!important;margin:0 10px!important;border-left:5px solid yellowgreen!important;background:#9acd3259!important;} .MPcontent > li{list-style-type:none!important;width:800px!important;height:auto!important;padding:10px 5px 0px 5px!important;margin:5px 20px!important;float:left!important;border-bottom:1px dashed #00000020!important;} .MPcontent > li:hover{box-shadow:inset 1px 1px 1px 3px #9acd32de!important;} .MPcontent >li span:nth-child(2){background:#00000010!important;text-align:left!important;padding:4px 10px!important;height:20px!important;width:auto!important;float:left!important;} .MPcontent >li span:nth-child(3){max-height:28px!important;float:right!important;} .MPcontent input[type="text"]{width:250px!important;height:26px!important;margin:0 10px!important;text-align:center!important;border:0!important;background:#0000000C!important;font-size:20px!important;} .MPcontent input[type="checkbox"]{width:0!important;} .MPcontent select{width:100%!important;height:100%!important;} #FunsList{width:800px!important;border:0!important;overflow:hidden!important;} .FunsListHide{height:40px!important;} .FunsListShow{height:auto!important;} #FunsList>li{display:inline-block!important;width:300px!important;height:30px!important;margin:5px!important;text-align:left!important;} span.tag{margin:2px 7px!important;padding:0!important;border:0!important;font-size:11px!important;white-space:nowrap!important;font-weight:bold!important;} span.tag span:first-child{color:white!important;background:#555!important;margin:0!important;padding:3px 3px 3px 7px!important;border:0!important;border-radius:4px 0 0 4px!important;} span.tag span:last-child{color:white!important;margin:0!important;border:0!important;padding:3px 7px 3px 3px!important;border-radius:0 4px 4px 0!important;} span.tag.yellow span:last-child{background:#FFB400!important;} span.tag.blue span:last-child{background:#1182C2!important;} span.tag.green span:last-child{background:#4DC71F!important;} span.tag.darkcyan span:last-child{background:#4DB798!important;} .MPcontent > li[data-type=t2n] span:first-child{background:#FFB40030!important;color:#FFB400!important;} .MPcontent > li[data-type=dt2n] span:first-child{background:#4DC71F30!important;color:#4DC71F!important;} .MPcontent > li[data-type=dl2n] span:first-child{background:#1182C230!important;color:#1182C2!important;} .MPcontent > li[data-type=di2n] span:first-child{background:#4DB79830!important;color:#4DB798!important;} .MPcontent > li span:first-child{text-align:left!important;font-size:18px!important;font-weight:bold!important;padding:2px 10px!important;width:auto!important;height:24px!important;float:left!important;border-left:10px solid!important;margin-right:20px!important;} #mg2>li>span{margin-bottom:10px!important;} #mg2>li>span:nth-child(3)>input {font-family: MParrow;} #mg2 > li span:nth-child(5), .MPcontent > li span:nth-child(6), .MPcontent > li span:nth-child(7){max-height:30px!important;margin-bottom:100px!important;white-space:nowrap!important;} .MPcontent > li span:nth-child(5) select{width:auto!important;height:26px!important;} /*label 作为开关*/ label.switchOn{background:#4dc71f20!important;display:inline-block!important;color:#4DC71F!important;font-weight:bolder!important;min-width:40px!important;height:24px!important;padding:2px 5px!important;border-left:15px solid #4DC71F!important;border-radius:5px!important;} label.switchOff{background:#33333370!important;display:inline-block!important;color:#333333a0!important;text-decoration:line-through!important;min-width:40px!important;height:24px!important;padding:2px 5px!important;border-right:15px solid #333333!important;border-radius:5px!important;} input[type=checkbox].switch{width:0px!important;} `; let span = '', isOn = '', isChecked = '', settingDiv, settingParent, //菜单栏HTML txt = `<div id="MPmenu"><span id="MPlogo">☈</span><li data-target="mg1"><span>◧</span><b>Config</b></li><li data-target="mg2"><span>↯</span><b>Gesture</b></li><li data-target="mg3"><span>❓</span><b>About</b></li><li id="close"><span>?</span><b>Close</b></li></div>`; let setting = { mg1Start: {eletype: '1', id: 'mg1'}, mg1title1: {eletype: '2'}, maxLineWidth: {type: 'input', name: 'maxLineWidth', more: 'num'}, lineGrowth: {type: 'input', name: 'lineGrowth', more: 'num'}, fontSize: {type: 'input', name: 'fontSize', more: ''}, lineColor: {type: 'input', name: 'lineColor', more: 'color'}, funNotDefine: {type: 'input', name: 'funNotDefine', more: ''}, language: {type: 'input', name: 'language', more: 'num'}, sensitivity: {type: 'input', name: 'sensitivity', more: 'num'}, tipsBackground: {type: 'input', name: 'tipsBackground', more: 'color'}, translateTimeout: {type: 'input', name: 'translateTimeout', more: ''}, mg1title2: {eletype: '2'}, dragtext: {type: 'checkbox', name: 'dragtext', more: ''}, draginput: {type: 'checkbox', name: 'draginput', more: ''}, draglink: {type: 'checkbox', name: 'draglink', more: ''}, dragimage: {type: 'checkbox', name: 'dragimage', more: ''}, //imgfirst: {imgfirstcheck: {type: 'checkbox', name: 'imgfirstcheck', more: ''}, setdragurl: {type: 'checkbox', name: 'setdragurl', more: ''}, mg1end: {eletype: '3'} }; let selectobjs = { //languages translateTo: {"Afrikaans":"af","Haitian Creole":"ht","Querétaro Otomi":"otq","Arabic":"ar","Hebrew":"he","Romanian":"ro","Bangla":"bn","Hindi":"hi","Russian":"ru","Bosnian (Latin)":"bs-Latn","Hmong Daw":"mww","Samoan":"sm","Bulgarian":"bg","Hungarian":"hu","Serbian (Cyrillic)":"sr-Cyrl","Cantonese (Traditional)":"yue","Indonesian":"id","Serbian (Latin)":"sr-Latn","Catalan":"ca","Italian":"it","Slovak":"sk","Chinese Simplified":"zh-CHS","Japanese":"ja","Slovenian":"sl","Chinese Traditional":"zh-CHT","Kiswahili":"sw","Spanish":"es","Croatian":"hr","Klingon":"tlh","Swedish":"sv","Czech":"cs","Korean":"ko","Tahitian":"ty","Danish":"da","Latvian":"lv","Tamil":"ta","Dutch":"nl","Lithuanian":"lt","Thai":"th","English":"en","Malagasy":"mg","Tongan":"to","Estonian":"et","Malay":"ms","Turkish":"tr","Fijian":"fj","Maltese":"mt","Ukrainian":"uk","Filipino":"fil","Norwegian Bokmål":"no","Urdu":"ur","Finnish":"fi","Persian":"fa","Vietnamese":"vi","French":"fr","Polish":"pl","Welsh":"cy","German":"de","Portuguese":"pt","Yucatec Maya":"yua","Greek":"el"}, imgSearchEnging: { // image searching BaiduImage: "https://image.baidu.com/n/pc_search?queryImageUrl=%URL&uptype=urlsearch", GoogleImage: "https://www.google.com/searchbyimage?image_url=%URL", TinEye: "http://www.tineye.com/search?url=%URL" }, searchEnging: { // text searching google: "http://www.google.com/search?q=", baidu: "http://www.baidu.com/s?wd=", yandex: "http://www.yandex.com/yandsearch?text=", Bing: "http://www.bing.com/search?q=", yahoo: "http://search.yahoo.com/search?p=", wiki: "http://en.wikipedia.org/w/index.php?search=", taobao: "http://s.taobao.com/search?q=", amazon: "http://www.amazon.com/s/&field-keywords=", sogou: "https://www.sogou.com/web?query=", s360: "http://www.haosou.com/s?q=" }, vipAPI:{ 疯狂: "http://goudidiao.com/?url=", 噗噗: "http://pupudy.com/play?make=url&id=" } }; let local = { arg: { searchText:{ description:[['搜索引擎', '后台打开', '右边插入'], ['SearchingEnging', 'Load In Background', 'Insert After Current Tab']], arg:['select:searchEnging', 'checkbox', 'checkbox'] }, searchImg:{ description:[['图片搜索引擎', '后台打开', '右边插入'], ['Image SearchingEnging', 'Load In Background', 'Insert After Current Tab']], arg:['select:imgSearchEnging', 'checkbox', 'checkbox'] }, translate:{ description:[['目标语言'], ['Translate To']], arg:['select:translateTo'] }, fkVip:{ description:[['视频解析接口'], ['Videos Parser API']], arg:['select:vipAPI'] } }, FunsListTitle: { t2n: ['手势', 'Gesture'], dt2n: ['拖拽文本', 'Drag Text'], dl2n: ['拖拽链接', 'Drag Link'], di2n: ['拖拽图片', 'Drag Image'] }, tips: ['说明', 'Description'], addFunction: ['增加一个功能', 'Add Function'], //setting prefix: SET => SET + functionName + Item mg1title1ITEM: ['界面', 'UI'], maxLineWidthITEM: ['轨迹宽度', 'Line Width'], maxLineWidthDESC: ['鼠标轨迹最大宽度,单位"px"', 'Mouse Track Max. Line Width'], lineGrowthITEM: ['轨迹增长', 'Line Grow'], lineGrowthDESC: ['轨迹增长速度,单位"px"', 'Track Growing Speed, Unit "px"'], fontSizeITEM: ['提示字体大小', 'Tips Font Size'], fontSizeDESC: ['功能提示字体的大小,单位"px"', 'Function Tips Font Size, Unit "px"'], lineColorITEM: ['轨迹颜色', 'Line Color'], lineColorDESC: ['3|6|8位16进制值,如 0f0 ,00ff00, 00ff0080','3|6|8 Hexadecimal Value, eg. 0f0,00ff00,00ff0080'], funNotDefineITEM: ['未定义提示', 'Not Define Tips'], funNotDefineDESC: ['手势或者功能未定义时的提示信息', 'Undefined Function Tips'], languageITEM: ['语言', 'Language'], languageDESC: ['0 表示中文 1 表示英语', '0 for Chinese, 1 for English'], sensitivityITEM: ['识别距离', 'Sensitivigy'], sensitivityDESC: ['方向变化计算距离', 'Min Direction Change Distance'], tipsBackgroundITEM: ['提示文字背景颜色', 'Tis Background Color'], tipsBackgroundDESC: ['提示文字的背景颜色', 'Tips Background Color'], vipApiITEM: ['破解视频接口', 'Parse Video API'], vipApiDESC: ['VIP视频及杰解析接口', 'VIP Videos Parser API'], translateTimeoutITEM:['等待时间', 'Timeout'], translateTimeoutDESC:['翻译等待时间,超时作废', 'Translation Timeout'], mg1title2ITEM: ['设定', 'Setting'], dragtextITEM: ['启用拖拽文字', 'Enable Drag Text'], dragtextDESC: ['选中文字并且拖拽时候的功能', 'Enable Drag Text'], draginputITEM: ['启用拖拽文本框文字', 'Enable Drag Text-in-Inputbox'], draginputDESC: ['文本框中选中文字并且拖拽时候,使用拖拽的功能','Enable Drag Text-in-Inputbox'], draglinkITEM: ['启用拖拽链接', 'Enable Drag Link'], draglinkDESC: ['拖拽链接时候的功能', 'Enable Drag Link'], dragimageITEM: ['启用拖拽图片', 'Enable Drag Image'], dragimageDESC: ['拖拽图片时候的功能', 'Enable Drag Image'], imgfirstcheckITEM: ['图片链接识别为图片', 'Drag ImageLink as Drag Image'], imgfirstcheckDESC: ['拖拽图片链接时候,识别为拖拽图片的功能','Drag Image-Link, Treat as Drag Image'], setdragurlITEM: ['拖拽文本链接', 'Drag LinkText as Drag Link'], setdragurlDESC: ['拖拽文本为链接时候,识别为拖拽链接','Drag Link-Text, Treat as Drag Link'] }; let arg2html = function(argument, type, trk){ let html ="", argu, i,rand, trackTxt, name, argValue = [], agrDetail = [], description; typeof argument === "object" ? argu = argument : argu = JSON.parse(argument); trackTxt = trk || ''; name = argu.name; html += `<span>${name}</span><span>${fn[type][name][cfg.language]}</span><span><input type="text" name="${name}" value="${trackTxt}" data-mark="${type}"></span><br/>`; if(argu.arg.length > 0){ argValue = trackTxt ? argu.arg : []; agrDetail = local.arg[name].arg; description = local.arg[name].description[cfg.language]; for(i in agrDetail){ rand = Math.floor(Math.random()*1000); switch (agrDetail[i].slice(0,5)) { case 'input': html += '<span><input type="text"></span>'; break; case 'check': html += `<span><input type="checkbox" id="${name + rand}" value=${argValue[i] || false} ${argValue[i] ? "checked" : ''} class="switch"><label for="${name + rand}" ${argValue[i] ? 'class="switchOn"' : 'class="switchOff"'}>${description[i]}</label></span>`; break; case 'selec': selectName = agrDetail[i].split(':').pop(); html += `<span><input type="text" value=${argValue[i] || ''}><select>`; for (let k in selectobjs[selectName]){ html += `<option value=${selectobjs[selectName][k]}>${k}</option>`; } html += '</select></span>'; break; default: html = `<span style="visibility:hidden;"><span></span></span>`; break; } } } return html; }, makeFunsList = function(){ let html = '',i=0,j,hasArgument,item2,arg,color=['yellow', 'green', 'blue', 'darkcyan']; ['t2n','dt2n','dl2n','di2n'].forEach((item1) => { for( item2 in fn[item1]){ local.arg.hasOwnProperty(item2) ? arg = Object.assign({name:item2},local.arg[item2]) : arg = {name:item2,arg:[]}; html +=` <li data-arg='${JSON.stringify(arg)}' data-type="${item1}" title="${fn[item1][item2][cfg.language]}"><span class="tag ${color[i]}"><span>${local.FunsListTitle[item1][cfg.language]}</span><span>${item2}</span></span></li> `; } i += 1; }); html = `<fieldset id="FunsList" class="FunsListHide"><h1>${local.addFunction[cfg.language]} ➕ </h1><br/>${html}</fieldset>`; return html; }, makeDefinedFunsList = function(type){ let i, html =''; for(i in cfg[type]){ html += `<li data-arg='${JSON.stringify(cfg[type][i])}' data-type='${type}'>${arg2html(cfg[type][i], type, i)}`; } return html; }, clickToMakeEle = function(){ let tarEle = event.target.tagName === 'LI' ? event.target : (event.target.parentNode.tagName === "LI" ? event.target.parentNode : event.target.parentNode.parentNode); let ele = document.createElement('li'); ele.setAttribute('data-arg', tarEle.dataset.arg); ele.setAttribute('data-type', tarEle.dataset.type); ele.innerHTML = arg2html(tarEle.dataset.arg, tarEle.dataset.type); document.getElementById('mg2').insertBefore(ele, document.querySelector(`#mg2>li`)); try { if(ele.children[4]) ele.children[4].children[1].addEventListener('change', formChange, false); if(ele.children[5]) { ele.children[5].firstElementChild.addEventListener('change', formChange, false); ele.children[5].firstElementChild.addEventListener('change', onOff, false); } if(ele.children[6]) { ele.children[6].firstElementChild.addEventListener('change', formChange, false); ele.children[6].firstElementChild.addEventListener('change', onOff, false); } } catch(e) { } //轨迹框 失去焦点 更新设置 ele.children[2].firstElementChild.addEventListener('blur', updateFns, false); ele.children[2].firstElementChild.addEventListener('keyup', function(event) { event.target.value = letter2arrow(event.target.value); }, false); //函数列表收缩, 回滚到顶部 toggleFunsList(); document.documentElement.scrollTo(0, 0); }, updateFns = function(){ var typeObject = {}, tarEle = event.target; tarEle.tagName === "LI" ? null : (tarEle.parentNode.tagName === "LI" ? tarEle = tarEle.parentNode : tarEle = tarEle.parentNode.parentNode); [].forEach.call(document.querySelectorAll(`#mg2>li[data-type=${tarEle.dataset.type}]`), function(element, index) { updateItem(element); }); function updateItem(item){ let childrens, trk, argValue=[], name, dataArgObject; trk = item.children[2].firstElementChild.value; //if mouse track is not empty , update Fns if(trk !== ''){ childrens = item.children; dataArgObject = JSON.parse(item.dataset.arg); if(childrens[4]) { if(childrens[4].firstElementChild.value && childrens[4].firstElementChild.value !== "undefined"){ argValue[0] = childrens[4].firstElementChild.value; } else{ argValue[0] = ''; } } if(childrens[5]) { if(childrens[5].firstElementChild.value && childrens[5].firstElementChild.value !== "undefined"){ argValue[1] = childrens[5].firstElementChild.value; } else{ argValue[1] = ''; } } if(childrens[6]) { if(childrens[6].firstElementChild.value && childrens[6].firstElementChild.value !== "undefined"){ argValue[2] = childrens[6].firstElementChild.value; } else{ argValue[2] = ''; } } typeObject[trk] = {name: dataArgObject.name, arg: argValue}; } } cfg[tarEle.dataset.type] = typeObject; GM_setValue('cfg', cfg); GM_setValue('configChanged', Date()); }, updateCfgUsr = function(e){ switch (e.target.dataset.mark) { case 'color': cfg[e.target.name] = e.target.value; e.target.setAttribute('style', `background: #${e.target.value} !important;`); break; case 'num': let b; switch (e.target.name) { case 'language': b = (e.target.value == 1 || e.target.value == 0) ? e.target.value : cfg[e.target.name]; break; case 'sensitivity': case 'fontSize': b = parseInt(e.target.value); break; default: b = parseFloat(parseFloat(e.target.value).toFixed(2)); break; } cfg[e.target.name] = b; break; case 'select': case 'normal': cfg[e.target.name] = e.target.value; break; default: // cfg[e.target.id] = updateFns(`input[data-mark="${e.target.dataset.mark}"]`); break; } GM_setValue('cfg', cfg); GM_setValue('configChanged', Date()); }, formChange = function(){ if(event.target.type === 'checkbox'){ event.target.value = event.target.checked; updateFns(); } if(event.target.tagName === 'SELECT'){ event.target.previousElementSibling.value = event.target.value; updateFns(); } }, letter2arrow = function(str){ return str.replace(/[^uUdDlLrR4682]/g, '').replace(/[lL]/g, '4').replace(/[rR]/g, '6').replace(/[dD]/g, '8').replace(/[uU]/g, '2'); }, onOff = function(e) { cfg[e.target.id] = e.target.checked; if (cfg[e.target.id]) { e.target.nextElementSibling.setAttribute('class', 'switchOn'); } else { e.target.nextElementSibling.setAttribute('class', 'switchOff'); } //GM*** }, toggleFunsList = function(){ let a = document.getElementById('FunsList'); if(a.getAttribute('class') === "FunsListHide"){ a.setAttribute('class', 'FunsListShow'); }else{ a.setAttribute('class', 'FunsListHide'); } }, selected = function(e) { let tar; if (e.target.tagName === "LI") { tar = e.target; } else { tar = e.target.parentNode; } [].forEach.call(document.querySelectorAll('#MPmenu li'), function(item) { item.setAttribute('class', ''); }); tar.setAttribute('class', 'MPselected'); [].forEach.call(document.querySelectorAll('.MPcontent'), function(item) { item.style.display = "none"; }); document.getElementById(tar.dataset.target).setAttribute('style', 'display:block;'); }; GM_addStyle(CSS); //#mg1 config for (let i in setting) { if (setting[i].eletype) { switch (setting[i].eletype) { case '1': txt += `<div id="${setting[i].id}" class="MPcontent">`; break; case '2': txt += `<h1>${local[i+'ITEM'][cfg.language]}</h1>`; break; case 1: txt += `<div id="${setting[i].id}" class="MPcontent">`; break; default: txt += `</div>`; break; } } else { if (setting[i].type === 'input') { if (setting[i].more === 'color') { span = `<input type="text" name="${setting[i].name}" value="${cfg[setting[i].name]}" style="background:#${cfg[setting[i].name]};" data-mark="color">`; } else if (setting[i].more === 'num') { span = `<input type="text" name="${setting[i].name}" value="${cfg[setting[i].name]}" data-mark="num">`; } else { span = `<input type="text" name="${setting[i].name}" value="${cfg[setting[i].name]}" data-mark="normal">`; } } else { isChecked = cfg[setting[i].name] ? 'checked' : ''; isOn = cfg[setting[i].name] ? 'class="switchOn"' : 'class="switchOff"'; span = `<input type="checkbox" id="${setting[i].name}" name="${setting[i].name}" ${isChecked} class="switch"><label for="${setting[i].name}" ${isOn}></label>`; } txt += `<li><span>${local[i+'ITEM'][cfg.language]}</span><span title='${local[i+'DESC'][cfg.language]}'>${local.tips[cfg.language]}</span><span>${span}</span></li>`; } } //#mg2 Defined FunsList htms Gesture/Darg funcs txt +='<div id="mg2" class="MPcontent">'; txt += makeFunsList(); //#mg2 FunsList html txt += makeDefinedFunsList('t2n'); txt += makeDefinedFunsList('dt2n'); txt += makeDefinedFunsList('dl2n'); txt += makeDefinedFunsList('di2n'); txt += '</div>'; //#mg2 end //#mg3 txt += '<div id="mg3" class="MPcontent"><a href="https://github.com/woolition/greasyforks/blob/master/mouseGesture/HY-MouseGesture.md" style="display:block;width: 90%;height: auto;font-family:MParrow;font-size: 40px!important;text-decoration: none;font-weight: bolder;padding: 30px 30px; color:yellowgreen;">手势输入:<br>u or U: 2<br>r or R: 6<br> d or D: 8<br> l or L: 4<br><br>(● ̄(エ) ̄●)づ <br>点我看更多介绍! </a></div>'; settingDiv = document.createElement('div'); settingDiv.id = "MPsetting"; settingDiv.innerHTML = txt; settingParent = document.body || document.documentElement; settingParent.appendChild(settingDiv); [document.querySelectorAll('#MPmenu li')[0],document.querySelectorAll('#MPmenu li')[1],document.querySelectorAll('#MPmenu li')[2]].forEach(function(item) { item.addEventListener('click', selected, false); }); [].forEach.call(document.querySelectorAll('#mg1 input[type=text]'), function(item) { item.addEventListener('blur', updateCfgUsr, false); }); [].forEach.call(document.querySelectorAll('#mg1 input[type=checkbox], #mg2 input[type=checkbox]'), function(item) { item.addEventListener('change', onOff, false); if(item.parentNode.parentNode.parentNode.id === 'mg1'){ item.addEventListener('change',updateCfgUsr,false); } }); [].forEach.call(document.querySelectorAll('#FunsList li'),(item)=>{ item.addEventListener('click', clickToMakeEle, false); }); [].forEach.call(document.querySelectorAll('#mg2 input[type=text]'), function(item) { item.addEventListener('blur', updateFns, false); }); [].forEach.call(document.querySelectorAll('#mg2 select, #mg2 input[type=checkbox]'), function(item) { item.addEventListener('change', formChange, false); }); [].forEach.call(document.querySelectorAll('#mg2>li'), function(item) { item.children[2].firstElementChild.addEventListener('keyup', function(event) { let a = event.target.value; a = letter2arrow(a); if(a.charAt(a.length -1) === a.charAt(a.length-2)) a = a.slice(0,-1); event.target.value = a; }, false); }); //init [].forEach.call(document.querySelectorAll('.MPcontent'), function(item) { item.style.display = "none"; }); document.querySelector('#FunsList h1').addEventListener('click', toggleFunsList, false); document.getElementById('mg1').style.display = 'block'; document.getElementById('close').addEventListener('click', function(e) { try { document.documentElement.removeChild(document.getElementById("MPsetting")); } catch(event) { document.body.removeChild(document.getElementById("MPsetting")); } }, false); }; // return; })();