Functional key handling in Opera TV Store applications
The Opera TV Store is designed to use the standard four-way directional keys on a remote control for spatial navigation. Authors should test that their applications work correctly using the default spatial navigation built into the Opera TV Store browser.
Opera's spatial navigation works in a similar way to traditional TAB based keyboard access in most browsers, allowing users to move from between focusable elements (links, form controls, image map areas). In addition, spatial navigation also employs heuristics that make arbitrary elements with attached click and mouseover JavaScript events focusable as well. Lastly, as the name implies, spatial navigation in Opera allows the user to move between those elements based on their spatial relationship on screen, rather than in source order (as with TAB navigation).
In most cases, authors can simply rely on Opera's spatial navigation to handle their application's controls. There are simple mechanisms to further tweak spatial navigation for TV browsing using CSS3.
For maximum control, authors may also choose to handle the navigation of their application themselves by intercepting key presses from the remote control. This allows to not only react to the basic directional buttons (UP, RIGHT, DOWN, LEFT), but to further bind functionality to the various shortcut and functional keys (such as BACK, INFO, OPTIONS or the RED button). As the exact key codes for remote control keys varies between different devices, the Opera TV Store browser provides built-in global constants mapped to the hardware-specific codes used by the current device.
List of available functional buttons
| Hardware key | Key code constant | Comment |
|---|---|---|
| ↑ | VK_UP | Always available* |
| → | VK_RIGHT | Always available* |
| ↓ | VK_DOWN | Always available* |
| ← | VK_LEFT | Always available* |
| Confirm/Select/OK | VK_ENTER | Always available* |
| Exit | N/A | Always available (handled by native firmware) |
| Back/Return | VK_BACK_SPACE | Optional but recommended |
| BLUE | VK_BLUE | Optional but recommended |
| RED | VK_RED | Optional but recommended |
| GREEN | VK_GREEN | Optional but recommended |
| YELLOW | VK_YELLOW | Optional but recommended |
| Menu | VK_MENU | Optional |
| 0 | VK_0 | Optional |
| 1 | VK_1 | Optional |
| 2 | VK_2 | Optional |
| 3 | VK_3 | Optional |
| 4 | VK_4 | Optional |
| 5 | VK_5 | Optional |
| 6 | VK_6 | Optional |
| 7 | VK_7 | Optional |
| 8 | VK_8 | Optional |
| 9 | VK_9 | Optional |
| PLAY | VK_PLAY | Optional |
| PAUSE | VK_PAUSE | Optional |
| STOP | VK_STOP | Optional |
| NEXT | VK_TRACK_NEXT | Optional |
| PREV | VK_TRACK_PREV | Optional |
| FF (Fast-Forward) | VK_FAST_FWD | Optional |
| REWIND | VK_REWIND | Optional |
| SUBTITLE | VK_SUBTITLE | Optional |
| INFORMATION | VK_INFO | Optional |
Note: CONFIRM, EXIT and directional buttons are mandatory for device manufacturers to implement, so they are always available for the end user via the remote control of any device that the Opera TV Store is integrated with. The EXIT key is handled by the Opera TV Store browser itself, to ensure that each application can be closed. For this reason VK_EXIT will not be sent to the application.
Handling keypress events
Key events can be handled by adding an onkeypress attribute to an element (note though that keypresses will then only be handled if that element actually received focus):
<ELEMENT onkeypress="handler">
This can of course also be achieved directly via JavaScript, either by adding the onkeypress property of using addEventListener:
object.onkeypress = handler;
object.addEventListener("keypress", handler, useCapture);
In the handler function, you can then compare the event.keyCode to the set of global constants for functional keys provided in the Opera TV Store.
function handler(event){
…
if (VK_RED == event.keyCode){
/* VK_RED was pressed … do something useful */
}
…
}
Depending on the application, it is advisable not to include a large number of separate event handlers to various elements in the page, but to instead take advantage of event capture / bubbling and use an event delegation mechanism, hooking the keypress handler on a top-level element (for instance, the body) or object (window or similar):
window.addEventListener("keypress", handler, useCapture);
In your handler function, you may need to determine the element where the event originated. A reference to this can be easily obtained from the event.target:
function handler(event){
…
var target = event.target;
…
}
Preventing default spatial navigation
When handling key events directly, you will probably want to stop the Opera TV Store browser from carrying out its normal spatial navigation and element activation behaviours. This can simply be suppressed in the handler function:
function handler(event){
…
event.preventDefault();
…
}
Determining support for a specific functional key
Authors can check if a specific functional key has been defined on the current device using a simple JavaScript check. If a button is supported, the constant will contain the device-specific key code of the button; otherwise, the constant will return a null value. For example, to test for the VK_RED key:
if (VK_RED !== null) {
/* VK_RED is supported */
…
}
Although all devices running the Opera TV Store should have all the global constants listed above defined (though their value may be null, if the device's default remote control doesn't have a particular button), it is still advisable to also check for the existence of the constant before using it, to avoid any Unhandled Error: Undefined variable JavaScript errors.
if (('VK_RED' in window)&&(VK_RED !== null)) {
/* VK_RED is supported */
…
}
This precaution should also be taken when checking event.keyCode values against those constants:
function handler(event){
…
if (('VK_RED' in window)&&(VK_RED == event.keyCode)){
/* VK_RED was pressed … do something useful */
}
…
}
The list of VK_* global constants is currently set in a user.js file, which OEMs include as part of their Opera TV Store installation at integration time. Device manufacturers will include the buttons and their respective key codes based on the default remote controls that ship with their devices. With this approach, however, any third-party or alternative remote controls may not match the standard remote's set of functional buttons – the constants may be defined and present, but the actual remote doesn't have those physical keys. For this reason, it's still advisable to use caution and to make applications work with the minimal set of Always available keys.
About this article
| Published in | Dev.Opera |
|---|---|
| Date | February 10, 2012 |
| Author | Patrick H. Lauke |
| Tags | javascript, opera tv store, tv |
| Original | Internet Archive |