バグのサマリが良くないんですが、このバグの修正で、オーディオのボリュームに関するkeyCode
値が新たに定義されました。
const unsigned long DOM_VK_VOLUME_MUTE = 0xB6;
const unsigned long DOM_VK_VOLUME_DOWN = 0xB7;
const unsigned long DOM_VK_VOLUME_UP = 0xB8;
という感じで値が割り当てられ、現在、Windowsではマッピングされています。Windowsで実際にこれらのキーが利用されているキーボードドライバは知りませんが……
レガシーなkeyCode
値を新たに定義したのは、内部処理で必要だから、ということです。
Firefox 14までは、Windows/Linux/Macで、キーボードレイアウトとプラットフォームによってはほとんどのキーがkeyCode
値が0になっていたり、同じキーボードレイアウトの同じキーがプラットフォーム毎に違う値を返すことがあったりするバグが長年、問題になっていたので、Firefox 15では、Bug-org 630810 (Windows)の修正、Bug-org 677252 (Mac)の修正、Bug-org 447757 (Linux)の修正で、ほぼ、これらの問題を一掃しましたが、その際に今まで、Windowsでは、ネイティブのvirtual keycode値でDOM keyCode
値が定義されていないものに関してはそのままの値をセットするというのを取りやめ、マッピングできないもの、つまり、一般的なWebアプリで処理されるべきではないキーに関しては、keyCode
値が0になるようになりました。
このバグは、特定の顧客に向けたWebアプリを提供する報告者の視点からすると、IEやWindows版のWebKitと同じkeyCode
値が来ないのは困るというのものでした。
まず、上記バグで新たに定義したkeyCode
値は今更動かすとさらに混乱が増すので、これらと重なる値については断念せざるを得ません。しかし、幸い、報告者が問題にしているkeyCode
値はこれらとかぶっているものがありませんでした。
しかし、報告者が必要とするkeyCode
値にはいくつか問題がありました。まず、顧客の利用している特殊なキーボードの実際のキーの刻印に反して、適切なvirtual keycode値が利用されておらず、OEM specificキーの値を多用している、さらに、Windows SDKで未定義、もしくは予約されているvirtual keycode値も利用している、複数のキーで同じvirtual keycodeを利用している(scan code値は異なっている)、というものです。
OEM specificキーは特殊なハードウェアにWindowsを組み込む際に内部利用用に予約されているようなものですので、本来はWebアプリから見える必要すらありません。その値から、キーの意味を知ることができないからです(つまり、Windows以外の環境ではマッピングしようがないので、非Windows環境でアクセシビリティ上、問題のあるものしか作れない)。しかし、上述のように、特定の顧客に向けたソリューションでは決め打ちで利用することに価値がありますので、これらの値をWindowsでのみ、Webアプリから利用可能にしました。以下がその一覧(定義)です。
// OEM specific virtual keyCode of Windows should pass through DOM keyCode
// for compatibility with the other web browsers on Windows.
const unsigned long DOM_VK_WIN_OEM_FJ_JISHO = 0x92;
const unsigned long DOM_VK_WIN_OEM_FJ_MASSHOU = 0x93;
const unsigned long DOM_VK_WIN_OEM_FJ_TOUROKU = 0x94;
const unsigned long DOM_VK_WIN_OEM_FJ_LOYA = 0x95;
const unsigned long DOM_VK_WIN_OEM_FJ_ROYA = 0x96;
// OEM specific virtual keyCode of Windows should pass through DOM keyCode
// for compatibility with the other web browsers on Windows.
const unsigned long DOM_VK_WIN_ICO_HELP = 0xE3;
const unsigned long DOM_VK_WIN_ICO_00 = 0xE4;
const unsigned long DOM_VK_WIN_ICO_CLEAR = 0xE6;
const unsigned long DOM_VK_WIN_OEM_RESET = 0xE9;
const unsigned long DOM_VK_WIN_OEM_JUMP = 0xEA;
const unsigned long DOM_VK_WIN_OEM_PA1 = 0xEB;
const unsigned long DOM_VK_WIN_OEM_PA2 = 0xEC;
const unsigned long DOM_VK_WIN_OEM_PA3 = 0xED;
const unsigned long DOM_VK_WIN_OEM_WSCTRL = 0xEE;
const unsigned long DOM_VK_WIN_OEM_CUSEL = 0xEF;
const unsigned long DOM_VK_WIN_OEM_ATTN = 0xF0;
const unsigned long DOM_VK_WIN_OEM_FINISH = 0xF1;
const unsigned long DOM_VK_WIN_OEM_COPY = 0xF2;
const unsigned long DOM_VK_WIN_OEM_AUTO = 0xF3;
const unsigned long DOM_VK_WIN_OEM_ENLW = 0xF4;
const unsigned long DOM_VK_WIN_OEM_BACKTAB = 0xF5;
// OEM specific virtual keyCode of Windows should pass through DOM keyCode
// for compatibility with the other web browsers on Windows.
const unsigned long DOM_VK_WIN_OEM_CLEAR = 0xFE;
実際に、これらの値がどれほど変なものかというと、身近なJISキーボードにある特殊なキーを押してみると分かります。以下の表を見てみて下さい。
JISキーボードレイアウトの特殊キーと、virtual keycode値、DOM keyCode値の対応表
キー | virtual keycode | DOM keyCode |
半角/全角 | VK_OEM_AUTO (WM_KEYUP )、VK_OEM_ENLW (WM_KEYDOWN ) (もう一度押すと、逆になる) | KeyboardEvent.DOM_VK_WIN_OEM_AUTO (keyup )、KeyboardEvent.DOM_VK_WIN_OEM_ENLW (Keydown 、keypress ) |
漢字(Alt + 半角/全角) | VK_KANJI (WM_SYSKEYDOWN 、WM_SYSKEYUP ) | KeyboardEvent.DOM_VK_KANJI (keydown 、keypress 、keyup ) |
英数 | VK_OEM_ATTN (WM_KEYDOWN のみ) | KeyboardEvent.DOM_VK_WIN_OEM_ATTN (keydown 、keypress のみ) |
CapsLock (Shift + 英数) | VK_CAPITAL | KeyboardEvent.DOM_VK_CAPS_LOCK (keydown 、keyup ) |
カタカナ ひらがな | VK_OEM_COPY (WM_KEYDOWN のみ。VK_OEM_ATTN のWM_KEYUP が先に発生することもあり) | KeyboardEvent.DOM_VK_WIN_OEM_COPY (keydown 、keypress のみ。VK_OEM_ATTN が先行した場合は、KeyboardEvent.DOM_VK_WIN_OEM_ATTN のkeyup が先行する) |
ローマ字 (Alt + カタカナ ひらがな) | VK_ATTN (WM_SYSKEYUP )、VK_OEM_BACKTAB (WM_SYSKEYDOWN ) (もう一度押すと逆になる) | KeyboardEvent.DOM_VK_ATTN (keyup )、KeyboardEvent.DOM_VK_WIN_OEM_BACKTAB (keydown 、keypress ) |
と、このような感じです。VK_OEM_AUTO
とVK_OEM_ENLW
が特に複雑で、どちらかが半角を意味し、どちらかが全角を意味していて、どちらかが押されっぱなしの状態を作り出していることがうかがえます。とてもではないですが、Webアプリからすると、JISキーボードのハンドリングとしては使えたものではない挙動です。
これ以外にも、以下のkeyCode
が副作用も考えられないので定義されました。
// Following keys are not used on most keyboards. However, for compatibility
// with other browsers on Windows, we should define them.
const unsigned long DOM_VK_ATTN = 0xF6;
const unsigned long DOM_VK_CRSEL = 0xF7;
const unsigned long DOM_VK_EXSEL = 0xF8;
const unsigned long DOM_VK_EREOF = 0xF9;
const unsigned long DOM_VK_PLAY = 0xFA;
const unsigned long DOM_VK_ZOOM = 0xFB;
const unsigned long DOM_VK_PA1 = 0xFD;
DOM_VK_ZOOM
以外は、昔のIBMのコンピュータのキーボードに存在したキー向けと思われるので、Linuxでも同等のものをマッピングしています。ちなみに、VK_ZOOM
を利用するキーボードは私は知りません。
これら以外の未定義や、予約済みのvirtual keycode値はWebアプリに渡す予定はありません。これらの値が将来定義され、他のプラットフォームでマッピングが必要になるかもしれないからです。