| 334 | // This generates and installs a nested key-to-command mapping structure. There is an example in |
| 335 | // mode_key_handler.js. |
| 336 | async installKeyStateMapping() { |
| 337 | const keyStateMapping = {}; |
| 338 | for (const keys of Object.keys(this.keyToRegistryEntry || {})) { |
| 339 | const registryEntry = this.keyToRegistryEntry[keys]; |
| 340 | let currentMapping = keyStateMapping; |
| 341 | for (let index = 0; index < registryEntry.keySequence.length; index++) { |
| 342 | const key = registryEntry.keySequence[index]; |
| 343 | if (currentMapping[key] != null ? currentMapping[key].command : undefined) { |
| 344 | // Do not overwrite existing command bindings, they take priority. NOTE(smblott) This is |
| 345 | // the legacy behaviour. |
| 346 | break; |
| 347 | } else if (index < (registryEntry.keySequence.length - 1)) { |
| 348 | currentMapping = currentMapping[key] != null |
| 349 | ? currentMapping[key] |
| 350 | : (currentMapping[key] = {}); |
| 351 | } else { |
| 352 | currentMapping[key] = Object.assign({}, registryEntry); |
| 353 | // We don't need these properties in the content scripts. |
| 354 | for (const prop of ["keySequence"]) { |
| 355 | delete currentMapping[key][prop]; |
| 356 | } |
| 357 | } |
| 358 | } |
| 359 | } |
| 360 | await chrome.storage.session.set({ |
| 361 | normalModeKeyStateMapping: keyStateMapping, |
| 362 | // Inform `KeyboardUtils.isEscape()` whether `<c-[>` should be interpreted as `Escape` (which it |
| 363 | // is by default). |
| 364 | useVimLikeEscape: !("<c-[>" in keyStateMapping), |
| 365 | }); |
| 366 | }, |
| 367 | |
| 368 | // Build the "commandToOptionsToKeys" data structure and place it in chrome's session storage. |
| 369 | // This is used by the help page and commands listing. |