リンクを左ボタン長押しによって新規タブに開きたい
かざぐるマウスというソフトでできる(左ボタン長押しにCtrl+Shift+クリックを割り当て)んだけど、僕の環境だとFirefoxだけうまく作用しない(効くリンクと効かないリンクがある)ので自分で作ることにした。
最初はGreasemonkeyスクリプトとして作っていたんだけど、Greasemonkeyでは新規タブを前面に開くことができないみたい。試したのは以下の方法。
- window.open
- ポップアップブロックに阻まれる
- GM_openInTab
- 背面にしか開けない(browser.tabs.loadInBackgroundの設定に依存)
- createEvent, initEvent, dispatchEventでCtrl+Shift+クリックイベントを生成・発火
- Firefoxではデフォルトアクション(リンク先に移動)が実行されない
// ==UserScript== // @name openLinkByLongPress // @namespace http://rikuba.com/ // @include * // ==/UserScript== const WAIT = 500; (function (listener) { document.addEventListener('mousedown', listener, false); document.addEventListener('click', listener, false); })({ timer: null, getAncestorOrSelfAnchor: function () { var expr = document.createExpression('ancestor-or-self::*[@href and not(starts-with(@href, "javascript:"))]', null); var xr = null; return function (node) { xr = expr.evaluate(node, XPathResult.ANY_UNORDERED_NODE_TYPE, xr); return xr.singleNodeValue; }; }(), handleEvent: function (e) { if (e.button === 0) { this['on' + e.type](e); } }, onmousedown: function (e) { var anchor = this.getAncestorOrSelfAnchor(e.target); if (anchor) { this.timer = e.timeStamp; } }, onclick: function (e) { var anchor = this.getAncestorOrSelfAnchor(e.target); if (anchor) { if (WAIT < e.timeStamp - this.timer) { e.view.open(anchor.href); e.preventDefault(); } } } });以下のuserChrome.jsスクリプトはバグがある。
(function() { var tid; var opened; function isLink(node) { if ((node instanceof HTMLAnchorElement || node instanceof HTMLAreaElement) && node.hasAttribute('href')) return node; return false; } gBrowser.mPanelContainer.addEventListener('mousedown', function(e) { if (e.button !== 0) return; var node = isLink(e.target) || isLink(e.target.parentNode); if (!node) return; tid = setTimeout(function() { gBrowser.selectedTab = gBrowser.addTab(node.href); opened = true; }, 500); }, false); gBrowser.mPanelContainer.addEventListener('mousemove', function(e) { if (tid == null) return; clearTimeout(tid); tid = null; }, false); gBrowser.mPanelContainer.addEventListener('click', function(e) { if (tid == null) return; if (opened) { e.preventDefault(); opened = false; } else { clearTimeout(tid); } tid = null; }, false); })();