wheels 0.0.48 → 0.0.49

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 (215) hide show
  1. data/VERSION +1 -1
  2. data/app/controllers/access_control_entries_controller.rb +4 -4
  3. data/app/controllers/external_links_controller.rb +5 -0
  4. data/app/controllers/feedbacks_controller.rb +10 -0
  5. data/app/controllers/menus_controller.rb +2 -0
  6. data/app/controllers/pages_controller.rb +16 -29
  7. data/app/controllers/sitemaps_controller.rb +135 -0
  8. data/app/helpers/application_helper.rb +4 -3
  9. data/app/helpers/external_links_helper.rb +2 -0
  10. data/app/helpers/feedbacks_helper.rb +2 -0
  11. data/app/helpers/menus_helper.rb +2 -0
  12. data/app/helpers/sitemaps_helper.rb +12 -0
  13. data/app/mailers/feedback_mailer.rb +10 -0
  14. data/app/models/ability.rb +2 -1
  15. data/app/models/access_control_entry.rb +17 -15
  16. data/app/models/external_link.rb +4 -0
  17. data/app/models/feedback.rb +13 -0
  18. data/app/models/image.rb +1 -1
  19. data/app/models/menu.rb +4 -0
  20. data/app/models/page.rb +2 -5
  21. data/app/models/sitemap.rb +153 -0
  22. data/app/models/user.rb +7 -1
  23. data/app/validators/email_validator.rb +22 -0
  24. data/app/views/access_control_entries/_form.html.haml +1 -1
  25. data/app/views/access_control_entries/_index.html.haml +3 -3
  26. data/app/views/access_control_entries/_show.html.haml +1 -1
  27. data/app/views/external_links/_fields_for.html.haml +2 -0
  28. data/app/views/external_links/_form.html.haml +18 -0
  29. data/app/views/external_links/_show.html.haml +7 -0
  30. data/app/views/external_links/edit.html.haml +7 -0
  31. data/app/views/external_links/index.html.haml +23 -0
  32. data/app/views/external_links/new.html.haml +5 -0
  33. data/app/views/external_links/show.html.haml +2 -0
  34. data/app/views/feedback_mailer/submit_feedback.html.haml +22 -0
  35. data/app/views/feedbacks/_form.html.haml +37 -0
  36. data/app/views/feedbacks/index.html.haml +27 -0
  37. data/app/views/feedbacks/new.html.haml +5 -0
  38. data/app/views/feedbacks/show.html.haml +19 -0
  39. data/app/views/layouts/application.html.haml +21 -16
  40. data/app/views/layouts/bare.html.haml +2 -0
  41. data/app/views/loadbehind/_view.js.haml +1 -2
  42. data/app/views/menus/_form.html.haml +13 -0
  43. data/app/views/menus/edit.html.haml +7 -0
  44. data/app/views/menus/index.html.haml +19 -0
  45. data/app/views/menus/new.html.haml +5 -0
  46. data/app/views/menus/show.html.haml +7 -0
  47. data/app/views/pages/_child_pages_links.html.haml +1 -1
  48. data/app/views/pages/_control_panel.html.haml +1 -6
  49. data/app/views/pages/_form.html.haml +2 -2
  50. data/app/views/pages/_form_fields.html.haml +7 -2
  51. data/app/views/pages/_show.html.haml +4 -0
  52. data/app/views/pages/create.js.haml +2 -1
  53. data/app/views/pages/destroy.js.haml +3 -0
  54. data/app/views/pages/edit.js.haml +4 -0
  55. data/app/views/pages/index.html.haml +4 -2
  56. data/app/views/pages/index.js.haml +3 -0
  57. data/app/views/pages/new.js.haml +3 -0
  58. data/app/views/pages/show.html.haml +2 -10
  59. data/app/views/pages/show.js.haml +3 -0
  60. data/app/views/pages/update.js.haml +2 -2
  61. data/app/views/sitemaps/edit.html.haml +12 -0
  62. data/app/views/sitemaps/edit.js.erb +0 -0
  63. data/app/views/sitemaps/index.html.haml +93 -0
  64. data/app/views/sitemaps/index.json.erb +23 -0
  65. data/app/views/sitemaps/new.html.haml +8 -0
  66. data/app/views/sitemaps/new.js.erb +0 -0
  67. data/app/views/users/edit.html.haml +45 -0
  68. data/db/migrate/{add_fields_to_users.rb → 0010_add_fields_to_users.rb} +0 -0
  69. data/db/migrate/{create_blogs.rb → 0020_create_blogs.rb} +0 -0
  70. data/db/migrate/{create_galleries.rb → 0030_create_galleries.rb} +0 -0
  71. data/db/migrate/{create_images.rb → 0040_create_images.rb} +0 -0
  72. data/db/migrate/{create_profiles.rb → 0050_create_profiles.rb} +0 -0
  73. data/db/migrate/{insert_admin_user_and_roles.rb → 0060_insert_admin_user_and_roles.rb} +0 -0
  74. data/db/migrate/{create_pages.rb → 0070_create_pages.rb} +0 -0
  75. data/db/migrate/{create_forums.rb → 0080_create_forums.rb} +0 -0
  76. data/db/migrate/{create_discussions.rb → 0090_create_discussions.rb} +0 -0
  77. data/db/migrate/{create_forum_messages.rb → 0100_create_forum_messages.rb} +0 -0
  78. data/db/migrate/{create_access_control_entries.rb → 0110_create_access_control_entries.rb} +3 -3
  79. data/db/migrate/{create_attachments.rb → 0120_create_attachments.rb} +0 -4
  80. data/db/migrate/{create_roles.rb → 0130_create_roles.rb} +0 -0
  81. data/db/migrate/0140_create_feedbacks.rb +20 -0
  82. data/db/migrate/0150_create_external_links.rb +14 -0
  83. data/db/migrate/0160_create_sitemaps.rb +17 -0
  84. data/db/migrate/0170_create_menus.rb +14 -0
  85. data/lib/development_mail_interceptor.rb +7 -0
  86. data/lib/generators/wheels/recipes/wheels.rb +18 -12
  87. data/lib/wheels/base.rb +7 -0
  88. data/lib/wheels/routes.rb +8 -3
  89. data/lib/wheels.rb +2 -0
  90. data/public/javascripts/jquery-validate/additional-methods.js +259 -0
  91. data/public/javascripts/jquery-validate/changelog.txt +239 -0
  92. data/public/javascripts/jquery-validate/jquery.validate.js +1146 -0
  93. data/public/javascripts/jquery-validate/jquery.validate.min.js +16 -0
  94. data/public/javascripts/jquery-validate/jquery.validate.pack.js +15 -0
  95. data/public/javascripts/jquery-validate/lib/jquery-1.4.2.js +6240 -0
  96. data/public/javascripts/jquery-validate/lib/jquery.form.js +660 -0
  97. data/public/javascripts/jquery-validate/lib/jquery.js +4376 -0
  98. data/public/javascripts/jquery-validate/lib/jquery.metadata.js +122 -0
  99. data/public/javascripts/jquery-validate/localization/messages_ar.js +24 -0
  100. data/public/javascripts/jquery-validate/localization/messages_bg.js +23 -0
  101. data/public/javascripts/jquery-validate/localization/messages_cn.js +23 -0
  102. data/public/javascripts/jquery-validate/localization/messages_cs.js +23 -0
  103. data/public/javascripts/jquery-validate/localization/messages_da.js +20 -0
  104. data/public/javascripts/jquery-validate/localization/messages_de.js +20 -0
  105. data/public/javascripts/jquery-validate/localization/messages_el.js +24 -0
  106. data/public/javascripts/jquery-validate/localization/messages_es.js +23 -0
  107. data/public/javascripts/jquery-validate/localization/messages_fa.js +23 -0
  108. data/public/javascripts/jquery-validate/localization/messages_fi.js +21 -0
  109. data/public/javascripts/jquery-validate/localization/messages_fr.js +23 -0
  110. data/public/javascripts/jquery-validate/localization/messages_he.js +23 -0
  111. data/public/javascripts/jquery-validate/localization/messages_hu.js +20 -0
  112. data/public/javascripts/jquery-validate/localization/messages_it.js +23 -0
  113. data/public/javascripts/jquery-validate/localization/messages_kk.js +23 -0
  114. data/public/javascripts/jquery-validate/localization/messages_lt.js +23 -0
  115. data/public/javascripts/jquery-validate/localization/messages_lv.js +23 -0
  116. data/public/javascripts/jquery-validate/localization/messages_nl.js +23 -0
  117. data/public/javascripts/jquery-validate/localization/messages_no.js +23 -0
  118. data/public/javascripts/jquery-validate/localization/messages_pl.js +23 -0
  119. data/public/javascripts/jquery-validate/localization/messages_ptbr.js +23 -0
  120. data/public/javascripts/jquery-validate/localization/messages_ptpt.js +23 -0
  121. data/public/javascripts/jquery-validate/localization/messages_ro.js +23 -0
  122. data/public/javascripts/jquery-validate/localization/messages_ru.js +23 -0
  123. data/public/javascripts/jquery-validate/localization/messages_se.js +21 -0
  124. data/public/javascripts/jquery-validate/localization/messages_sk.js +20 -0
  125. data/public/javascripts/jquery-validate/localization/messages_tr.js +23 -0
  126. data/public/javascripts/jquery-validate/localization/messages_tw.js +23 -0
  127. data/public/javascripts/jquery-validate/localization/messages_ua.js +23 -0
  128. data/public/javascripts/jquery-validate/localization/methods_de.js +12 -0
  129. data/public/javascripts/jquery-validate/localization/methods_nl.js +9 -0
  130. data/public/javascripts/jquery-validate/localization/methods_pt.js +9 -0
  131. data/public/javascripts/jquery-validate/todo +172 -0
  132. data/public/javascripts/jquery.cookie.js +96 -0
  133. data/public/javascripts/jquery.filedrop.js +253 -0
  134. data/public/javascripts/jquery.hotkeys.js +99 -0
  135. data/public/javascripts/jquery.js +6240 -0
  136. data/public/javascripts/jquery.jstree.js +3510 -0
  137. data/public/javascripts/jquery.uploadify.js +26 -0
  138. data/public/javascripts/jquery.validate.js +1147 -0
  139. data/public/javascripts/sitemap_jstree.js +329 -0
  140. data/public/javascripts/swfobject.js +4 -0
  141. data/public/jstree/_demo/_dump.sql +20 -0
  142. data/public/jstree/_demo/_inc/__mysql_errors.log +0 -0
  143. data/public/jstree/_demo/_inc/class._database.php +146 -0
  144. data/public/jstree/_demo/_inc/class._database_i.php +152 -0
  145. data/public/jstree/_demo/_inc/class.tree.php +602 -0
  146. data/public/jstree/_demo/_install.txt +6 -0
  147. data/public/jstree/_demo/config.php +14 -0
  148. data/public/jstree/_demo/index.html +262 -0
  149. data/public/jstree/_demo/server.php +69 -0
  150. data/public/jstree/_docs/!style.css +37 -0
  151. data/public/jstree/_docs/_drive.png +0 -0
  152. data/public/jstree/_docs/_html_data.html +2 -0
  153. data/public/jstree/_docs/_json_data.json +4 -0
  154. data/public/jstree/_docs/_search_data.json +6 -0
  155. data/public/jstree/_docs/_search_result.json +1 -0
  156. data/public/jstree/_docs/_xml_flat.xml +12 -0
  157. data/public/jstree/_docs/_xml_nest.xml +18 -0
  158. data/public/jstree/_docs/checkbox.html +148 -0
  159. data/public/jstree/_docs/contextmenu.html +120 -0
  160. data/public/jstree/_docs/cookies.html +96 -0
  161. data/public/jstree/_docs/core.html +622 -0
  162. data/public/jstree/_docs/crrm.html +315 -0
  163. data/public/jstree/_docs/dnd.html +197 -0
  164. data/public/jstree/_docs/hotkeys.html +81 -0
  165. data/public/jstree/_docs/html_data.html +174 -0
  166. data/public/jstree/_docs/index.html +75 -0
  167. data/public/jstree/_docs/json_data.html +240 -0
  168. data/public/jstree/_docs/languages.html +138 -0
  169. data/public/jstree/_docs/search.html +114 -0
  170. data/public/jstree/_docs/sort.html +84 -0
  171. data/public/jstree/_docs/syntax/!script.js +2232 -0
  172. data/public/jstree/_docs/syntax/!style.css +511 -0
  173. data/public/jstree/_docs/syntax/clipboard.swf +0 -0
  174. data/public/jstree/_docs/syntax/help.png +0 -0
  175. data/public/jstree/_docs/syntax/magnifier.png +0 -0
  176. data/public/jstree/_docs/syntax/page_white_code.png +0 -0
  177. data/public/jstree/_docs/syntax/page_white_copy.png +0 -0
  178. data/public/jstree/_docs/syntax/printer.png +0 -0
  179. data/public/jstree/_docs/syntax/wrapping.png +0 -0
  180. data/public/jstree/_docs/themeroller.html +98 -0
  181. data/public/jstree/_docs/themes.html +126 -0
  182. data/public/jstree/_docs/types.html +173 -0
  183. data/public/jstree/_docs/ui.html +188 -0
  184. data/public/jstree/_docs/unique.html +70 -0
  185. data/public/jstree/_docs/xml_data.html +214 -0
  186. data/public/jstree/_lib/jquery.cookie.js +96 -0
  187. data/public/jstree/_lib/jquery.hotkeys.js +99 -0
  188. data/public/jstree/_lib/jquery.js +6240 -0
  189. data/public/jstree/jquery.jstree.js +3510 -0
  190. data/public/jstree/jstree.html +237 -0
  191. data/public/jstree/themes/apple/bg.jpg +0 -0
  192. data/public/jstree/themes/apple/d.png +0 -0
  193. data/public/jstree/themes/apple/dot_for_ie.gif +0 -0
  194. data/public/jstree/themes/apple/style.css +60 -0
  195. data/public/jstree/themes/apple/throbber.gif +0 -0
  196. data/public/jstree/themes/classic/d.png +0 -0
  197. data/public/jstree/themes/classic/dot_for_ie.gif +0 -0
  198. data/public/jstree/themes/classic/style.css +59 -0
  199. data/public/jstree/themes/classic/throbber.gif +0 -0
  200. data/public/jstree/themes/default/d.gif +0 -0
  201. data/public/jstree/themes/default/d.png +0 -0
  202. data/public/jstree/themes/default/style.css +73 -0
  203. data/public/jstree/themes/default/throbber.gif +0 -0
  204. data/public/jstree/themes/default-rtl/d.gif +0 -0
  205. data/public/jstree/themes/default-rtl/d.png +0 -0
  206. data/public/jstree/themes/default-rtl/dots.gif +0 -0
  207. data/public/jstree/themes/default-rtl/style.css +83 -0
  208. data/public/jstree/themes/default-rtl/throbber.gif +0 -0
  209. data/public/stylesheets/sass/dreamy.sass +21 -56
  210. data/public/stylesheets/sass/menu.sass +43 -9
  211. data/public/stylesheets/sass/uploadify.sass +52 -0
  212. data/public/stylesheets/ui-lightness/images/ui-icons_228ef1_256x240.png +0 -0
  213. data/public/stylesheets/ui-lightness/jquery-ui-1.8.4.custom.css +549 -0
  214. data/wheels.gemspec +187 -15
  215. metadata +188 -16
@@ -0,0 +1,253 @@
1
+ /*
2
+ * Default text - jQuery plugin for html5 dragging files from desktop to browser
3
+ *
4
+ * Author: Weixi Yen
5
+ *
6
+ * Email: [Firstname][Lastname]@gmail.com
7
+ *
8
+ * Copyright (c) 2010 Resopollution
9
+ *
10
+ * Licensed under the MIT license:
11
+ * http://www.opensource.org/licenses/mit-license.php
12
+ *
13
+ * Project home:
14
+ * http://www.github.com/weixiyen/jquery-filedrop
15
+ *
16
+ * Version: 0.1.0
17
+ *
18
+ * Features:
19
+ * Allows sending of extra parameters with file.
20
+ * Works with Firefox 3.6+
21
+ * Future-compliant with HTML5 spec (will work with Webkit browsers and IE9)
22
+ * Usage:
23
+ * See README at project homepage
24
+ *
25
+ */
26
+ (function($){
27
+
28
+ var opts = {},
29
+ default_opts = {
30
+ url: '',
31
+ refresh: 1000,
32
+ paramname: 'userfile',
33
+ maxfiles: 25,
34
+ maxfilesize: 1, // MBs
35
+ data: {},
36
+ drop: empty,
37
+ dragEnter: empty,
38
+ dragOver: empty,
39
+ dragLeave: empty,
40
+ docEnter: empty,
41
+ docOver: empty,
42
+ docLeave: empty,
43
+ error: function(err, file){alert(err);},
44
+ uploadStarted: empty,
45
+ uploadFinished: empty,
46
+ progressUpdated: empty,
47
+ speedUpdated: empty
48
+ },
49
+ errors = ["BrowserNotSupported", "TooManyFiles", "FileTooLarge"],
50
+ doc_leave_timer,
51
+ stop_loop = false;
52
+
53
+ $.fn.filedrop = function(options) {
54
+ opts = $.extend( {}, default_opts, options );
55
+
56
+ this.get(0).addEventListener("drop", drop, true);
57
+ this.bind('dragenter', dragEnter).bind('dragover', dragOver).bind('dragleave', dragLeave);
58
+
59
+ document.addEventListener("drop", docDrop, true);
60
+ $(document).bind('dragenter', docEnter).bind('dragover', docOver).bind('dragleave', docLeave);
61
+ };
62
+
63
+ function drop(e) {
64
+ opts.drop(e);
65
+ upload(e.dataTransfer.files);
66
+ e.preventDefault();
67
+ return false;
68
+ }
69
+
70
+ function getBuilder(filename, filedata, boundary) {
71
+ var dashdash = '--',
72
+ crlf = '\r\n',
73
+ builder = '';
74
+
75
+ $.each(opts.data, function(i, val) {
76
+ if (typeof val === 'function') val = val();
77
+ builder += dashdash;
78
+ builder += boundary;
79
+ builder += crlf;
80
+ builder += 'Content-Disposition: form-data; name="'+i+'"';
81
+ builder += crlf;
82
+ builder += val;
83
+ builder += crlf;
84
+ });
85
+
86
+ builder += dashdash;
87
+ builder += boundary;
88
+ builder += crlf;
89
+
90
+ builder += dashdash;
91
+ builder += boundary;
92
+ builder += crlf;
93
+ builder += 'Content-Disposition: form-data; name="'+opts.paramname+'"';
94
+ builder += '; filename="' + filename + '"';
95
+ builder += crlf;
96
+
97
+ builder += 'Content-Type: application/octet-stream';
98
+ builder += crlf;
99
+ builder += crlf;
100
+
101
+ builder += filedata;
102
+ builder += crlf;
103
+
104
+ builder += dashdash;
105
+ builder += boundary;
106
+ builder += dashdash;
107
+ builder += crlf;
108
+ return builder;
109
+ }
110
+
111
+ function progress(e) {
112
+ if (e.lengthComputable) {
113
+ var percentage = Math.round((e.loaded * 100) / e.total);
114
+ if (this.currentProgress != percentage) {
115
+
116
+ this.currentProgress = percentage;
117
+ opts.progressUpdated(this.index, this.file, this.currentProgress);
118
+
119
+ var elapsed = new Date().getTime();
120
+ var diffTime = elapsed - this.currentStart;
121
+ if (diffTime >= opts.refresh) {
122
+ var diffData = e.loaded - this.startData;
123
+ var speed = diffData / diffTime; // KB per second
124
+ opts.speedUpdated(this.index, this.file, speed);
125
+ this.startData = e.loaded;
126
+ this.currentStart = elapsed;
127
+ }
128
+ }
129
+ }
130
+ }
131
+
132
+
133
+
134
+ function upload(files) {
135
+ stop_loop = false;
136
+ if (!files) {
137
+ opts.error(errors[0]);
138
+ return false;
139
+ }
140
+ var len = files.length;
141
+
142
+ if (len > opts.maxfiles) {
143
+ opts.error(errors[1]);
144
+ return false;
145
+ }
146
+
147
+ for (var i=0; i<len; i++) {
148
+ if (stop_loop) return false;
149
+ try {
150
+ if (i === len) return;
151
+ var reader = new FileReader(),
152
+ max_file_size = 1048576 * opts.maxfilesize;
153
+
154
+ reader.index = i;
155
+ reader.file = files[i];
156
+ reader.len = len;
157
+ if (reader.file.size > max_file_size) {
158
+ opts.error(errors[2], reader.file);
159
+ return false;
160
+ }
161
+
162
+ reader.addEventListener("loadend", send, false);
163
+ reader.readAsBinaryString(files[i]);
164
+ } catch(err) {
165
+ opts.error(errors[0]);
166
+ return false;
167
+ }
168
+ }
169
+
170
+ function send(e) {
171
+ var xhr = new XMLHttpRequest(),
172
+ upload = xhr.upload,
173
+ file = e.target.file,
174
+ index = e.target.index,
175
+ start_time = new Date().getTime(),
176
+ boundary = '------multipartformboundary' + (new Date).getTime(),
177
+ builder = getBuilder(file.name, e.target.result, boundary);
178
+
179
+ upload.index = index;
180
+ upload.file = file;
181
+ upload.downloadStartTime = start_time;
182
+ upload.currentStart = start_time;
183
+ upload.currentProgress = 0;
184
+ upload.startData = 0;
185
+ upload.addEventListener("progress", progress, false);
186
+
187
+ xhr.open("POST", opts.url, true);
188
+ xhr.setRequestHeader('content-type', 'multipart/form-data; boundary='
189
+ + boundary);
190
+
191
+ xhr.sendAsBinary(builder);
192
+
193
+ opts.uploadStarted(index, file, e.target.len);
194
+
195
+ xhr.onload = function() {
196
+ if (xhr.responseText) {
197
+ var now = new Date().getTime(),
198
+ timeDiff = now - start_time,
199
+ result = opts.uploadFinished(index, file, eval( '[' + xhr.responseText + ']' ), timeDiff);
200
+ if (result === false) stop_loop = true;
201
+ }
202
+ };
203
+ }
204
+ }
205
+
206
+ function dragEnter(e) {
207
+ clearTimeout(doc_leave_timer);
208
+ e.preventDefault();
209
+ opts.dragEnter(e);
210
+ }
211
+
212
+ function dragOver(e) {
213
+ clearTimeout(doc_leave_timer);
214
+ e.preventDefault();
215
+ opts.docOver(e);
216
+ opts.dragOver(e);
217
+ }
218
+
219
+ function dragLeave(e) {
220
+ clearTimeout(doc_leave_timer);
221
+ opts.dragLeave(e);
222
+ e.stopPropagation();
223
+ }
224
+
225
+ function docDrop(e) {
226
+ e.preventDefault();
227
+ opts.docLeave(e);
228
+ return false;
229
+ }
230
+
231
+ function docEnter(e) {
232
+ clearTimeout(doc_leave_timer);
233
+ e.preventDefault();
234
+ opts.docEnter(e);
235
+ return false;
236
+ }
237
+
238
+ function docOver(e) {
239
+ clearTimeout(doc_leave_timer);
240
+ e.preventDefault();
241
+ opts.docOver(e);
242
+ return false;
243
+ }
244
+
245
+ function docLeave(e) {
246
+ doc_leave_timer = setTimeout(function(){
247
+ opts.docLeave(e);
248
+ }, 200);
249
+ }
250
+
251
+ function empty(){}
252
+
253
+ })(jQuery);
@@ -0,0 +1,99 @@
1
+ /*
2
+ * jQuery Hotkeys Plugin
3
+ * Copyright 2010, John Resig
4
+ * Dual licensed under the MIT or GPL Version 2 licenses.
5
+ *
6
+ * Based upon the plugin by Tzury Bar Yochay:
7
+ * http://github.com/tzuryby/hotkeys
8
+ *
9
+ * Original idea by:
10
+ * Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/
11
+ */
12
+
13
+ (function(jQuery){
14
+
15
+ jQuery.hotkeys = {
16
+ version: "0.8",
17
+
18
+ specialKeys: {
19
+ 8: "backspace", 9: "tab", 13: "return", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause",
20
+ 20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home",
21
+ 37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "del",
22
+ 96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7",
23
+ 104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".", 111 : "/",
24
+ 112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8",
25
+ 120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scroll", 191: "/", 224: "meta"
26
+ },
27
+
28
+ shiftNums: {
29
+ "`": "~", "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&",
30
+ "8": "*", "9": "(", "0": ")", "-": "_", "=": "+", ";": ": ", "'": "\"", ",": "<",
31
+ ".": ">", "/": "?", "\\": "|"
32
+ }
33
+ };
34
+
35
+ function keyHandler( handleObj ) {
36
+ // Only care when a possible input has been specified
37
+ if ( typeof handleObj.data !== "string" ) {
38
+ return;
39
+ }
40
+
41
+ var origHandler = handleObj.handler,
42
+ keys = handleObj.data.toLowerCase().split(" ");
43
+
44
+ handleObj.handler = function( event ) {
45
+ // Don't fire in text-accepting inputs that we didn't directly bind to
46
+ if ( this !== event.target && (/textarea|select/i.test( event.target.nodeName ) ||
47
+ event.target.type === "text") ) {
48
+ return;
49
+ }
50
+
51
+ // Keypress represents characters, not special keys
52
+ var special = event.type !== "keypress" && jQuery.hotkeys.specialKeys[ event.which ],
53
+ character = String.fromCharCode( event.which ).toLowerCase(),
54
+ key, modif = "", possible = {};
55
+
56
+ // check combinations (alt|ctrl|shift+anything)
57
+ if ( event.altKey && special !== "alt" ) {
58
+ modif += "alt+";
59
+ }
60
+
61
+ if ( event.ctrlKey && special !== "ctrl" ) {
62
+ modif += "ctrl+";
63
+ }
64
+
65
+ // TODO: Need to make sure this works consistently across platforms
66
+ if ( event.metaKey && !event.ctrlKey && special !== "meta" ) {
67
+ modif += "meta+";
68
+ }
69
+
70
+ if ( event.shiftKey && special !== "shift" ) {
71
+ modif += "shift+";
72
+ }
73
+
74
+ if ( special ) {
75
+ possible[ modif + special ] = true;
76
+
77
+ } else {
78
+ possible[ modif + character ] = true;
79
+ possible[ modif + jQuery.hotkeys.shiftNums[ character ] ] = true;
80
+
81
+ // "$" can be triggered as "Shift+4" or "Shift+$" or just "$"
82
+ if ( modif === "shift+" ) {
83
+ possible[ jQuery.hotkeys.shiftNums[ character ] ] = true;
84
+ }
85
+ }
86
+
87
+ for ( var i = 0, l = keys.length; i < l; i++ ) {
88
+ if ( possible[ keys[i] ] ) {
89
+ return origHandler.apply( this, arguments );
90
+ }
91
+ }
92
+ };
93
+ }
94
+
95
+ jQuery.each([ "keydown", "keyup", "keypress" ], function() {
96
+ jQuery.event.special[ this ] = { add: keyHandler };
97
+ });
98
+
99
+ })( jQuery );