OLD | NEW |
| (Empty) |
1 <!-- Copyright (c) 2014 The Chromium Authors. All rights reserved. | |
2 Use of this source code is governed by a BSD-style license that can be | |
3 found in the LICENSE file. --> | |
4 | |
5 <!-- | |
6 Use to add keyboard shortcuts to your components. The last inserted componen
t | |
7 will always receive the events (and others will not). This prevents the | |
8 common bug where you have two listeners and multiple actions are taken for | |
9 the same keyboard shortcut. | |
10 | |
11 <cr-keyboard | |
12 on-key-j="{{ forward }}" | |
13 on-key-k="{{ backwards }}" | |
14 on-key-delete="{{ remove }}"></cr-keyboard> | |
15 | |
16 or | |
17 | |
18 keyboard.addEventListener("key-left", previousSlide); | |
19 keyboard.addEventListener("key-right", nextSlide); | |
20 | |
21 The "global" attribute configures this keyboard listener to be a global key | |
22 binding which means the <cr-keyboard> instances is assumed to exist all the | |
23 time but only apply when a non-editable element is focused and no dialogs | |
24 are open. | |
25 --> | |
26 <polymer-element name="cr-keyboard" attributes="global"> | |
27 <template> | |
28 <style> | |
29 :host { display: none; } | |
30 </style> | |
31 </template> | |
32 <script> | |
33 (function() { | |
34 var instances = []; | |
35 | |
36 // TODO(esprehn): Remove once M35 is stable. | |
37 var globalSupported = !navigator.userAgent.contains("Chrome/35."); | |
38 | |
39 Polymer("cr-keyboard", { | |
40 created: function() { | |
41 this.global = false; | |
42 }, | |
43 attached: function() { | |
44 instances.unshift(this); | |
45 }, | |
46 detached: function() { | |
47 var i = instances.indexOf(this); | |
48 if (i >= 0) | |
49 instances.splice(i, 1); | |
50 }, | |
51 isActive: function() { | |
52 if (!this.global) | |
53 return true; | |
54 if (!globalSupported) | |
55 return false; | |
56 // TODO(esprehn): This doesn't support contenteditable, but we d
on't use | |
57 // that yet so there's no need to add the complexity. | |
58 var activeElement = document.querySelector("* /deep/ :focus"); | |
59 if (activeElement && (activeElement.tagName == "INPUT" || active
Element.tagName == "TEXTAREA")) | |
60 return false; | |
61 var activeDialog = document.querySelector("* /deep/ dialog[open]
"); | |
62 if (activeDialog) | |
63 return activeDialog.contains(this); | |
64 return true; | |
65 }, | |
66 }); | |
67 | |
68 var KEY_CODES = { | |
69 8: "delete", | |
70 9: "tab", | |
71 20: "space", | |
72 27: "escape", | |
73 }; | |
74 | |
75 var KEY_NAMES = { | |
76 "!": "exclamation", | |
77 "@": "at", | |
78 "#": "pound", | |
79 "$": "dollar", | |
80 "%": "percent", | |
81 "^": "caret", | |
82 "&": "amp", | |
83 "*": "asterisk", | |
84 "(": "open-paren", | |
85 ")": "close-paren", | |
86 "-": "dash", | |
87 "_": "underscore", | |
88 "+": "plus", | |
89 "=": "equals", | |
90 "{": "open-brace", | |
91 "}": "close-brace", | |
92 "[": "open-bracket", | |
93 "]": "close-bracket", | |
94 "|": "pipe", | |
95 "\\": "backslash", | |
96 "\"": "double-quote", | |
97 "'": "single-quote", | |
98 ";": "semi-colon", | |
99 ":": "colon", | |
100 "?": "question-mark", | |
101 "/": "forward-slash", | |
102 ">": "greater-than", | |
103 ".": "period", | |
104 "<": "less-than", | |
105 "`": "backtick", | |
106 "~": "tilde", | |
107 }; | |
108 | |
109 function convertKey(event) { | |
110 var key = event.keyIdentifier || event.key; | |
111 if (key.indexOf("U+") != -1) { | |
112 var code = parseInt(key.replace("U+", "0x"), 16); | |
113 var chr = String.fromCharCode(code).toLowerCase() | |
114 if (KEY_CODES[code]) | |
115 return KEY_CODES[code]; | |
116 if (KEY_NAMES[chr]) | |
117 return KEY_NAMES[chr]; | |
118 return chr; | |
119 } | |
120 if (KEY_NAMES[key]) | |
121 return KEY_NAMES[key]; | |
122 return key.toLowerCase(); | |
123 } | |
124 | |
125 function handleKeyDown(event) { | |
126 var key = convertKey(event); | |
127 if (!key) | |
128 return; | |
129 var instance = instances.find(function(instance) { | |
130 return instance.isActive() && instance.hasAttribute("on-key-" +
key); | |
131 }); | |
132 if (instance && instance.fire("key-" + key, event).defaultPrevented) | |
133 event.preventDefault(); | |
134 } | |
135 | |
136 window.addEventListener("keydown", handleKeyDown); | |
137 })(); | |
138 </script> | |
139 </polymer-element> | |
OLD | NEW |