Greasy Fork 支持简体中文。

HY-MouseGesture

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 'S' to costomize, track:ULDRDLU

目前為 2017-11-20 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name HY-MouseGesture
  3. // @name:zh-CN 鼠标手势
  4. // @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 'S' to costomize, track:ULDRDLU
  5. // @description:zh-CN 鼠标手势脚本,支持右键轨迹手势和左键拖拽功能.可以拖拽[文本],[链接]和[图片],支持自定义设置:鼠标画S形,路径 ULDRDLU
  6. // @version 1.0
  7. // @include *
  8. // @noframes
  9. // @run-at document-start
  10. // @grant GM_openInTab
  11. // @grant GM_addStyle
  12. // @grant GM_setValue
  13. // @grant GM_getValue
  14. // @grant GM_setClipboard
  15. // @grant GM_download
  16. // @grant window.close
  17. // @namespace https://greasyfork.org/users/104201
  18. // ==/UserScript==
  19. /* jshint esversion: 6 */
  20. // due to modul pattern: http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html
  21.  
  22.  
  23. const MouseGesture = (function() {
  24. let MG = {};
  25. let defaultTrack2name = {
  26. U: "toTop",
  27. D: "toBottom",
  28. L: "back",
  29. R: "forward",
  30. DR: "close",
  31. LU: "reopenLatestCloseTab",
  32. ULDRDLU: 'setting'
  33. },
  34. defaultDragText2name = {
  35. L: "copySelectedText",
  36. R: "searchSelectedText"
  37. },
  38. defaultDragLink2name = {
  39. R: 'openLink',
  40. L: 'copyLink'
  41. },
  42. defaultDragImg2name = {
  43. D: 'saveImg',
  44. R: 'searchImg',
  45. U: 'copyImgURL',
  46. L: 'selectTheImage'
  47. },
  48. defaultConfig = {
  49. //canvas setting
  50. minLineWidth: 1,
  51. lineGrowth: 0.6,
  52. maxLineWidth: 10,
  53. lineColor: '00AAA0',
  54. // tips div.style.background
  55. tipsBackground: "00000055",
  56. //language 0:Chinese 1:English
  57. language: 1,
  58. SENSITIVITY: 10, // minLength
  59. searchEnging: "https://www.baidu.com/s?ie=UTF-8&wd=%s",
  60. // 0:open new tab background 1:open new tab active
  61. notBackground: 1,
  62. zoom: 2,
  63. //drag config
  64. dragType: "",
  65. // isDrag:false,
  66. dragtext: true,
  67. draginput: true,
  68. draglink: true,
  69. dragimage: true,
  70. imgfirst: false,
  71. imgfirstcheck: true,
  72. setdragurl: true,
  73. // image searching
  74. // forground:true background false
  75. isImgSearchTabActive: true,
  76. // image searching enging
  77. imgSearchEnging: "https://image.baidu.com/n/pc_search?queryImageUrl=%URL&uptype=urlsearch"
  78. };
  79. //save the latest closed tab Url, used in : reopenLatestCloseTab
  80. window.addEventListener('unload', function() {
  81. GM_setValue('latestTab', window.location.href);
  82. }, false);
  83. MG.config = GM_getValue('config', defaultConfig);
  84.  
  85. let flag = {
  86. actionType: '',
  87. //if drag ,isDrag = true
  88. isDrag: false,
  89. //if mouse right key is press,ispress = true
  90. isPress: false,
  91. //if document has <canvas> hascanvas = true
  92. hascanvas: false,
  93. //zoom mode
  94. isZoom: false
  95. };
  96. let funcValues = {
  97. // image searching
  98. imgBaidu: {
  99. s: "https://image.baidu.com/n/pc_search?queryImageUrl=%URL&uptype=urlsearch",
  100. name: "Baidu Image"
  101. },
  102. imgGoogle: {
  103. s: "https://www.google.com/searchbyimage?image_url=%URL",
  104. name: "Google Image"
  105. },
  106. imgTinEye: {
  107. s: "http://www.tineye.com/search?url=",
  108. name: "TinEye"
  109. },
  110. // common searching
  111. google: {
  112. s: "http://www.google.com/search?q=",
  113. name: "Google"
  114. },
  115. baidu: {
  116. s: "http://www.baidu.com/s?wd=",
  117. name: "Baidu"
  118. },
  119. yandex: {
  120. s: "http://www.yandex.com/yandsearch?text=",
  121. name: "Yandex"
  122. },
  123. Bing: {
  124. s: "http://www.bing.com/search?q=",
  125. name: "Bing"
  126. },
  127. yahoo: {
  128. s: "http://search.yahoo.com/search?p=",
  129. name: "Yahoo"
  130. },
  131. wiki: {
  132. s: "http://en.wikipedia.org/w/index.php?search=",
  133. name: "Wiki"
  134. },
  135. taobao: {
  136. s: "http://s.taobao.com/search?q=",
  137. name: "Taobao"
  138. },
  139. amazon: {
  140. s: "http://www.amazon.com/s/&field-keywords=",
  141. name: "Amazon"
  142. },
  143. sogou: {
  144. s: "https://www.sogou.com/web?query=",
  145. name: "sougou"
  146. },
  147. s360: {
  148. s: "http://www.haosou.com/s?q=",
  149. name: "360"
  150. }
  151. };
  152. let fn = {
  153. gesture: {
  154. stopLoading: ['停止加载', 'StopLoading'],
  155. reload: ['刷新', 'Refresh'],
  156. close: ['关闭', 'Close'],
  157. back: ['后退', 'Back'],
  158. forward: ['前进', 'Forward'],
  159. toTop: ['到顶部', 'Scroll to Top'],
  160. toBottom: ['到底部', 'Scroll to Bottom'],
  161. reopenLatestCloseTab: ['打开最近关闭窗口', 'Reopen Latest Closed Window'],
  162. setting: ['设置', 'Settings'],
  163. URLLevelUp: ['网址向上一层', 'URL hierarchy up'],
  164. cloneTab: ['克隆标签页', 'Duplicate tab'],
  165. openBlankTab: ['打开空白页', 'Open New Blank Tab'],
  166. },
  167. dragText: {
  168. searchSelectedText: ['搜索选中文本', 'Search Selected Text'],
  169. copySelectedText: ['复制选中文本', 'Copy Selected Text']
  170. },
  171. dragLink: {
  172. openLink: ['打开链接', 'Open Link'],
  173. copyLink: ['复制链接', 'Copy Link']
  174. },
  175. dragImg: {
  176. saveImg: ['保存图片', 'Save Image'],
  177. searchImg: ['搜索图片', 'Search Image'],
  178. copyImage: ['复制图片', 'Copy Image to ClickBoard'],
  179. copyImgURL: ['复制图片链接', 'Copy ImageURL'],
  180. openImgNewTab: ['新标签打开图片', 'Open Image in New Tab'],
  181. image2DataURL: ['复制图片为DataURL', 'Copy Image as DataURL'],
  182. selectTheImage: ['选中图片', 'Select This Image']
  183. }
  184. };
  185. //gesture functions
  186. MG.name2func = {
  187. stopLoading: function() {
  188. window.stop();
  189. },
  190. reload: function() {
  191. history.go(0);
  192. },
  193. close: function() {
  194. window.close();
  195. },
  196. back: function() {
  197. history.back();
  198. },
  199. forward: function() {
  200. history.forward();
  201. },
  202. toTop: function() {
  203. document.documentElement.scrollTo(0, 0);
  204. },
  205. toBottom: function() {
  206. document.documentElement.scrollTo(0, 9999999);
  207. },
  208. reopenLatestCloseTab: function() {
  209. //GreasyMonkdy:
  210. // GM_openInTab(GM_getValue('latestTab'),false);
  211. //TamperMonkey:
  212. GM_openInTab(GM_getValue('latestTab'), {
  213. active: true
  214. });
  215. },
  216. URLLevelUp: function() {
  217. //当前网址的层次结构向上一层
  218. if (window.location.href[window.location.href.length - 1] === "/")
  219. window.location.href = "../";
  220. else
  221. window.location.href = "./";
  222. },
  223. //clone curren tab ,background
  224. cloneTab: function() {
  225. GM_openInTab(location.href, {
  226. active: false
  227. });
  228. },
  229. //open new blank tab
  230. openBlankTab: function() {
  231. window.open('about:blank');
  232. },
  233.  
  234. /*
  235. //not torking
  236. zoomIn: function(){
  237. setTimeout(zoomer, 200);
  238. function zoomer(evt){
  239. let a, b,isZoom = true;
  240. a = document.elementFromPoint(evt.clientX,evt.clientY).style.zoom=MG.config.zoom;
  241. a.setAttribute('data-zoom', 'true');
  242. [].every.forEach(document.querySelectorAll('*[data-zoom=true]'), function(item){
  243. if (item !== a) item.style.zoom = null;
  244. });
  245. }
  246. },*/
  247.  
  248. searchSelectedText: function(searchEnging) {
  249. //get text
  250. let txt = window.getSelection().toString();
  251. txt = encodeURIComponent(txt);
  252. //get search enging
  253. openURL = MG.config.searchEnging.replace(/%s/, txt);
  254. // openURL = searchEnging.replace(/%s/,txt);
  255. GM_openInTab(openURL, {
  256. active: MG.config.notBackground
  257. });
  258. },
  259. copySelectedText: function() {
  260. GM_setClipboard(MG.dragObject.text, "text");
  261. },
  262. openLink: function() {
  263. //TamperMonkey
  264. GM_openInTab(MG.dragObject.link, {
  265. active: true
  266. });
  267. },
  268. copyLink: function() {
  269. //TamperMonkey
  270. GM_setClipboard(MG.dragObject.link, "text");
  271. },
  272. saveImg: function() {
  273. //TamperMonkey
  274. let arr = MG.dragObject.img.split('/');
  275. let name = arr[arr.length - 1];
  276. GM_download(MG.dragObject.img, name);
  277. //method 2
  278. /*
  279. let a = document.createElement('a');
  280. a.href = MG.dragObject.img; a.setAttribute('download', MG.dragObject.img.split('/').pop());
  281. document.documentElement.appendChild(a);
  282. a.click();
  283. a.parentElement.remove(a);
  284. */
  285. /* //jQuery:
  286. $("<a>").attr("href", actionFn.request.selimg).attr("download", actionFn.request.selimg.split('/').pop()).appendTo("body");
  287. a[0].click();
  288. a.remove();
  289. */
  290. },
  291. searchImg: function() {
  292. //TamperMonkey
  293. GM_openInTab(MG.config.imgSearchEnging.replace(/%URL/, MG.dragObject.img), {
  294. active: MG.config.isImgSearchTabActive
  295. });
  296. },
  297. selectTheImage: function() {
  298. // it may not working on some browsers [develping standard]
  299. //TamperMonkey
  300. document.execCommand('selectAll');
  301. let sel = document.getSelection();
  302. sel.collapse(MG.dragObject.target, 0);
  303. sel.modify("extend", "forward", "character");
  304. },
  305. //not working:
  306. copyImage: function(e) {
  307. let canvas = canvasDrawTheImage(e);
  308. // get image as blob
  309. canvas.canvas.toBlob((blob) => {
  310. GM_setClipboard(blob, {
  311. type: canvas.type,
  312. mimetype: canvas.mime
  313. });
  314. }, canvas.mime);
  315. },
  316. image2DataURL: function(e) {
  317. //canvas绘制图片,由于浏览器的安全考虑:
  318. //如果在使用canvas绘图的过程中,使用到了外域的图片资源,那么在toDataURL()时会抛出安全异常:
  319. let canvas = canvasDrawTheImage(e).canvas;
  320. let dataURL = canvas.toDataURL();
  321. GM_setClipboard(dataURL, "text");
  322. },
  323. copyImgURL: function() {
  324. //TamperMonkey
  325. GM_setClipboard(MG.dragObject.img, "text");
  326. },
  327. openImgNewTab: function() {
  328. //TamperMonkey
  329. GM_openInTab(MG.dragObject.img, {
  330. active: true
  331. });
  332. },
  333. setting: function() {
  334. if (document.getElementById('HYMGSetting')) {
  335. return;
  336. }
  337. createSeetingUi();
  338. }
  339. };
  340. // support functions========================
  341. //check if string is an url
  342. function isURL(string) {
  343. try {
  344. new URL(string);
  345. } catch (e) {
  346. return false;
  347. }
  348. return true;
  349. }
  350. //==>> return: {canvas:canvas,type:fileType,mime:mimeType}
  351. function canvasDrawTheImage(e) {
  352. // let img = e.target,
  353. let img = MG.dragObject.target,
  354. fileType = img.src.split('/').pop().split('.').pop().toLowerCase(),
  355. mimeType = 'image/' + fileType,
  356. canvas = document.createElement('canvas');
  357. canvas.width = getNaturalSize(img).width;
  358. canvas.height = getNaturalSize(img).height;
  359. canvas.getContext('2d', {
  360. alpha: true
  361. }).drawImage(img, 0, 0);
  362. return {
  363. canvas: canvas,
  364. type: fileType,
  365. mime: mimeType
  366. };
  367. }
  368. // get image natural width and height
  369. function getNaturalSize(ele) {
  370. let i, rw, rh;
  371. if (typeof ele.naturalWidth == 'undefined') { // IE 6/7/8
  372. i = new Image();
  373. i.src = ele.src;
  374. rw = i.width;
  375. rh = i.height;
  376. } else { // HTML5 browsers
  377. rw = ele.naturalWidth;
  378. rh = ele.naturalHeight;
  379. }
  380. return {
  381. width: rw,
  382. height: rh
  383. };
  384. }
  385. //========================================
  386.  
  387. MG.track2name = GM_getValue('track2name', defaultTrack2name);
  388. //dragType = "text"
  389. MG.dragText2name = GM_getValue('dragText2name', defaultDragText2name);
  390. //dragType = "link"
  391. MG.dragLink2name = GM_getValue('dragLink2name', defaultDragLink2name);
  392. //dragType = "img"
  393. MG.dragImg2name = GM_getValue('dragImg2name', defaultDragImg2name);
  394. //canvas start coordinate
  395. MG.startX = 0;
  396. MG.startY = 0;
  397.  
  398. //create <canvas>
  399. MG.canvas = document.createElement("canvas");
  400. MG.canvas.style.cssText = "position:fixed;top:0;left:0;z-index:9999999;";
  401. MG.ctx = MG.canvas.getContext("2d");
  402.  
  403. //create tips<div>
  404. MG.tips = document.createElement('div');
  405. MG.tips.style.cssText = `
  406. all: initial !important;
  407. position: fixed !important;
  408. z-index: 9999998 !important;
  409. top: 50% !important;
  410. left: 50% !important;
  411. transform: translate(-50%, -50%) !important;
  412. font-family: "Orkney Regular", "Arial", sans-serif !important;
  413. font-size: 50px !important;
  414. color:white !important;
  415. white-space: nowrap !important;
  416. line-height: normal !important;
  417. text-shadow: 1px 1px 5px rgba(0,0,0, 0.8) !important;
  418. text-align: center !important;
  419. padding: 25px 20px 20px 20px !important;
  420. border-radius: 5px !important;
  421. font-weight: bold !important;
  422. background:#${MG.config.tipsBackground} !important;
  423. `;
  424.  
  425. let x, y, track = "",
  426. //use to show tips
  427. symbol = '',
  428. symbolTrack = '';
  429. MG.dragObject = {};
  430. // when a gesture is not define, show this tips
  431. function showGestureNotDefineTips() {
  432. MG.tips.innerHTML = symbolTrack + '<br/> (◔ ‸◔)?';
  433. }
  434.  
  435. const tracer = function(e) {
  436. let cx = e.clientX,
  437. cy = e.clientY,
  438. dx = Math.abs(cx - x),
  439. dy = Math.abs(cy - y),
  440. distance = dx * dx + dy * dy;
  441. if (distance < MG.config.SENSITIVITY * MG.config.SENSITIVITY) {
  442. return;
  443. }
  444. //if mouse right key is press and document has no <canvas>,then creaet <canvas> and append it
  445. //到里面才添加元素是为了避免 鼠标一按下,还没有移动就已经图层了
  446. if (flag.isPress && !flag.hascanvas) addCanvas(e);
  447. let direction = '',
  448. symbol = "";
  449. if (dx < dy) {
  450. direction = cy > y ? "D" : "U";
  451. symbol = cy > y ? "⬇" : "⬆";
  452. } else {
  453. direction = cx > x ? "R" : "L";
  454. symbol = cx > x ? "➞" : "⬅";
  455. }
  456. if (track.charAt(track.length - 1) !== direction) {
  457. track += direction;
  458. symbolTrack += symbol;
  459.  
  460. //show action tips
  461. switch (flag.actionType) {
  462. case "drag":
  463. switch (MG.config.dragType) {
  464. case "text":
  465. if (MG.dragText2name[track] !== undefined) {
  466. MG.tips.innerHTML = symbolTrack + '<br/>' + fn.dragText[MG.dragText2name[track]][MG.config.language];
  467. } else {
  468. showGestureNotDefineTips();
  469. }
  470. break;
  471. case "link":
  472. if (MG.dragLink2name[track] !== undefined) {
  473. MG.tips.innerHTML = symbolTrack + '<br/>' + fn.dragLink[MG.dragLink2name[track]][MG.config.language];
  474. } else {
  475. showGestureNotDefineTips();
  476. }
  477. break;
  478. case "image":
  479. if (MG.dragImg2name[track] !== undefined) {
  480. MG.tips.innerHTML = symbolTrack + '<br/>' + fn.dragImg[MG.dragImg2name[track]][MG.config.language];
  481. } else {
  482. showGestureNotDefineTips();
  483. }
  484. break;
  485. default:
  486. break;
  487. }
  488. break;
  489. case "common":
  490. if (MG.track2name[track] !== undefined) {
  491. //show gesture track and function name
  492. MG.tips.innerHTML = symbolTrack + '<br/>' + fn.gesture[MG.track2name[track]][MG.config.language];
  493. } else {
  494. showGestureNotDefineTips();
  495. }
  496. break;
  497. default:
  498. break;
  499. }
  500. }
  501.  
  502. //draw track on canvas
  503. if (flag.hascanvas) {
  504. MG.ctx.lineWidth = Math.min(MG.config.maxLineWidth, MG.ctx.lineWidth += MG.config.lineGrowth);
  505. MG.ctx.beginPath();
  506. MG.ctx.moveTo(x, y);
  507. MG.ctx.lineTo(e.clientX, e.clientY);
  508. MG.ctx.stroke();
  509. MG.ctx.closePath();
  510. }
  511. // update (x,y)
  512. x = cx;
  513. y = cy;
  514. };
  515.  
  516. window.addEventListener('mousedown', function(e) {
  517. // 3 : mouse.right ; 1:mouse.left
  518. if (e.which === 3) {
  519. x = e.clientX;
  520. y = e.clientY;
  521. track = "";
  522.  
  523. symbolTrack = "";
  524. flag.isPress = true;
  525. flag.actionType = "common";
  526. window.addEventListener('mousemove', tracer, false);
  527. }
  528. }, false);
  529.  
  530. //create <canvas> to show track,create <div> to show tips
  531. function addCanvas(e) {
  532. //append tips <div>
  533. document.documentElement.appendChild(MG.tips);
  534. //append <canvas>
  535. document.documentElement.appendChild(MG.canvas);
  536. //set canvas attribute or clear content
  537. MG.canvas.left = 0 + "px";
  538. MG.canvas.top = 0 + "px";
  539. MG.canvas.width = window.innerWidth;
  540. MG.canvas.height = window.innerHeight;
  541. MG.ctx.lineCap = "round";
  542. MG.ctx.lineJoin = "round";
  543. MG.ctx.lineWidth = MG.config.minLineWidth;
  544. MG.ctx.strokeStyle = '#' + MG.config.lineColor; //like delicious link color//line color
  545. MG.startX = e.clientX;
  546. MG.startY = e.clientY;
  547.  
  548. flag.hascanvas = true;
  549.  
  550. //clear track & symbolTrack
  551. track = "";
  552. symbolTrack = "";
  553. }
  554. //remove <canvas> and tips<div> .ect
  555. function reset() {
  556. if (flag.hascanvas) {
  557. document.documentElement.removeChild(MG.canvas);
  558. document.documentElement.removeChild(MG.tips);
  559. flag.hascanvas = false;
  560. }
  561. flag.isPress = false;
  562. }
  563.  
  564. window.addEventListener('contextmenu', function(e) {
  565. reset();
  566. window.removeEventListener('mousemove', tracer, false);
  567. if (track !== "") {
  568. e.preventDefault();
  569. if (MG.track2name.hasOwnProperty(track)) {
  570. MG.name2func[MG.track2name[track]]();
  571. }
  572. }
  573. }, false);
  574.  
  575. window.addEventListener('dragstart', function(e) {
  576. x = e.clientX;
  577. y = e.clientY;
  578. track = "";
  579. symbolTrack = '';
  580. flag.isPress = true;
  581. flag.isDrag = true;
  582. flag.actionType = "drag";
  583. processDrag(e);
  584. // console.log(MG.dragObject);
  585. window.addEventListener('drag', tracer, false);
  586. //避免释放鼠标时候,坐标跑到(0,0) window.allowDrop
  587. this.allowDrop = function(ev) {
  588. ev.preventDefault();
  589. };
  590. MG.tips.setAttribute("ondragover", "allowDrop(event)");
  591. MG.canvas.setAttribute("ondragover", "allowDrop(event)");
  592. }, false);
  593.  
  594. window.addEventListener('dragend', function(e) {
  595. window.removeEventListener('drag', tracer, false);
  596. MG.tips.setAttribute("ondragover", "");
  597. MG.canvas.setAttribute("ondragover", "");
  598. reset();
  599. isDrag = false;
  600. if (track !== "") {
  601. // dragType + track => function
  602. switch (MG.config.dragType) {
  603. case "text":
  604. if (MG.dragText2name.hasOwnProperty(track)) {
  605. console.log('text');
  606. MG.name2func[MG.dragText2name[track]]();
  607. }
  608. break;
  609. case "link":
  610. if (MG.dragLink2name.hasOwnProperty(track)) {
  611. console.log('link');
  612. MG.name2func[MG.dragLink2name[track]]();
  613. }
  614. break;
  615. case "image":
  616. if (MG.dragImg2name.hasOwnProperty(track)) {
  617. console.log('img');
  618. MG.name2func[MG.dragImg2name[track]](e);
  619. }
  620. break;
  621. default:
  622. break;
  623. }
  624. }
  625.  
  626. }, false);
  627.  
  628. function processDrag(e) {
  629. //========这部分借鉴 crxMouse Chrome™ Gestures, crxID:jlgkpaicikihijadgifklkbpdajbkhjo===========
  630. MG.dragObject.target = e.target;
  631. let nodetype = e.target.nodeType;
  632. //confirm dragType
  633. if (nodetype === 3) {
  634. let isLink = e.target.parentNode.href;
  635. if (MG.config.dragtext && !isLink) {
  636. MG.config.dragType = "text";
  637. } else if (isLink) { //use regular express to match?
  638. e = e.target.parentNode;
  639. MG.config.dragType = "link";
  640. }
  641. }
  642. if (nodetype === 1) {
  643. if (e.target.value && MG.config.dragtext && MG.config.draginput) {
  644. MG.config.dragType = "text";
  645. } else if (e.target.href) {
  646. if (window.getSelection().toString() == "" || e.target.textContent.length > window.getSelection().toString().lenght) {
  647. if (MG.config.draglink) {
  648. MG.config.dragType = "link";
  649. }
  650. } else {
  651. if (MG.config.dragtext) {
  652. MG.config.dragType = "text";
  653. }
  654. }
  655. if (!MG.config.dragtext && MG.config.draglink) {
  656. MG.config.dragType = "link";
  657. }
  658. } else if (e.target.src) {
  659. if (e.target.parentNode.href) {
  660. if (MG.config.dragimage && (e[MG.config.imgfirst + "Key"] || MG.config.imgfirstcheck)) {
  661. MG.config.dragType = "image";
  662. } else if (MG.config.draglink) {
  663. MG.config.dragType = "link";
  664. e = e.target.parentNode;
  665. }
  666.  
  667. } else if (MG.config.dragimage) {
  668. MG.config.dragType = "image";
  669. }
  670. }
  671.  
  672. }
  673.  
  674.  
  675. if (!MG.config.dragType) {
  676. flag.isDrag = false;
  677. return;
  678. }
  679. MG.dragObject.text = window.getSelection().toString() || e.target.innerHTML;
  680. MG.dragObject.link = e.href || e.target.href;
  681. MG.dragObject.img = e.target.src;
  682. if (MG.config.setdragurl && MG.config.dragType == "text") {
  683. var tolink;
  684. if (MG.dragObject.text.indexOf("http://") != 0 && MG.dragObject.text.indexOf("https://") != 0 && MG.dragObject.text.indexOf("ftp://") != 0 && MG.dragObject.text.indexOf("rtsp://") != 0 && MG.dragObject.text.indexOf("mms://") != 0 && MG.dragObject.text.indexOf("chrome-extension://") != 0 && MG.dragObject.text.indexOf("chrome://") != 0) {
  685. tolink = "http://" + MG.dragObject.text;
  686. } else {
  687. tolink = MG.dragObject.text;
  688. }
  689. var urlreg = /^((chrome|chrome-extension|ftp|http(s)?):\/\/)([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/;
  690. if (urlreg.test(tolink)) {
  691. MG.config.dragType = "link";
  692. MG.dragObject.link = tolink;
  693. }
  694. }
  695. //========== crxID:jlgkpaicikihijadgifklkbpdajbkhjo END===========
  696. return MG.dragObject;
  697. }
  698.  
  699. // Setting UI
  700. function createSeetingUi() {
  701. let CSS = `
  702. #HYMGSetting {z-index:999997;width:960px;height:540px;margin:0;padding:0;font-family:"微软雅黑";background:white;border:7px solid yellowgreen;border-radius:10px;position:fixed;top:50px;left:50px;box-shadow:2px 2px 2px 4px darkcyan;}
  703. #MGlogo {width:90px;height:85px;display:block;font-size:90px;font-weight:bolder;text-align:center;position:relative;top:-23px;color:#000;vertical-align:top;text-decoration:blink;text-shadow:5px 5px 3px #05fde7;}
  704. #MGmenu {z-index:999999;height:100%;width:90px;background:yellowgreen;color:white;}
  705. #MGmenu li {list-style-type:none;background:yellowgreen;border-top:1px dashed white;}
  706. .MGselected {box-shadow:inset 2px 2px 1px 4px rgba(16,12,12,0.6);}
  707. #MGmenu li:hover {background:#05FDE7 !important;color:#FF841D;animation:MGmenuLi 0.4s;-moz-animation:MGmenuLi 0.4s;-webkit-animation:MGmenuLi 0.4s;-o-animation:myfirst 0.4s;}
  708. @keyframes MGmenuLi {from {background:yellowgreen;color:white;} to {background:#05FDE7;} }
  709. @-moz-keyframes MGmenuLi {from {background:yellowgreen;} to {background:#05FDE7;} }
  710. @-webkit-keyframes MGmenuLi {from {background:yellowgreen;} to {background:#05FDE7;} }
  711. @-o-keyframes MGmenuLi {from {background:#16DA00;} to {background:#05FDE7;} }
  712. #MGmenu li span {display:block;width:50px;height:50px;font-size:50px;padding:5px 20px;text-align:center;}
  713. #MGmenu b {display:block;height:30px;font-size:20px;width:90px;text-align:center;}
  714. /*#mg1,#mg2,#mg3,#mg4,#mg5*/.HYMGcontent {height:540px;overflow-x:hidden;width:870px;font-size:16px;font-family:"微软雅黑";overflow-y:scroll;position:absolute;left:90px;top:0;z-index:999998;padding:10px,20px;}
  715. .HYMGcontent * {border-radius:8px;}
  716. .HYMGcontent h1 {display:block;width:820px;font-size:30px;float:left;top:0;left:90px;padding:5px;margin:0 10px;border-left:5px solid yellowgreen;background:#9acd3259;}
  717. .HYMGcontent li {list-style-type:none;width:810px;height:56px;padding:5px 5px;margin:5px 20px;float:left;}
  718. .HYMGcontent li:hover {box-shadow:inset 1px 1px 1px 3px #9acd32de;}
  719. .HYMGcontent li span:first-child {display:inline-block;font-size:18px;font-weight:bold;padding:2px 10px;width:450px;height:24px;float:left;}
  720. .HYMGcontent li span:nth-child(2) {display:inline-block;padding:2px 10px;height:20px;width:530px;float:left;}
  721. .HYMGcontent li span:nth-child(3) {display:inline-block;width:200px;height:30px;padding:5px;margin:8px 20px;position:relative;right:0;top:0;border:1px solid #66666652;}
  722. .HYMGcontent input[type="text"] {width:100%;height:100%;text-align:center;background:transparent;border:0;font-size:20px;}
  723. .HYMGcontent input[type="checkbox"] {width:0px;}
  724. .HYMGcontent label {width:100%;height:100%;display:block;}
  725. `;
  726.  
  727. let setting = {
  728. mg1Start: {
  729. type: '1',
  730. id: 'mg1'
  731. },
  732. mg1title1: {
  733. item: ['界面', 'UI'],
  734. type: '2'
  735. },
  736. maxLineWidth: {
  737. item: ['线条宽度', 'Line Width'],
  738. description: ['鼠标轨迹最大宽度,单位"px"'],
  739. data: {
  740. type: 'input',
  741. name: 'maxLineWidth',
  742. more: ''
  743. }
  744. },
  745. lineGrowth: {
  746. item: ["线条宽度", 'Line Grow'],
  747. description: ['轨迹增长速度,单位"px"'],
  748. data: {
  749. type: 'input',
  750. name: 'lineGrowth',
  751. more: ''
  752. }
  753. },
  754. lineColor: {
  755. item: ["线条颜色", 'Line Color'],
  756. description: ['允许3|6|8位16进值,如 0f0 或 00ff00 都表示绿色,8位值后2位表示透明度'],
  757. data: {
  758. type: 'input',
  759. name: 'lineColor',
  760. more: 'color'
  761. }
  762. },
  763. language: {
  764. item: ["语言", 'Language'],
  765. description: ['0 表示中文 1 for English'],
  766. data: {
  767. type: 'input',
  768. name: 'language',
  769. more: ''
  770. }
  771. },
  772. SENSITIVITY: {
  773. item: ["识别距离", 'Sensitivigy'],
  774. description: ['方向变化计算距离'],
  775. data: {
  776. type: 'input',
  777. name: 'SENSITIVITY',
  778. more: ''
  779. }
  780. },
  781. tipsBackground: {
  782. item: ["提示文字背景颜色", 'Tis Background Color'],
  783. description: ['提示文字的背景颜色'],
  784. data: {
  785. type: 'input',
  786. name: 'tipsBackground',
  787. more: 'color'
  788. }
  789. },
  790. mg1title2: {
  791. item: ['设定', 'Setting'],
  792. type: '2'
  793. },
  794. notBackground: {
  795. item: ["新标签在前台", 'Tis Background Color'],
  796. description: ['打开新标签后马上转到新标签'],
  797. data: {
  798. type: 'checkbox',
  799. name: 'notBackground',
  800. more: ''
  801. }
  802. },
  803. imgSearchEnging: {
  804. item: ["图片搜索引擎", 'Image Search Enging'],
  805. description: ['用 %URL 代替 图片'],
  806. data: {
  807. type: 'input',
  808. name: 'imgSearchEnging',
  809. more: ''
  810. }
  811. },
  812. dragtext: {
  813. item: ["启用拖拽文字", 'Enable Drag Text'],
  814. description: ['选中文字并且拖拽时候的功能'],
  815. data: {
  816. type: 'checkbox',
  817. name: 'dragtext',
  818. more: ''
  819. }
  820. },
  821. draginput: {
  822. item: ["启用拖拽文本框文字", 'Enable Drag Text'],
  823. description: ['文本框中选中文字并且拖拽时候,使用拖拽的功能'],
  824. data: {
  825. type: 'checkbox',
  826. name: 'draginput',
  827. more: ''
  828. }
  829. },
  830. draglink: {
  831. item: ["启用拖拽链接", 'Enable Drag Link'],
  832. description: ['拖拽链接时候的功能'],
  833. data: {
  834. type: 'checkbox',
  835. name: 'draglink',
  836. more: ''
  837. }
  838. },
  839. dragimage: {
  840. item: ["启用拖拽图片", 'Enable Drag Image'],
  841. description: ['拖拽图片时候的功能'],
  842. data: {
  843. type: 'checkbox',
  844. name: 'dragimage',
  845. more: ''
  846. }
  847. },
  848. //imgfirst:{item:["启用拖拽图片优先",'Enable Drag Image Priority'],description:['拖拽有链接的图片时候,优先识别为图片'],data:{type:'checkbox',name:'imgfirst',more:''}},
  849. imgfirstcheck: {
  850. item: ["图片链接识别为图片", 'Enable Drag Image'],
  851. description: ['拖拽图片链接时候,识别为拖拽图片的功能'],
  852. data: {
  853. type: 'checkbox',
  854. name: 'imgfirstcheck',
  855. more: ''
  856. }
  857. },
  858. setdragurl: {
  859. item: ["拖拽文本链接", 'Enable Drag Image'],
  860. description: ['拖拽文本为链接时候,识别为拖拽链接'],
  861. data: {
  862. type: 'checkbox',
  863. name: 'setdragurl',
  864. more: ''
  865. }
  866. },
  867. mg1end: {
  868. type: '3'
  869. }
  870. };
  871. //UI menu
  872. let span = '',
  873. xx = '',
  874. isOn = '',
  875. isChecked = '',
  876. t = '',
  877. txt = `
  878. <div id="MGmenu">
  879. <span id="MGlogo">☈</span>
  880. <li data-target="mg1"><span>◧</span><b>Config</b></li>
  881. <li data-target="mg2"><span>↯</span><b>Gesture</b></li>
  882. <li data-target="mg3"><span>⎘</span><b>Drag</b></li>
  883. <li data-target="mg4"><span>❓</span><b>About</b></li>
  884. <li data-target="mg5" id="MGClose"><span>?</span><b>Close</b></li>
  885. </div>
  886. `;
  887. //Setting main: config
  888. for (let i in setting) {
  889. if (setting[i].type) {
  890. switch (setting[i].type) {
  891. case '1':
  892. txt += `<div id="${setting[i].id}" class="HYMGcontent">`;
  893. break;
  894. case '2':
  895. txt += `<h1>${setting[i].item[0]}</h1>`;
  896. break;
  897. case 1:
  898. txt += `<div id="${setting[i].id}" class="HYMGcontent">`;
  899. break;
  900. default:
  901. txt += `</div>`;
  902. break;
  903. }
  904. } else {
  905. if (setting[i].data.type === 'input') {
  906. if (setting[i].data.more === 'color') {
  907. span = `<input type="text" name="${setting[i].data.name}" value="${GM_getValue(setting[i].data.name,MG.config[setting[i].data.name])}" style="background:#${GM_getValue(setting[i].data.name,MG.config[setting[i].data.name])};" onblur="setConfig(event)" data-mark="color">`;
  908. } else {
  909. span = `<input type="text" name="${setting[i].data.name}" value="${GM_getValue(setting[i].data.name,MG.config[setting[i].data.name])}" onblur="setConfig(event)" data-mark="normal">`;
  910. }
  911. } else {
  912. isChecked = GM_getValue(setting[i].data.name, MG.config[setting[i].data.name]) ? 'checked' : '';
  913. isOn = GM_getValue(setting[i].data.name, MG.config[setting[i].data.name]) ? 'style = "background:yellowgreen;"' : 'style = "background:gray;"';
  914. // console.log(isOn);
  915. span = `<label for="${setting[i].data.name}" ${isOn}><input type="checkbox" id="${setting[i].data.name}" onchange="onOff(event)" ${isChecked}></label>`;
  916.  
  917. }
  918. txt += `<li><span>${setting[i].item[0]}</span><span>${setting[i].description[0]}</span><span>${span}</span></li>`;
  919. }
  920. }
  921.  
  922. //setting main: gestures
  923. let _local = {
  924. gesture: ['手势', 'Gesture'],
  925. dragText: ['拖拽文本', 'Drag Text'],
  926. dragLink: ['拖拽链接', 'Drag Link'],
  927. dragImg: ['拖拽图片', 'Drag Image'],
  928. };
  929. this.letter2arrow = function(str) {
  930. // function letter2arrow(str){
  931. return str.replace(/[^uUdDlLrR⬅➞⬇⬆]/g, '').replace(/[lL]/g, '⬅').replace(/[rR]/g, '➞').replace(/[dD]/g, '⬇').replace(/[uU]/g, '⬆');
  932. };
  933. this.arrow2letter = function(str) {
  934. // function arrow2letter(str){
  935. return str.replace(/⬅/g, 'L').replace(/➞/g, 'R').replace(/⬇/g, 'D').replace(/⬆/g, 'U');
  936. };
  937.  
  938. function makeDragUI(type, curren) {
  939. let tt = '';
  940. tt += `<h1>${_local[type][MG.config.language]}</h1>`;
  941. for (let i in fn[type]) {
  942. t = '';
  943. for (let j in curren) {
  944. if (i === curren[j]) {
  945. t = j;
  946. }
  947. }
  948. tt += `<li><span>${i}</span><span>${fn[type][i][MG.config.language]}</span><span><input type="text" name="${i}" value="${letter2arrow(t)}" onkeyup="this.value=letter2arrow(this.value)" onblur="setConfig(event)" data-mark="${type}" data-track="${t}"></span></li>`;
  949. }
  950. return tt;
  951. }
  952. //gesture
  953. txt += '<div id="mg2" class="HYMGcontent">' + makeDragUI('gesture', MG.track2name) + '</div>';
  954.  
  955. txt += '<div id="mg3" class="HYMGcontent">' + makeDragUI('dragText', MG.dragText2name) + makeDragUI('dragLink', MG.dragLink2name) + makeDragUI('dragImg', MG.dragImg2name) + '</div>';
  956. txt += '<div id="mg4" class="HYMGcontent"><a href="https://github.com/woolition/greasyforks/blob/master/mouseGesture/HY-MouseGesture.md" style="display:block;width: 90%;height: auto;font-size: 60px;text-decoration: none;font-weight: bolder;padding: 50px 30px; color:yellowgreen;"> (● ̄(エ) ̄●)づ <br>点我看更多介绍! </a></div>';
  957.  
  958. GM_addStyle(CSS);
  959. let a = document.createElement('div');
  960. a.id = "HYMGSetting";
  961. a.innerHTML = txt;
  962. document.documentElement.appendChild(a);
  963. this.selected = function(e) {
  964. let tar;
  965. if (e.target.tagName === "LI") {
  966. tar = e.target;
  967. } else {
  968. tar = e.target.parentNode;
  969. }
  970. [].forEach.call(document.querySelectorAll('#MGmenu li'), function(item) {
  971. item.setAttribute('class', '');
  972. });
  973. tar.setAttribute('class', 'MGselected');
  974. [].forEach.call(document.querySelectorAll('.HYMGcontent'), function(item) {
  975. item.style.display = "none";
  976. });
  977. document.getElementById(tar.dataset.target).setAttribute('style', 'display:block;');
  978. };
  979. this.setConfig = function(e) {
  980. // this.updateFns = function(cssSelector){
  981. function updateFns(cssSelector) {
  982. let a = {};
  983. [].forEach.call(document.querySelectorAll(cssSelector), function(item) {
  984. if (item.value) {
  985. a[arrow2letter(item.value)] = item.name;
  986. item.style.background = 'yellowgreen';
  987. } else {
  988. item.style.background = 'gray';
  989. }
  990. });
  991. return a;
  992. }
  993. switch (e.target.dataset.mark) {
  994. case 'color':
  995. MG.config[e.target.name] = e.target.value;
  996. GM_setValue('config', MG.config);
  997. e.target.style.background = '#' + e.target.value;
  998. break;
  999. case 'normal':
  1000. MG.config[e.target.name] = e.target.value;
  1001. console.log(MG.config[e.target.name]);
  1002. GM_setValue('config', MG.config);
  1003. break;
  1004. case 'gesture':
  1005. MG.track2name = updateFns('input[data-mark="gesture"]');
  1006. GM_setValue('track2name', MG.track2name);
  1007. break;
  1008. case 'dragText':
  1009. e.target.value = letter2arrow(e.target.value);
  1010. MG.dragText2name = updateFns('input[data-mark="dragText"]');
  1011. GM_setValue('dragText2name', MG.dragText2name);
  1012. break;
  1013. case 'dragLink':
  1014. e.target.value = letter2arrow(e.target.value);
  1015. MG.dragLink2name = updateFns('input[data-mark="dragLink"]');
  1016. GM_setValue('dragLink2name', MG.dragLink2name);
  1017. break;
  1018. case 'dragImg':
  1019. e.target.value = letter2arrow(e.target.value);
  1020. MG.dragImg2name = updateFns('input[data-mark="dragImg"]');
  1021. GM_setValue('dragImg2name', MG.dragImg2name);
  1022. break;
  1023. default:
  1024. break;
  1025. }
  1026. };
  1027. this.onOff = function(e) {
  1028. MG.config[e.target.id] = e.target.checked;
  1029. GM_setValue('config', MG.config);
  1030. if (MG.config[e.target.id]) {
  1031. e.target.parentNode.style.background = "yellowgreen";
  1032. } else {
  1033. e.target.parentNode.style.background = "gray";
  1034. }
  1035. };
  1036. [].forEach.call(document.querySelectorAll('#MGmenu li'), function(item) {
  1037. item.setAttribute('onclick', 'selected(event)');
  1038. });
  1039. //init
  1040. [].forEach.call(document.querySelectorAll('.HYMGcontent'), function(item) {
  1041. item.style.display = "none";
  1042. });
  1043. document.getElementById('mg1').style.display = 'block';
  1044. document.getElementById('MGClose').setAttribute('onclick', 'document.documentElement.removeChild(document.getElementById("HYMGSetting"))');
  1045.  
  1046. }
  1047.  
  1048. })();