Index: chrome/browser/resources/md_extensions/shortcut_input.js |
diff --git a/chrome/browser/resources/md_extensions/shortcut_input.js b/chrome/browser/resources/md_extensions/shortcut_input.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e32cc6e256f17f76144f45562b478d004ec5d52f |
--- /dev/null |
+++ b/chrome/browser/resources/md_extensions/shortcut_input.js |
@@ -0,0 +1,159 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+cr.define('extensions', function() { |
+ 'use strict'; |
+ |
+ // The UI to display and manage keyboard shortcuts set for extension commands. |
+ var ShortcutInput = Polymer({ |
+ is: 'extensions-shortcut-input', |
+ |
+ properties: { |
+ item: { |
+ type: String, |
+ value: '', |
+ }, |
+ commandName: { |
+ type: String, |
+ value: '', |
+ }, |
+ shortcut: { |
+ type: String, |
+ value: '', |
+ }, |
+ /** @private */ |
+ capturing_: { |
+ type: Boolean, |
+ value: false, |
+ }, |
+ /** @private */ |
+ pendingShortcut_: { |
+ type: String, |
+ value: '', |
+ }, |
+ }, |
+ |
+ behaviors: [I18nBehavior], |
+ |
+ ready: function() { |
+ var node = this.$['input']; |
+ node.addEventListener('mouseup', this.startCapture_.bind(this)); |
+ node.addEventListener('blur', this.endCapture_.bind(this)); |
+ node.addEventListener('focus', this.startCapture_.bind(this)); |
+ node.addEventListener('keydown', this.onKeyDown_.bind(this)); |
+ node.addEventListener('keyup', this.onKeyUp_.bind(this)); |
+ }, |
+ |
+ /** @private */ |
+ startCapture_: function() { |
+ if (this.capturing_) |
+ return; |
+ this.capturing_ = true; |
+ this.fire('shortcut-capture-started'); |
+ }, |
+ |
+ /** @private */ |
+ endCapture_: function() { |
+ if (!this.capturing_) |
+ return; |
+ this.pendingShortcut_ = ''; |
+ this.capturing_ = false; |
+ this.$['input'].blur(); |
+ this.fire('shortcut-capture-ended'); |
+ }, |
+ |
+ /** |
+ * @param {!KeyboardEvent} e |
+ * @private |
+ */ |
+ onKeyDown_: function(e) { |
+ if (e.keyCode == extensions.Key.Escape) { |
+ if (!this.capturing_) { |
+ // If we're not currently capturing, allow escape to propagate. |
+ return; |
+ } |
+ // Otherwise, escape cancels capturing. |
+ this.endCapture_(); |
+ e.preventDefault(); |
+ e.stopPropagation(); |
+ return; |
+ } |
+ if (e.keyCode == extensions.Key.Tab) { |
+ // Allow tab propagation for keyboard navigation. |
+ return; |
+ } |
+ |
+ if (!this.capturing_) |
+ this.startCapture_(); |
+ |
+ this.handleKey_(e); |
+ }, |
+ |
+ /** |
+ * @param {!KeyboardEvent} e |
+ * @private |
+ */ |
+ onKeyUp_: function(e) { |
+ if (e.keyCode == extensions.Key.Escape || e.keyCode == extensions.Key.Tab) |
+ return; |
+ |
+ this.handleKey_(e); |
+ }, |
+ |
+ /** |
+ * @param {!KeyboardEvent} e |
+ * @private |
+ */ |
+ handleKey_: function(e) { |
+ // While capturing, we prevent all events from bubbling, to prevent |
+ // shortcuts lacking the right modifier (F3 for example) from activating |
+ // and ending capture prematurely. |
+ e.preventDefault(); |
+ e.stopPropagation(); |
+ |
+ // We don't allow both Ctrl and Alt in the same keybinding. |
+ // TODO(devlin): This really should go in extensions.hasValidModifiers, |
+ // but that requires updating the existing page as well. |
+ if ((e.ctrlKey && e.altKey) || !extensions.hasValidModifiers(e)) { |
+ this.pendingShortcut_ = 'invalid'; |
+ return; |
+ } |
+ |
+ this.pendingShortcut_ = extensions.keystrokeToString(e); |
+ |
+ if (extensions.isValidKeyCode(e.keyCode)) { |
+ this.commitPending_(); |
+ this.endCapture_(); |
+ } |
+ }, |
+ |
+ /** @private */ |
+ commitPending_: function() { |
+ this.shortcut = this.pendingShortcut_; |
+ this.fire('shortcut-updated', {keybinding: this.shortcut, |
+ item: this.item, |
+ commandName: this.commandName}); |
+ }, |
+ |
+ /** |
+ * @return {string} The text to be displayed in the shortcut field. |
+ * @private |
+ */ |
+ computeText_: function() { |
+ if (this.capturing_) |
+ return this.pendingShortcut_ || this.i18n('shortcutTypeAShortcut'); |
+ return this.shortcut || this.i18n('shortcutNotSet'); |
+ }, |
+ |
+ /** @private */ |
+ onClearTap_: function() { |
+ if (this.shortcut) { |
+ this.pendingShortcut_ = ''; |
+ this.commitPending_(); |
+ } |
+ }, |
+ }); |
+ |
+ return {ShortcutInput: ShortcutInput}; |
+}); |