Created
November 11, 2010 14:01
-
-
Save xulapp/672527 to your computer and use it in GitHub Desktop.
long middle click == shift + middle click
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name middleClickFocusTab.uc.js | |
// @description long middle click == shift + middle click | |
// @include main | |
// @charset utf-8 | |
// @compatibility Firefox 3.6+ | |
// @namespace http://twitter.com/xulapp | |
// @author xulapp | |
// @license MIT License | |
// @version 2010/11/22 00:50 +09:00 | |
// ==/UserScript== | |
// @version 2010/10/13 00:30 +09:00 | |
(function middleClickFocusTab() { | |
const TIMEOUT = 300; | |
const TARGET_XPATH = 'ancestor-or-self::html:a | ancestor-or-self::html:area | ancestor-or-self::xul:toolbarbutton | ancestor-or-self::xul:*[@onclick] | ancestor-or-self::*[@xlink:href]'; | |
const NAMESPACE = { | |
xul: 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul', | |
html: 'http://www.w3.org/1999/xhtml', | |
xlink: 'http://www.w3.org/1999/xlink', | |
}; | |
const resolveNS = function resolveNS(name) NAMESPACE[name]; | |
const tooltip = document.createElementNS(NAMESPACE.xul, 'tooltip'); | |
tooltip.setAttribute('id', 'longclick-tooltip'); | |
tooltip.setAttribute('label', '\u9577\u62bc\u3057'); | |
document.getElementById('mainPopupSet').appendChild(tooltip); | |
document.addEventListener('mousedown', function({originalTarget, button, screenX, screenY}) { | |
if (button !== 1) return; | |
var clickable = originalTarget.ownerDocument.evaluate( | |
TARGET_XPATH, | |
originalTarget, | |
resolveNS, | |
XPathResult.BOOLEAN_TYPE, | |
null | |
).booleanValue; | |
if (!clickable) return; | |
first([ | |
function(next) timeout(next, TIMEOUT, null), | |
function(next) listen(document, 'mouseup', next, true, false), | |
], function(e) { | |
if (e) return; | |
tooltip.openPopupAtScreen(screenX, screenY); | |
listenOnce(document, 'mouseup', function onMouseUp(event) { | |
tooltip.hidePopup(); | |
if (event.originalTarget !== originalTarget) return; | |
listenOnce(document, 'click', function onClick(event) { | |
var {shiftKey} = event; | |
event.__defineGetter__('shiftKey', function() !shiftKey); | |
}, true, false); | |
}, true, false); | |
}); | |
}, false, false); | |
function timeout() { | |
var timer = setTimeout.apply(null, arguments); | |
return function() clearTimeout(timer); | |
} | |
function listen(node) { | |
var args = Array.slice(arguments, 1); | |
node.addEventListener.apply(node, args); | |
return function() node.removeEventListener.apply(node, args); | |
} | |
function listenOnce() { | |
var args = Array.slice(arguments); | |
var listener = args[2]; | |
args[2] = function onceGate() { | |
cancel(); | |
return listener.apply(this, arguments); | |
}; | |
var cancel = listen.apply(null, args); | |
return cancel; | |
} | |
function first(tasks, callback) { | |
var closed = false; | |
var cancelers = []; | |
var next = function(arg) { | |
if (closed) return; | |
callback(arg); | |
close(); | |
}; | |
var close = function() { | |
cancelers.forEach(function(fn) fn()); | |
closed = true; | |
}; | |
tasks.some(function(fn) { | |
var abort = fn(next); | |
if (closed) | |
return true; | |
if (typeof abort === 'function') | |
cancelers.push(abort); | |
}); | |
return close; | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment