/**
 * @license
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*

How to Add a Keyboard Shortcut
==============================

A keyboard shortcut is composed of the following parts:

  1. A semantic identifier (e.g. OPEN_CHANGE, NEXT_PAGE)
  2. Documentation for the keyboard shortcut help dialog
  3. A binding between key combos and the semantic identifier
  4. A binding between the semantic identifier and a listener

Parts (1) and (2) for all shortcuts are defined in this file. The semantic
identifier is declared in the Shortcut enum near the head of this script:

  const Shortcut = {
    // ...
    TOGGLE_LEFT_PANE: 'TOGGLE_LEFT_PANE',
    // ...
  };

Immediately following the Shortcut enum definition, there is a _describe
function defined which is then invoked many times to populate the help dialog.
Add a new invocation here to document the shortcut:

  _describe(Shortcut.TOGGLE_LEFT_PANE, ShortcutSection.DIFFS,
      'Hide/show left diff');

When an attached view binds one or more key combos to this shortcut, the help
dialog will display this text in the given section (in this case, "Diffs"). See
the ShortcutSection enum immediately below for the list of supported sections.

Part (3), the actual key bindings, are declared by gr-app. In the future, this
system may be expanded to allow key binding customizations by plugins or user
preferences. Key bindings are defined in the following forms:

  // Ordinary shortcut with a single binding.
  this.bindShortcut(
      this.Shortcut.TOGGLE_LEFT_PANE, 'shift+a');

  // Ordinary shortcut with multiple bindings.
  this.bindShortcut(
      this.Shortcut.CURSOR_NEXT_FILE, 'j', 'down');

  // A "go-key" keyboard shortcut, which is combined with a previously and
  // continuously pressed "go" key (the go-key is hard-coded as 'g').
  this.bindShortcut(
      this.Shortcut.GO_TO_OPENED_CHANGES, this.GO_KEY, 'o');

  // A "doc-only" keyboard shortcut. This declares the key-binding for help
  // dialog purposes, but doesn't actually implement the binding. It is up
  // to some element to implement this binding using iron-a11y-keys-behavior's
  // keyBindings property.
  this.bindShortcut(
      this.Shortcut.EXPAND_ALL_COMMENT_THREADS, this.DOC_ONLY, 'e');

Part (4), the listener definitions, are declared by the view or element that
implements the shortcut behavior. This is done by implementing a method named
keyboardShortcuts() in an element that mixes in this behavior, returning an
object that maps semantic identifiers (as property names) to listener method
names, like this:

  keyboardShortcuts() {
    return {
      [this.Shortcut.TOGGLE_LEFT_PANE]: '_handleToggleLeftPane',
    };
  },

You can implement key bindings in an element that is hosted by a view IF that
element is always attached exactly once under that view (e.g. the search bar in
gr-app). When that is not the case, you will have to define a doc-only binding
in gr-app, declare the shortcut in the view that hosts the element, and use
iron-a11y-keys-behavior's keyBindings attribute to implement the binding in the
element. An example of this is in comment threads. A diff view supports actions
on comment threads, but there may be zero or many comment threads attached at
any given point. So the shortcut is declared as doc-only by the diff view and
by gr-app, and actually implemented by gr-comment-thread.

NOTE: doc-only shortcuts will not be customizable in the same way that other
shortcuts are.
*/

import {IronA11yKeysBehavior} from '@polymer/iron-a11y-keys-behavior/iron-a11y-keys-behavior.js';
import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';

const DOC_ONLY = 'DOC_ONLY';
const GO_KEY = 'GO_KEY';

// The maximum age of a keydown event to be used in a jump navigation. This
// is only for cases when the keyup event is lost.
const GO_KEY_TIMEOUT_MS = 1000;

const ShortcutSection = {
  ACTIONS: 'Actions',
  DIFFS: 'Diffs',
  EVERYWHERE: 'Everywhere',
  FILE_LIST: 'File list',
  NAVIGATION: 'Navigation',
  REPLY_DIALOG: 'Reply dialog',
};

const Shortcut = {
  OPEN_SHORTCUT_HELP_DIALOG: 'OPEN_SHORTCUT_HELP_DIALOG',
  GO_TO_USER_DASHBOARD: 'GO_TO_USER_DASHBOARD',
  GO_TO_OPENED_CHANGES: 'GO_TO_OPENED_CHANGES',
  GO_TO_MERGED_CHANGES: 'GO_TO_MERGED_CHANGES',
  GO_TO_ABANDONED_CHANGES: 'GO_TO_ABANDONED_CHANGES',
  GO_TO_WATCHED_CHANGES: 'GO_TO_WATCHED_CHANGES',

  CURSOR_NEXT_CHANGE: 'CURSOR_NEXT_CHANGE',
  CURSOR_PREV_CHANGE: 'CURSOR_PREV_CHANGE',
  OPEN_CHANGE: 'OPEN_CHANGE',
  NEXT_PAGE: 'NEXT_PAGE',
  PREV_PAGE: 'PREV_PAGE',
  TOGGLE_CHANGE_REVIEWED: 'TOGGLE_CHANGE_REVIEWED',
  TOGGLE_CHANGE_STAR: 'TOGGLE_CHANGE_STAR',
  REFRESH_CHANGE_LIST: 'REFRESH_CHANGE_LIST',

  OPEN_REPLY_DIALOG: 'OPEN_REPLY_DIALOG',
  OPEN_DOWNLOAD_DIALOG: 'OPEN_DOWNLOAD_DIALOG',
  EXPAND_ALL_MESSAGES: 'EXPAND_ALL_MESSAGES',
  COLLAPSE_ALL_MESSAGES: 'COLLAPSE_ALL_MESSAGES',
  UP_TO_DASHBOARD: 'UP_TO_DASHBOARD',
  UP_TO_CHANGE: 'UP_TO_CHANGE',
  TOGGLE_DIFF_MODE: 'TOGGLE_DIFF_MODE',
  REFRESH_CHANGE: 'REFRESH_CHANGE',
  EDIT_TOPIC: 'EDIT_TOPIC',

  NEXT_LINE: 'NEXT_LINE',
  PREV_LINE: 'PREV_LINE',
  VISIBLE_LINE: 'VISIBLE_LINE',
  NEXT_CHUNK: 'NEXT_CHUNK',
  PREV_CHUNK: 'PREV_CHUNK',
  EXPAND_ALL_DIFF_CONTEXT: 'EXPAND_ALL_DIFF_CONTEXT',
  NEXT_COMMENT_THREAD: 'NEXT_COMMENT_THREAD',
  PREV_COMMENT_THREAD: 'PREV_COMMENT_THREAD',
  EXPAND_ALL_COMMENT_THREADS: 'EXPAND_ALL_COMMENT_THREADS',
  COLLAPSE_ALL_COMMENT_THREADS: 'COLLAPSE_ALL_COMMENT_THREADS',
  LEFT_PANE: 'LEFT_PANE',
  RIGHT_PANE: 'RIGHT_PANE',
  TOGGLE_LEFT_PANE: 'TOGGLE_LEFT_PANE',
  NEW_COMMENT: 'NEW_COMMENT',
  SAVE_COMMENT: 'SAVE_COMMENT',
  OPEN_DIFF_PREFS: 'OPEN_DIFF_PREFS',
  TOGGLE_DIFF_REVIEWED: 'TOGGLE_DIFF_REVIEWED',

  NEXT_FILE: 'NEXT_FILE',
  PREV_FILE: 'PREV_FILE',
  NEXT_FILE_WITH_COMMENTS: 'NEXT_FILE_WITH_COMMENTS',
  PREV_FILE_WITH_COMMENTS: 'PREV_FILE_WITH_COMMENTS',
  NEXT_UNREVIEWED_FILE: 'NEXT_UNREVIEWED_FILE',
  CURSOR_NEXT_FILE: 'CURSOR_NEXT_FILE',
  CURSOR_PREV_FILE: 'CURSOR_PREV_FILE',
  OPEN_FILE: 'OPEN_FILE',
  TOGGLE_FILE_REVIEWED: 'TOGGLE_FILE_REVIEWED',
  TOGGLE_ALL_INLINE_DIFFS: 'TOGGLE_ALL_INLINE_DIFFS',
  TOGGLE_INLINE_DIFF: 'TOGGLE_INLINE_DIFF',

  OPEN_FIRST_FILE: 'OPEN_FIRST_FILE',
  OPEN_LAST_FILE: 'OPEN_LAST_FILE',

  SEARCH: 'SEARCH',
  SEND_REPLY: 'SEND_REPLY',
  EMOJI_DROPDOWN: 'EMOJI_DROPDOWN',
  TOGGLE_BLAME: 'TOGGLE_BLAME',
};

const _help = new Map();

function _describe(shortcut, section, text) {
  if (!_help.has(section)) {
    _help.set(section, []);
  }
  _help.get(section).push({shortcut, text});
}

_describe(Shortcut.SEARCH, ShortcutSection.EVERYWHERE, 'Search');
_describe(Shortcut.OPEN_SHORTCUT_HELP_DIALOG, ShortcutSection.EVERYWHERE,
    'Show this dialog');
_describe(Shortcut.GO_TO_USER_DASHBOARD, ShortcutSection.EVERYWHERE,
    'Go to User Dashboard');
_describe(Shortcut.GO_TO_OPENED_CHANGES, ShortcutSection.EVERYWHERE,
    'Go to Opened Changes');
_describe(Shortcut.GO_TO_MERGED_CHANGES, ShortcutSection.EVERYWHERE,
    'Go to Merged Changes');
_describe(Shortcut.GO_TO_ABANDONED_CHANGES, ShortcutSection.EVERYWHERE,
    'Go to Abandoned Changes');
_describe(Shortcut.GO_TO_WATCHED_CHANGES, ShortcutSection.EVERYWHERE,
    'Go to Watched Changes');

_describe(Shortcut.CURSOR_NEXT_CHANGE, ShortcutSection.ACTIONS,
    'Select next change');
_describe(Shortcut.CURSOR_PREV_CHANGE, ShortcutSection.ACTIONS,
    'Select previous change');
_describe(Shortcut.OPEN_CHANGE, ShortcutSection.ACTIONS,
    'Show selected change');
_describe(Shortcut.NEXT_PAGE, ShortcutSection.ACTIONS, 'Go to next page');
_describe(Shortcut.PREV_PAGE, ShortcutSection.ACTIONS, 'Go to previous page');
_describe(Shortcut.OPEN_REPLY_DIALOG, ShortcutSection.ACTIONS,
    'Open reply dialog to publish comments and add reviewers');
_describe(Shortcut.OPEN_DOWNLOAD_DIALOG, ShortcutSection.ACTIONS,
    'Open download overlay');
_describe(Shortcut.EXPAND_ALL_MESSAGES, ShortcutSection.ACTIONS,
    'Expand all messages');
_describe(Shortcut.COLLAPSE_ALL_MESSAGES, ShortcutSection.ACTIONS,
    'Collapse all messages');
_describe(Shortcut.REFRESH_CHANGE, ShortcutSection.ACTIONS,
    'Reload the change at the latest patch');
_describe(Shortcut.TOGGLE_CHANGE_REVIEWED, ShortcutSection.ACTIONS,
    'Mark/unmark change as reviewed');
_describe(Shortcut.TOGGLE_FILE_REVIEWED, ShortcutSection.ACTIONS,
    'Toggle review flag on selected file');
_describe(Shortcut.REFRESH_CHANGE_LIST, ShortcutSection.ACTIONS,
    'Refresh list of changes');
_describe(Shortcut.TOGGLE_CHANGE_STAR, ShortcutSection.ACTIONS,
    'Star/unstar change');
_describe(Shortcut.EDIT_TOPIC, ShortcutSection.ACTIONS,
    'Add a change topic');

_describe(Shortcut.NEXT_LINE, ShortcutSection.DIFFS, 'Go to next line');
_describe(Shortcut.PREV_LINE, ShortcutSection.DIFFS, 'Go to previous line');
_describe(Shortcut.VISIBLE_LINE, ShortcutSection.DIFFS,
    'Move cursor to currently visible code');
_describe(Shortcut.NEXT_CHUNK, ShortcutSection.DIFFS,
    'Go to next diff chunk');
_describe(Shortcut.PREV_CHUNK, ShortcutSection.DIFFS,
    'Go to previous diff chunk');
_describe(Shortcut.EXPAND_ALL_DIFF_CONTEXT, ShortcutSection.DIFFS,
    'Expand all diff context');
_describe(Shortcut.NEXT_COMMENT_THREAD, ShortcutSection.DIFFS,
    'Go to next comment thread');
_describe(Shortcut.PREV_COMMENT_THREAD, ShortcutSection.DIFFS,
    'Go to previous comment thread');
_describe(Shortcut.EXPAND_ALL_COMMENT_THREADS, ShortcutSection.DIFFS,
    'Expand all comment threads');
_describe(Shortcut.COLLAPSE_ALL_COMMENT_THREADS, ShortcutSection.DIFFS,
    'Collapse all comment threads');
_describe(Shortcut.LEFT_PANE, ShortcutSection.DIFFS, 'Select left pane');
_describe(Shortcut.RIGHT_PANE, ShortcutSection.DIFFS, 'Select right pane');
_describe(Shortcut.TOGGLE_LEFT_PANE, ShortcutSection.DIFFS,
    'Hide/show left diff');
_describe(Shortcut.NEW_COMMENT, ShortcutSection.DIFFS, 'Draft new comment');
_describe(Shortcut.SAVE_COMMENT, ShortcutSection.DIFFS, 'Save comment');
_describe(Shortcut.OPEN_DIFF_PREFS, ShortcutSection.DIFFS,
    'Show diff preferences');
_describe(Shortcut.TOGGLE_DIFF_REVIEWED, ShortcutSection.DIFFS,
    'Mark/unmark file as reviewed');
_describe(Shortcut.TOGGLE_DIFF_MODE, ShortcutSection.DIFFS,
    'Toggle unified/side-by-side diff');
_describe(Shortcut.NEXT_UNREVIEWED_FILE, ShortcutSection.DIFFS,
    'Mark file as reviewed and go to next unreviewed file');
_describe(Shortcut.TOGGLE_BLAME, ShortcutSection.DIFFS, 'Toggle blame');

_describe(Shortcut.NEXT_FILE, ShortcutSection.NAVIGATION, 'Go to next file');
_describe(Shortcut.PREV_FILE, ShortcutSection.NAVIGATION,
    'Go to previous file');
_describe(Shortcut.NEXT_FILE_WITH_COMMENTS, ShortcutSection.NAVIGATION,
    'Go to next file that has comments');
_describe(Shortcut.PREV_FILE_WITH_COMMENTS, ShortcutSection.NAVIGATION,
    'Go to previous file that has comments');
_describe(Shortcut.OPEN_FIRST_FILE, ShortcutSection.NAVIGATION,
    'Go to first file');
_describe(Shortcut.OPEN_LAST_FILE, ShortcutSection.NAVIGATION,
    'Go to last file');
_describe(Shortcut.UP_TO_DASHBOARD, ShortcutSection.NAVIGATION,
    'Up to dashboard');
_describe(Shortcut.UP_TO_CHANGE, ShortcutSection.NAVIGATION, 'Up to change');

_describe(Shortcut.CURSOR_NEXT_FILE, ShortcutSection.FILE_LIST,
    'Select next file');
_describe(Shortcut.CURSOR_PREV_FILE, ShortcutSection.FILE_LIST,
    'Select previous file');
_describe(Shortcut.OPEN_FILE, ShortcutSection.FILE_LIST,
    'Go to selected file');
_describe(Shortcut.TOGGLE_ALL_INLINE_DIFFS, ShortcutSection.FILE_LIST,
    'Show/hide all inline diffs');
_describe(Shortcut.TOGGLE_INLINE_DIFF, ShortcutSection.FILE_LIST,
    'Show/hide selected inline diff');

_describe(Shortcut.SEND_REPLY, ShortcutSection.REPLY_DIALOG, 'Send reply');
_describe(Shortcut.EMOJI_DROPDOWN, ShortcutSection.REPLY_DIALOG,
    'Emoji dropdown');

// Must be declared outside behavior implementation to be accessed inside
// behavior functions.

/** @return {!(Event|PolymerDomApi|PolymerEventApi)} */
const getKeyboardEvent = function(e) {
  e = dom(e.detail ? e.detail.keyboardEvent : e);
  // When e is a keyboardEvent, e.event is not null.
  if (e.event) { e = e.event; }
  return e;
};

class ShortcutManager {
  constructor() {
    this.activeHosts = new Map();
    this.bindings = new Map();
    this.listeners = new Set();
  }

  bindShortcut(shortcut, ...bindings) {
    this.bindings.set(shortcut, bindings);
  }

  getBindingsForShortcut(shortcut) {
    return this.bindings.get(shortcut);
  }

  attachHost(host) {
    if (!host.keyboardShortcuts) { return; }
    const shortcuts = host.keyboardShortcuts();
    this.activeHosts.set(host, new Map(Object.entries(shortcuts)));
    this.notifyListeners();
    return shortcuts;
  }

  detachHost(host) {
    if (this.activeHosts.delete(host)) {
      this.notifyListeners();
      return true;
    }
    return false;
  }

  addListener(listener) {
    this.listeners.add(listener);
    listener(this.directoryView());
  }

  removeListener(listener) {
    return this.listeners.delete(listener);
  }

  getDescription(section, shortcutName) {
    const binding =
        _help.get(section).find(binding => binding.shortcut == shortcutName);
    return binding ? binding.text : '';
  }

  getShortcut(shortcutName) {
    const binding = this.bindings.get(shortcutName);
    return binding ? this.describeBinding(binding) : '';
  }

  activeShortcutsBySection() {
    const activeShortcuts = new Set();
    this.activeHosts.forEach(shortcuts => {
      shortcuts.forEach((_, shortcut) => activeShortcuts.add(shortcut));
    });

    const activeShortcutsBySection = new Map();
    _help.forEach((shortcutList, section) => {
      shortcutList.forEach(shortcutHelp => {
        if (activeShortcuts.has(shortcutHelp.shortcut)) {
          if (!activeShortcutsBySection.has(section)) {
            activeShortcutsBySection.set(section, []);
          }
          activeShortcutsBySection.get(section).push(shortcutHelp);
        }
      });
    });
    return activeShortcutsBySection;
  }

  directoryView() {
    const view = new Map();
    this.activeShortcutsBySection().forEach((shortcutHelps, section) => {
      const sectionView = [];
      shortcutHelps.forEach(shortcutHelp => {
        const bindingDesc = this.describeBindings(shortcutHelp.shortcut);
        if (!bindingDesc) { return; }
        this.distributeBindingDesc(bindingDesc).forEach(bindingDesc => {
          sectionView.push({
            binding: bindingDesc,
            text: shortcutHelp.text,
          });
        });
      });
      view.set(section, sectionView);
    });
    return view;
  }

  distributeBindingDesc(bindingDesc) {
    if (bindingDesc.length === 1 ||
        this.comboSetDisplayWidth(bindingDesc) < 21) {
      return [bindingDesc];
    }
    // Find the largest prefix of bindings that is under the
    // size threshold.
    const head = [bindingDesc[0]];
    for (let i = 1; i < bindingDesc.length; i++) {
      head.push(bindingDesc[i]);
      if (this.comboSetDisplayWidth(head) >= 21) {
        head.pop();
        return [head].concat(
            this.distributeBindingDesc(bindingDesc.slice(i)));
      }
    }
  }

  comboSetDisplayWidth(bindingDesc) {
    const bindingSizer = binding => binding.reduce(
        (acc, key) => acc + key.length, 0);
    // Width is the sum of strings + (n-1) * 2 to account for the word
    // "or" joining them.
    return bindingDesc.reduce(
        (acc, binding) => acc + bindingSizer(binding), 0) +
        2 * (bindingDesc.length - 1);
  }

  describeBindings(shortcut) {
    const bindings = this.bindings.get(shortcut);
    if (!bindings) { return null; }
    if (bindings[0] === GO_KEY) {
      return [['g'].concat(bindings.slice(1))];
    }
    return bindings
        .filter(binding => binding !== DOC_ONLY)
        .map(binding => this.describeBinding(binding));
  }

  describeBinding(binding) {
    if (binding.length === 1) {
      return [binding];
    }
    return binding.split(':')[0].split('+').map(part => {
      switch (part) {
        case 'shift':
          return 'Shift';
        case 'meta':
          return 'Meta';
        case 'ctrl':
          return 'Ctrl';
        case 'enter':
          return 'Enter';
        case 'up':
          return '↑';
        case 'down':
          return '↓';
        case 'left':
          return '←';
        case 'right':
          return '→';
        default:
          return part;
      }
    });
  }

  notifyListeners() {
    const view = this.directoryView();
    this.listeners.forEach(listener => listener(view));
  }
}

const shortcutManager = new ShortcutManager();

/** @polymerBehavior Gerrit.KeyboardShortcutBehavior*/
export const KeyboardShortcutBehavior = [
  IronA11yKeysBehavior,
  {
    // Exports for convenience. Note: Closure compiler crashes when
    // object-shorthand syntax is used here.
    // eslint-disable-next-line object-shorthand
    DOC_ONLY: DOC_ONLY,
    // eslint-disable-next-line object-shorthand
    GO_KEY: GO_KEY,
    // eslint-disable-next-line object-shorthand
    Shortcut: Shortcut,
    // eslint-disable-next-line object-shorthand
    ShortcutSection: ShortcutSection,

    properties: {
      _shortcut_go_key_last_pressed: {
        type: Number,
        value: null,
      },

      _shortcut_go_table: {
        type: Array,
        value() { return new Map(); },
      },
    },

    modifierPressed(e) {
      e = getKeyboardEvent(e);
      return e.altKey || e.ctrlKey || e.metaKey || e.shiftKey;
    },

    isModifierPressed(e, modifier) {
      return getKeyboardEvent(e)[modifier];
    },

    shouldSuppressKeyboardShortcut(e) {
      e = getKeyboardEvent(e);
      const tagName = dom(e).rootTarget.tagName;
      if (tagName === 'INPUT' || tagName === 'TEXTAREA' ||
          (e.keyCode === 13 && tagName === 'A')) {
        // Suppress shortcuts if the key is 'enter' and target is an anchor.
        return true;
      }
      for (let i = 0; e.path && i < e.path.length; i++) {
        if (e.path[i].tagName === 'GR-OVERLAY') { return true; }
      }

      this.dispatchEvent(new CustomEvent('shortcut-triggered', {
        detail: {
          event: e,
          goKey: this._inGoKeyMode(),
        },
        composed: true, bubbles: true,
      }));
      return false;
    },

    // Alias for getKeyboardEvent.
    /** @return {!Event} */
    getKeyboardEvent(e) {
      return getKeyboardEvent(e);
    },

    getRootTarget(e) {
      return dom(getKeyboardEvent(e)).rootTarget;
    },

    bindShortcut(shortcut, ...bindings) {
      shortcutManager.bindShortcut(shortcut, ...bindings);
    },

    createTitle(shortcutName, section) {
      const desc = shortcutManager.getDescription(section, shortcutName);
      const shortcut = shortcutManager.getShortcut(shortcutName);
      return (desc && shortcut) ? `${desc} (shortcut: ${shortcut})` : '';
    },

    _addOwnKeyBindings(shortcut, handler) {
      const bindings = shortcutManager.getBindingsForShortcut(shortcut);
      if (!bindings) {
        return;
      }
      if (bindings[0] === DOC_ONLY) {
        return;
      }
      if (bindings[0] === GO_KEY) {
        this._shortcut_go_table.set(bindings[1], handler);
      } else {
        this.addOwnKeyBinding(bindings.join(' '), handler);
      }
    },

    /** @override */
    attached() {
      const shortcuts = shortcutManager.attachHost(this);
      if (!shortcuts) { return; }

      for (const key of Object.keys(shortcuts)) {
        this._addOwnKeyBindings(key, shortcuts[key]);
      }

      // If any of the shortcuts utilized GO_KEY, then they are handled
      // directly by this behavior.
      if (this._shortcut_go_table.size > 0) {
        this.addOwnKeyBinding('g:keydown', '_handleGoKeyDown');
        this.addOwnKeyBinding('g:keyup', '_handleGoKeyUp');
        this._shortcut_go_table.forEach((handler, key) => {
          this.addOwnKeyBinding(key, '_handleGoAction');
        });
      }
    },

    /** @override */
    detached() {
      if (shortcutManager.detachHost(this)) {
        this.removeOwnKeyBindings();
      }
    },

    keyboardShortcuts() {
      return {};
    },

    addKeyboardShortcutDirectoryListener(listener) {
      shortcutManager.addListener(listener);
    },

    removeKeyboardShortcutDirectoryListener(listener) {
      shortcutManager.removeListener(listener);
    },

    _handleGoKeyDown(e) {
      if (this.modifierPressed(e)) { return; }
      this._shortcut_go_key_last_pressed = Date.now();
    },

    _handleGoKeyUp(e) {
      this._shortcut_go_key_last_pressed = null;
    },

    _inGoKeyMode() {
      return this._shortcut_go_key_last_pressed &&
          (Date.now() - this._shortcut_go_key_last_pressed <=
              GO_KEY_TIMEOUT_MS);
    },

    _handleGoAction(e) {
      if (!this._inGoKeyMode() ||
          !this._shortcut_go_table.has(e.detail.key) ||
          this.shouldSuppressKeyboardShortcut(e)) {
        return;
      }
      e.preventDefault();
      const handler = this._shortcut_go_table.get(e.detail.key);
      this[handler](e);
    },
  },
];

export const KeyboardShortcutBinder = {
  DOC_ONLY,
  GO_KEY,
  Shortcut,
  ShortcutManager,
  ShortcutSection,

  bindShortcut(shortcut, ...bindings) {
    shortcutManager.bindShortcut(shortcut, ...bindings);
  },
};

// TODO(dmfilippov) Remove the following lines with assignments
// Plugins can use the behavior because it was accessible with
// the global Gerrit... variable. To avoid breaking changes in plugins
// temporary assign global variables.
window.Gerrit = window.Gerrit || {};
window.Gerrit.KeyboardShortcutBehavior = KeyboardShortcutBehavior;
window.Gerrit.KeyboardShortcutBinder = KeyboardShortcutBinder;
