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
// ==UserScript== // @name Open links in current tab // @author wOxxOm // @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 // @namespace http://target._blank.is.retarded // @version 2.3.0 // @include * // @run-at document-start // @grant GM_openInTab // ==/UserScript== if (window === top) { window.addEventListener('message', function (e) { if (!/^{/.test(e.data)) return; var data = tryParse(e.data); if (data.name === GM_info.script.name) navigate(data.url); }); } var pageBase = location.href.split('#', 1)[0]; var suppressing, clickedElement; window.addEventListener('click', prevent, true); window.addEventListener('auxclick', prevent, true); window.addEventListener('mousedown', remember, true); window.addEventListener('mouseup', check, true); function remember(e) { clickedElement = e.composedPath ? e.composedPath()[0] : e.target; } function check(e) { var el = e.composedPath ? e.composedPath()[0] : e.target; if (e.button > 1 || el !== clickedElement) return; var a = el.closest('a'); if (!a) return; blockWindowOpenAndMutations(a); var url = a.href; if (url.lastIndexOf('javascript:', 0) === 0) return; var base = document.querySelector('base[target="_blank"]'); if (base) base.target = ''; if (!url || url.split('#', 1)[0] === pageBase) { clearLinkTarget(a); return; } var b = e.button, c = e.ctrlKey, alt = e.altKey, s = e.shiftKey, m = e.metaKey; if (b === 1 || c && !alt && !m) GM_openInTab(url, !s || b === 1); else if ((window.chrome || !CSS.supports('-moz-appearance', 'none')) && b === 0 && s && !c && !alt && !m) a.cloneNode().dispatchEvent(new MouseEvent('click', {shiftKey: true})); else if (!c && !s && !m && !alt) { clearLinkTarget(a); return; } else return; suppressing = true; prevent(e); } function clearLinkTarget(a) { if (a.target === '_blank') a.target = ''; } function prevent(e) { if (!suppressing) return; e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); setTimeout(function () { suppressing = false; }, 50); } function blockWindowOpenAndMutations(a) { var observer = new MutationObserver(function () { if (a.target === '_blank') { a.removeAttribute('target'); console.log('[Open links in current tab] prevented dynamic target=_blank for', a.href); navigate(a.href); } }); observer.observe(a, {attributes: true, attributeFilter: ['target'], characterData: true}); var _open = unsafeWindow.open; var timeout = setTimeout(function () { unsafeWindow.open = _open; observer.disconnect(); }, 50); unsafeWindow.open = function (url, name, opts) { let o0 = `${opts || ''}`, o1, o2, rel = [ (o1 = o0.replace(/(^|,)\s*noopener\s*($|,)/gi, '')) !== o0 && 'noopener', (o2 = o1.replace(/(^|,)\s*noreferrer\s*($|,)/gi, '')) !== o1 && 'noreferrer', ]; if (!o2.trim()) { console.log('[Open links in current tab] prevented window.open for', url); if (rel.some(Boolean)) a.relList.add.apply(a.relList, rel.filter(Boolean)); navigate(a.href); } else _open(url, name, opts); unsafeWindow.open = _open; clearTimeout(timeout); }; } function navigate(url) { if (window === top) { var a = document.createElement('a'); a.href = url; a.dispatchEvent(new MouseEvent('click')); } else top.postMessage(JSON.stringify({name: GM_info.script.name, url: url}), '*'); } function tryParse(str) { try { return JSON.parse(str); } catch (e) {} }