Refactor keyboard shortcut handling into a behavior
Change-Id: I25687959ba7dab846236af28cdb13786e87dc38e
This commit is contained in:
		
							
								
								
									
										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="../behaviors/keyboard-shortcut-behavior.html"> | ||||
| <link rel="import" href="../styles/gr-change-list-styles.html"> | ||||
| <link rel="import" href="gr-change-list-item.html"> | ||||
|  | ||||
| @@ -114,19 +115,13 @@ limitations under the License. | ||||
|           type: Boolean, | ||||
|           value: false, | ||||
|         }, | ||||
|         _boundKeyHandler: { | ||||
|           type: Function, | ||||
|           value: function() { return this._handleKey.bind(this); }, | ||||
|         } | ||||
|         keyEventTarget: { | ||||
|           type: Object, | ||||
|           value: function() { return document.body; }, | ||||
|         }, | ||||
|       }, | ||||
|  | ||||
|       attached: function() { | ||||
|         document.body.addEventListener('keydown', this._boundKeyHandler); | ||||
|       }, | ||||
|  | ||||
|       detached: function() { | ||||
|         document.body.removeEventListener('keydown', this._boundKeyHandler); | ||||
|       }, | ||||
|       behaviors: [ Gerrit.KeyboardShortcutBehavior ], | ||||
|  | ||||
|       _computeLabelNames: function(groups) { | ||||
|         var labels = []; | ||||
| @@ -168,7 +163,7 @@ limitations under the License. | ||||
|       }, | ||||
|  | ||||
|       _handleKey: function(e) { | ||||
|         if (util.shouldSupressKeyboardShortcut(e)) { return; } | ||||
|         if (this.shouldSupressKeyboardShortcut(e)) { return; } | ||||
|  | ||||
|         if (this.groups == null) { return; } | ||||
|         var len = 0; | ||||
|   | ||||
| @@ -15,6 +15,7 @@ limitations under the License. | ||||
| --> | ||||
|  | ||||
| <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="gr-account-link.html"> | ||||
| <link rel="import" href="gr-ajax.html"> | ||||
| @@ -292,6 +293,10 @@ limitations under the License. | ||||
|           value: function() { return {}; }, | ||||
|         }, | ||||
|         serverConfig: Object, | ||||
|         keyEventTarget: { | ||||
|           type: Object, | ||||
|           value: function() { return document.body; }, | ||||
|         }, | ||||
|  | ||||
|         _comments: Object, | ||||
|         _change: { | ||||
| @@ -317,13 +322,12 @@ limitations under the License. | ||||
|           type: Function, | ||||
|           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() { | ||||
|         app.accountReady.then(function() { | ||||
| @@ -334,12 +338,10 @@ limitations under the License. | ||||
|  | ||||
|       attached: function() { | ||||
|         window.addEventListener('scroll', this._boundScrollHandler); | ||||
|         document.body.addEventListener('keydown', this._boundKeyHandler); | ||||
|       }, | ||||
|  | ||||
|       detached: function() { | ||||
|         window.removeEventListener('scroll', this._boundScrollHandler); | ||||
|         document.body.removeEventListener('keydown', this._boundKeyHandler); | ||||
|       }, | ||||
|  | ||||
|       _handleBodyScroll: function(e) { | ||||
| @@ -515,7 +517,7 @@ limitations under the License. | ||||
|       }, | ||||
|  | ||||
|       _handleKey: function(e) { | ||||
|         if (util.shouldSupressKeyboardShortcut(e)) { return; } | ||||
|         if (this.shouldSupressKeyboardShortcut(e)) { return; } | ||||
|  | ||||
|         switch(e.keyCode) { | ||||
|           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/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="gr-ajax.html"> | ||||
| <link rel="import" href="gr-diff.html"> | ||||
| @@ -156,6 +157,11 @@ limitations under the License. | ||||
|           type: Object, | ||||
|           observer: '_paramsChanged', | ||||
|         }, | ||||
|         keyEventTarget: { | ||||
|           type: Object, | ||||
|           value: function() { return document.body; }, | ||||
|         }, | ||||
|  | ||||
|         _patchRange: Object, | ||||
|         _change: Object, | ||||
|         _changeNum: String, | ||||
| @@ -165,37 +171,31 @@ limitations under the License. | ||||
|           value: function() { return []; }, | ||||
|         }, | ||||
|         _path: String, | ||||
|         _boundKeyHandler: { | ||||
|           type: Function, | ||||
|           value: function() { return this._handleKey.bind(this); }, | ||||
|         }, | ||||
|         _loggedIn: { | ||||
|           type: Boolean, | ||||
|           value: false, | ||||
|         }, | ||||
|       }, | ||||
|  | ||||
|       behaviors: [ | ||||
|         Gerrit.KeyboardShortcutBehavior, | ||||
|         Gerrit.RESTClientBehavior, | ||||
|       ], | ||||
|  | ||||
|       ready: function() { | ||||
|         app.accountReady.then(function() { | ||||
|           this._loggedIn = app.loggedIn; | ||||
|         }.bind(this)); | ||||
|       }, | ||||
|  | ||||
|       behaviors: [ Gerrit.RESTClientBehavior ], | ||||
|  | ||||
|       attached: function() { | ||||
|         if (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) { | ||||
|         if (util.shouldSupressKeyboardShortcut(e)) { return; } | ||||
|         if (this.shouldSupressKeyboardShortcut(e)) { return; } | ||||
|  | ||||
|         switch(e.keyCode) { | ||||
|           case 219:  // '[' | ||||
|   | ||||
| @@ -15,6 +15,7 @@ limitations under the License. | ||||
| --> | ||||
|  | ||||
| <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="gr-ajax.html"> | ||||
|  | ||||
| @@ -112,23 +113,18 @@ limitations under the License. | ||||
|           type: Number, | ||||
|           notify: true, | ||||
|         }, | ||||
|         keyEventTarget: { | ||||
|           type: Object, | ||||
|           value: function() { return document.body; }, | ||||
|         }, | ||||
|  | ||||
|         _drafts: Object, | ||||
|         _boundKeyHandler: { | ||||
|           type: Function, | ||||
|           value: function() { return this._handleKey.bind(this); }, | ||||
|         } | ||||
|       }, | ||||
|  | ||||
|       behaviors: [ Gerrit.RESTClientBehavior ], | ||||
|  | ||||
|       attached: function() { | ||||
|         document.body.addEventListener('keydown', this._boundKeyHandler); | ||||
|       }, | ||||
|  | ||||
|       detached: function() { | ||||
|         document.body.removeEventListener('keydown', this._boundKeyHandler); | ||||
|       }, | ||||
|       behaviors: [ | ||||
|         Gerrit.KeyboardShortcutBehavior, | ||||
|         Gerrit.RESTClientBehavior, | ||||
|       ], | ||||
|  | ||||
|       reload: function() { | ||||
|         if (!this.changeNum || !this.patchNum) { | ||||
| @@ -183,7 +179,7 @@ limitations under the License. | ||||
|       }, | ||||
|  | ||||
|       _handleKey: function(e) { | ||||
|         if (util.shouldSupressKeyboardShortcut(e)) { return; } | ||||
|         if (this.shouldSupressKeyboardShortcut(e)) { return; } | ||||
|  | ||||
|         switch(e.keyCode) { | ||||
|           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/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-request.html"> | ||||
|  | ||||
| @@ -173,26 +174,19 @@ limitations under the License. | ||||
|             return this._handleBodyClick.bind(this); | ||||
|           }, | ||||
|         }, | ||||
|         _boundKeyHandler: { | ||||
|           type: Function, | ||||
|           value: function() { return this._handleKey.bind(this); }, | ||||
|         }, | ||||
|  | ||||
|         // Used for testing. | ||||
|         _lastAutocompleteRequest: Object, | ||||
|         _xhrPromise: Object, | ||||
|       }, | ||||
|  | ||||
|       behaviors: [ Gerrit.KeyboardShortcutBehavior ], | ||||
|  | ||||
|       observers: [ | ||||
|         '_reviewersChanged(change.reviewers.*, change.owner)', | ||||
|       ], | ||||
|  | ||||
|       attached: function() { | ||||
|         this.addEventListener('keydown', this._boundKeyHandler); | ||||
|       }, | ||||
|  | ||||
|       detached: function() { | ||||
|         this.removeEventListener('keydown', this._boundKeyHandler); | ||||
|         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/iron-input/iron-input.html"> | ||||
| <link rel="import" href="../behaviors/keyboard-shortcut-behavior.html"> | ||||
|  | ||||
| <dom-module id="gr-search-bar"> | ||||
|   <template> | ||||
| @@ -55,6 +56,8 @@ limitations under the License. | ||||
|     Polymer({ | ||||
|       is: 'gr-search-bar', | ||||
|  | ||||
|       behaviors: [ Gerrit.KeyboardShortcutBehavior ], | ||||
|  | ||||
|       listeners: { | ||||
|         'searchInput.keydown': '_inputKeyDownHandler', | ||||
|         'searchButton.tap': '_preventDefaultAndNavigateToInputVal', | ||||
| @@ -67,20 +70,12 @@ limitations under the License. | ||||
|           notify: true, | ||||
|           observer: '_valueChanged', | ||||
|         }, | ||||
|         keyEventTarget: { | ||||
|           type: Object, | ||||
|           value: function() { return document.body; }, | ||||
|         }, | ||||
|  | ||||
|         _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) { | ||||
| @@ -100,7 +95,7 @@ limitations under the License. | ||||
|       }, | ||||
|  | ||||
|       _handleKey: function(e) { | ||||
|         if (util.shouldSupressKeyboardShortcut(e)) { return; } | ||||
|         if (this.shouldSupressKeyboardShortcut(e)) { return; } | ||||
|         switch(e.keyCode) { | ||||
|           case 191:  // '/' | ||||
|             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) { | ||||
|   var key = name + '='; | ||||
|   var cookies = document.cookie.split(';'); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Andrew Bonventre
					Andrew Bonventre