There are 3 previous versions of this script.
// ==UserScript==
// @name Google Reader Key Customize
// @namespace http://fxwiki.blog63.fc2.com/
// @description Customize keyboard shortcuts in Google Reader.
// @version 1.1
// @include http://www.google.tld/reader/*
// @include https://www.google.tld/reader/*
// ==/UserScript==
// http://userscripts.org/scripts/show/48220
(function() {
var g_timeout = 2000;
var key = {}, $ = function(id) { return document.getElementById(id); }
var init = function() {
var ja = [
'キーボードショートカットのカスタマイズ',
'"g"以外の英数字を登録。(例 b: bキーで動作 B: shift+bキーで動作)',
'ナビゲーション', 'アイテム', 'ジャンプ', 'アプリケーション', 'その他',
'j', '次のアイテムを表示 ( j )',
'k', '前のアイテムを表示 ( k )',
'n', '次のアイテムを選択 ( n )',
'p', '前のアイテムを選択 ( p )',
'N', '次のフィード/フォルダを選択 ( N )',
'P', '前のフィード/フォルダを選択 ( P )',
'O', '選択したフィード/フォルダを開く ( O )',
'NO', '次のフィード/フォルダを開く ( N-O )',
'PO', '前のフィード/フォルダを開く ( P-O )',
'X', 'フォルダを開閉する ( X )',
'c', 'アイテムにメモを追加 ( c )',
'e', 'アイテムをメールで送信 ( e )',
'm', 'アイテムを既読/未読にする ( m )',
'o', 'アイテムを開閉する ( o )',
's', 'アイテムにスターを付ける ( s )',
't', 'アイテムにタグを付ける ( t )',
'v', 'アイテムのソースページを開く ( v )',
'A', 'アイテムをすべて既読にする ( A )',
'C', 'メモを表示 ( C )',
'D', 'アイテムにメモをして共有する ( D )',
'S', 'アイテムを共有する ( S )',
'ga', '「すべてのアイテム」に移動 ( g-a )',
'gc', '「Comment view」に移動 ( g-c )',
'gd', '「フィードを検索」に移動 ( g-d )',
'gf', '友だち選択ツールを表示 ( g-f )',
'gh', '「ホーム」に移動 ( g-h )',
'gs', '「スター付きアイテム」に移動 ( g-s )',
'gu', 'フィード選択ツールを表示 ( g-u )',
'gt', 'タグ選択ツールを表示 ( g-t )',
'gF', '「友だちの共有アイテム」に移動 ( g-F )',
'gS', '「共有アイテム」に移動 ( g-S )',
'gT', '「トレンド」に移動 ( g-T )',
'stuff', '「コンテンツ」に移動',
'notes', '「メモ」に移動',
'_1', '全文表示に切り替える ( 1 )',
'_2', 'リスト表示に切り替える ( 2 )',
'a', 'フィードを登録 ( a )',
'r', '更新 ( r )',
'u', '全画面表示の切り替え ( u )',
'U', 'ナビゲーションパネルをポップアップ ( U )',
'plus', '選択アイテムの文字サイズを大きく ( + )',
'minus', '選択アイテムの文字サイズを小さく ( - )',
'slash', 'カーソルを検索ボックスに置く ( / )',
'pUp', '上に1ページ分スクロール ( PageUp )',
'pDown', '下に1ページ分スクロール ( PageDown )',
'Home', '先頭にスクロール ( Home )',
'End', '末尾にスクロール ( End )',
'up', '上に1行分スクロール ( ↑ )',
'down', '下に1行分スクロール ( ↓ )',
'space', '次のアイテムにスクロール ( Space )',
'SPACE', '前のアイテムにスクロール ( Shift+Space )',
'newItem', '新着アイテムを表示',
'allItem', 'すべてのアイテムを表示'
];
var en = [
'Customize keyboard shortcuts',
'An alphanumeric character except "g". (for example, b: b, B: shift-b)',
'Navigation', 'Items', 'Jumping', 'Application', 'Others',
'j', 'next item ( j )',
'k', 'previous item ( k )',
'n', 'item scan down ( n )',
'p', 'item scan up ( p )',
'N', 'next subscription ( N )',
'P', 'previous subscription ( P )',
'O', 'open subscription or folder ( O )',
'NO', 'next & open subscription or folder ( N-O )',
'PO', 'previous & open subscription or folder ( P-O )',
'X', 'expand folder ( X )',
'c', 'add comment ( c )',
'e', 'email item ( e )',
'm', 'mark item as read/unread ( m )',
'o', 'expand/collapse item ( o )',
's', 'star item ( s )',
't', 'tag item ( t )',
'v', 'view original ( v )',
'A', 'mark all as read ( A )',
'C', 'view comments ( C )',
'D', 'share item with note ( D )',
'S', 'share item ( S )',
'ga', 'go to all items ( g-a )',
'gc', 'go to comment view ( g-c )',
'gd', 'go to discovery page ( g-d )',
'gf', 'open friend selector ( g-f )',
'gh', 'go home ( g-h )',
'gs', 'go to starred items ( g-s )',
'gu', 'open subscription selector ( g-u )',
'gt', 'open tag selector ( g-t )',
'gF', 'go to friends\' shared items ( g-F )',
'gS', 'go to shared items ( g-S )',
'gT', 'go to trends page ( g-T )',
'stuff', 'go to your stuff page',
'notes', 'go to your notes page',
'_1', 'switch to expanded view ( 1 )',
'_2', 'switch to list view ( 2 )',
'a', 'add a subscription ( a )',
'r', 'refresh ( r )',
'u', 'toggle full screen mode ( u )',
'U', 'popup navigation pane ( U )',
'plus', 'increase magnification ( + )',
'minus', 'decrease magnification ( - )',
'slash', 'move cursor to search box ( / )',
'pUp', 'scroll page up ( PageUp )',
'pDown', 'scroll page down ( PageDown )',
'Home', 'scroll top ( Home )',
'End', 'scroll end ( End )',
'up', 'scroll line up ( ↑ )',
'down', 'scroll line down ( ↓ )',
'space', 'scroll next item ( Space )',
'SPACE', 'scroll previous item ( Shift+Space )',
'newItem', 'view new items',
'allItem', 'view all items'
];
var css = '\
#grkc_setting {color: white; padding: 0 0 1em 0;\
position: absolute; top: 20px; left: 20px; z-index: 1234;\
background: rgba(10%, 15%, 10%, 0.9); -moz-border-radius: 10px; }\
#grkc_setting input { margin-right: 0.5em; text-align: center; width: 1.2em; }\
#grkc_titlebar { background: rgba(40%, 40%, 60%, 0.5);\
-moz-border-radius: 10px 10px 0 0; padding: 2px 10px; }\
#grkc_title a { font-weight: bold; color: white; text-decoration: none; }\
#grkc_title a:hover { color: #FF9; }\
#grkc_btn { float: right; position: absolute; right: 10px; }\
#grkc_desc { padding: 0 0.5em; margin: 0.5em 0 1em 0; }\
#grkc_tab { padding: 0 0.5em; margin: 1em 0; }\
#grkc_tab span { border: 1px solid #999; padding: 2px 8px;\
-moz-border-radius: 8px 8px 0 0; cursor: pointer; }\
#grkc_tab span:hover { background: rgba(100%, 100%, 80%, 0.2); }\
#grkc_form { padding: 0.5em; }\
#grkc_item, #grkc_jump, #grkc_app, #grkc_etc { display: none; }\
.grkc_row { float: left; padding: 0 5px; }\
#grkc_ok { margin-right: 0.5em; padding: 0 3ex; }\
#grkc_cancel { padding: 0 1ex; }\
#grkc_ok, #grkc_cancel { font-size: 90%; border: 1px solid #999; }\
#grkc_ok:hover, #grkc_cancel:hover { cursor: pointer;\
background: rgba(80%, 100%, 80%, 0.2); }\
';
var link = document.createElement("link");
link.rel = "stylesheet";
link.href = "data:text/css," + escape(css);
document.getElementsByTagName("head")[0].appendChild(link);
var div = document.createElement('div');
div.id = 'grkc_setting';
div.style.display = 'none';
document.body.appendChild(div);
if (document.title.match(/Google\s?リーダー/)) var a = ja;
else var a = en;
var tabID = ['nav', 'item', 'jump', 'app', 'etc'];
var s = '<div id="grkc_titlebar"><span id="grkc_title">'
+ '<a href="http://userscripts.org/scripts/show/48220" target="_blank">'
+ a[0] + '</a></span><span id="grkc_btn"><span id="grkc_ok">OK</span>'
+ '<span id="grkc_cancel">Cancel</span></span></div><div id="grkc_desc">'
+ a[1] + '</div><div id="grkc_tab">';
for (var i=0; i<tabID.length; i++) s += '<span id="grkc_tab_' + tabID[i] + '">' + a[i+2] + '</span>';
s += '</div><div id="grkc_form">';
var addLabel = function(n1, n2, n3, id) {
s += '<div id="grkc_' + id + '"><span class="grkc_row">';
for (var i=n1; i<n2; i=i+2) s += '<label><input id="'
+ a[i] + '" type="text" maxlength="1">' + a[i+1] + '</label><br>';
s += '</span><span class="grkc_row">';
for (var i=n2; i<n3; i=i+2) s += '<label><input id="'
+ a[i] + '" type="text" maxlength="1">' + a[i+1] + '</label><br>';
s += '</span></div>';
}
addLabel(7, 17, 27, tabID[0]);
addLabel(27, 39, 49, tabID[1]);
addLabel(49, 63, 75, tabID[2]);
addLabel(75, 85, 93, tabID[3]);
addLabel(93, 103, 113, tabID[4]);
s += '</div>';
$('grkc_setting').innerHTML = s;
var addEvent = function(id) {
var tab = $('grkc_tab_' + id);
var col = 'rgba(80%, 100%, 80%, 0.2)';
if (id == 'nav') tab.style.background = col;
tab.addEventListener('click', function() {
for (var i=0; i<tabID.length; i++) {
$('grkc_' + tabID[i]).style.display = 'none';
$('grkc_tab_' + tabID[i]).style.background = '';
}
$('grkc_' + id).style.display = 'block';
tab.style.background = col;
}, false);
}
for (var i=0; i<tabID.length; i++) addEvent(tabID[i]);
var loadKey = function() {
key = eval(GM_getValue("key")) || {};
var e = document.evaluate('id("grkc_form")/div/span/label/input', document, null, 7, null);
var i = 0;
for (var p in key) {
e.snapshotItem(i).value = (key[p]) ? key[p] : '';
i ++;
}
for (var p in key) {
if (key[p].match(/[A-Z]/)) key[p] = '@' + key[p];
else key[p] = key[p].toUpperCase();
}
}
$('grkc_ok').addEventListener('click', function() {
$('grkc_setting').style.display = 'none';
var e = document.evaluate('id("grkc_form")/div/span/label/input', document, null, 7, null);
for (var n=0,d={}; n<e.snapshotLength; n++) {
if (! e.snapshotItem(n).value.match(/[0-9a-fh-zA-Z]/)) e.snapshotItem(n).value = '';
d[e.snapshotItem(n).id] = e.snapshotItem(n).value;
}
GM_setValue("key",d.toSource());
loadKey();
}, false);
$('grkc_cancel').addEventListener('click', function() {
document.getElementById('grkc_setting').style.display = 'none';
loadKey();
}, false);
loadKey();
}
var grKeyCustomize = function(e) {
var set = $('grkc_setting');
if (! set) return;
if (e.ctrlKey && e.shiftKey && e.keyCode == 191) {
if (set.style.display != 'block') set.style.display = 'block';
else set.style.display = 'none';
}
if (e.ctrlKey || e.altKey || e.metaKey || set.style.display == 'block'
|| e.target.tagName.match(/input|textarea/i)) return;
var code = String.fromCharCode(e.keyCode), evt, cha;
if (e.shiftKey) code = '@' + code;
if (code == 'G') {
document.removeEventListener('keydown', grKeyCustomize, true);
setTimeout(function() {
document.addEventListener('keydown', grKeyCustomize, true);
}, g_timeout);
return;
}
switch (code) {
case key.a: case key.A: case key.ga:
cha = 'A'; break;
case key.c: case key.C: case key.gc:
cha = 'C'; break;
case key.D: case key.gd:
cha = 'D'; break;
case key.e:
cha = 'E'; break;
case key.gf: case key.gF:
cha = 'F'; break;
case key.gh:
cha = 'H'; break;
case key.j:
cha = 'J'; break;
case key.k:
cha = 'K'; break;
case key.m:
cha = 'M'; break;
case key.n: case key.N: case key.NO:
cha = 'N'; break;
case key.o: case key.O:
cha = 'O'; break;
case key.p: case key.P: case key.PO:
cha = 'P'; break;
case key.r:
cha = 'R'; break;
case key.s: case key.S: case key.gs: case key.gS:
cha = 'S'; break;
case key.t: case key.gt: case key.gT:
cha = 'T'; break;
case key.u: case key.U: case key.gu:
cha = 'U'; break;
case key.v:
cha = 'V'; break;
case key.X:
cha = 'X'; break;
case key.pUp:
cha = 33; break;
case key.pDown:
cha = 34; break;
case key.Home:
cha = 36; break;
case key.End:
cha = 35; break;
case key.up:
cha = 38; break;
case key.down:
cha = 40; break;
case key._1:
cha = 49; break;
case key._2:
cha = 50; break;
case key.plus:
cha = 107; break;
case key.minus:
cha = 109; break;
case key.slash:
cha = 191; break;
case key.stuff: case key.notes: case key.newItem: case key.allItem:
case key.space: case key.SPACE:
cha = -1; break;
defalut: return;
}
if (! cha) return;
if (cha && isNaN(cha)) cha = cha.charCodeAt();
e.stopPropagation();
evt = document.createEvent('KeyboardEvent');
switch (code) {
case key.a: case key.c: case key.e: case key.j: case key.k: case key.m:
case key.n: case key.o: case key.p: case key.r: case key.s: case key.t:
case key.u: case key.v: case key._1: case key._2: case key.slash:
case key.plus: case key.minus: case key.pUp: case key.pDown:
case key.Home: case key.End: case key.up: case key.down:
evt.initKeyEvent('keypress', 1, 1, null, 0, 0, 0, 0, cha, 0);
break;
case key.A: case key.C: case key.D: case key.N: case key.O:
case key.P: case key.S: case key.U: case key.X:
case key.NO: case key.PO:
evt.initKeyEvent('keypress', 1, 1, null, 0, 0, 1, 0, cha, 0);
break;
case key.ga: case key.gc: case key.gd: case key.gf:
case key.gh: case key.gs: case key.gt: case key.gu:
case key.gF: case key.gS: case key.gT:
evt.initKeyEvent('keypress', 1, 1, null, 0, 0, 0, 0, 71, 0);
break;
case key.space:
evt.initKeyEvent('keypress', 1, 1, null, 0, 0, 0, 0, 32, 0);
break;
case key.SPACE:
evt.initKeyEvent('keypress', 1, 1, null, 0, 0, 1, 0, 32, 0);
break;
case key.stuff: case key.notes: case key.newItem: case key.allItem:
evt = document.createEvent('MouseEvents');
evt.initEvent('click', 1, 1);
break;
default: return;
}
switch (code) {
case key.stuff:
$('your-items-tree-item-0-link').dispatchEvent(evt);
return;
case key.notes:
$('your-items-tree-item-2-link').dispatchEvent(evt);
return;
case key.newItem:
$('show-new').dispatchEvent(evt);
return;
case key.allItem:
$('show-all').dispatchEvent(evt);
return;
}
document.dispatchEvent(evt);
switch (code) {
case key.NO: case key.PO:
evt.initKeyEvent('keypress', 1, 1, null, 0, 0, 1, 0, 79, 0);
break;
case key.ga: case key.gc: case key.gd: case key.gf:
case key.gh: case key.gs: case key.gt: case key.gu:
evt.initKeyEvent('keypress', 1, 1, null, 0, 0, 0, 0, cha, 0);
break;
case key.gF: case key.gS: case key.gT:
evt.initKeyEvent('keypress', 1, 1, null, 0, 0, 1, 0, cha, 0);
break;
default: return;
}
document.dispatchEvent(evt);
}
window.addEventListener('load', function() {
document.addEventListener('keydown', grKeyCustomize, true);
init();
}, false);
window.removeEventListener('unload', function() {
document.removeEventListener('keydown', grKeyCustomize, true);
}, false);
})();
