enki-engine 0.0.2

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. data/.gitignore +13 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +3 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +284 -0
  6. data/README.textile +112 -0
  7. data/Rakefile +13 -0
  8. data/TODO.textile +8 -0
  9. data/app/assets/images/admin/flash_bg.gif +0 -0
  10. data/app/assets/images/admin/future_bg.png +0 -0
  11. data/app/assets/images/admin/gray_bg.gif +0 -0
  12. data/app/assets/images/admin/new_button.png +0 -0
  13. data/app/assets/images/admin/silver_bg.gif +0 -0
  14. data/app/assets/images/admin/submit_bg.gif +0 -0
  15. data/app/assets/images/admin/subnav_bg.gif +0 -0
  16. data/app/assets/images/openid_icon.png +0 -0
  17. data/app/assets/images/rails.png +0 -0
  18. data/app/assets/images/silk/arrow_undo.png +0 -0
  19. data/app/assets/images/silk/delete.png +0 -0
  20. data/app/assets/images/silk/pencil.png +0 -0
  21. data/app/assets/javascripts/admin/actions.js +18 -0
  22. data/app/assets/javascripts/admin/comments.js +3 -0
  23. data/app/assets/javascripts/admin/common.js +109 -0
  24. data/app/assets/javascripts/admin/dashboard.js +33 -0
  25. data/app/assets/javascripts/admin/edit-preview.js +40 -0
  26. data/app/assets/javascripts/admin/pages.js +1 -0
  27. data/app/assets/javascripts/admin/posts.js +1 -0
  28. data/app/assets/javascripts/admin/shortcut.js +223 -0
  29. data/app/assets/javascripts/admin.js +17 -0
  30. data/app/assets/javascripts/application.js +15 -0
  31. data/app/assets/javascripts/common.js +22 -0
  32. data/app/assets/javascripts/enki.js +13 -0
  33. data/app/assets/javascripts/live-comment-preview.js +36 -0
  34. data/app/assets/stylesheets/admin.css +304 -0
  35. data/app/assets/stylesheets/application.css.scss +486 -0
  36. data/app/assets/stylesheets/humanmsg.css +112 -0
  37. data/app/assets/stylesheets/login.css +65 -0
  38. data/app/controllers/enki/admin/base_controller.rb +15 -0
  39. data/app/controllers/enki/admin/comments_controller.rb +52 -0
  40. data/app/controllers/enki/admin/dashboard_controller.rb +12 -0
  41. data/app/controllers/enki/admin/health_controller.rb +20 -0
  42. data/app/controllers/enki/admin/pages_controller.rb +97 -0
  43. data/app/controllers/enki/admin/posts_controller.rb +104 -0
  44. data/app/controllers/enki/admin/undo_items_controller.rb +43 -0
  45. data/app/controllers/enki/application_controller.rb +21 -0
  46. data/app/controllers/enki/archives_controller.rb +7 -0
  47. data/app/controllers/enki/base_controller.rb +5 -0
  48. data/app/controllers/enki/comments_controller.rb +43 -0
  49. data/app/controllers/enki/pages_controller.rb +7 -0
  50. data/app/controllers/enki/posts_controller.rb +27 -0
  51. data/app/helpers/enki/admin/navigation_helper.rb +10 -0
  52. data/app/helpers/enki/application_helper.rb +35 -0
  53. data/app/helpers/enki/date_helper.rb +15 -0
  54. data/app/helpers/enki/form_helper.rb +7 -0
  55. data/app/helpers/enki/host_helper.rb +19 -0
  56. data/app/helpers/enki/navigation_helper.rb +23 -0
  57. data/app/helpers/enki/page_title_helper.rb +33 -0
  58. data/app/helpers/enki/posts_helper.rb +9 -0
  59. data/app/helpers/enki/tag_helper.rb +7 -0
  60. data/app/helpers/enki/url_helper.rb +25 -0
  61. data/app/models/enki/base/post.rb +153 -0
  62. data/app/models/enki/comment.rb +75 -0
  63. data/app/models/enki/comment_activity.rb +33 -0
  64. data/app/models/enki/delete_comment_undo.rb +33 -0
  65. data/app/models/enki/delete_page_undo.rb +32 -0
  66. data/app/models/enki/delete_post_undo.rb +36 -0
  67. data/app/models/enki/page.rb +42 -0
  68. data/app/models/enki/post.rb +4 -0
  69. data/app/models/enki/stats.rb +19 -0
  70. data/app/models/enki/tag.rb +19 -0
  71. data/app/models/enki/tagging.rb +7 -0
  72. data/app/models/enki/undo_item.rb +10 -0
  73. data/app/views/enki/admin/comments/_comment.html.erb +12 -0
  74. data/app/views/enki/admin/comments/index.html.erb +30 -0
  75. data/app/views/enki/admin/comments/show.html.erb +9 -0
  76. data/app/views/enki/admin/dashboard/show.html.erb +61 -0
  77. data/app/views/enki/admin/health/index.html.erb +3 -0
  78. data/app/views/enki/admin/pages/_form.html.erb +3 -0
  79. data/app/views/enki/admin/pages/_page.html.erb +12 -0
  80. data/app/views/enki/admin/pages/index.html.erb +25 -0
  81. data/app/views/enki/admin/pages/new.html.erb +8 -0
  82. data/app/views/enki/admin/pages/show.html.erb +8 -0
  83. data/app/views/enki/admin/posts/_form.html.erb +11 -0
  84. data/app/views/enki/admin/posts/_post.html.erb +12 -0
  85. data/app/views/enki/admin/posts/_taggings_form.html.erb +4 -0
  86. data/app/views/enki/admin/posts/_upload_form.html.erb +0 -0
  87. data/app/views/enki/admin/posts/index.html.erb +25 -0
  88. data/app/views/enki/admin/posts/new.html.erb +8 -0
  89. data/app/views/enki/admin/posts/show.html.erb +8 -0
  90. data/app/views/enki/admin/undo_items/index.html.erb +24 -0
  91. data/app/views/enki/archives/index.html.erb +17 -0
  92. data/app/views/enki/comments/_comment.html.erb +4 -0
  93. data/app/views/enki/pages/_page.html.erb +3 -0
  94. data/app/views/enki/pages/show.html.erb +5 -0
  95. data/app/views/enki/posts/_post.html.erb +13 -0
  96. data/app/views/enki/posts/index.atom.builder +27 -0
  97. data/app/views/enki/posts/index.html.erb +15 -0
  98. data/app/views/enki/posts/show.html.erb +37 -0
  99. data/autotest/discover.rb +2 -0
  100. data/config/cucumber.yml +8 -0
  101. data/config/enki.yml.sample +16 -0
  102. data/config/initializers/enki_ext.rb +3 -0
  103. data/config/initializers/set_chronic_timezone.rb +1 -0
  104. data/config/initializers/verification.rb +135 -0
  105. data/config/routes.rb +34 -0
  106. data/db/migrate/20110709024316_initialize_db.rb +97 -0
  107. data/db/seeds.rb +8 -0
  108. data/enki-engine.gemspec +47 -0
  109. data/features/admin_dashboard.feature +10 -0
  110. data/features/admin_health.feature +10 -0
  111. data/features/admin_undo.feature +20 -0
  112. data/features/browsing.feature +16 -0
  113. data/features/step_definitions/admin.rb +27 -0
  114. data/features/step_definitions/browsing.rb +3 -0
  115. data/features/step_definitions/posts.rb +11 -0
  116. data/features/step_definitions/web_steps.rb +1 -0
  117. data/features/support/env.rb +59 -0
  118. data/features/support/paths.rb +35 -0
  119. data/features/support/selectors.rb +39 -0
  120. data/lib/core_extensions/object.rb +9 -0
  121. data/lib/core_extensions/string.rb +22 -0
  122. data/lib/enki/config.rb +44 -0
  123. data/lib/enki/engine.rb +19 -0
  124. data/lib/enki/html5_tags.rb +8 -0
  125. data/lib/enki/pagination_shim.rb +25 -0
  126. data/lib/enki/version.rb +3 -0
  127. data/lib/enki.rb +14 -0
  128. data/lib/enki_formatter.rb +11 -0
  129. data/lib/tag_list.rb +2 -0
  130. data/lib/tags_helper.rb +13 -0
  131. data/lib/tasks/cucumber.rake +65 -0
  132. data/lib/tasks/enki.rake +29 -0
  133. data/lib/undo_failed.rb +2 -0
  134. data/script/cucumber +10 -0
  135. data/spec/controllers/admin/comments_controller_spec.rb +140 -0
  136. data/spec/controllers/admin/dashboard_controller_spec.rb +47 -0
  137. data/spec/controllers/admin/health_controller_spec.rb +49 -0
  138. data/spec/controllers/admin/pages_controller_spec.rb +136 -0
  139. data/spec/controllers/admin/posts_controller_spec.rb +183 -0
  140. data/spec/controllers/admin/undo_items_controller_spec.rb +93 -0
  141. data/spec/controllers/archives_controller_spec.rb +37 -0
  142. data/spec/controllers/comments_controller_spec.rb +126 -0
  143. data/spec/controllers/pages_controller_spec.rb +46 -0
  144. data/spec/controllers/posts_controller_spec.rb +168 -0
  145. data/spec/dummy/Gemfile +5 -0
  146. data/spec/dummy/Rakefile +7 -0
  147. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  148. data/spec/dummy/config/application.rb +34 -0
  149. data/spec/dummy/config/boot.rb +10 -0
  150. data/spec/dummy/config/database.yml +6 -0
  151. data/spec/dummy/config/enki.yml +20 -0
  152. data/spec/dummy/config/environment.rb +5 -0
  153. data/spec/dummy/config/environments/development.rb +34 -0
  154. data/spec/dummy/config/environments/test.rb +32 -0
  155. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  156. data/spec/dummy/config/initializers/session_store.rb +8 -0
  157. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  158. data/spec/dummy/config/locales/en.yml +5 -0
  159. data/spec/dummy/config/routes.rb +14 -0
  160. data/spec/dummy/config.ru +6 -0
  161. data/spec/dummy/script/rails +6 -0
  162. data/spec/factories/factories.rb +36 -0
  163. data/spec/helpers/page_title_helper_spec.rb +54 -0
  164. data/spec/helpers/url_helper_spec.rb +23 -0
  165. data/spec/lib/slugorize_spec.rb +44 -0
  166. data/spec/models/comment_activity_spec.rb +60 -0
  167. data/spec/models/comment_spec.rb +125 -0
  168. data/spec/models/delete_comment_undo_spec.rb +52 -0
  169. data/spec/models/delete_post_undo_spec.rb +18 -0
  170. data/spec/models/page_spec.rb +75 -0
  171. data/spec/models/post_spec.rb +257 -0
  172. data/spec/models/stats_spec.rb +28 -0
  173. data/spec/models/tag_spec.rb +13 -0
  174. data/spec/models/tagging_spec.rb +30 -0
  175. data/spec/rcov.opts +2 -0
  176. data/spec/routing/admin/pages_routing_spec.rb +29 -0
  177. data/spec/routing/archives_routing_spec.rb +9 -0
  178. data/spec/routing/comments_routing_spec.rb +17 -0
  179. data/spec/routing/pages_routing_spec.rb +9 -0
  180. data/spec/routing/posts_routing_spec.rb +26 -0
  181. data/spec/spec.opts +4 -0
  182. data/spec/spec_helper.rb +60 -0
  183. data/spec/support/be_valid_html5.rb +150 -0
  184. data/spec/support/be_valid_xhtml.rb +148 -0
  185. data/spec/support/routes_override_helper.rb +12 -0
  186. data/spec/views/admin/comments/index.html_spec.rb +26 -0
  187. data/spec/views/admin/comments/show.html_spec.rb +28 -0
  188. data/spec/views/admin/dashboard/show.html_spec.rb +37 -0
  189. data/spec/views/admin/pages/index.html_spec.rb +23 -0
  190. data/spec/views/admin/pages/new.html_spec.rb +16 -0
  191. data/spec/views/admin/pages/show.html_spec.rb +16 -0
  192. data/spec/views/admin/posts/index.html_spec.rb +24 -0
  193. data/spec/views/admin/posts/new.html_spec.rb +16 -0
  194. data/spec/views/admin/posts/show.html_spec.rb +16 -0
  195. data/spec/views/admin/undo_items/index.html_spec.rb +19 -0
  196. data/spec/views/archives/index.html_spec.rb +34 -0
  197. data/spec/views/pages/show.html_spec.rb +23 -0
  198. data/spec/views/posts/index.atom.builder_spec.rb +36 -0
  199. data/spec/views/posts/index.html_spec.rb +39 -0
  200. data/spec/views/posts/show.html_spec.rb +49 -0
  201. data/vendor/assets/javascripts/humanmsg.js +86 -0
  202. data/vendor/assets/javascripts/jquery.easing.1.3.js +205 -0
  203. data/vendor/assets/javascripts/jquery.form.js +869 -0
  204. data/vendor/assets/javascripts/jquery.jfeed.js +143 -0
  205. data/vendor/assets/javascripts/jquery.livequery.js +250 -0
  206. metadata +464 -0
@@ -0,0 +1,40 @@
1
+ $(document).ready(function() {
2
+ var form = $('form.formtastic, form.simple_form');
3
+
4
+ if (form.length > 0 && form.attr('id').match(/^(new_enki_post|edit_enki_post|new_enki_page|edit_enki_page)/)) {
5
+ var dest = window.location.href;
6
+ dest = dest.replace(/\/(new|\d+)$/, '')
7
+ dest = dest + '/preview'
8
+
9
+ var toggle_preview = function() {
10
+ if ($('#preview').length == 0) {
11
+ form.hide();
12
+ form.after('<div id="preview"><h3>Your entry will be formatted like this:</h3><p>Use Ctrl+E to return to edit mode.</p><div class="content"><p>Please wait...</p></div></div>');
13
+
14
+ jQuery.ajax({
15
+ type: 'POST',
16
+ data: form.serialize().replace(/&*_method=\w+&*/, ''),
17
+ url: dest,
18
+ dataType: 'html',
19
+ error: function() {
20
+ $('#preview .content').html('<p>Failed to generate preview. Toggle back to edit mode and check that all required fields are filled in and valid.</p>');
21
+ },
22
+ success: function(r) {
23
+ $('#preview .content').html(r);
24
+ }
25
+ });
26
+ }
27
+ else {
28
+ $('#preview').remove();
29
+ form.show();
30
+ }
31
+ }
32
+
33
+ $(document).keyup(function(e) {
34
+ if (e.ctrlKey && (e.which == 69)) { // Works in recent Safari and FF, unsure about IE
35
+ toggle_preview();
36
+ e.preventDefault();
37
+ }
38
+ });
39
+ }
40
+ });
@@ -0,0 +1 @@
1
+ $(document).ready(destroyAndUndoBehaviour('pages')); // Defined in admin/common.js
@@ -0,0 +1 @@
1
+ $(document).ready(destroyAndUndoBehaviour('posts')); // Defined in admin/common.js
@@ -0,0 +1,223 @@
1
+ /**
2
+ * http://www.openjs.com/scripts/events/keyboard_shortcuts/
3
+ * Version : 2.01.A
4
+ * By Binny V A
5
+ * License : BSD
6
+ */
7
+ shortcut = {
8
+ 'all_shortcuts':{},//All the shortcuts are stored in this array
9
+ 'add': function(shortcut_combination,callback,opt) {
10
+ //Provide a set of default options
11
+ var default_options = {
12
+ 'type':'keydown',
13
+ 'propagate':false,
14
+ 'disable_in_input':false,
15
+ 'target':document,
16
+ 'keycode':false
17
+ }
18
+ if(!opt) opt = default_options;
19
+ else {
20
+ for(var dfo in default_options) {
21
+ if(typeof opt[dfo] == 'undefined') opt[dfo] = default_options[dfo];
22
+ }
23
+ }
24
+
25
+ var ele = opt.target
26
+ if(typeof opt.target == 'string') ele = document.getElementById(opt.target);
27
+ var ths = this;
28
+ shortcut_combination = shortcut_combination.toLowerCase();
29
+
30
+ //The function to be called at keypress
31
+ var func = function(e) {
32
+ e = e || window.event;
33
+
34
+ if(opt['disable_in_input']) { //Don't enable shortcut keys in Input, Textarea fields
35
+ var element;
36
+ if(e.target) element=e.target;
37
+ else if(e.srcElement) element=e.srcElement;
38
+ if(element.nodeType==3) element=element.parentNode;
39
+
40
+ if(element.tagName == 'INPUT' || element.tagName == 'TEXTAREA') return;
41
+ }
42
+
43
+ //Find Which key is pressed
44
+ if (e.keyCode) code = e.keyCode;
45
+ else if (e.which) code = e.which;
46
+ var character = String.fromCharCode(code).toLowerCase();
47
+
48
+ if(code == 188) character=","; //If the user presses , when the type is onkeydown
49
+ if(code == 190) character="."; //If the user presses , when the type is onkeydown
50
+
51
+ var keys = shortcut_combination.split("+");
52
+ //Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked
53
+ var kp = 0;
54
+
55
+ //Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken
56
+ var shift_nums = {
57
+ "`":"~",
58
+ "1":"!",
59
+ "2":"@",
60
+ "3":"#",
61
+ "4":"$",
62
+ "5":"%",
63
+ "6":"^",
64
+ "7":"&",
65
+ "8":"*",
66
+ "9":"(",
67
+ "0":")",
68
+ "-":"_",
69
+ "=":"+",
70
+ ";":":",
71
+ "'":"\"",
72
+ ",":"<",
73
+ ".":">",
74
+ "/":"?",
75
+ "\\":"|"
76
+ }
77
+ //Special Keys - and their codes
78
+ var special_keys = {
79
+ 'esc':27,
80
+ 'escape':27,
81
+ 'tab':9,
82
+ 'space':32,
83
+ 'return':13,
84
+ 'enter':13,
85
+ 'backspace':8,
86
+
87
+ 'scrolllock':145,
88
+ 'scroll_lock':145,
89
+ 'scroll':145,
90
+ 'capslock':20,
91
+ 'caps_lock':20,
92
+ 'caps':20,
93
+ 'numlock':144,
94
+ 'num_lock':144,
95
+ 'num':144,
96
+
97
+ 'pause':19,
98
+ 'break':19,
99
+
100
+ 'insert':45,
101
+ 'home':36,
102
+ 'delete':46,
103
+ 'end':35,
104
+
105
+ 'pageup':33,
106
+ 'page_up':33,
107
+ 'pu':33,
108
+
109
+ 'pagedown':34,
110
+ 'page_down':34,
111
+ 'pd':34,
112
+
113
+ 'left':37,
114
+ 'up':38,
115
+ 'right':39,
116
+ 'down':40,
117
+
118
+ 'f1':112,
119
+ 'f2':113,
120
+ 'f3':114,
121
+ 'f4':115,
122
+ 'f5':116,
123
+ 'f6':117,
124
+ 'f7':118,
125
+ 'f8':119,
126
+ 'f9':120,
127
+ 'f10':121,
128
+ 'f11':122,
129
+ 'f12':123
130
+ }
131
+
132
+ var modifiers = {
133
+ shift: { wanted:false, pressed:false},
134
+ ctrl : { wanted:false, pressed:false},
135
+ alt : { wanted:false, pressed:false},
136
+ meta : { wanted:false, pressed:false} //Meta is Mac specific
137
+ };
138
+
139
+ if(e.ctrlKey) modifiers.ctrl.pressed = true;
140
+ if(e.shiftKey) modifiers.shift.pressed = true;
141
+ if(e.altKey) modifiers.alt.pressed = true;
142
+ if(e.metaKey) modifiers.meta.pressed = true;
143
+
144
+ for(var i=0; k=keys[i],i<keys.length; i++) {
145
+ //Modifiers
146
+ if(k == 'ctrl' || k == 'control') {
147
+ kp++;
148
+ modifiers.ctrl.wanted = true;
149
+
150
+ } else if(k == 'shift') {
151
+ kp++;
152
+ modifiers.shift.wanted = true;
153
+
154
+ } else if(k == 'alt') {
155
+ kp++;
156
+ modifiers.alt.wanted = true;
157
+ } else if(k == 'meta') {
158
+ kp++;
159
+ modifiers.meta.wanted = true;
160
+ } else if(k.length > 1) { //If it is a special key
161
+ if(special_keys[k] == code) kp++;
162
+
163
+ } else if(opt['keycode']) {
164
+ if(opt['keycode'] == code) kp++;
165
+
166
+ } else { //The special keys did not match
167
+ if(character == k) kp++;
168
+ else {
169
+ if(shift_nums[character] && e.shiftKey) { //Stupid Shift key bug created by using lowercase
170
+ character = shift_nums[character];
171
+ if(character == k) kp++;
172
+ }
173
+ }
174
+ }
175
+ }
176
+
177
+ if(kp == keys.length &&
178
+ modifiers.ctrl.pressed == modifiers.ctrl.wanted &&
179
+ modifiers.shift.pressed == modifiers.shift.wanted &&
180
+ modifiers.alt.pressed == modifiers.alt.wanted &&
181
+ modifiers.meta.pressed == modifiers.meta.wanted) {
182
+ callback(e);
183
+
184
+ if(!opt['propagate']) { //Stop the event
185
+ //e.cancelBubble is supported by IE - this will kill the bubbling process.
186
+ e.cancelBubble = true;
187
+ e.returnValue = false;
188
+
189
+ //e.stopPropagation works in Firefox.
190
+ if (e.stopPropagation) {
191
+ e.stopPropagation();
192
+ e.preventDefault();
193
+ }
194
+ return false;
195
+ }
196
+ }
197
+ }
198
+ this.all_shortcuts[shortcut_combination] = {
199
+ 'callback':func,
200
+ 'target':ele,
201
+ 'event': opt['type']
202
+ };
203
+ //Attach the function with the event
204
+ if(ele.addEventListener) ele.addEventListener(opt['type'], func, false);
205
+ else if(ele.attachEvent) ele.attachEvent('on'+opt['type'], func);
206
+ else ele['on'+opt['type']] = func;
207
+ },
208
+
209
+ //Remove the shortcut - just specify the shortcut and I will remove the binding
210
+ 'remove':function(shortcut_combination) {
211
+ shortcut_combination = shortcut_combination.toLowerCase();
212
+ var binding = this.all_shortcuts[shortcut_combination];
213
+ delete(this.all_shortcuts[shortcut_combination])
214
+ if(!binding) return;
215
+ var type = binding['event'];
216
+ var ele = binding['target'];
217
+ var callback = binding['callback'];
218
+
219
+ if(ele.detachEvent) ele.detachEvent('on'+type, callback);
220
+ else if(ele.removeEventListener) ele.removeEventListener(type, callback, false);
221
+ else ele['on'+type] = false;
222
+ }
223
+ }
@@ -0,0 +1,17 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // the compiled file.
9
+ //
10
+ // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11
+ // GO AFTER THE REQUIRES BELOW.
12
+ //
13
+ //= require jquery.livequery
14
+ //= require jquery.form
15
+ //= require jquery.easing.1.3
16
+ //= require humanmsg
17
+ //= require_tree ./admin
@@ -0,0 +1,15 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // the compiled file.
9
+ //
10
+ // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11
+ // GO AFTER THE REQUIRES BELOW.
12
+ //
13
+ //= require common
14
+ //= require live-comment-preview
15
+ //= require_self
@@ -0,0 +1,22 @@
1
+ // Based on http://www.germanforblack.com/javascript-sleeping-keypress-delays-and-bashing-bad-articles
2
+ Function.prototype.only_every = function (millisecond_delay) {
3
+ if (!window.only_every_func)
4
+ {
5
+ var function_object = this;
6
+ window.only_every_func = setTimeout(function() { function_object(); window.only_every_func = null}, millisecond_delay);
7
+ }
8
+ };
9
+
10
+ // http://www.ivanuzunov.net/top-10-javascript-stringprototype-extensions/
11
+ String.prototype.endsWith = function(t, i) {
12
+ if (i==false) {
13
+ return (t == this.substring(this.length - t.length));
14
+ } else {
15
+ return (t.toLowerCase() == this.substring(this.length - t.length).toLowerCase());
16
+ }
17
+ }
18
+
19
+ // jQuery extensions
20
+ jQuery.prototype.any = function(callback) {
21
+ return (this.filter(callback).length > 0)
22
+ }
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // the compiled file.
9
+ //
10
+ // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11
+ // GO AFTER THE REQUIRES BELOW.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,36 @@
1
+ $(function() { // onload
2
+ var comment_form = $('#new_comment')
3
+ var input_elements = comment_form.find(':text, textarea')
4
+ var fetch_comment_preview = function() {
5
+ var dest = window.location.href;
6
+ dest = dest.split('#')[0];
7
+ dest = dest.split('?')[0];
8
+
9
+ if (!dest.endsWith('comments'))
10
+ dest += '/comments';
11
+
12
+ jQuery.ajax({
13
+ data: comment_form.serialize(),
14
+ url: dest + '/new',
15
+ timeout: 2000,
16
+ error: function() {
17
+ if ($('#comment-preview').length == 0) {
18
+ comment_form.after('<div id="comment-preview"></div>')
19
+ }
20
+ $('#comment-preview').text("Failed to submit");
21
+ },
22
+ success: function(r) {
23
+ if ($('#comment-preview').length == 0) {
24
+ comment_form.after('<h2>Your comment will look like this:</h2><div id="comment-preview"></div>')
25
+ }
26
+ $('#comment-preview').html(r)
27
+ }
28
+ })
29
+ }
30
+
31
+ input_elements.keyup(function () {
32
+ fetch_comment_preview.only_every(1000);
33
+ })
34
+ if (input_elements.any(function() { return $(this).val().length > 0 }))
35
+ fetch_comment_preview();
36
+ })
@@ -0,0 +1,304 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require humanmsg
13
+ */
14
+
15
+ #nav {
16
+ position: absolute;
17
+ width: 100%;
18
+ top: 0px;
19
+ left: 0px;
20
+ background-color: #222222;
21
+ }
22
+
23
+ #nav ul {
24
+ list-style-type: none;
25
+ margin: 10px;
26
+ padding: 0;
27
+ }
28
+
29
+ #nav ul li {
30
+ display: inline;
31
+ margin-right: 10px;
32
+ }
33
+
34
+ #nav a {
35
+ color: #eeeeee;
36
+ text-decoration: none;
37
+ font-weight: bold;
38
+ }
39
+ #nav a.current {
40
+ border-bottom: solid 3px #eeeeee;
41
+ }
42
+
43
+ body {
44
+ padding-top: 30px;
45
+ background-color: #dddddd;
46
+ font-family: Helvetica, Sans-serif;
47
+ font-size: 10pt;
48
+ margin: 10px;
49
+ }
50
+
51
+ .panel {
52
+ float: left;
53
+ margin-top: 10px;
54
+ margin-right: 10px;
55
+ color: #222222;
56
+ background-color: #ececec;
57
+ padding: 1em;
58
+ padding-top: 0.2em;
59
+ padding-bottom: 0.2em;
60
+ width: 34em;
61
+ min-height: 270px;
62
+ }
63
+
64
+ .panel h2 {
65
+ margin-bottom: 2px;
66
+ }
67
+
68
+ .panel p {
69
+ margin-top: 0;
70
+ }
71
+
72
+ .panel a {
73
+ color: #222222;
74
+ font-weight: bold;
75
+ text-decoration: none;
76
+ }
77
+
78
+ .panel ul {
79
+ margin-left: 0px;
80
+ padding-left: 0px;
81
+ list-style-type: none;
82
+ }
83
+
84
+ .panel ul li.item {
85
+ overflow: hidden;
86
+ margin-top: 4px;
87
+ padding-top: 6px;
88
+ border-top: solid 1px #cccccc;
89
+ }
90
+
91
+ .panel ul li.first {
92
+ border: none;
93
+ }
94
+
95
+ .panel h3 {
96
+ float: left;
97
+ font-size: 10pt;
98
+ margin: 0;
99
+ margin-right: 1em;
100
+ }
101
+
102
+ .panel .date {
103
+ float: left;
104
+ font-size: 10pt;
105
+ }
106
+
107
+ .panel .count {
108
+ float: right;
109
+ }
110
+
111
+ .panel .count a {
112
+ font-weight: bold;
113
+ color: #888888;
114
+ }
115
+
116
+ #recent-comments ul ul {
117
+ clear: left;
118
+ }
119
+
120
+ #recent-comments ul ul li {
121
+ display: inline;
122
+ }
123
+
124
+ #recent-comments ul ul li:after {
125
+ content: ", ";
126
+ }
127
+
128
+ #recent-comments ul ul li.last:after {
129
+ content: "";
130
+ }
131
+
132
+ #recent-comments .count {
133
+ font-size: 22pt;
134
+ line-height: 1;
135
+ }
136
+
137
+ #recent-comments .comment-body {
138
+ position: absolute;
139
+ width: 33.1em;
140
+ background-color: #ffffff;
141
+ border: solid 1px #cccccc;
142
+ padding: 5px;
143
+ margin-top: 4px;
144
+ }
145
+
146
+ #recent-comments .comment-body p {
147
+ margin: 0;
148
+ }
149
+
150
+ #recent-comments .comment-body table {
151
+ margin: 0;
152
+ }
153
+
154
+ #recent-comments .comment-link {
155
+ font-weight: normal;
156
+ }
157
+
158
+ #recent-comments .comment-body div.comment-actions {
159
+ margin-bottom: 10px;
160
+ color: #888888;
161
+ }
162
+
163
+ #recent-comments .comment-body a {
164
+ font-weight: normal;
165
+ color: #888888;
166
+ }
167
+ #summary {
168
+ text-align: center;
169
+ max-width: 970px;
170
+ width: 100%;
171
+ color: #222222;
172
+ }
173
+ #summary h1 {
174
+ margin-bottom: 0;
175
+ }
176
+ #summary a {
177
+ text-decoration: none;
178
+ }
179
+
180
+ #summary p {
181
+ margin-top: 2px;
182
+ font-weight: bold;
183
+ font-size: 12px;
184
+ }
185
+
186
+ a {
187
+ color: #222222;
188
+ }
189
+
190
+ /* -------- FORMS */
191
+ form input,
192
+ form select,
193
+ form textarea,
194
+ form button {
195
+ font: 8pt "lucida grande", "lucida sans unicode", "lucida", sans-serif;
196
+ }
197
+
198
+ #post_body,
199
+ #page_body {
200
+ width: 600px;
201
+ height: 450px;
202
+ }
203
+
204
+ form fieldset { margin-bottom: 10px; width: 622px; padding: 10px; }
205
+ form fieldset.buttons { text-align: center; }
206
+ form fieldset.buttons input { width: 300px; }
207
+
208
+ p.inline-hints { clear: both; }
209
+ form fieldset ol li {
210
+ border: none;
211
+ }
212
+
213
+ form fieldset ol {
214
+ list-style-type: none;
215
+ padding: 0px;
216
+ margin: 0px;
217
+ }
218
+
219
+ form fieldset ol li label {
220
+ width: 100px;
221
+ }
222
+
223
+ form fieldset ol li p.inline-hints {
224
+ margin-left: 100px;
225
+ }
226
+ form fieldset ol li.boolean label {
227
+ padding-left: 100px;
228
+ }
229
+
230
+ /* ---------- TABLES */
231
+ table {
232
+ font-size: 12px;
233
+ color: #222222;
234
+ background-color: #ececec;
235
+ margin-bottom: 20px;
236
+ border-collapse: collapse;
237
+ padding: 0;
238
+ }
239
+
240
+ table td {
241
+ padding: 5px;
242
+ }
243
+
244
+ table tr.alt td {
245
+ background-color: #dddddd;
246
+ }
247
+
248
+ table th,
249
+ table tr.pagination td {
250
+ background-color: #222222;
251
+ color: #eeeeee;
252
+ padding: 5px;
253
+ }
254
+
255
+ table form {
256
+ display: inline;
257
+ }
258
+
259
+ div.pagination {
260
+ text-align: center;
261
+ }
262
+
263
+ div.pagination a {
264
+ color: #eeeeee;
265
+ }
266
+
267
+ .comment-actions img,
268
+ table img {
269
+ float: left;
270
+ border: none;
271
+ display: inline;
272
+ }
273
+
274
+ /* --------- MESSAGING */
275
+ .humanMsg .undo-link {
276
+ display: none;
277
+ }
278
+
279
+ /* --------- EDIT PREVIEW */
280
+ #preview {
281
+ padding-bottom: 10px;
282
+ }
283
+
284
+ #preview > h3 {
285
+ margin: 0;
286
+ }
287
+
288
+ #preview > p {
289
+ color: #666666;
290
+ margin-top: 0.3em;
291
+ }
292
+
293
+ #preview .content {
294
+ color: #222222;
295
+ background-color: #ececec;
296
+ padding: 1em;
297
+ padding-top: 0.2em;
298
+ padding-bottom: 0.2em;
299
+ margin-top: 1.7em;
300
+ }
301
+
302
+ #preview .content table {
303
+ margin-bottom: 0;
304
+ }