From b50e4033bbde7ccbffebf5bcab0cdb64d3b5a55f Mon Sep 17 00:00:00 2001 From: wlt Date: Tue, 8 Feb 2011 12:33:11 +0900 Subject: ステータスバーパネルをクリックできるプラグインです。 --- statusbar_panel.js | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 statusbar_panel.js (limited to 'statusbar_panel.js') diff --git a/statusbar_panel.js b/statusbar_panel.js new file mode 100644 index 0000000..6e68e6c --- /dev/null +++ b/statusbar_panel.js @@ -0,0 +1,151 @@ +let INFO = //{{{ + + wlt + MIT License + +

+ ステータスバー(アドオンバー)にあるパネル(アイコン)をクリックするコマンドを提供します。 +

+ + :statusbar + :statusbar -button=l | m | r -double-click panel-id + +

+ panel-idで指定するID属性を持つステータスバーパネル(アイコン)をクリックします。 + クリックするボタンは-button=で指定できます: +

+
+
l
+
左ボタン(デフォルト)
+
m
+
中ボタン(スクロールボタン)
+
r
+
右ボタン
+
+

-double-clickを指定するとダブルクリックになります。

+
+
+
; +//}}} + +let MOUSE_BUTTON_LEFT = 0; +let MOUSE_BUTTON_MIDDLE = 1; +let MOUSE_BUTTON_RIGHT = 2; + +function getImages(panel) { + var images = []; + // 普通の子孫要素のimage要素探索 + for (let [k, node] in Iterator(panel.getElementsByTagName('image'))) images.push(node); + // 匿名コンテントの子孫要素のimage要素探索 + var anonymousNodes = document.getAnonymousNodes(panel); + for (let [k, anonymousNode] in Iterator(anonymousNodes)) { + let node; + let result = document.evaluate('descendant-or-self::xul:image', anonymousNode, function() XUL.uri, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); + while ((node = result.iterateNext())) images.push(node); + } + + return images; +} + +function makeIcon(panel) { + var icon = ; + var image = getImages(panel)[0]; + + if (image) { + let style = window.getComputedStyle(image, null); + let src = image.src || style.listStyleImage.replace(/^url\("(.+)"\)$/, '$1'); + if (src != '') { + icon.@style = 'list-style-image: url("' + src + '");' + + '-moz-image-region: ' + style.MozImageRegion; + } + } + return icon; +} + +function generateStatusbarpaneIDlList(filter) { + var panels = document.getElementsByTagNameNS(XUL.uri, 'statusbarpanel'); + for ([k, p] in Iterator(panels)) { + if (p.hidden != true) { + yield { + text: p.id, + desc: 'statusbarpanel', + icon: makeIcon(p) + }; + } + } +} + +function createAndDispatchEvent(target, type, detail, screenX, screenY, button) { + var ev = document.createEvent('MouseEvents'); + ev.initMouseEvent(type, true, true, window, detail, screenX, screenY, 0, 0, false, false, false, false, button, null); + target.dispatchEvent(ev); +} + +function clickStatusIcon(panel, button, doubleClick) { + var target = getImages(panel)[0] || panel; + if (!target) return; + var x = target.boxObject.screenX; + var y = target.boxObject.screenY; + x += target.clientWidth / 2; + y += target.clientHeight / 2; + + // イベントの発生順序 http://www.quirksmode.org/dom/events/click.html + createAndDispatchEvent(target, 'mousedown', 0, x, y, button); + createAndDispatchEvent(target, 'mouseup', 0, x, y, button); + createAndDispatchEvent(target, 'click', 1, x, y, button); + + if (doubleClick) { + createAndDispatchEvent(target, 'mousedown', 0, x, y, button); + createAndDispatchEvent(target, 'mouseup', 0, x, y, button); + createAndDispatchEvent(target, 'click', 1, x, y, button); + createAndDispatchEvent(target, 'dblclick', 2, x, y, button); + } else if (button == MOUSE_BUTTON_RIGHT) { + createAndDispatchEvent(target, 'contextmenu', 1, x, y, button); + } +} + +commands.addUserCommand(['statusbar'],'click statusbar panel', + function(args) { + var id = args[0]; + var panel = document.getElementById(id); + if (!panel) { + liberator.echoerr('No such statusbar panel: ' + id); + return; + } + var button = MOUSE_BUTTON_LEFT; + switch (args['-button']) { + case 'm': button = MOUSE_BUTTON_MIDDLE; break; + case 'r': button = MOUSE_BUTTON_RIGHT; break; + case 'l': default: button = MOUSE_BUTTON_LEFT; break; + } + clickStatusIcon(panel, button, args['-double-click']); + }, { + argCount: '1', + options: [ + [['-button', '-b'], commands.OPTION_STRING, + function(arg) /^[lmr]$/.test(arg), + [['l', 'Left click (default)'], + ['m', 'Middle click'], + ['r', 'Right click']]], + [['-double-click', '-d'], commands.OPTION_NOARG] + ], + completer: function(context, args) { + var arg = args[0]; + context.anchored = false; + context.title = ['Panel ID']; + context.keys = { text: 'text', description: 'desc', icon: 'icon' }; + context.compare = CompletionContext.Sort.unsorted; + context.process = [function (item, text) { + return <>{item.icon ? item.icon : <>}{text} + }]; + + var list = generateStatusbarpaneIDlList(arg); + context.completions = list; + } + }, true); + +// vim: set sw=4 ts=4 et fdm=marker : -- cgit v1.2.3