Snap Links Mod shortcuts

从网页中批量复制、打开链接,选择复选框

  1. // ==UserScript==
  2. // @name Snap Links Mod shortcuts
  3. // @name:en Snap Links Mod shortcuts
  4. // @name:zh 批量复制-快捷键版
  5. // @description 从网页中批量复制、打开链接,选择复选框
  6. // @description:en snap Links(open, copy), radios, chenkboxs, images from website
  7. // @author Griever, ywzhaiqi, lastdream2013, Hanchy Hill
  8. // @namespace http://minhill.com/slms
  9. // @match http://*/*
  10. // @match https://*/*
  11. // @version 2023.03.08
  12. // @license The MIT License (MIT); http://opensource.org/licenses/MIT
  13. // @grant GM_getValue
  14. // @grant GM_setValue
  15. // @grant GM_openInTab
  16. // @grant GM_deleteValue
  17. // @grant GM_addStyle
  18. // @run-at document-start
  19. // @grant GM_registerMenuCommand
  20. // @grant GM_setClipboard
  21. // @grant GM_log
  22. // @compatible firefox
  23. // @compatible chrome
  24. // @compatible edge
  25. // @icon http://minhill.com/blog/wp-content/uploads/2012/03/favicon.ico
  26. // @note 2016/11/22 改写的第一个版本,存在BUG:无法正确选取图像
  27. // ==/UserScript==
  28.  
  29. var snapLinks = {
  30. timer: null,
  31. button: 0,
  32.  
  33. init: function () {
  34. /*if (!snapLinks.inited) {
  35. var menuitem = document.getElementById("SnapLinksCopyLinksSetFormat");
  36. if (menuitem) {
  37. var func = function() {
  38. var format = prompt('请输入需要设置的格式(%t:标题,%u:链接,%n:序号,%r:反向序号)',
  39. '<a href="%u">%r. %t</a><br>');
  40. snapLinks.copyLinks(null, false, format);
  41. };
  42. menuitem.addEventListener('command', func, false);
  43. }
  44.  
  45. snapLinks.inited = true;
  46. }*/
  47.  
  48.  
  49. this.win = window;
  50. if (snapLinks.win == window) snapLinks.win = window;
  51. this.doc = this.win.document;
  52. this.body = this.doc.body;
  53. if (!this.body instanceof HTMLBodyElement) {
  54. alert("Can not snaplinks.");
  55. return false;
  56. }
  57.  
  58. this.root = snapLinks.doc.documentElement;
  59. //this.utils = this.win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
  60. this.popup = document.getElementById("snapLinksMenupopup");
  61.  
  62. this.bodyCursor = this.body.style.cursor;
  63. this.rootCursor = this.root.style.cursor;
  64. this.body.style.setProperty("cursor", "crosshair", "important");
  65. this.root.style.setProperty("cursor", "crosshair", "important");
  66.  
  67. this.highlights = [];
  68. this.elements = [];
  69.  
  70.  
  71. this.doc.addEventListener("mousedown", snapLinks.handleEvent, true);
  72. this.doc.addEventListener("pagehide", snapLinks.handleEvent, true);
  73. },
  74. uninit: function () {
  75.  
  76. snapLinks.doc.removeEventListener("mousedown", snapLinks.handleEvent, true);
  77. snapLinks.doc.removeEventListener("mousemove", snapLinks.handleEvent, true);
  78. snapLinks.doc.removeEventListener("pagehide", snapLinks.handleEvent, true);
  79. snapLinks.doc.removeEventListener("mouseup", snapLinks.handleEvent, true);//?
  80. setTimeout(function (self) {
  81. snapLinks.doc.removeEventListener("click", snapLinks.handleEvent, true);
  82. }, 10, snapLinks);
  83.  
  84. if (snapLinks.box && snapLinks.box.parentNode) snapLinks.box.parentNode.removeChild(snapLinks.box);
  85. snapLinks.box = null;
  86. snapLinks.body.style.cursor = snapLinks.bodyCursor;
  87. snapLinks.root.style.cursor = snapLinks.rootCursor;
  88. },
  89. destroy: function () {
  90. snapLinks.uninit();
  91. snapLinks.lowlightAll();
  92. document.removeEventListener("click", snapLinks.destroy, false);
  93.  
  94. var sslpop = document.getElementById("snapLinksMenupopup")
  95. sslpop.setAttribute("class", "hidden_popup");
  96. sslpop.setAttribute("style", null);
  97.  
  98. },
  99. handleEvent: function (event) {
  100.  
  101. switch (event.type) {
  102. case "mousedown":
  103. if (event.button != 0 || event.ctrlKey || event.shiftKey || event.altKey) return;
  104. event.preventDefault();
  105. event.stopPropagation();
  106.  
  107. snapLinks.draw(event);
  108. break;
  109. case "mousemove":
  110. event.preventDefault();
  111. event.stopPropagation();
  112. var moveX = event.pageX;
  113. var moveY = event.pageY;
  114. if (snapLinks.downX > moveX) snapLinks.box.style.left = moveX + "px";
  115. if (snapLinks.downY > moveY) snapLinks.box.style.top = moveY + "px";
  116. snapLinks.box.style.width = Math.abs(moveX - snapLinks.downX) + "px";
  117. snapLinks.box.style.height = Math.abs(moveY - snapLinks.downY) + "px";
  118.  
  119. if (snapLinks.timer) {
  120. clearTimeout(snapLinks.timer);
  121. snapLinks.timer = null;
  122. }
  123. var timeStamp = new Date().getTime();
  124. if (timeStamp - snapLinks.lastHiglightedTime > 150) {
  125. snapLinks.boxRect = snapLinks.box.getBoundingClientRect();
  126. snapLinks.highlightAll();
  127. } else {
  128. var self = snapLinks;
  129. snapLinks.timer = setTimeout(function () {
  130. self.boxRect = self.box.getBoundingClientRect();
  131. self.highlightAll();
  132. }, 200);
  133. }
  134. break;
  135. case "mouseup":
  136.  
  137. if (event.button != snapLinks.button || event.ctrlKey || event.shiftKey) return;
  138. event.preventDefault();
  139. event.stopPropagation();
  140.  
  141. if (snapLinks.timer) {
  142. clearTimeout(snapLinks.timer);
  143. snapLinks.timer = null;
  144. }
  145. snapLinks.boxRect = snapLinks.box.getBoundingClientRect();
  146. snapLinks.highlightAll();
  147.  
  148.  
  149.  
  150.  
  151. for (let e of snapLinks.highlights) {
  152. if (e instanceof HTMLImageElement) {
  153. let link = snapLinks.doc.evaluate(
  154. 'ancestor::*[@href]', e, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
  155. if (snapLinks.highlights.indexOf(link) === -1) {
  156. snapLinks.elements[snapLinks.elements.length] = link;
  157. }
  158. continue;
  159. }
  160. snapLinks.elements[snapLinks.elements.length] = e;
  161. }
  162. snapLinks.elements = snapLinks.elements;//?
  163.  
  164. snapLinks.uninit();
  165. snapLinks.showPopup(event);
  166. break;
  167. case "click":
  168. event.preventDefault();
  169. event.stopPropagation();
  170. break;
  171. case "pagehide":
  172. snapLinks.destroy();
  173. break;
  174. }
  175. },
  176. draw: function (aEvent) {
  177. this.lastHiglightedTime = new Date().getTime();
  178. this.downX = aEvent.pageX;
  179. this.downY = aEvent.pageY;
  180. this.box = this.doc.createElement("div");
  181. this.box.id = "snap-links-box";
  182. this.box.style.cssText = [
  183. 'background-color: rgba(0,128,255,.1) !important;',
  184. 'border: 1px solid rgb(255,255,0) !important;',
  185. 'box-sizing: border-box !important;',
  186. '-moz-box-sizing: border-box !important;',
  187. 'position: absolute !important;',
  188. 'z-index: 2147483647 !important;',
  189. 'top:' + this.downY + 'px;',
  190. 'left:' + this.downX + 'px;',
  191. 'cursor: crosshair !important;',
  192. 'margin: 0px !important;',
  193. 'padding: 0px !important;',
  194. 'outline: none !important;',
  195. ].join(" ");
  196. this.body.appendChild(this.box);
  197.  
  198. this.doc.removeEventListener("mousedown", this.handleEvent, true);
  199. this.doc.addEventListener("mousemove", this.handleEvent, true);
  200. this.doc.addEventListener("mouseup", this.handleEvent, true);
  201. this.doc.addEventListener("click", this.handleEvent, true);
  202. },
  203. highlightAll: function () {
  204. var a = '[href]:not([href^="javascript:"]):not([href^="mailto:"]):not([href^="#"])';
  205. var selector = a + ', ' + a + ' img, input[type="checkbox"], input[type="radio"]';
  206. selector += ', a.b-in-blk.input-cbx[href^="javascript:"]'; // 百度盘的特殊多选框
  207.  
  208. var contains = this.getContainsElements();
  209. contains.reverse();
  210. var matches = [];
  211. for (let e of contains) {
  212. if (e.nodeType !== 1 || !e.matches(selector)) continue;
  213.  
  214. if (e.hasAttribute('href')) {
  215. let imgs = Array.prototype.slice.call(e.getElementsByTagName('img'));
  216. if (imgs[0]) {
  217. [].push.apply(contains, imgs);
  218. continue;
  219. }
  220. }
  221.  
  222. if (!("defStyle" in e)) this.highlight(e);
  223. matches[matches.length] = e;
  224. }
  225.  
  226. this.highlights.forEach(function (e, i, a) {
  227. if (matches.indexOf(e) === -1) this.lowlight(e);
  228. }, this);
  229.  
  230. this.highlights = matches;
  231. this.lastHiglightedTime = new Date().getTime();
  232. },
  233. lowlightAll: function () {
  234. this.highlights.forEach(function (e) {
  235. this.lowlight(e);
  236. }, this);
  237. },
  238. highlight: function (elem) {
  239. if (!('defStyle' in elem)) elem.defStyle = elem.getAttribute('style');
  240. //elem.style.setProperty('outline', '2px solid #ff0000', 'important');
  241. elem.style.setProperty('outline', '2px solid #ff0000', null);
  242. elem.style.setProperty('outline-offset', '-1px', null);
  243. //elem.style.setProperty('outline-offset', '-1px', 'important');
  244. },
  245. lowlight: function (elem) {
  246. if ("defStyle" in elem) {
  247. elem.defStyle ?
  248. elem.style.cssText = elem.defStyle :
  249. elem.removeAttribute("style");
  250. delete elem.defStyle;
  251. }
  252. },
  253. getContainsElements: function () {
  254. if (!this.boxRect) return;
  255. var a = '[href]:not([href^="javascript:"]):not([href^="mailto:"]):not([href^="#"])';
  256. var selector = a + ', ' + a + ' img, input[type="checkbox"], input[type="radio"]';
  257. selector += ', a.b-in-blk.input-cbx[href^="javascript:"]';
  258. //var nodes = document.querySelectorAll("a[href],img,radio,checkbox");
  259. var nodes = document.querySelectorAll(selector);
  260. var arraynode = [], len = nodes.length, i;
  261.  
  262.  
  263.  
  264. for (i = 0; i < len; i++) {
  265. if (this.inSelect(nodes[i])) arraynode.push(nodes[i]);
  266. }
  267.  
  268. return arraynode;
  269.  
  270. },
  271.  
  272. inSelect: function (node) {
  273. var boxPos = snapLinks.boxRect;
  274. var xmin = boxPos.left, xmax = boxPos.right, ymin = boxPos.top, ymax = boxPos.bottom;
  275.  
  276. var pos = this.getOffset(node);
  277. var point = new Array();
  278.  
  279. point = [pos.x, pos.x + pos.width, pos.y, pos.y + pos.height];
  280.  
  281. var swithcase = [];
  282. if ((point[0] > xmin && point[0] < xmax) ||
  283. (point[1] > xmin && point[1] < xmax) ||
  284. (point[0] < xmin && point[1] > xmax)) {
  285. swithcase[0] = true;
  286. }
  287. if ((point[2] > ymin && point[2] < ymax) ||
  288. (point[3] > ymin && point[3] < ymax) ||
  289. (point[2] < ymin && point[3] > ymax)) {
  290. swithcase[1] = true;
  291. }
  292.  
  293. if (swithcase[0] && swithcase[1]) {
  294. return true;
  295. }
  296.  
  297. else {
  298. return false;
  299. }
  300.  
  301. },
  302.  
  303. getOffset: function (node) {
  304. var rect = node.getBoundingClientRect();
  305.  
  306. return {
  307. //x: window.pageXOffset + rect.left,
  308. //y: window.pageYOffset + rect.top,
  309. x: rect.left,
  310. y: rect.top,
  311. width: rect.width,
  312. height: rect.height
  313. };
  314. },
  315.  
  316.  
  317. showPopup: function (aEvent) {
  318.  
  319. var cls = [];
  320.  
  321. var linkcount = 0;
  322. var specialLinkCount = 0; // 特殊的类似多选框的链接
  323. var imagecount = 0;
  324. var checkboxcount = 0;
  325. var radiocount = 0;
  326. for (let elem of this.elements) {
  327. if (elem instanceof HTMLAnchorElement) elem.href.indexOf('javascript:') == 0 ? specialLinkCount++ : linkcount++;
  328. }
  329. for (let elem of this.elements) {
  330. if (elem instanceof HTMLAnchorElement && /\.(jpe?g|png|gif|bmp)$/i.test(elem.href)) imagecount++;
  331. }
  332. for (let elem of this.elements) {
  333. if (elem instanceof HTMLInputElement && elem.type === 'checkbox') {
  334. checkboxcount++;
  335. }
  336. }
  337. for (let elem of this.elements) {
  338. if (elem instanceof HTMLInputElement && elem.type === 'radio') {
  339. radiocount++;
  340. }
  341. }
  342. if (linkcount > 0) cls.push("hasLink");
  343. if (imagecount > 0) cls.push("hasImageLink");
  344. if (checkboxcount > 0) cls.push("hasCheckbox");
  345. if (radiocount > 0) cls.push("hasRadio");
  346. if (specialLinkCount > 0) cls.push("hasSpecialLink");
  347.  
  348.  
  349.  
  350. var setCount = function (id, label) {
  351. let currentEntry = document.getElementById(id);
  352. if (currentEntry) currentEntry.innerHTML = label;
  353. };
  354.  
  355. var data = {
  356. "SnapLinksOpenLinks": "在新标签打开所有链接 (" + linkcount + ")",
  357. "SnapLinksCopyLinks": "复制所有链接URL (" + linkcount + ")",
  358. "SnapLinksCopyLinksReverse": "复制所有链接URL (" + linkcount + ") (反向)",
  359. "SnapLinksCopyLinksAndTitles": "复制所有链接标题 + URL (" + linkcount + ")",
  360. "SnapLinksCopyLinksAndTitlesMD": "复制所有链接标题 + URL (" + linkcount + ") (MD)",
  361. "SnapLinksCopyLinksAndTitlesBBS": "复制所有链接标题 + URL (" + linkcount + ") (BBS)",
  362. "SnapLinksCopyLinksRegExp": "复制所有链接标题 + URL (" + linkcount + ") (筛选)",
  363. "SnapLinksCopyLinksSetFormat": "复制所有链接标题 + URL (" + linkcount + ") (设置复制格式)",
  364. "SnapLinksOpenImageLinks": "在新标签页打开所有图片链接 (" + imagecount + ")",
  365. "SnapLinksImageLinksOnePage": "在一个标签页显示所有图片链接 (" + imagecount + ")",
  366. "SnapLinksCheckBoxSelect": "复选框 - 选中 (" + checkboxcount + ")",
  367. "SnapLinksCheckBoxCancel": "复选框 - 取消 (" + checkboxcount + ")",
  368. "SnapLinksCheckBoxTaggle": "复选框 - 反选 (" + checkboxcount + ")",
  369. "SnapLinksRadioSelect": "单选框 - 选中 (" + radiocount + ")",
  370. "SnapLinksRadioCancel": "单选框 - 取消 (" + radiocount + ")",
  371. "SnapLinksClickLinks": "特殊单选框 - 选中 (" + specialLinkCount + ")",
  372. };
  373.  
  374. for (let id in data) {
  375. setCount(id, data[id]);
  376. }
  377.  
  378.  
  379. var setStyleNode = function (showList) {
  380. var setList = ["hasLink", "hasImageLink", "hasCheckbox", "hasRadio", "hasSpecialLink"];
  381. setList.forEach(
  382. function (elist) {
  383. var eClass = document.getElementsByClassName(elist);
  384. if (eClass) {
  385. if (showList.indexOf(elist) == -1) {
  386. for (var i = 0; i < eClass.length; i++) {
  387. eClass[i].style = "display:none";
  388. }
  389. //eClass.forEach(function(enode){enode.setAttribute("stlye","display:none")})
  390. } else {
  391. for (let i = 0; i < eClass.length; i++) {
  392. eClass[i].style = "display:block";
  393. }
  394. //eClass.forEach(function(enode){enode.setAttribute("stlye","display:block")})
  395. }
  396. }
  397. }
  398. )
  399. }
  400.  
  401.  
  402.  
  403.  
  404. if (cls.length > 0) {
  405. setStyleNode(cls);
  406. this.openPopupAtScreen(aEvent.pageX, aEvent.pageY, aEvent.clientX, aEvent.clientY);
  407.  
  408. //snapLinks.popup.className = cls.join(' ');
  409.  
  410. } else {
  411. this.lowlightAll();
  412. }
  413. },
  414. openPopupAtScreen: function (ax, ay, cx, cy) {
  415.  
  416. var popMenu = document.getElementById("snapLinksMenupopup");
  417. var midx = document.documentElement.clientWidth / 2;
  418. var midy = document.documentElement.clientHeight / 2;
  419. //GM_log("pointerY:"+ay);
  420. //GM_log("screen:"+midy*2);
  421.  
  422.  
  423.  
  424. popMenu.className = "trigger_popup";
  425. //popMenu.style.position = "absolute";
  426.  
  427. var menuRight = ax - popMenu.clientWidth;
  428.  
  429. var menuDown = ay - popMenu.clientHeight;
  430.  
  431. document.addEventListener("click", snapLinks.destroy, false);
  432.  
  433. var xaxis = (cx < midx) ? "left: " + ax.toString() + "px;" : "left: " + menuRight.toString() + "px;";
  434.  
  435. var yaxis = (cy < midy) ? " top: " + ay.toString() + "px;" : " top: " + menuDown.toString() + "px;";
  436. popMenu.setAttribute("style", xaxis + yaxis);
  437.  
  438.  
  439.  
  440. },
  441. openLinks: function (regexp) {
  442. var obj = {};
  443. for (let elem of this.elements) {
  444. if (!elem.href || /^(?:javascript:|mailto:|#)/i.test(elem.href)) continue;
  445. if (!regexp || regexp.test(elem.href)) obj[elem.href] = true;
  446. }
  447. for (let [key, val] of Object.entries(obj)) {
  448.  
  449. GM_openInTab(key);
  450. //gBrowser.addTab(key, { ownerTab: gBrowser.mCurrentTab });
  451. }
  452. },
  453. clickLinks: function () {
  454. for (let elem of this.elements) {
  455. if (!elem.href || /^(?:javascript:|mailto:|#)/i.test(elem.href)) {
  456. elem.click();
  457. }
  458. }
  459. },
  460. copyLinks: function (regexp, reverse, format) {
  461.  
  462.  
  463.  
  464.  
  465. //GM_log(selements);
  466. var links = this.elements.filter(function (elem) {
  467. return elem instanceof HTMLAnchorElement && (!regexp || regexp.test(elem.href))
  468. });
  469.  
  470. var num = 1,
  471. numReverse = links.length;
  472. links = links.map(function (e) {
  473. if (format) {
  474. return format.replace(/%t/g, e.textContent)
  475. .replace(/%u/g, e.href)
  476. .replace(/%r/g, numReverse--)
  477. .replace(/%n/g, num++);
  478. }
  479. return e.href;
  480. });
  481.  
  482. // 筛选出重复的
  483. links = snapLinks.unique(links);
  484.  
  485. if (reverse) links = links.reverse();
  486.  
  487. if (links.length) {
  488. GM_setClipboard(links.join('\n'));
  489. //Components.classes["@mozilla.org/widget/clipboardhelper;1"]
  490. // .getService(Components.interfaces.nsIClipboardHelper)
  491. // .copyString(links.join('\n'));
  492. }
  493. },
  494. imageOnePage: function () {
  495. var htmlsrc = [
  496. '<style>'
  497. , 'img { max-width: 100%; max-height: 100%; }'
  498. , '</style>'].join('');
  499. for (let elem of this.elements) {
  500. if (elem instanceof HTMLAnchorElement && /\.(jpe?g|png|gif|bmp)$/i.test(elem.href)){
  501. htmlsrc += '\n<img src="' + elem.href + '">'
  502. }
  503. }
  504. GM_openInTab("data:text/html;charset=utf-8," +
  505. '<html><head><title>' + snapLinks.doc.domain + ' 图象列表</title><body>' +
  506. encodeURIComponent(htmlsrc));
  507. },
  508. checkbox: function (bool) {
  509. for (let elem of this.elements) {
  510. if (elem instanceof HTMLInputElement && elem.type === 'checkbox') {
  511. elem.checked = arguments.length == 0 ?
  512. !elem.checked :
  513. bool;
  514. }
  515. }
  516. },
  517. radio: function (bool) {
  518. for (let elem of this.elements) {
  519. if (elem instanceof HTMLInputElement && elem.type === 'radio') {
  520. elem.checked = arguments.length == 0 ?
  521. !elem.checked :
  522. bool;
  523. }
  524. }
  525. },
  526. unique: function (a) {
  527. var o = {},
  528. r = [],
  529. t;
  530. for (var i = 0, l = a.length; i < l; i++) {
  531. t = a[i];
  532. if (!o[t]) {
  533. o[t] = true;
  534. r.push(t);
  535. }
  536. }
  537. return r;
  538. }
  539. };
  540.  
  541.  
  542.  
  543.  
  544.  
  545. function begin() {
  546. var ibody = document.getElementsByTagName("body")[0];
  547.  
  548.  
  549. var popup = document.createElement("div");
  550. //popup.setAttribute("onclick","snapLinks.lowlightAll();");
  551. popup.setAttribute("id", "snapLinksMenupopup");
  552. popup.setAttribute("class", "hidden_popup");
  553. popup.innerHTML = '<div class = "-hasLink-">' +
  554. '<div id="SnapLinksOpenLinks" class="hasLink" >在新标签打开所有链接</div>' +
  555. '<div id="SnapLinksCopyLinks" class="hasLink" >复制所有链接URL</div>' +
  556. '<div id="SnapLinksCopyLinksReverse" class="hasLink" >复制所有链接URL(反向)</div>' +
  557. '<div id="SnapLinksCopyLinksAndTitles" class="hasLink" >复制所有链接标题 + URL</div>' +
  558. '<div id="SnapLinksCopyLinksAndTitlesMD" class="hasLink" >复制所有链接标题 + URL (MD)</div>' +
  559. '<div id="SnapLinksCopyLinksAndTitlesBBS" class="hasLink">复制所有链接标题 + URL (BBS)</div>' +
  560. '<div id="SnapLinksCopyLinksRegExp" class="hasLink" >复制所有链接标题 + URL (筛选)</div>' +
  561. '<div id="SnapLinksCopyLinksSetFormat" class="hasLink" >复制所有链接标题 + URL (设置复制格式)</div>' +
  562. '<div id="SnapLinksOpenImageLinks" class="hasImageLink" >在新标签页打开所有图片链接</div>' +
  563. '<div id="SnapLinksImageLinksOnePage" class="hasImageLink" >在一个标签页显示所有图片链接</div>' +
  564. '</div>' +
  565. '<div class="hasLink-hasCheckbox-hasRadio" >' +
  566. '<div id="SnapLinksCheckBoxSelect" class="hasCheckbox" >复选框 - 选中</div>' +
  567. '<div id="SnapLinksCheckBoxCancel" class="hasCheckbox" >复选框 - 取消</div>' +
  568. '<div id="SnapLinksCheckBoxTaggle" class="hasCheckbox" >复选框 - 反选</div>' +
  569. '<div id="SnapLinksRadioSelect" class="hasRadio" >单选框 - 选中</div>' +
  570. '<div id="SnapLinksRadioCancel" class="hasRadio">单选框 - 取消</div>' +
  571. '<div id="SnapLinksClickLinks" class="hasSpecialLink" >特殊单选框 - 选中</div>' +
  572. '</div>';
  573. ibody.appendChild(popup);
  574.  
  575.  
  576.  
  577. //popup.addEventListener("click",function(){snapLinks.lowlightAll()},false);
  578. document.getElementById("SnapLinksOpenLinks").addEventListener("click", function () { snapLinks.openLinks(); }, false);
  579. document.getElementById("SnapLinksCopyLinks").addEventListener("click", function () { snapLinks.copyLinks(); }, false);
  580. document.getElementById("SnapLinksCopyLinksReverse").addEventListener("click", function () { snapLinks.copyLinks(null, true); }, false);
  581. document.getElementById("SnapLinksCopyLinksAndTitles").addEventListener("click", function () { snapLinks.copyLinks(null, false, '%t\n%u'); }, false);
  582. document.getElementById("SnapLinksCopyLinksAndTitlesMD").addEventListener("click", function () { snapLinks.copyLinks(null, false, '[%t](%u)'); }, false);
  583. document.getElementById("SnapLinksCopyLinksAndTitlesBBS").addEventListener("click", function () { snapLinks.copyLinks(null, false, '[url=%u]%t[/url]'); }, false);
  584. document.getElementById("SnapLinksCopyLinksRegExp").addEventListener("click", function () { var reg = prompt('请输入需要筛选的 RegExp', ''); snapLinks.copyLinks(new RegExp(reg)); }, false);
  585. //document.getElementById("SnapLinksCopyLinksSetFormat").addEventListener("click",function(){snapLinks.copyLinks()},false);
  586.  
  587. document.getElementById("SnapLinksOpenImageLinks").addEventListener("click", function () { snapLinks.openLinks(/\.(jpe?g|png|gif|bmp)$/i); }, false);
  588. document.getElementById("SnapLinksImageLinksOnePage").addEventListener("click", function () { snapLinks.imageOnePage(); }, false);
  589. document.getElementById("SnapLinksCheckBoxSelect").addEventListener("click", function () { snapLinks.checkbox(true); }, false);
  590. document.getElementById("SnapLinksCheckBoxCancel").addEventListener("click", function () { snapLinks.checkbox(false); }, false);
  591. document.getElementById("SnapLinksCheckBoxTaggle").addEventListener("click", function () { snapLinks.checkbox(); }, false);
  592. document.getElementById("SnapLinksRadioSelect").addEventListener("click", function () { snapLinks.radio(true); }, false);
  593. document.getElementById("SnapLinksRadioCancel").addEventListener("click", function () { snapLinks.radio(false); }, false);
  594. document.getElementById("SnapLinksClickLinks").addEventListener("click", function () { snapLinks.clickLinks(); }, false);
  595.  
  596. GM_addStyle(".hidden_popup { display:none!important; } .trigger_popup{display:block!important;z-index:99999}" +
  597.  
  598. " #snapLinksMenupopup{position:absolute;background-color: rgb(45,53,63);border-bottom: 0px solid rgb(20,20,20); padding:5px;" +
  599. "border-bottom: 0px solid rgb(20,20,20);cursor:pointer;border-radius: 4px;border: 1px solid rgb(22,25,28);box-shadow:0 1px 0 rgba(162,184,204,0.25) inset,0 0 4px hsla(0,0%,0%,0.95);}" +
  600. "#snapLinksMenupopup div{color: white;} #snapLinksMenupopup > div > div:hover{color: rgb(51,159,255);" +
  601. "background-color: transparent; background-image:linear-gradient(to bottom,rgb(37,46,54),rgb(36,40,45));} ");
  602. }
  603.  
  604. function register_shoutcut(e) {
  605. // console.log(e.key);
  606. var keyCode = e.key.toLowerCase();
  607. var altKey = e.altKey
  608. if (altKey) {
  609. //这里可以处理同时按下ctrl和shift时的逻辑,加上其他按键可以实现快捷键功能
  610. switch (keyCode) {
  611. case 'z':
  612. begin();
  613. snapLinks.init();
  614. break;
  615. default:
  616. break;
  617. }
  618. }
  619. }
  620. document.addEventListener('keydown', register_shoutcut)

QingJ © 2025

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