epuber 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
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);