There are 9 previous versions of this script.
// ==UserScript==
// @name Google Reader Key Customize
// @description Customize keyboard shortcuts in Google Reader. / Googleリーダーのキーボードショートカットをカスタマイズします。
// @namespace http://fxwiki.blog63.fc2.com/
// @homepage http://userscripts.org/scripts/show/48220
// @updateURL https://userscripts.org/scripts/source/48220.meta.js
// @include http://www.google.tld/reader/view/*
// @include https://www.google.tld/reader/view/*
// @version 1.6
// ==/UserScript==
(function() {
var g_timeout = 2000;
var key = {}, $ = function(id) { return document.getElementById(id); };
var init = function() {
var ja1 = [
'キーボードショートカットのカスタマイズ',
'"g"以外の英数字を登録。(例 b: Bキーで動作 B: Shift+Bキーで動作)',
'ナビゲーション',
'アイテム',
'ジャンプ',
'アプリケーション',
'その他',
'設定'
];
var ja2 = [
'j', '次のアイテムを表示 ( j )',
'k', '前のアイテムを表示 ( k )',
'n', '次のアイテムを選択 ( n )',
'p', '前のアイテムを選択 ( p )',
'N', '次のフィード/フォルダを選択 ( N / J )',
'P', '前のフィード/フォルダを選択 ( P / K )',
'O', '選択したフィード/フォルダを開く ( O )',
'NO', '次のフィード/フォルダを開く ( N-O )',
'PO', '前のフィード/フォルダを開く ( P-O )',
'X', 'フォルダを開閉する ( X )',
'c', 'アイテムにコメントを追加 ( c )',
'e', 'アイテムをメールで送信 ( e )',
'l', 'アイテムをお気に入りに登録 ( l )',
'm', 'アイテムを既読/未読にする ( m )',
'o', 'アイテムを開閉する ( o / enter )',
's', 'アイテムにスターを付ける ( s )',
't', 'アイテムにタグを付ける ( t )',
'v', 'アイテムのソースページを開く ( v )',
'A', 'アイテムをすべて既読にする ( A )',
'C', 'アイテムのコメントを表示 ( C )',
'D', 'アイテムにコメントを付けて共有 ( D )',
'S', 'アイテムを共有 ( S )',
'T', '[送信先]メニューを開く ( T )',
'ga', '「すべてのアイテム」に移動 ( g-a )',
'gc', '「コメント表示」に移動 ( g-c )',
'gd', '「フィードを検索」に移動 ( g-d )',
'ge', '「ピックアップ」に移動 ( g-e )',
'gf', '友だち選択ツールを表示 ( g-f )',
'gh', '「ホーム」に移動 ( g-h )',
'gp', '「おすすめのアイテム」に移動 ( g-p )',
'gs', '「スター付きアイテム」に移動 ( g-s )',
'gu', 'フィード選択ツールを表示 ( g-u )',
'gt', 'タグ選択ツールを表示 ( g-t )',
'gF', '「友だちの共有アイテム」に移動 ( g-F )',
'gS', '「共有アイテム」に移動 ( g-S )',
'gT', '「トレンド」に移動 ( g-T )',
'_1', '全文表示に切り替える ( 1 )',
'_2', 'リスト表示に切り替える ( 2 )',
'a', 'フィードを登録 ( a )',
'f', '全画面表示の切り替え ( f )',
'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 en1 = [
'Customize keyboard shortcuts',
'An alphanumeric character except "g". (for example, b: b, B: Shift-b)',
'Navigation',
'Items',
'Jumping',
'Application',
'Others',
'Settings'
];
var en2 = [
'j', 'next item ( j )',
'k', 'previous item ( k )',
'n', 'item scan down ( n )',
'p', 'item scan up ( p )',
'N', 'next subscription ( N / J )',
'P', 'previous subscription ( P / K )',
'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 )',
'l', 'like item ( l )',
'm', 'mark item as read/unread ( m )',
'o', 'expand/collapse item ( o/enter )',
'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 )',
'T', 'open “send to” menu ( T )',
'ga', 'go to all items ( g-a )',
'gc', 'go to comment view ( g-c )',
'gd', 'go to discovery page ( g-d )',
'ge', 'go to explore ( g-e )',
'gf', 'open friend selector ( g-f )',
'gh', 'go home ( g-h )',
'gp', 'go to popular items ( g-p )',
'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 )',
'_1', 'switch to expanded view ( 1 )',
'_2', 'switch to list view ( 2 )',
'a', 'add a subscription ( a )',
'f', 'toggle full screen mode ( f )',
'r', 'refresh ( r )',
'u', 'hide/unhide the sidebar ( u )',
'U', 'temporary view the sidebar ( 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: 90100; background: rgba(10%, 15%, 10%, 0.9); -moz-border-radius: 10px; border-radius: 10px; }',
'#grkc_setting input { margin-right: 0.5em; text-align: center; width: 1.2em; }',
'#grkc_titlebar { background: rgba(60%, 60%, 100%, 0.3); -moz-border-radius: 10px 10px 0 0; 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; 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.3); }'
].join('');
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'), loc1, loc2;
div.id = 'grkc_setting';
div.style.display = 'none';
document.body.appendChild(div);
if (/Google\s?リーダー/.test(document.title)) {
loc1 = ja1; loc2 = ja2;
} else {
loc1 = en1; loc2 = en2;
}
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">' +
loc1[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">' +
loc1[1] + '</div><div id="grkc_tab">';
for (var i1=0; i1<tabID.length; i1++) s += '<span id="grkc_tab_' + tabID[i1] + '">' + loc1[i1+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 i2=n1; i2<n2; i2=i2+2) s += '<label><input id="grkc_key-' + loc2[i2] + '" type="text" maxlength="1">' + loc2[i2+1] + '</label><br>';
s += '</span><span class="grkc_row">';
for (var i3=n2; i3<n3; i3=i3+2) s += '<label><input id="grkc_key-' + loc2[i3] + '" type="text" maxlength="1">' + loc2[i3+1] + '</label><br>';
s += '</span></div>';
};
addLabel(0, 10, 20, tabID[0]);
addLabel(20, 34, 46, tabID[1]);
addLabel(46, 60, 72, tabID[2]);
addLabel(72, 82, 92, tabID[3]);
addLabel(92, 102, 112, 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 = JSON.parse(GM_getValue('key')) || {};
for (var p in key) {
if (key.hasOwnProperty(p)) {
if ($('grkc_key-' + p)) $('grkc_key-' + p).value = key[p];
if (/[A-Z]/.test(key[p])) 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 (! /[0-9a-fh-zA-Z]/.test(e.snapshotItem(n).value)) e.snapshotItem(n).value = '';
if (e.snapshotItem(n).value) d[e.snapshotItem(n).id.slice(9)] = e.snapshotItem(n).value;
}
try {
GM_setValue('key',JSON.stringify(d));
} catch(er) {
GM_setValue('key',d.toSource());
}
loadKey();
}, false);
$('grkc_cancel').addEventListener('click', function() {
document.getElementById('grkc_setting').style.display = 'none';
loadKey();
}, false);
if ($('gbd5')) {
var ol = document.evaluate('id("gbd5")/div/ol', document, null, 9, null).singleNodeValue;
if (ol) {
var li = document.createElement('li');
li.className = 'gbkc gbmtc';
li.innerHTML = '<a href="javascript:void(0);" id="grkc_settingmenu" class="gbmt">Key Customize ' + loc1[7] + '</a>';
ol.appendChild(li);
}
} else if ($('gbg')) {
var a = document.createElement('a');
a.id = 'grkc_settingmenu';
a.className = 'gb2';
a.href = 'javascript:void(0);';
a.innerHTML = 'Key Customize ' + loc1[7];
$('gbg').appendChild(a);
}
var viewSettings = function() {
var se = $('grkc_setting');
if ($('settings-button-menu')) $('settings-button').blur();
if (se) se.style.display = (se.style.display !== 'block') ? 'block' : 'none';
};
if ($('settings-button-menu')) {
var d1 = document.evaluate('id("settings-button-menu")', document, null, 9, null).singleNodeValue;
if (d1) {
var d2 = document.createElement('div');
d2.id = 'grkc_settingmenu2';
d2.className = 'goog-menuitem';
d2.setAttribute('role', 'menuitem');
d2.setAttribute('style', '-moz-user-select: none;');
d2.innerHTML = '<div id="grkc_settingmenu2child" class="goog-menuitem-content">Key Customize ' + loc1[7] + '</div>';
d1.appendChild(d2);
}
$('grkc_settingmenu2').addEventListener('mouseover', function() {
$('grkc_settingmenu2').className = 'goog-menuitem goog-menuitem-highlight';
}, false);
$('grkc_settingmenu2').addEventListener('mouseout', function() {
$('grkc_settingmenu2').className = 'goog-menuitem';
}, false);
}
$('grkc_settingmenu').addEventListener('click', function() {
viewSettings();
}, false);
$('grkc_settingmenu2').addEventListener('click', function() {
viewSettings();
}, false);
loadKey();
};
var keyDown = function(e) {
var set = $('grkc_setting');
if (! set) return;
if (e.ctrlKey && e.shiftKey && e.keyCode === 191)
set.style.display = (set.style.display !== 'block') ? 'block' : 'none';
if (e.ctrlKey || e.altKey || e.metaKey || set.style.display === 'block' || /input|textarea/i.test(e.target.tagName)) return;
var code = String.fromCharCode(e.keyCode), evt, cha;
if (e.shiftKey) code = '@' + code;
if (code === 'G') {
document.removeEventListener('keydown', keyDown, true);
setTimeout(function() {
document.addEventListener('keydown', keyDown, 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: case key.ge:
cha = 'E'; break;
case key.f: 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.l:
cha = 'L'; 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: case key.gp:
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.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.newItem: case key.allItem:
case key.space: case key.SPACE:
cha = -1; break;
}
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.f: case key.j:
case key.k: case key.l: 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.T: 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.ge: case key.gf:
case key.gh: case key.gp: 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.newItem: case key.allItem:
evt = document.createEvent('MouseEvents');
evt.initEvent('mousedown', 1, 1);
break;
default: return;
}
switch (code) {
case key.newItem:
var vvoText = $('viewer-view-options').firstChild.textContent;
if (vvoText && !new RegExp(/\d+/).exec(vvoText)) {
$('viewer-view-options').dispatchEvent(evt);
evt = document.createEvent('MouseEvents');
evt.initEvent('mouseover', 1, 1);
$(':8').dispatchEvent(evt);
evt.initEvent('mouseup', 1, 1);
$(':8').dispatchEvent(evt);
$(':8').dispatchEvent(evt);
$('viewer-view-options').blur();
}
return;
case key.allItem:
var vvoText = $('viewer-view-options').firstChild.textContent;
if (vvoText && new RegExp(/\d+/).exec(vvoText)) {
$('viewer-view-options').dispatchEvent(evt);
evt = document.createEvent('MouseEvents');
evt.initEvent('mouseover', 1, 1);
$(':7').dispatchEvent(evt);
evt.initEvent('mouseup', 1, 1);
$(':7').dispatchEvent(evt);
$(':7').dispatchEvent(evt);
$('viewer-view-options').blur();
}
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);
};
var keyUp = function(e) {
if (/^grkc_key/.test(e.target.id)) {
if (! /[0-9a-fh-zA-Z]/.test(e.target.value)) e.target.value = null;
var el = document.evaluate('id("grkc_form")/div/span/label/input', document, null, 7, null);
var check = function(a, b, c) {
var i = 0;
if (a.some(function(d) {
if (d === b) i++;
if (i > 1) return true;
})) c.style.backgroundColor = '#FFFF66';
else c.style.backgroundColor = null;
};
for (var n1=0,key=[],v1; n1<el.snapshotLength; n1++) {
v1 = el.snapshotItem(n1).value;
if (/[0-9a-fh-zA-Z]/.test(v1)) key.push(v1);
}
for (var n2=0,s,v2; n2<el.snapshotLength; n2++) {
s = el.snapshotItem(n2); v2 = s.value;
if (! /[0-9a-fh-zA-Z]/.test(v2)) {
s.style.backgroundColor = null;
continue;
}
check(key, v2, s);
}
}
};
window.addEventListener('load', function() {
document.addEventListener('keydown', keyDown, true);
document.addEventListener('keyup', keyUp, true);
init();
}, false);
window.removeEventListener('unload', function() {
document.removeEventListener('keydown', keyDown, true);
document.removeEventListener('keyup', keyUp, true);
}, false);
})();