Refactor keyboard shortcut handling into a behavior
Change-Id: I25687959ba7dab846236af28cdb13786e87dc38e
This commit is contained in:
parent
8949944b03
commit
b272b8711e
63
polygerrit-ui/app/behaviors/keyboard-shortcut-behavior.html
Normal file
63
polygerrit-ui/app/behaviors/keyboard-shortcut-behavior.html
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<link rel="import" href="../bower_components/polymer/polymer.html">
|
||||||
|
<script>
|
||||||
|
(function(window) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var KeyboardShortcutBehavior = {
|
||||||
|
properties: {
|
||||||
|
keyEventTarget: {
|
||||||
|
type: Object,
|
||||||
|
value: function() { return this; },
|
||||||
|
},
|
||||||
|
|
||||||
|
_boundKeyHandler: {
|
||||||
|
type: Function,
|
||||||
|
readonly: true,
|
||||||
|
value: function() { return this._handleKey.bind(this); },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
attached: function() {
|
||||||
|
this.keyEventTarget.addEventListener('keydown', this._boundKeyHandler);
|
||||||
|
},
|
||||||
|
|
||||||
|
detached: function() {
|
||||||
|
this.keyEventTarget.removeEventListener('keydown', this._boundKeyHandler);
|
||||||
|
},
|
||||||
|
|
||||||
|
shouldSupressKeyboardShortcut: function(e) {
|
||||||
|
var getModifierState = e.getModifierState ?
|
||||||
|
e.getModifierState.bind(e) :
|
||||||
|
function() { return false; };
|
||||||
|
var target = e.detail ? e.detail.keyboardEvent : e.target;
|
||||||
|
return getModifierState('Control') ||
|
||||||
|
getModifierState('Alt') ||
|
||||||
|
getModifierState('Meta') ||
|
||||||
|
getModifierState('Fn') ||
|
||||||
|
target.tagName == 'INPUT' ||
|
||||||
|
target.tagName == 'TEXTAREA' ||
|
||||||
|
target.tagName == 'SELECT' ||
|
||||||
|
target.tagName == 'BUTTON' ||
|
||||||
|
target.tagName == 'A';
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
window.Gerrit = window.Gerrit || {};
|
||||||
|
window.Gerrit.KeyboardShortcutBehavior = KeyboardShortcutBehavior;
|
||||||
|
})(window);
|
||||||
|
</script>
|
@ -15,6 +15,7 @@ limitations under the License.
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<link rel="import" href="../bower_components/polymer/polymer.html">
|
<link rel="import" href="../bower_components/polymer/polymer.html">
|
||||||
|
<link rel="import" href="../behaviors/keyboard-shortcut-behavior.html">
|
||||||
<link rel="import" href="../styles/gr-change-list-styles.html">
|
<link rel="import" href="../styles/gr-change-list-styles.html">
|
||||||
<link rel="import" href="gr-change-list-item.html">
|
<link rel="import" href="gr-change-list-item.html">
|
||||||
|
|
||||||
@ -114,19 +115,13 @@ limitations under the License.
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
value: false,
|
value: false,
|
||||||
},
|
},
|
||||||
_boundKeyHandler: {
|
keyEventTarget: {
|
||||||
type: Function,
|
type: Object,
|
||||||
value: function() { return this._handleKey.bind(this); },
|
value: function() { return document.body; },
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
attached: function() {
|
behaviors: [ Gerrit.KeyboardShortcutBehavior ],
|
||||||
document.body.addEventListener('keydown', this._boundKeyHandler);
|
|
||||||
},
|
|
||||||
|
|
||||||
detached: function() {
|
|
||||||
document.body.removeEventListener('keydown', this._boundKeyHandler);
|
|
||||||
},
|
|
||||||
|
|
||||||
_computeLabelNames: function(groups) {
|
_computeLabelNames: function(groups) {
|
||||||
var labels = [];
|
var labels = [];
|
||||||
@ -168,7 +163,7 @@ limitations under the License.
|
|||||||
},
|
},
|
||||||
|
|
||||||
_handleKey: function(e) {
|
_handleKey: function(e) {
|
||||||
if (util.shouldSupressKeyboardShortcut(e)) { return; }
|
if (this.shouldSupressKeyboardShortcut(e)) { return; }
|
||||||
|
|
||||||
if (this.groups == null) { return; }
|
if (this.groups == null) { return; }
|
||||||
var len = 0;
|
var len = 0;
|
||||||
|
@ -15,6 +15,7 @@ limitations under the License.
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<link rel="import" href="../bower_components/polymer/polymer.html">
|
<link rel="import" href="../bower_components/polymer/polymer.html">
|
||||||
|
<link rel="import" href="../behaviors/keyboard-shortcut-behavior.html">
|
||||||
<link rel="import" href="../behaviors/rest-client-behavior.html">
|
<link rel="import" href="../behaviors/rest-client-behavior.html">
|
||||||
<link rel="import" href="gr-account-link.html">
|
<link rel="import" href="gr-account-link.html">
|
||||||
<link rel="import" href="gr-ajax.html">
|
<link rel="import" href="gr-ajax.html">
|
||||||
@ -292,6 +293,10 @@ limitations under the License.
|
|||||||
value: function() { return {}; },
|
value: function() { return {}; },
|
||||||
},
|
},
|
||||||
serverConfig: Object,
|
serverConfig: Object,
|
||||||
|
keyEventTarget: {
|
||||||
|
type: Object,
|
||||||
|
value: function() { return document.body; },
|
||||||
|
},
|
||||||
|
|
||||||
_comments: Object,
|
_comments: Object,
|
||||||
_change: {
|
_change: {
|
||||||
@ -317,13 +322,12 @@ limitations under the License.
|
|||||||
type: Function,
|
type: Function,
|
||||||
value: function() { return this._handleBodyScroll.bind(this); },
|
value: function() { return this._handleBodyScroll.bind(this); },
|
||||||
},
|
},
|
||||||
_boundKeyHandler: {
|
|
||||||
type: Function,
|
|
||||||
value: function() { return this._handleKey.bind(this); },
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
behaviors: [ Gerrit.RESTClientBehavior ],
|
behaviors: [
|
||||||
|
Gerrit.KeyboardShortcutBehavior,
|
||||||
|
Gerrit.RESTClientBehavior,
|
||||||
|
],
|
||||||
|
|
||||||
ready: function() {
|
ready: function() {
|
||||||
app.accountReady.then(function() {
|
app.accountReady.then(function() {
|
||||||
@ -334,12 +338,10 @@ limitations under the License.
|
|||||||
|
|
||||||
attached: function() {
|
attached: function() {
|
||||||
window.addEventListener('scroll', this._boundScrollHandler);
|
window.addEventListener('scroll', this._boundScrollHandler);
|
||||||
document.body.addEventListener('keydown', this._boundKeyHandler);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
detached: function() {
|
detached: function() {
|
||||||
window.removeEventListener('scroll', this._boundScrollHandler);
|
window.removeEventListener('scroll', this._boundScrollHandler);
|
||||||
document.body.removeEventListener('keydown', this._boundKeyHandler);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_handleBodyScroll: function(e) {
|
_handleBodyScroll: function(e) {
|
||||||
@ -515,7 +517,7 @@ limitations under the License.
|
|||||||
},
|
},
|
||||||
|
|
||||||
_handleKey: function(e) {
|
_handleKey: function(e) {
|
||||||
if (util.shouldSupressKeyboardShortcut(e)) { return; }
|
if (this.shouldSupressKeyboardShortcut(e)) { return; }
|
||||||
|
|
||||||
switch(e.keyCode) {
|
switch(e.keyCode) {
|
||||||
case 65: // 'a'
|
case 65: // 'a'
|
||||||
|
@ -16,6 +16,7 @@ limitations under the License.
|
|||||||
|
|
||||||
<link rel="import" href="../bower_components/polymer/polymer.html">
|
<link rel="import" href="../bower_components/polymer/polymer.html">
|
||||||
<link rel="import" href="../bower_components/iron-dropdown/iron-dropdown.html">
|
<link rel="import" href="../bower_components/iron-dropdown/iron-dropdown.html">
|
||||||
|
<link rel="import" href="../behaviors/keyboard-shortcut-behavior.html">
|
||||||
<link rel="import" href="../behaviors/rest-client-behavior.html">
|
<link rel="import" href="../behaviors/rest-client-behavior.html">
|
||||||
<link rel="import" href="gr-ajax.html">
|
<link rel="import" href="gr-ajax.html">
|
||||||
<link rel="import" href="gr-diff.html">
|
<link rel="import" href="gr-diff.html">
|
||||||
@ -156,6 +157,11 @@ limitations under the License.
|
|||||||
type: Object,
|
type: Object,
|
||||||
observer: '_paramsChanged',
|
observer: '_paramsChanged',
|
||||||
},
|
},
|
||||||
|
keyEventTarget: {
|
||||||
|
type: Object,
|
||||||
|
value: function() { return document.body; },
|
||||||
|
},
|
||||||
|
|
||||||
_patchRange: Object,
|
_patchRange: Object,
|
||||||
_change: Object,
|
_change: Object,
|
||||||
_changeNum: String,
|
_changeNum: String,
|
||||||
@ -165,37 +171,31 @@ limitations under the License.
|
|||||||
value: function() { return []; },
|
value: function() { return []; },
|
||||||
},
|
},
|
||||||
_path: String,
|
_path: String,
|
||||||
_boundKeyHandler: {
|
|
||||||
type: Function,
|
|
||||||
value: function() { return this._handleKey.bind(this); },
|
|
||||||
},
|
|
||||||
_loggedIn: {
|
_loggedIn: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
value: false,
|
value: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
behaviors: [
|
||||||
|
Gerrit.KeyboardShortcutBehavior,
|
||||||
|
Gerrit.RESTClientBehavior,
|
||||||
|
],
|
||||||
|
|
||||||
ready: function() {
|
ready: function() {
|
||||||
app.accountReady.then(function() {
|
app.accountReady.then(function() {
|
||||||
this._loggedIn = app.loggedIn;
|
this._loggedIn = app.loggedIn;
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
behaviors: [ Gerrit.RESTClientBehavior ],
|
|
||||||
|
|
||||||
attached: function() {
|
attached: function() {
|
||||||
if (this._path) {
|
if (this._path) {
|
||||||
this.fire('title-change', {title: this._path});
|
this.fire('title-change', {title: this._path});
|
||||||
}
|
}
|
||||||
document.body.addEventListener('keydown', this._boundKeyHandler);
|
|
||||||
},
|
|
||||||
|
|
||||||
detached: function() {
|
|
||||||
document.body.removeEventListener('keydown', this._boundKeyHandler);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_handleKey: function(e) {
|
_handleKey: function(e) {
|
||||||
if (util.shouldSupressKeyboardShortcut(e)) { return; }
|
if (this.shouldSupressKeyboardShortcut(e)) { return; }
|
||||||
|
|
||||||
switch(e.keyCode) {
|
switch(e.keyCode) {
|
||||||
case 219: // '['
|
case 219: // '['
|
||||||
|
@ -15,6 +15,7 @@ limitations under the License.
|
|||||||
-->
|
-->
|
||||||
|
|
||||||
<link rel="import" href="../bower_components/polymer/polymer.html">
|
<link rel="import" href="../bower_components/polymer/polymer.html">
|
||||||
|
<link rel="import" href="../behaviors/keyboard-shortcut-behavior.html">
|
||||||
<link rel="import" href="../behaviors/rest-client-behavior.html">
|
<link rel="import" href="../behaviors/rest-client-behavior.html">
|
||||||
<link rel="import" href="gr-ajax.html">
|
<link rel="import" href="gr-ajax.html">
|
||||||
|
|
||||||
@ -112,23 +113,18 @@ limitations under the License.
|
|||||||
type: Number,
|
type: Number,
|
||||||
notify: true,
|
notify: true,
|
||||||
},
|
},
|
||||||
|
keyEventTarget: {
|
||||||
|
type: Object,
|
||||||
|
value: function() { return document.body; },
|
||||||
|
},
|
||||||
|
|
||||||
_drafts: Object,
|
_drafts: Object,
|
||||||
_boundKeyHandler: {
|
|
||||||
type: Function,
|
|
||||||
value: function() { return this._handleKey.bind(this); },
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
behaviors: [ Gerrit.RESTClientBehavior ],
|
behaviors: [
|
||||||
|
Gerrit.KeyboardShortcutBehavior,
|
||||||
attached: function() {
|
Gerrit.RESTClientBehavior,
|
||||||
document.body.addEventListener('keydown', this._boundKeyHandler);
|
],
|
||||||
},
|
|
||||||
|
|
||||||
detached: function() {
|
|
||||||
document.body.removeEventListener('keydown', this._boundKeyHandler);
|
|
||||||
},
|
|
||||||
|
|
||||||
reload: function() {
|
reload: function() {
|
||||||
if (!this.changeNum || !this.patchNum) {
|
if (!this.changeNum || !this.patchNum) {
|
||||||
@ -183,7 +179,7 @@ limitations under the License.
|
|||||||
},
|
},
|
||||||
|
|
||||||
_handleKey: function(e) {
|
_handleKey: function(e) {
|
||||||
if (util.shouldSupressKeyboardShortcut(e)) { return; }
|
if (this.shouldSupressKeyboardShortcut(e)) { return; }
|
||||||
|
|
||||||
switch(e.keyCode) {
|
switch(e.keyCode) {
|
||||||
case 74: // 'j'
|
case 74: // 'j'
|
||||||
|
@ -16,6 +16,7 @@ limitations under the License.
|
|||||||
|
|
||||||
<link rel="import" href="../bower_components/polymer/polymer.html">
|
<link rel="import" href="../bower_components/polymer/polymer.html">
|
||||||
<link rel="import" href="../bower_components/iron-input/iron-input.html">
|
<link rel="import" href="../bower_components/iron-input/iron-input.html">
|
||||||
|
<link rel="import" href="../behaviors/keyboard-shortcut-behavior.html">
|
||||||
<link rel="import" href="gr-ajax.html">
|
<link rel="import" href="gr-ajax.html">
|
||||||
<link rel="import" href="gr-request.html">
|
<link rel="import" href="gr-request.html">
|
||||||
|
|
||||||
@ -173,26 +174,19 @@ limitations under the License.
|
|||||||
return this._handleBodyClick.bind(this);
|
return this._handleBodyClick.bind(this);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
_boundKeyHandler: {
|
|
||||||
type: Function,
|
|
||||||
value: function() { return this._handleKey.bind(this); },
|
|
||||||
},
|
|
||||||
|
|
||||||
// Used for testing.
|
// Used for testing.
|
||||||
_lastAutocompleteRequest: Object,
|
_lastAutocompleteRequest: Object,
|
||||||
_xhrPromise: Object,
|
_xhrPromise: Object,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
behaviors: [ Gerrit.KeyboardShortcutBehavior ],
|
||||||
|
|
||||||
observers: [
|
observers: [
|
||||||
'_reviewersChanged(change.reviewers.*, change.owner)',
|
'_reviewersChanged(change.reviewers.*, change.owner)',
|
||||||
],
|
],
|
||||||
|
|
||||||
attached: function() {
|
|
||||||
this.addEventListener('keydown', this._boundKeyHandler);
|
|
||||||
},
|
|
||||||
|
|
||||||
detached: function() {
|
detached: function() {
|
||||||
this.removeEventListener('keydown', this._boundKeyHandler);
|
|
||||||
this._clearInputRequestHandle();
|
this._clearInputRequestHandle();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ limitations under the License.
|
|||||||
|
|
||||||
<link rel="import" href="../bower_components/polymer/polymer.html">
|
<link rel="import" href="../bower_components/polymer/polymer.html">
|
||||||
<link rel="import" href="../bower_components/iron-input/iron-input.html">
|
<link rel="import" href="../bower_components/iron-input/iron-input.html">
|
||||||
|
<link rel="import" href="../behaviors/keyboard-shortcut-behavior.html">
|
||||||
|
|
||||||
<dom-module id="gr-search-bar">
|
<dom-module id="gr-search-bar">
|
||||||
<template>
|
<template>
|
||||||
@ -55,6 +56,8 @@ limitations under the License.
|
|||||||
Polymer({
|
Polymer({
|
||||||
is: 'gr-search-bar',
|
is: 'gr-search-bar',
|
||||||
|
|
||||||
|
behaviors: [ Gerrit.KeyboardShortcutBehavior ],
|
||||||
|
|
||||||
listeners: {
|
listeners: {
|
||||||
'searchInput.keydown': '_inputKeyDownHandler',
|
'searchInput.keydown': '_inputKeyDownHandler',
|
||||||
'searchButton.tap': '_preventDefaultAndNavigateToInputVal',
|
'searchButton.tap': '_preventDefaultAndNavigateToInputVal',
|
||||||
@ -67,20 +70,12 @@ limitations under the License.
|
|||||||
notify: true,
|
notify: true,
|
||||||
observer: '_valueChanged',
|
observer: '_valueChanged',
|
||||||
},
|
},
|
||||||
|
keyEventTarget: {
|
||||||
|
type: Object,
|
||||||
|
value: function() { return document.body; },
|
||||||
|
},
|
||||||
|
|
||||||
_inputVal: String,
|
_inputVal: String,
|
||||||
_boundKeyHandler: {
|
|
||||||
type: Function,
|
|
||||||
value: function() { return this._handleKey.bind(this); },
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
attached: function() {
|
|
||||||
document.body.addEventListener('keydown', this._boundKeyHandler);
|
|
||||||
},
|
|
||||||
|
|
||||||
detached: function() {
|
|
||||||
document.body.removeEventListener('keydown', this._boundKeyHandler);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_valueChanged: function(value) {
|
_valueChanged: function(value) {
|
||||||
@ -100,7 +95,7 @@ limitations under the License.
|
|||||||
},
|
},
|
||||||
|
|
||||||
_handleKey: function(e) {
|
_handleKey: function(e) {
|
||||||
if (util.shouldSupressKeyboardShortcut(e)) { return; }
|
if (this.shouldSupressKeyboardShortcut(e)) { return; }
|
||||||
switch(e.keyCode) {
|
switch(e.keyCode) {
|
||||||
case 191: // '/'
|
case 191: // '/'
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -39,22 +39,6 @@ util.escapeHTML = function(str) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
util.shouldSupressKeyboardShortcut = function(e) {
|
|
||||||
var getModifierState = e.getModifierState ?
|
|
||||||
e.getModifierState.bind(e) :
|
|
||||||
function() { return false; };
|
|
||||||
var target = e.detail ? e.detail.keyboardEvent : e.target;
|
|
||||||
return getModifierState('Control') ||
|
|
||||||
getModifierState('Alt') ||
|
|
||||||
getModifierState('Meta') ||
|
|
||||||
getModifierState('Fn') ||
|
|
||||||
target.tagName == 'INPUT' ||
|
|
||||||
target.tagName == 'TEXTAREA' ||
|
|
||||||
target.tagName == 'SELECT' ||
|
|
||||||
target.tagName == 'BUTTON' ||
|
|
||||||
target.tagName == 'A';
|
|
||||||
};
|
|
||||||
|
|
||||||
util.getCookie = function(name) {
|
util.getCookie = function(name) {
|
||||||
var key = name + '=';
|
var key = name + '=';
|
||||||
var cookies = document.cookie.split(';');
|
var cookies = document.cookie.split(';');
|
||||||
|
Loading…
Reference in New Issue
Block a user