WebAPI/BrowserAPI/KeyboardEvent: Difference between revisions

Update follow up bugs
(Update follow up bugs)
 
(21 intermediate revisions by 6 users not shown)
Line 1: Line 1:
== Dispatch KeyboardEvent across BrowserElements ==
== Dispatch KeyboardEvent across BrowserElements ==


This is a proposal to enable applications to handle/override the behavior of certain KeyboardEvent.
This is a proposal to enable applications to handle/override the behavior of certain KeyboardEvent. For implementation, see {{bug|989198}}.


There are four scenarios which should be fulfilled:
There are four scenarios which should be fulfilled:
Line 8: Line 8:
! Scenario !! Description !! Example Keys
! Scenario !! Description !! Example Keys
|-
|-
| SYSTEM-ONLY || For keys which should be handled by mozbrowser embedder iframe only. || 'Power', 'VolumeUp', 'VolumeDown', 'VolumeMute', 'DisplaySwap'
| SYSTEM-ONLY || For keys which should be handled by mozbrowser embedder iframe only. || 'Power', 'DisplaySwap'
|-
|-
| SYSTEM-FIRST || For keys which can be handled by mozbrowser embedder iframe first and can also be handled by mozbrowser embedded iframe then. || 'Info', 'Settings'
| SYSTEM-FIRST || For keys which can be handled by mozbrowser embedder iframe first and can also be handled by mozbrowser embedded iframe then. || 'Info', 'Settings'
|-
|-
| APP-ONLY || For keys which should be handled by mozbrowser embedded iframe only. || 'ColorF0Red', 'ColorF1Green', 'ColorF2Yellow', 'ColorF3Blue', 'ColorF4Grey'
| APP-CANCELLED || For keys which should be handled by mozbrowser embedded iframe only. || 'ColorF0Red', 'ColorF1Green', 'ColorF2Yellow', 'ColorF3Blue', 'ColorF4Grey'
|-
|-
| APP-FIRST || For keys which keys can be handled by mozbrowser embedded iframe first and can also be handled by mozbrowser embedder iframe then. || 'Info', 'Settings'
| APP-FIRST || For keys which keys can be handled by mozbrowser embedded iframe first and can also be handled by mozbrowser embedder iframe then. || 'Info', 'Settings'
Line 25: Line 25:
Four new events are proposed:
Four new events are proposed:
* mozbrowserbeforekeydown
* mozbrowserbeforekeydown
* mozbrowserkeydown
* mozbrowserafterkeydown
* mozbrowserbeforekeyup
* mozbrowserbeforekeyup
* mozbrowserkeyup
* mozbrowserafterkeyup




Line 33: Line 33:
# 'mozbrowserbeforekeydown' is dispatched to mozbrowser-embedder iframe
# 'mozbrowserbeforekeydown' is dispatched to mozbrowser-embedder iframe
# 'keydown' is dispatched to mozbrowser-embedded iframe
# 'keydown' is dispatched to mozbrowser-embedded iframe
# 'mozbrowserkeydown' is dispatched to mozbrowser-embedder iframe
# 'mozbrowserafterkeydown' is dispatched to mozbrowser-embedder iframe




Line 39: Line 39:
# 'mozbrowserbeforekeyup' is dispatched to mozbrowser-embedder iframe
# 'mozbrowserbeforekeyup' is dispatched to mozbrowser-embedder iframe
# 'keyup' is dispatched to mozbrowser-embedded iframe
# 'keyup' is dispatched to mozbrowser-embedded iframe
# 'mozbrowserkeyup' is dispatched to mozbrowser-embedder iframe
# 'mozbrowserafterkeyup' is dispatched to mozbrowser-embedder iframe
 


==== Nested mozbrowser iframes case ====
This proposal can be extended to nested mozbrowser iframes. The four new events will be dispatched to all mozbrowser-embedder iframes.
This proposal can be extended to nested mozbrowser iframes. The four new events will be dispatched to all mozbrowser-embedder iframes.


Line 61: Line 61:


  function checkAttrAndHandleEvent(event) {
  function checkAttrAndHandleEvent(event) {
  dump("Receive event \'" + event.type + "\' with embeddedCancelled equals to \'" + event.embeddedCancelled + "\'.");
   if (!event.embeddedCancelled) {
   if (!event.embeddedCancelled) {
     dump("Receive event \'" + event.type + "\'.");
     // do something
   }
   }
  };
  };
Line 70: Line 71:
     window.addEventListener('mozbrowserbeforekeydown', handleEventAndPreventDefault);
     window.addEventListener('mozbrowserbeforekeydown', handleEventAndPreventDefault);
     window.addEventListener('mozbrowserbeforekeyup', handleEventAndPreventDefault);
     window.addEventListener('mozbrowserbeforekeyup', handleEventAndPreventDefault);
     window.addEventListener('mozbrowserkeydown', function() { });
     window.addEventListener('mozbrowserafterkeydown', function() { });
     window.addEventListener('mozbrowserkeyup', function() { });
     window.addEventListener('mozbrowserafterkeyup', function() { });
* mozbrowser-embedded iframe
* mozbrowser-embedded iframe
     window.addEventListener('keydown', handleEvent);
     window.addEventListener('keydown', handleEvent);
Line 81: Line 82:
  | 1 || mozbrowserbeforekeydown || || Receive event 'mozbrowserbeforekeydown'.
  | 1 || mozbrowserbeforekeydown || || Receive event 'mozbrowserbeforekeydown'.
  |-
  |-
  | 2 || mozbrowserkeydown || ||
  | 2 || mozbrowserafterkeydown || ||
  |-
  |-
  | 3 || mozbrowserbeforekeyup || || Receive event 'mozbrowserbeforekeyup'.
  | 3 || mozbrowserbeforekeyup || || Receive event 'mozbrowserbeforekeyup'.
  |-
  |-
  | 4 || mozbrowserkeyup || ||
  | 4 || mozbrowserafterkeyup || ||
  |}
  |}


Line 92: Line 93:
     window.addEventListener('mozbrowserbeforekeydown', handleEvent);
     window.addEventListener('mozbrowserbeforekeydown', handleEvent);
     window.addEventListener('mozbrowserbeforekeyup', handleEvent);
     window.addEventListener('mozbrowserbeforekeyup', handleEvent);
     window.addEventListener('mozbrowserkeydown', function() { });
     window.addEventListener('mozbrowserafterkeydown', function() { });
     window.addEventListener('mozbrowserkeyup', function() { });
     window.addEventListener('mozbrowserafterkeyup', function() { });
* mozbrowser-embedded iframe
* mozbrowser-embedded iframe
     window.addEventListener('keydown', handleEvent);
     window.addEventListener('keydown', handleEvent);
Line 105: Line 106:
  | 2 || || keydown || Receive event 'keydown'.
  | 2 || || keydown || Receive event 'keydown'.
  |-
  |-
  | 3 || mozbrowserkeydown || ||
  | 3 || mozbrowserafterkeydown || ||
  |-
  |-
  | 4 || mozbrowserbeforekeyup || || Receive event 'mozbrowserbeforekeyup'.
  | 4 || mozbrowserbeforekeyup || || Receive event 'mozbrowserbeforekeyup'.
Line 111: Line 112:
  | 5 || || keyup || Receive event 'keyup'.
  | 5 || || keyup || Receive event 'keyup'.
  |-
  |-
  | 6 || mozbrowserkeyup || ||
  | 6 || mozbrowserafterkeyup || ||
  |}
  |}


==== Scenario APP-ONLY ====
==== Scenario APP-CANCELLED ====
* mozbrowser-embedder iframe
* mozbrowser-embedder iframe
     window.addEventListener('mozbrowserbeforekeydown', function() { });
     window.addEventListener('mozbrowserbeforekeydown', function() { });
     window.addEventListener('mozbrowserbeforekeyup', function() { });
     window.addEventListener('mozbrowserbeforekeyup', function() { });
     window.addEventListener('mozbrowserkeydown', checkAttrAndHandleEvent);
     window.addEventListener('mozbrowserafterkeydown', checkAttrAndHandleEvent);
     window.addEventListener('mozbrowserkeyup', checkAttrAndHandleEvent);
     window.addEventListener('mozbrowserafterkeyup', checkAttrAndHandleEvent);
* mozbrowser-embedded iframe
* mozbrowser-embedded iframe
     window.addEventListener('keydown', handleEventAndPreventDefault);
     window.addEventListener('keydown', handleEventAndPreventDefault);
Line 131: Line 132:
  | 2 || || keydown || Receive event 'keydown'.
  | 2 || || keydown || Receive event 'keydown'.
  |-
  |-
  | 3 || mozbrowserkeydown || ||
  | 3 || mozbrowserafterkeydown || || Receive event 'mozbrowserafterkeydown' with embeddedCancelled equals to 'true'.
  |-
  |-
  | 4 || mozbrowserbeforekeyup || ||
  | 4 || mozbrowserbeforekeyup || ||
Line 137: Line 138:
  | 5 || || keyup || Receive event 'keyup'.
  | 5 || || keyup || Receive event 'keyup'.
  |-
  |-
  | 6 || mozbrowserup || ||
  | 6 || mozbrowserup || || Receive event 'mozbrowserafterkeyup' with embeddedCancelled equals to 'true'.
  |}
  |}


Line 144: Line 145:
     window.addEventListener('mozbrowserbeforekeydown', function() { });
     window.addEventListener('mozbrowserbeforekeydown', function() { });
     window.addEventListener('mozbrowserbeforekeyup', function() { });
     window.addEventListener('mozbrowserbeforekeyup', function() { });
     window.addEventListener('mozbrowserkeydown', checkAttrAndHandleEvent);
     window.addEventListener('mozbrowserafterkeydown', checkAttrAndHandleEvent);
     window.addEventListener('mozbrowserkeyup', checkAttrAndHandleEvent);
     window.addEventListener('mozbrowserafterkeyup', checkAttrAndHandleEvent);
* mozbrowser-embedded iframe
* mozbrowser-embedded iframe
     window.addEventListener('keydown', handleEvent);
     window.addEventListener('keydown', handleEvent);
Line 157: Line 158:
  | 2 || || keydown || Receive event 'keydown'.
  | 2 || || keydown || Receive event 'keydown'.
  |-
  |-
  | 3 || mozbrowserkeydown || || Receive event 'mozbrowserkeydown'.
  | 3 || mozbrowserafterkeydown || || Receive event 'mozbrowserafterkeyup' with embeddedCancelled equals to 'false'.
  |-
  |-
  | 4 || mozbrowserbeforekeyup || ||
  | 4 || mozbrowserbeforekeyup || ||
Line 163: Line 164:
  | 5 || || keyup || Receive event 'keyup'.
  | 5 || || keyup || Receive event 'keyup'.
  |-
  |-
  | 6 || mozbrowserkeyup || || Receive event 'mozbrowserkeyup'.
  | 6 || mozbrowserafterkeyup || || Receive event 'mozbrowserafterkeyup' with embeddedCancelled equals to 'false'.
  |}
  |}


Line 212: Line 213:
|-
|-
! Default action
! Default action
| Set mozbrowserkeydown.embeddedCancelled to false
| Set mozbrowserafterkeydown.embeddedCancelled to false; others defined in http://www.w3.org/TR/DOM-Level-3-Events/#event-type-keydown
|}
|}


==== mozbrowserkeydown ====
==== mozbrowserafterkeydown ====
{| border="1"
{| border="1"
! Type
! Type
Line 284: Line 285:
|-
|-
! Default action
! Default action
| Set mozbrowserkeyup.embeddedCancelled to false
| Set mozbrowserafterkeyup.embeddedCancelled to false; others defined in http://www.w3.org/TR/DOM-Level-3-Events/#event-type-keyup
|}
|}


==== mozbrowserkeyup ====
==== mozbrowserafterkeyup ====
{| border="1"
{| border="1"
! Type
! Type
| mozbrowserkeyup
| mozbrowserafterkeyup
|-
|-
! Interface
! Interface
Line 310: Line 311:
| None
| None
|}
|}
== Related Gaia Changes ==
=== Current Implementation ===
Currently, shell.js filters all hardware key event and wraps them in mozChromeEvent and then dispatch to Gaia System app. In Gaia System app, hardware_buttons.js listens for these low-level `mozChromeEvents`, processes them and generates higher-level events to handle autorepeat on the volume key long presses on Home and Sleep, and the Home+Sleep key combination. Other system app modules should listen for the high-level button events generated by this module.
[[File:Hardware buttons.png|800px|frameless|How hardware buttons handle in B2G currently]]
The low level input events wrapped in mozChromeEvent are:
* home-button-press
* home-button-release
* sleep-button-press
* sleep-button-release
* volume-up-button-press
* volume-up-button-release
* volume-down-button-press
* volume-down-button-release
Hardware Buttons module (hardware_buttons.js) implements a state machine in it. Each state object has a mandatory `process()` method to process incoming low level input events and two optional `enter()` and `exit()` method when enter and exit state. Hardware Buttons module will listen to all low level input events and relay it to current state object to process. An all state transitions happen in `process()` or timer in `enter()` method.
=== Plan of Change ===
In patch of https://bugzilla.mozilla.org/show_bug.cgi?id=989198, Gina will keep both mozChromeEvents and new KeyboardEvents dispatching at the same time. But we only need to listen to one of them in Gaia.
==== Part 1 - Switch to new keyboard event ====
The state objects in hardware_buttons.js and software_button_manager.js all have dependency on low level input event names listed above.
In this part, we stop listening to 'mozChromeEvent' and start listening to 'mozbrowserbeforekeydown', 'mozbrowserbeforekeyup', 'keydown', and 'keyup' event, and do a translation in handleEvent of hardware_buttons.js.
Translations are as follows:
[[File:Mozbrowserkeyxxx translate.png|800px|frameless|center]]
This translation would make sure the original finite state machine in hardware_buttons.js and software_button_manager.js works as usual. All other outer module still listens to custom events generate in hardware_buttons.js (that is, home/sleep/home+sleep/holdhome/holdsleep/wake/volumeup/volumedown). In this part, these four events need to `preventDefault()`. Because we have not implement customization yet, and we should let hardware key handling process just as the same as before.
==== Part 2 - Key event handling customization ====
What needs to be customization?
# System app should decide which key event would propagate to inner iframe or not
# System app should decide how to handle key event when inner iframe did not handle it
Build time customization detail will be discussed later. Default Policy in System App for 'Power', 'Exit', 'VolumeUp', 'VolumeDown':
{| class="wikitable"
|-
! Key  !! Default Policy
|-
| Power || SYSTEM-ONLY
|-
| Exit || SYSTEM-ONLY
|-
| VolumeUp || APP-CANCELLED
|-
| VolumeDown || APP-CANCELLED
|}
Default Policy for other keys are APP-CANCELLED.
There is one more thing to do in this part. We only handle 'Power', 'Exit', 'VolumeUp', 'VolumDown' in part 1. But there will be more 'keys' need to be handled. We'll have to create a key mapping and handling table with customization in this part.
==== Part 3 - Remove all translated low-level input events ====
In this part, we need to refactor both hardware_buttons.js and software_button_manager.js to remove all low-level input event names.  In software_button_manager.js, we should dispatch events the same as new key event (such as mozbrowserbeforekeydown or keydown...etc)
=== Bugs ===
https://bugzilla.mozilla.org/show_bug.cgi?id=1014405
https://bugzilla.mozilla.org/show_bug.cgi?id=1014418
https://bugzilla.mozilla.org/show_bug.cgi?id=1103339
https://bugzilla.mozilla.org/show_bug.cgi?id=1094066
[[Category:Web APIs]]
Confirmed users
23

edits