Open links in current tab

Open links in current tab regardless of _target or site's preferences. Ctrl-click: background tab, Ctrl-Shift-click: foreground tab, Shift-click: new window, Alt-click: force open in current tab

目前为 2016-11-19 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Open links in current tab
  3. // @author wOxxOm
  4. // @description Open links in current tab regardless of _target or site's preferences. Ctrl-click: background tab, Ctrl-Shift-click: foreground tab, Shift-click: new window, Alt-click: force open in current tab
  5. // @namespace http://target._blank.is.retarded
  6. // @version 2.2.4
  7. // @include *
  8. // @run-at document-start
  9. // @grant GM_openInTab
  10. // ==/UserScript==
  11.  
  12. if (window == top) {
  13. window.addEventListener('message', function(e) {
  14. // some stupid sites choke on object data
  15. if (!/^\{/.test(e.data))
  16. return;
  17. var data = tryParse(e.data);
  18. if (data.name == GM_info.script.name)
  19. navigate(data.url);
  20. });
  21. }
  22.  
  23. var suppressing, clickedElement;
  24. window.addEventListener('mousedown', function(e) {
  25. clickedElement = e.target;
  26. }, true);
  27.  
  28. window.addEventListener('mouseup', function(e) {
  29. if (e.button > 1 || e.target != clickedElement)
  30. return;
  31. var link = pierceShadow(e);
  32. if (!link || (link.getAttribute('href') || '').match(/^(javascript|#|$)/))
  33. return;
  34. var b = e.button, c = e.ctrlKey, a = e.altKey, s = e.shiftKey, m = e.metaKey;
  35. if (b == 1 || c && !a && !m)
  36. GM_openInTab(link.href, !s || b == 1);
  37. else if (b == 1 && !c && !s && !m && (link.href.replace(/#.*/, '') != location.href.replace(/#.*/, '') || a || link.target == '_blank'))
  38. navigate(link.href);
  39. else if (!a && link.target != '_blank')
  40. return blockWindowOpenAndMutations(link);
  41. else if (window.chrome && !b && s && !c && !a && !m)
  42. link.cloneNode().dispatchEvent(new MouseEvent('click', {shiftKey: true}));
  43. else
  44. return;
  45. suppressing = true;
  46. prevent(e);
  47. }, true);
  48.  
  49. window.addEventListener('click', prevent, true);
  50. window.addEventListener('auxclick', prevent, true);
  51.  
  52. function prevent(e) {
  53. if (!suppressing)
  54. return;
  55. e.preventDefault();
  56. e.stopPropagation();
  57. e.stopImmediatePropagation();
  58. setTimeout(function() {
  59. suppressing = false;
  60. }, 50);
  61. }
  62.  
  63. function blockWindowOpenAndMutations(link) {
  64. var observer = new MutationObserver(function() {
  65. if (link.target == '_blank') {
  66. link.removeAttribute('target');
  67. console.log('[Open links in current tab] prevented dynamic target=_blank for', link.href);
  68. navigate(link.href);
  69. }
  70. });
  71. observer.observe(link, {attributes:true, attributeFilter:['target'], characterData:true});
  72.  
  73. var _open = unsafeWindow.open;
  74. var timeout = setTimeout(function() {
  75. unsafeWindow.open = _open;
  76. observer.disconnect();
  77. }, 50);
  78. unsafeWindow.open = exportFunction(function(url, name, features) {
  79. if (!features) {
  80. console.log('[Open links in current tab] prevented window.open for', url);
  81. navigate(link.href);
  82. } else
  83. _open(url, name, features);
  84. unsafeWindow.open = _open;
  85. clearTimeout(timeout);
  86. }, unsafeWindow);
  87. }
  88.  
  89. function pierceShadow(e) {
  90. var el = e.target;
  91. while (el.shadowRoot)
  92. el = el.shadowRoot.elementFromPoint(e.clientX, e.clientY);
  93. return el.closest('a');
  94. }
  95.  
  96. function navigate(url) {
  97. if (window == top) {
  98. var link = document.createElement('a');
  99. link.href = url;
  100. link.dispatchEvent(new MouseEvent('click'));
  101. } else
  102. top.postMessage(JSON.stringify({name: GM_info.script.name, url: url}), '*');
  103. }
  104.  
  105. function tryParse(str) {
  106. try { return JSON.parse(str); }
  107. catch(e) {}
  108. }

QingJ © 2025

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