epuber 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +6 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +46 -0
  5. data/bin/epuber +10 -0
  6. data/epuber.gemspec +51 -0
  7. data/lib/epuber.rb +14 -0
  8. data/lib/epuber/book.rb +267 -0
  9. data/lib/epuber/book/contributor.rb +90 -0
  10. data/lib/epuber/book/file_request.rb +68 -0
  11. data/lib/epuber/book/target.rb +284 -0
  12. data/lib/epuber/book/toc_item.rb +130 -0
  13. data/lib/epuber/checker.rb +19 -0
  14. data/lib/epuber/checker/text_checker.rb +129 -0
  15. data/lib/epuber/checker_transformer_base.rb +71 -0
  16. data/lib/epuber/command.rb +65 -0
  17. data/lib/epuber/command/compile.rb +142 -0
  18. data/lib/epuber/command/init.rb +145 -0
  19. data/lib/epuber/command/server.rb +59 -0
  20. data/lib/epuber/compiler.rb +255 -0
  21. data/lib/epuber/compiler/compilation_context.rb +86 -0
  22. data/lib/epuber/compiler/file_finders/abstract.rb +270 -0
  23. data/lib/epuber/compiler/file_finders/imaginary.rb +167 -0
  24. data/lib/epuber/compiler/file_finders/normal.rb +22 -0
  25. data/lib/epuber/compiler/file_resolver.rb +316 -0
  26. data/lib/epuber/compiler/file_types/abstract_file.rb +119 -0
  27. data/lib/epuber/compiler/file_types/bade_file.rb +39 -0
  28. data/lib/epuber/compiler/file_types/container_xml_file.rb +26 -0
  29. data/lib/epuber/compiler/file_types/generated_file.rb +29 -0
  30. data/lib/epuber/compiler/file_types/ibooks_display_options_file.rb +31 -0
  31. data/lib/epuber/compiler/file_types/image_file.rb +42 -0
  32. data/lib/epuber/compiler/file_types/mime_type_file.rb +20 -0
  33. data/lib/epuber/compiler/file_types/nav_file.rb +42 -0
  34. data/lib/epuber/compiler/file_types/opf_file.rb +27 -0
  35. data/lib/epuber/compiler/file_types/source_file.rb +52 -0
  36. data/lib/epuber/compiler/file_types/static_file.rb +18 -0
  37. data/lib/epuber/compiler/file_types/stylus_file.rb +20 -0
  38. data/lib/epuber/compiler/file_types/xhtml_file.rb +102 -0
  39. data/lib/epuber/compiler/generator.rb +67 -0
  40. data/lib/epuber/compiler/meta_inf_generator.rb +41 -0
  41. data/lib/epuber/compiler/nav_generator.rb +201 -0
  42. data/lib/epuber/compiler/opf_generator.rb +284 -0
  43. data/lib/epuber/compiler/xhtml_processor.rb +254 -0
  44. data/lib/epuber/config.rb +133 -0
  45. data/lib/epuber/dsl/attribute.rb +248 -0
  46. data/lib/epuber/dsl/attribute_support.rb +130 -0
  47. data/lib/epuber/dsl/object.rb +145 -0
  48. data/lib/epuber/dsl/tree_object.rb +101 -0
  49. data/lib/epuber/helper.rb +19 -0
  50. data/lib/epuber/lockfile.rb +55 -0
  51. data/lib/epuber/plugin.rb +108 -0
  52. data/lib/epuber/ruby_extensions/match_data.rb +40 -0
  53. data/lib/epuber/ruby_extensions/thread.rb +13 -0
  54. data/lib/epuber/server.rb +614 -0
  55. data/lib/epuber/server/auto_refresh/auto_refresh.coffee +97 -0
  56. data/lib/epuber/server/auto_refresh/connector.coffee +125 -0
  57. data/lib/epuber/server/auto_refresh/protocol.coffee +41 -0
  58. data/lib/epuber/server/auto_refresh/reloader.coffee +261 -0
  59. data/lib/epuber/server/base.styl +3 -0
  60. data/lib/epuber/server/basic.styl +211 -0
  61. data/lib/epuber/server/book_content.styl +39 -0
  62. data/lib/epuber/server/default_cover.png +0 -0
  63. data/lib/epuber/server/fonts/AvenirNext/AvenirNext-Bold.ttf +0 -0
  64. data/lib/epuber/server/fonts/AvenirNext/AvenirNext-BoldItalic.ttf +0 -0
  65. data/lib/epuber/server/fonts/AvenirNext/AvenirNext-Italic.ttf +0 -0
  66. data/lib/epuber/server/fonts/AvenirNext/AvenirNext-Regular.ttf +0 -0
  67. data/lib/epuber/server/handlers.rb +67 -0
  68. data/lib/epuber/server/keyboard_control.coffee +6 -0
  69. data/lib/epuber/server/pages/book.bade +75 -0
  70. data/lib/epuber/server/pages/common.bade +59 -0
  71. data/lib/epuber/server/pages/files.bade +17 -0
  72. data/lib/epuber/server/pages/toc.bade +29 -0
  73. data/lib/epuber/server/support.coffee +10 -0
  74. data/lib/epuber/templates/template.bookspec +143 -0
  75. data/lib/epuber/third_party/bower.rb +22 -0
  76. data/lib/epuber/third_party/bower/bower.json +10 -0
  77. data/lib/epuber/third_party/bower/bower_components/cookies-js/bower.json +10 -0
  78. data/lib/epuber/third_party/bower/bower_components/cookies-js/dist/cookies.d.ts +33 -0
  79. data/lib/epuber/third_party/bower/bower_components/cookies-js/dist/cookies.js +173 -0
  80. data/lib/epuber/third_party/bower/bower_components/cookies-js/dist/cookies.min.js +6 -0
  81. data/lib/epuber/third_party/bower/bower_components/jquery/MIT-LICENSE.txt +21 -0
  82. data/lib/epuber/third_party/bower/bower_components/jquery/bower.json +28 -0
  83. data/lib/epuber/third_party/bower/bower_components/jquery/dist/jquery.js +9210 -0
  84. data/lib/epuber/third_party/bower/bower_components/jquery/dist/jquery.min.js +5 -0
  85. data/lib/epuber/third_party/bower/bower_components/jquery/dist/jquery.min.map +1 -0
  86. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax.js +786 -0
  87. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/jsonp.js +89 -0
  88. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/load.js +75 -0
  89. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/parseJSON.js +13 -0
  90. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/parseXML.js +28 -0
  91. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/script.js +64 -0
  92. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/var/nonce.js +5 -0
  93. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/var/rquery.js +3 -0
  94. data/lib/epuber/third_party/bower/bower_components/jquery/src/ajax/xhr.js +136 -0
  95. data/lib/epuber/third_party/bower/bower_components/jquery/src/attributes.js +11 -0
  96. data/lib/epuber/third_party/bower/bower_components/jquery/src/attributes/attr.js +141 -0
  97. data/lib/epuber/third_party/bower/bower_components/jquery/src/attributes/classes.js +158 -0
  98. data/lib/epuber/third_party/bower/bower_components/jquery/src/attributes/prop.js +94 -0
  99. data/lib/epuber/third_party/bower/bower_components/jquery/src/attributes/support.js +35 -0
  100. data/lib/epuber/third_party/bower/bower_components/jquery/src/attributes/val.js +161 -0
  101. data/lib/epuber/third_party/bower/bower_components/jquery/src/callbacks.js +205 -0
  102. data/lib/epuber/third_party/bower/bower_components/jquery/src/core.js +502 -0
  103. data/lib/epuber/third_party/bower/bower_components/jquery/src/core/access.js +60 -0
  104. data/lib/epuber/third_party/bower/bower_components/jquery/src/core/init.js +123 -0
  105. data/lib/epuber/third_party/bower/bower_components/jquery/src/core/parseHTML.js +39 -0
  106. data/lib/epuber/third_party/bower/bower_components/jquery/src/core/ready.js +97 -0
  107. data/lib/epuber/third_party/bower/bower_components/jquery/src/core/var/rsingleTag.js +4 -0
  108. data/lib/epuber/third_party/bower/bower_components/jquery/src/css.js +450 -0
  109. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/addGetHookIf.js +22 -0
  110. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/curCSS.js +57 -0
  111. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/defaultDisplay.js +70 -0
  112. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/hiddenVisibleSelectors.js +15 -0
  113. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/support.js +96 -0
  114. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/swap.js +28 -0
  115. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/var/cssExpand.js +3 -0
  116. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/var/getStyles.js +12 -0
  117. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/var/isHidden.js +13 -0
  118. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/var/rmargin.js +3 -0
  119. data/lib/epuber/third_party/bower/bower_components/jquery/src/css/var/rnumnonpx.js +5 -0
  120. data/lib/epuber/third_party/bower/bower_components/jquery/src/data.js +178 -0
  121. data/lib/epuber/third_party/bower/bower_components/jquery/src/data/Data.js +181 -0
  122. data/lib/epuber/third_party/bower/bower_components/jquery/src/data/accepts.js +20 -0
  123. data/lib/epuber/third_party/bower/bower_components/jquery/src/data/var/data_priv.js +5 -0
  124. data/lib/epuber/third_party/bower/bower_components/jquery/src/data/var/data_user.js +5 -0
  125. data/lib/epuber/third_party/bower/bower_components/jquery/src/deferred.js +149 -0
  126. data/lib/epuber/third_party/bower/bower_components/jquery/src/deprecated.js +13 -0
  127. data/lib/epuber/third_party/bower/bower_components/jquery/src/dimensions.js +50 -0
  128. data/lib/epuber/third_party/bower/bower_components/jquery/src/effects.js +648 -0
  129. data/lib/epuber/third_party/bower/bower_components/jquery/src/effects/Tween.js +114 -0
  130. data/lib/epuber/third_party/bower/bower_components/jquery/src/effects/animatedSelector.js +13 -0
  131. data/lib/epuber/third_party/bower/bower_components/jquery/src/event.js +868 -0
  132. data/lib/epuber/third_party/bower/bower_components/jquery/src/event/ajax.js +13 -0
  133. data/lib/epuber/third_party/bower/bower_components/jquery/src/event/alias.js +39 -0
  134. data/lib/epuber/third_party/bower/bower_components/jquery/src/event/support.js +9 -0
  135. data/lib/epuber/third_party/bower/bower_components/jquery/src/exports/amd.js +24 -0
  136. data/lib/epuber/third_party/bower/bower_components/jquery/src/exports/global.js +32 -0
  137. data/lib/epuber/third_party/bower/bower_components/jquery/src/intro.js +44 -0
  138. data/lib/epuber/third_party/bower/bower_components/jquery/src/jquery.js +37 -0
  139. data/lib/epuber/third_party/bower/bower_components/jquery/src/manipulation.js +580 -0
  140. data/lib/epuber/third_party/bower/bower_components/jquery/src/manipulation/_evalUrl.js +18 -0
  141. data/lib/epuber/third_party/bower/bower_components/jquery/src/manipulation/support.js +32 -0
  142. data/lib/epuber/third_party/bower/bower_components/jquery/src/manipulation/var/rcheckableType.js +3 -0
  143. data/lib/epuber/third_party/bower/bower_components/jquery/src/offset.js +207 -0
  144. data/lib/epuber/third_party/bower/bower_components/jquery/src/outro.js +1 -0
  145. data/lib/epuber/third_party/bower/bower_components/jquery/src/queue.js +142 -0
  146. data/lib/epuber/third_party/bower/bower_components/jquery/src/queue/delay.js +22 -0
  147. data/lib/epuber/third_party/bower/bower_components/jquery/src/selector-native.js +172 -0
  148. data/lib/epuber/third_party/bower/bower_components/jquery/src/selector-sizzle.js +14 -0
  149. data/lib/epuber/third_party/bower/bower_components/jquery/src/selector.js +1 -0
  150. data/lib/epuber/third_party/bower/bower_components/jquery/src/serialize.js +111 -0
  151. data/lib/epuber/third_party/bower/bower_components/jquery/src/sizzle/dist/sizzle.js +2067 -0
  152. data/lib/epuber/third_party/bower/bower_components/jquery/src/sizzle/dist/sizzle.min.js +3 -0
  153. data/lib/epuber/third_party/bower/bower_components/jquery/src/sizzle/dist/sizzle.min.map +1 -0
  154. data/lib/epuber/third_party/bower/bower_components/jquery/src/traversing.js +199 -0
  155. data/lib/epuber/third_party/bower/bower_components/jquery/src/traversing/findFilter.js +100 -0
  156. data/lib/epuber/third_party/bower/bower_components/jquery/src/traversing/var/rneedsContext.js +6 -0
  157. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/arr.js +3 -0
  158. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/class2type.js +4 -0
  159. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/concat.js +5 -0
  160. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/hasOwn.js +5 -0
  161. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/indexOf.js +5 -0
  162. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/pnum.js +3 -0
  163. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/push.js +5 -0
  164. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/rnotwhite.js +3 -0
  165. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/slice.js +5 -0
  166. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/strundefined.js +3 -0
  167. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/support.js +4 -0
  168. data/lib/epuber/third_party/bower/bower_components/jquery/src/var/toString.js +5 -0
  169. data/lib/epuber/third_party/bower/bower_components/jquery/src/wrap.js +79 -0
  170. data/lib/epuber/third_party/bower/bower_components/keymaster/MIT-LICENSE +20 -0
  171. data/lib/epuber/third_party/bower/bower_components/keymaster/Makefile +4 -0
  172. data/lib/epuber/third_party/bower/bower_components/keymaster/README.markdown +212 -0
  173. data/lib/epuber/third_party/bower/bower_components/keymaster/bower.json +27 -0
  174. data/lib/epuber/third_party/bower/bower_components/keymaster/keymaster.js +296 -0
  175. data/lib/epuber/third_party/bower/bower_components/keymaster/package.json +11 -0
  176. data/lib/epuber/third_party/bower/bower_components/keymaster/test.html +93 -0
  177. data/lib/epuber/third_party/bower/bower_components/spin.js/LICENSE.txt +21 -0
  178. data/lib/epuber/third_party/bower/bower_components/spin.js/README.md +21 -0
  179. data/lib/epuber/third_party/bower/bower_components/spin.js/bower.json +18 -0
  180. data/lib/epuber/third_party/bower/bower_components/spin.js/jquery.spin.js +80 -0
  181. data/lib/epuber/third_party/bower/bower_components/spin.js/spin.js +337 -0
  182. data/lib/epuber/third_party/bower/bower_components/uri.js/LICENSE.txt +21 -0
  183. data/lib/epuber/third_party/bower/bower_components/uri.js/README.md +534 -0
  184. data/lib/epuber/third_party/bower/bower_components/uri.js/bower.json +16 -0
  185. data/lib/epuber/third_party/bower/bower_components/uri.js/contributing.md +19 -0
  186. data/lib/epuber/third_party/bower/bower_components/uri.js/src/IPv6.js +188 -0
  187. data/lib/epuber/third_party/bower/bower_components/uri.js/src/SecondLevelDomains.js +241 -0
  188. data/lib/epuber/third_party/bower/bower_components/uri.js/src/URI.fragmentQuery.js +104 -0
  189. data/lib/epuber/third_party/bower/bower_components/uri.js/src/URI.fragmentURI.js +97 -0
  190. data/lib/epuber/third_party/bower/bower_components/uri.js/src/URI.js +2115 -0
  191. data/lib/epuber/third_party/bower/bower_components/uri.js/src/URI.min.js +86 -0
  192. data/lib/epuber/third_party/bower/bower_components/uri.js/src/URITemplate.js +499 -0
  193. data/lib/epuber/third_party/bower/bower_components/uri.js/src/jquery.URI.js +235 -0
  194. data/lib/epuber/third_party/bower/bower_components/uri.js/src/jquery.URI.min.js +7 -0
  195. data/lib/epuber/third_party/bower/bower_components/uri.js/src/punycode.js +508 -0
  196. data/lib/epuber/transformer.rb +19 -0
  197. data/lib/epuber/transformer/text_transformer.rb +60 -0
  198. data/lib/epuber/user_interface.rb +186 -0
  199. data/lib/epuber/vendor/globals_context.rb +26 -0
  200. data/lib/epuber/vendor/hash_binding.rb +26 -0
  201. data/lib/epuber/vendor/nokogiri_extensions.rb +30 -0
  202. data/lib/epuber/vendor/ruby_templater.rb +71 -0
  203. data/lib/epuber/vendor/size.rb +20 -0
  204. data/lib/epuber/vendor/version.rb +83 -0
  205. data/lib/epuber/version.rb +4 -0
  206. metadata +556 -0
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011-2013 Thomas Fuchs
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,4 @@
1
+ # To run this, you'll need to install UglifyJS:
2
+ # npm install uglify-js@1 -g
3
+ default:
4
+ uglifyjs -o keymaster.min.js keymaster.js
@@ -0,0 +1,212 @@
1
+ # keymaster.js
2
+
3
+ Keymaster is a simple micro-library for defining and
4
+ dispatching keyboard shortcuts in web applications.
5
+
6
+ It has no dependencies.
7
+
8
+ *It’s a work in progress (e.g. beta), so spare me your nerdrage and instead
9
+ contribute! Patches are welcome, but they are not guaranteed to make
10
+ it in.*
11
+
12
+ ## Usage
13
+
14
+ Include `keymaster.js` in your web app*, by loading it as usual:
15
+
16
+ ```html
17
+ <script src="keymaster.js"></script>
18
+ ```
19
+
20
+ Keymaster has no dependencies and can be used completely standalone.
21
+ It should not interfere with any JavaScript libraries or frameworks.
22
+
23
+ _*Preferably use a minified version that fits your workflow. You can
24
+ run `make` to have UglifyJS (if you have it installed) create a
25
+ `keymaster.min.js` file for you._
26
+
27
+ ## Defining shortcuts
28
+
29
+ One global method is exposed, `key` which defines shortcuts when
30
+ called directly.
31
+
32
+ ```javascript
33
+ // define short of 'a'
34
+ key('a', function(){ alert('you pressed a!') });
35
+
36
+ // returning false stops the event and prevents default browser events
37
+ key('ctrl+r', function(){ alert('stopped reload!'); return false });
38
+
39
+ // multiple shortcuts that do the same thing
40
+ key('⌘+r, ctrl+r', function(){ });
41
+ ```
42
+
43
+ The handler method is called with two arguments set, the keydown `event` fired, and
44
+ an object containing, among others, the following two properties:
45
+
46
+ `shortcut`: a string that contains the shortcut used, e.g. `ctrl+r`
47
+ `scope`: a string describing the scope (or `all`)
48
+
49
+ ```javascript
50
+ key('⌘+r, ctrl+r', function(event, handler){
51
+ console.log(handler.shortcut, handler.scope);
52
+ });
53
+
54
+ // "ctrl+r", "all"
55
+ ```
56
+
57
+
58
+ ## Supported keys
59
+
60
+ Keymaster understands the following modifiers:
61
+ `⇧`, `shift`, `option`, `⌥`, `alt`, `ctrl`, `control`, `command`, and `⌘`.
62
+
63
+ The following special keys can be used for shortcuts:
64
+ `backspace`, `tab`, `clear`, `enter`, `return`, `esc`, `escape`, `space`,
65
+ `up`, `down`, `left`, `right`, `home`, `end`, `pageup`, `pagedown`, `del`, `delete`
66
+ and `f1` through `f19`.
67
+
68
+
69
+ ## Modifier key queries
70
+
71
+ At any point in time (even in code other than key shortcut handlers),
72
+ you can query the `key` object for the state of any keys. This
73
+ allows easy implementation of things like shift+click handlers. For example,
74
+ `key.shift` is `true` if the shift key is currently pressed.
75
+
76
+ ```javascript
77
+ if(key.shift) alert('shift is pressed, OMGZ!');
78
+ ```
79
+
80
+
81
+ ## Other key queries
82
+
83
+ At any point in time (even in code other than key shortcut handlers),
84
+ you can query the `key` object for the state of any key. This
85
+ is very helpful for game development using a game loop. For example,
86
+ `key.isPressed(77)` is `true` if the M key is currently pressed.
87
+
88
+ ```javascript
89
+ if(key.isPressed("M")) alert('M key is pressed, can ya believe it!?');
90
+ if(key.isPressed(77)) alert('M key is pressed, can ya believe it!?');
91
+ ```
92
+
93
+ You can also get these as an array using...
94
+ ```javascript
95
+ key.getPressedKeyCodes() // returns an array of key codes currently pressed
96
+ ```
97
+
98
+
99
+ ## Scopes
100
+
101
+ If you want to reuse the same shortcut for separate areas in your single page app,
102
+ Keymaster supports switching between scopes. Use the `key.setScope` method to set scope.
103
+
104
+ ```javascript
105
+ // define shortcuts with a scope
106
+ key('o, enter', 'issues', function(){ /* do something */ });
107
+ key('o, enter', 'files', function(){ /* do something else */ });
108
+
109
+ // set the scope (only 'all' and 'issues' shortcuts will be honored)
110
+ key.setScope('issues'); // default scope is 'all'
111
+ ```
112
+
113
+
114
+ ## Filter key presses
115
+
116
+ By default, when an `INPUT`, `SELECT` or `TEXTAREA` element is focused, Keymaster doesn't process any shortcuts.
117
+
118
+ You can change this by overwriting `key.filter` with a new function. This function is called before
119
+ Keymaster processes shortcuts, with the keydown event as argument.
120
+
121
+ If your function returns false, then the no shortcuts will be processed.
122
+
123
+ Here's the default implementation for reference:
124
+
125
+ ```javascript
126
+ function filter(event){
127
+ var tagName = (event.target || event.srcElement).tagName;
128
+ return !(tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA');
129
+ }
130
+ ```
131
+
132
+ If you only want _some_ shortcuts to work while in an input element, you can change the scope in the
133
+ `key.filter` function. Here's an example implementation, setting the scope to either `'input'` or `'other'`.
134
+ Don't forget to return `true` so the any shortcuts get processed.
135
+
136
+ ```javascript
137
+ key.filter = function(event){
138
+ var tagName = (event.target || event.srcElement).tagName;
139
+ key.setScope(/^(INPUT|TEXTAREA|SELECT)$/.test(tagName) ? 'input' : 'other');
140
+ return true;
141
+ }
142
+ ```
143
+
144
+ However a more robust way to handle this is to use proper
145
+ focus and blur event handlers on your input element, and change scopes there as you see fit.
146
+
147
+
148
+ ## noConflict mode
149
+
150
+ You can call ```key.noConflict``` to remove the ```key``` function from global scope and restore whatever ```key``` was defined to before Keymaster was loaded. Calling ```key.noConflict``` will return the Keymaster ```key``` function.
151
+
152
+ ```javascript
153
+ var k = key.noConflict();
154
+ k('a', function() { /* ... */ });
155
+
156
+ key()
157
+ // --> TypeError: 'undefined' is not a function
158
+ ```
159
+
160
+
161
+ ## Unbinding shortcuts
162
+
163
+ Similar to defining shortcuts, they can be unbound using `key.unbind`.
164
+
165
+ ```javascript
166
+ // unbind 'a' handler
167
+ key.unbind('a');
168
+
169
+ // unbind a key only for a single scope
170
+ // when no scope is specified it defaults to the current scope (key.getScope())
171
+ key.unbind('o, enter', 'issues');
172
+ key.unbind('o, enter', 'files');
173
+ ```
174
+
175
+
176
+ ## Notes
177
+
178
+ Keymaster should work with any browser that fires `keyup` and `keydown` events,
179
+ and is tested with IE (6+), Safari, Firefox and Chrome.
180
+
181
+ See [http://madrobby.github.com/keymaster/](http://madrobby.github.com/keymaster/) for a live demo.
182
+
183
+
184
+ ## CoffeeScript
185
+
186
+ If you're using CoffeeScript, configuring key shortcuts couldn't be simpler:
187
+
188
+ ```coffeescript
189
+ key 'a', -> alert('you pressed a!')
190
+
191
+ key '⌘+r, ctrl+r', ->
192
+ alert 'stopped reload!'
193
+ off
194
+
195
+ key 'o, enter', 'issues', ->
196
+ whatevs()
197
+
198
+ alert 'shift is pressed, OMGZ!' if key.shift
199
+ ```
200
+
201
+
202
+ ## Contributing
203
+
204
+ To contribute, please fork Keymaster, add your patch and tests for it (in the `test/` folder) and
205
+ submit a pull request.
206
+
207
+ ## TODOs
208
+
209
+ * Finish test suite
210
+
211
+ Keymaster is (c) 2011-2013 Thomas Fuchs and may be freely distributed under the MIT license.
212
+ See the `MIT-LICENSE` file.
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "keymaster",
3
+ "main": "keymaster.js",
4
+ "version": "1.6.3",
5
+ "homepage": "https://github.com/madrobby/keymaster",
6
+ "authors": [
7
+ "Thomas Fuchs <thomas@slash7.com> (http://mir.aculo.us)"
8
+ ],
9
+ "description": "library for defining and dispatching keyboard shortcuts",
10
+ "moduleType": [
11
+ "es6",
12
+ "globals"
13
+ ],
14
+ "keywords": [
15
+ "key",
16
+ "keyboard",
17
+ "shortcuts"
18
+ ],
19
+ "license": "MIT",
20
+ "ignore": [
21
+ "**/.*",
22
+ "node_modules",
23
+ "bower_components",
24
+ "test",
25
+ "tests"
26
+ ]
27
+ }
@@ -0,0 +1,296 @@
1
+ // keymaster.js
2
+ // (c) 2011-2013 Thomas Fuchs
3
+ // keymaster.js may be freely distributed under the MIT license.
4
+
5
+ ;(function(global){
6
+ var k,
7
+ _handlers = {},
8
+ _mods = { 16: false, 18: false, 17: false, 91: false },
9
+ _scope = 'all',
10
+ // modifier keys
11
+ _MODIFIERS = {
12
+ '⇧': 16, shift: 16,
13
+ '⌥': 18, alt: 18, option: 18,
14
+ '⌃': 17, ctrl: 17, control: 17,
15
+ '⌘': 91, command: 91
16
+ },
17
+ // special keys
18
+ _MAP = {
19
+ backspace: 8, tab: 9, clear: 12,
20
+ enter: 13, 'return': 13,
21
+ esc: 27, escape: 27, space: 32,
22
+ left: 37, up: 38,
23
+ right: 39, down: 40,
24
+ del: 46, 'delete': 46,
25
+ home: 36, end: 35,
26
+ pageup: 33, pagedown: 34,
27
+ ',': 188, '.': 190, '/': 191,
28
+ '`': 192, '-': 189, '=': 187,
29
+ ';': 186, '\'': 222,
30
+ '[': 219, ']': 221, '\\': 220
31
+ },
32
+ code = function(x){
33
+ return _MAP[x] || x.toUpperCase().charCodeAt(0);
34
+ },
35
+ _downKeys = [];
36
+
37
+ for(k=1;k<20;k++) _MAP['f'+k] = 111+k;
38
+
39
+ // IE doesn't support Array#indexOf, so have a simple replacement
40
+ function index(array, item){
41
+ var i = array.length;
42
+ while(i--) if(array[i]===item) return i;
43
+ return -1;
44
+ }
45
+
46
+ // for comparing mods before unassignment
47
+ function compareArray(a1, a2) {
48
+ if (a1.length != a2.length) return false;
49
+ for (var i = 0; i < a1.length; i++) {
50
+ if (a1[i] !== a2[i]) return false;
51
+ }
52
+ return true;
53
+ }
54
+
55
+ var modifierMap = {
56
+ 16:'shiftKey',
57
+ 18:'altKey',
58
+ 17:'ctrlKey',
59
+ 91:'metaKey'
60
+ };
61
+ function updateModifierKey(event) {
62
+ for(k in _mods) _mods[k] = event[modifierMap[k]];
63
+ };
64
+
65
+ // handle keydown event
66
+ function dispatch(event) {
67
+ var key, handler, k, i, modifiersMatch, scope;
68
+ key = event.keyCode;
69
+
70
+ if (index(_downKeys, key) == -1) {
71
+ _downKeys.push(key);
72
+ }
73
+
74
+ // if a modifier key, set the key.<modifierkeyname> property to true and return
75
+ if(key == 93 || key == 224) key = 91; // right command on webkit, command on Gecko
76
+ if(key in _mods) {
77
+ _mods[key] = true;
78
+ // 'assignKey' from inside this closure is exported to window.key
79
+ for(k in _MODIFIERS) if(_MODIFIERS[k] == key) assignKey[k] = true;
80
+ return;
81
+ }
82
+ updateModifierKey(event);
83
+
84
+ // see if we need to ignore the keypress (filter() can can be overridden)
85
+ // by default ignore key presses if a select, textarea, or input is focused
86
+ if(!assignKey.filter.call(this, event)) return;
87
+
88
+ // abort if no potentially matching shortcuts found
89
+ if (!(key in _handlers)) return;
90
+
91
+ scope = getScope();
92
+
93
+ // for each potential shortcut
94
+ for (i = 0; i < _handlers[key].length; i++) {
95
+ handler = _handlers[key][i];
96
+
97
+ // see if it's in the current scope
98
+ if(handler.scope == scope || handler.scope == 'all'){
99
+ // check if modifiers match if any
100
+ modifiersMatch = handler.mods.length > 0;
101
+ for(k in _mods)
102
+ if((!_mods[k] && index(handler.mods, +k) > -1) ||
103
+ (_mods[k] && index(handler.mods, +k) == -1)) modifiersMatch = false;
104
+ // call the handler and stop the event if neccessary
105
+ if((handler.mods.length == 0 && !_mods[16] && !_mods[18] && !_mods[17] && !_mods[91]) || modifiersMatch){
106
+ if(handler.method(event, handler)===false){
107
+ if(event.preventDefault) event.preventDefault();
108
+ else event.returnValue = false;
109
+ if(event.stopPropagation) event.stopPropagation();
110
+ if(event.cancelBubble) event.cancelBubble = true;
111
+ }
112
+ }
113
+ }
114
+ }
115
+ };
116
+
117
+ // unset modifier keys on keyup
118
+ function clearModifier(event){
119
+ var key = event.keyCode, k,
120
+ i = index(_downKeys, key);
121
+
122
+ // remove key from _downKeys
123
+ if (i >= 0) {
124
+ _downKeys.splice(i, 1);
125
+ }
126
+
127
+ if(key == 93 || key == 224) key = 91;
128
+ if(key in _mods) {
129
+ _mods[key] = false;
130
+ for(k in _MODIFIERS) if(_MODIFIERS[k] == key) assignKey[k] = false;
131
+ }
132
+ };
133
+
134
+ function resetModifiers() {
135
+ for(k in _mods) _mods[k] = false;
136
+ for(k in _MODIFIERS) assignKey[k] = false;
137
+ };
138
+
139
+ // parse and assign shortcut
140
+ function assignKey(key, scope, method){
141
+ var keys, mods;
142
+ keys = getKeys(key);
143
+ if (method === undefined) {
144
+ method = scope;
145
+ scope = 'all';
146
+ }
147
+
148
+ // for each shortcut
149
+ for (var i = 0; i < keys.length; i++) {
150
+ // set modifier keys if any
151
+ mods = [];
152
+ key = keys[i].split('+');
153
+ if (key.length > 1){
154
+ mods = getMods(key);
155
+ key = [key[key.length-1]];
156
+ }
157
+ // convert to keycode and...
158
+ key = key[0]
159
+ key = code(key);
160
+ // ...store handler
161
+ if (!(key in _handlers)) _handlers[key] = [];
162
+ _handlers[key].push({ shortcut: keys[i], scope: scope, method: method, key: keys[i], mods: mods });
163
+ }
164
+ };
165
+
166
+ // unbind all handlers for given key in current scope
167
+ function unbindKey(key, scope) {
168
+ var multipleKeys, keys,
169
+ mods = [],
170
+ i, j, obj;
171
+
172
+ multipleKeys = getKeys(key);
173
+
174
+ for (j = 0; j < multipleKeys.length; j++) {
175
+ keys = multipleKeys[j].split('+');
176
+
177
+ if (keys.length > 1) {
178
+ mods = getMods(keys);
179
+ }
180
+
181
+ key = keys[keys.length - 1];
182
+ key = code(key);
183
+
184
+ if (scope === undefined) {
185
+ scope = getScope();
186
+ }
187
+ if (!_handlers[key]) {
188
+ return;
189
+ }
190
+ for (i = 0; i < _handlers[key].length; i++) {
191
+ obj = _handlers[key][i];
192
+ // only clear handlers if correct scope and mods match
193
+ if (obj.scope === scope && compareArray(obj.mods, mods)) {
194
+ _handlers[key][i] = {};
195
+ }
196
+ }
197
+ }
198
+ };
199
+
200
+ // Returns true if the key with code 'keyCode' is currently down
201
+ // Converts strings into key codes.
202
+ function isPressed(keyCode) {
203
+ if (typeof(keyCode)=='string') {
204
+ keyCode = code(keyCode);
205
+ }
206
+ return index(_downKeys, keyCode) != -1;
207
+ }
208
+
209
+ function getPressedKeyCodes() {
210
+ return _downKeys.slice(0);
211
+ }
212
+
213
+ function filter(event){
214
+ var tagName = (event.target || event.srcElement).tagName;
215
+ // ignore keypressed in any elements that support keyboard data input
216
+ return !(tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA');
217
+ }
218
+
219
+ // initialize key.<modifier> to false
220
+ for(k in _MODIFIERS) assignKey[k] = false;
221
+
222
+ // set current scope (default 'all')
223
+ function setScope(scope){ _scope = scope || 'all' };
224
+ function getScope(){ return _scope || 'all' };
225
+
226
+ // delete all handlers for a given scope
227
+ function deleteScope(scope){
228
+ var key, handlers, i;
229
+
230
+ for (key in _handlers) {
231
+ handlers = _handlers[key];
232
+ for (i = 0; i < handlers.length; ) {
233
+ if (handlers[i].scope === scope) handlers.splice(i, 1);
234
+ else i++;
235
+ }
236
+ }
237
+ };
238
+
239
+ // abstract key logic for assign and unassign
240
+ function getKeys(key) {
241
+ var keys;
242
+ key = key.replace(/\s/g, '');
243
+ keys = key.split(',');
244
+ if ((keys[keys.length - 1]) == '') {
245
+ keys[keys.length - 2] += ',';
246
+ }
247
+ return keys;
248
+ }
249
+
250
+ // abstract mods logic for assign and unassign
251
+ function getMods(key) {
252
+ var mods = key.slice(0, key.length - 1);
253
+ for (var mi = 0; mi < mods.length; mi++)
254
+ mods[mi] = _MODIFIERS[mods[mi]];
255
+ return mods;
256
+ }
257
+
258
+ // cross-browser events
259
+ function addEvent(object, event, method) {
260
+ if (object.addEventListener)
261
+ object.addEventListener(event, method, false);
262
+ else if(object.attachEvent)
263
+ object.attachEvent('on'+event, function(){ method(window.event) });
264
+ };
265
+
266
+ // set the handlers globally on document
267
+ addEvent(document, 'keydown', function(event) { dispatch(event) }); // Passing _scope to a callback to ensure it remains the same by execution. Fixes #48
268
+ addEvent(document, 'keyup', clearModifier);
269
+
270
+ // reset modifiers to false whenever the window is (re)focused.
271
+ addEvent(window, 'focus', resetModifiers);
272
+
273
+ // store previously defined key
274
+ var previousKey = global.key;
275
+
276
+ // restore previously defined key and return reference to our key object
277
+ function noConflict() {
278
+ var k = global.key;
279
+ global.key = previousKey;
280
+ return k;
281
+ }
282
+
283
+ // set window.key and window.key.set/get/deleteScope, and the default filter
284
+ global.key = assignKey;
285
+ global.key.setScope = setScope;
286
+ global.key.getScope = getScope;
287
+ global.key.deleteScope = deleteScope;
288
+ global.key.filter = filter;
289
+ global.key.isPressed = isPressed;
290
+ global.key.getPressedKeyCodes = getPressedKeyCodes;
291
+ global.key.noConflict = noConflict;
292
+ global.key.unbind = unbindKey;
293
+
294
+ if(typeof module !== 'undefined') module.exports = assignKey;
295
+
296
+ })(this);