fae-railsz 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (328) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +5 -0
  3. data/Rakefile +37 -0
  4. data/app/assets/fonts/fae/icons.eot +0 -0
  5. data/app/assets/fonts/fae/icons.svg +56 -0
  6. data/app/assets/fonts/fae/icons.ttf +0 -0
  7. data/app/assets/fonts/fae/icons.woff +0 -0
  8. data/app/assets/fonts/fae/lato-bold-webfont.eot +0 -0
  9. data/app/assets/fonts/fae/lato-bold-webfont.svg +4551 -0
  10. data/app/assets/fonts/fae/lato-bold-webfont.ttf +0 -0
  11. data/app/assets/fonts/fae/lato-bold-webfont.woff +0 -0
  12. data/app/assets/fonts/fae/lato-light-webfont.eot +0 -0
  13. data/app/assets/fonts/fae/lato-light-webfont.svg +4241 -0
  14. data/app/assets/fonts/fae/lato-light-webfont.ttf +0 -0
  15. data/app/assets/fonts/fae/lato-light-webfont.woff +0 -0
  16. data/app/assets/fonts/fae/lato-regular-webfont.eot +0 -0
  17. data/app/assets/fonts/fae/lato-regular-webfont.svg +4241 -0
  18. data/app/assets/fonts/fae/lato-regular-webfont.ttf +0 -0
  19. data/app/assets/fonts/fae/lato-regular-webfont.woff +0 -0
  20. data/app/assets/fonts/fae/selection.json +1334 -0
  21. data/app/assets/images/fae/error_bg.jpg +0 -0
  22. data/app/assets/images/fae/error_sad_face.png +0 -0
  23. data/app/assets/images/fae/icons/alert.svg +9 -0
  24. data/app/assets/images/fae/icons/arrow_down.svg +8 -0
  25. data/app/assets/images/fae/icons/arrow_left.svg +9 -0
  26. data/app/assets/images/fae/icons/arrow_right.svg +9 -0
  27. data/app/assets/images/fae/icons/arrow_stacked.svg +8 -0
  28. data/app/assets/images/fae/icons/arrow_up.svg +8 -0
  29. data/app/assets/images/fae/icons/calendar.svg +17 -0
  30. data/app/assets/images/fae/icons/check.svg +7 -0
  31. data/app/assets/images/fae/icons/checkmark.svg +8 -0
  32. data/app/assets/images/fae/icons/chevron_down.svg +7 -0
  33. data/app/assets/images/fae/icons/chevron_left.svg +10 -0
  34. data/app/assets/images/fae/icons/chevron_right.svg +10 -0
  35. data/app/assets/images/fae/icons/chevron_up.svg +7 -0
  36. data/app/assets/images/fae/icons/delete.svg +8 -0
  37. data/app/assets/images/fae/icons/delete_x.svg +8 -0
  38. data/app/assets/images/fae/icons/edit.svg +11 -0
  39. data/app/assets/images/fae/icons/handle.svg +13 -0
  40. data/app/assets/images/fae/icons/home.svg +10 -0
  41. data/app/assets/images/fae/icons/logout.svg +12 -0
  42. data/app/assets/images/fae/icons/magnifying_glass.svg +10 -0
  43. data/app/assets/images/fae/icons/menu.svg +11 -0
  44. data/app/assets/images/fae/icons/offlink.svg +25 -0
  45. data/app/assets/images/fae/icons/plus.svg +8 -0
  46. data/app/assets/images/fae/icons/pulldown.svg +11 -0
  47. data/app/assets/images/fae/icons/search.svg +11 -0
  48. data/app/assets/images/fae/icons/settings.svg +12 -0
  49. data/app/assets/images/fae/icons/sort.svg +11 -0
  50. data/app/assets/images/fae/icons/support.svg +15 -0
  51. data/app/assets/images/fae/icons/trash.svg +10 -0
  52. data/app/assets/images/fae/icons/trumbowyg.svg +1 -0
  53. data/app/assets/images/fae/icons/user.svg +13 -0
  54. data/app/assets/images/fae/icons/users.svg +19 -0
  55. data/app/assets/images/fae/icons/zoom.svg +12 -0
  56. data/app/assets/images/fae/tutorial_model_location.png +0 -0
  57. data/app/assets/images/fae/youtube_helper.jpg +0 -0
  58. data/app/assets/javascripts/fae/_modals.js +60 -0
  59. data/app/assets/javascripts/fae/_tables.js +403 -0
  60. data/app/assets/javascripts/fae/admin.js.erb +11 -0
  61. data/app/assets/javascripts/fae/application.js +63 -0
  62. data/app/assets/javascripts/fae/fae_init.js +8 -0
  63. data/app/assets/javascripts/fae/form/_ajax.js +380 -0
  64. data/app/assets/javascripts/fae/form/_cancel.js +38 -0
  65. data/app/assets/javascripts/fae/form/_filtering.js +276 -0
  66. data/app/assets/javascripts/fae/form/_form.js +60 -0
  67. data/app/assets/javascripts/fae/form/_slugger.js.erb +100 -0
  68. data/app/assets/javascripts/fae/form/_validator.js +459 -0
  69. data/app/assets/javascripts/fae/form/fae_chosen.js +44 -0
  70. data/app/assets/javascripts/fae/form/fileinputer.js +178 -0
  71. data/app/assets/javascripts/fae/form/hinter.js +111 -0
  72. data/app/assets/javascripts/fae/form/inputs/_checkbox.js +27 -0
  73. data/app/assets/javascripts/fae/form/inputs/_color.js +42 -0
  74. data/app/assets/javascripts/fae/form/inputs/_dates.js +78 -0
  75. data/app/assets/javascripts/fae/form/inputs/_select.js +162 -0
  76. data/app/assets/javascripts/fae/form/inputs/_text.js +118 -0
  77. data/app/assets/javascripts/fae/navigation/_global_search.js +184 -0
  78. data/app/assets/javascripts/fae/navigation/_language.js +89 -0
  79. data/app/assets/javascripts/fae/navigation/_navigation.js +206 -0
  80. data/app/assets/javascripts/fae/navigation/_subnav_highlighter.js +81 -0
  81. data/app/assets/javascripts/fae/navigation/sticky.js +186 -0
  82. data/app/assets/javascripts/fae/vendor/chosen.jquery.min.js +2 -0
  83. data/app/assets/javascripts/fae/vendor/frob_core_helpers.js +587 -0
  84. data/app/assets/javascripts/fae/vendor/fryr.js +437 -0
  85. data/app/assets/javascripts/fae/vendor/jqColorPicker.min.js +4 -0
  86. data/app/assets/javascripts/fae/vendor/jquery.daterangepicker.js +1292 -0
  87. data/app/assets/javascripts/fae/vendor/jquery.multi-select.js +534 -0
  88. data/app/assets/javascripts/fae/vendor/jquery.simplemodal.1.4.4.js +719 -0
  89. data/app/assets/javascripts/fae/vendor/jquery.tablesorter.js +1901 -0
  90. data/app/assets/javascripts/fae/vendor/js.cookie.js +139 -0
  91. data/app/assets/javascripts/fae/vendor/moment.min.js +7 -0
  92. data/app/assets/javascripts/fae/vendor/simplemde.min.js +13 -0
  93. data/app/assets/javascripts/fae/vendor/touch_punch.js +11 -0
  94. data/app/assets/javascripts/fae/vendor/trumbowyg.js.erb +4 -0
  95. data/app/assets/javascripts/fae/vendor/trumbowyg/plugins/upload/trumbowyg.upload.js +223 -0
  96. data/app/assets/javascripts/fae/vendor/trumbowyg/trumbowyg.js +1603 -0
  97. data/app/assets/stylesheets/fae/application.css +8 -0
  98. data/app/assets/stylesheets/fae/base.scss +82 -0
  99. data/app/assets/stylesheets/fae/globals/_fonts.scss +43 -0
  100. data/app/assets/stylesheets/fae/globals/_icons.scss +15 -0
  101. data/app/assets/stylesheets/fae/globals/_plugins.scss +51 -0
  102. data/app/assets/stylesheets/fae/globals/_tags.scss +68 -0
  103. data/app/assets/stylesheets/fae/globals/imports/_extends.scss +53 -0
  104. data/app/assets/stylesheets/fae/globals/imports/_mixins.scss +58 -0
  105. data/app/assets/stylesheets/fae/globals/imports/_variables.scss +165 -0
  106. data/app/assets/stylesheets/fae/globals/imports/finescss/_fine.scss +7 -0
  107. data/app/assets/stylesheets/fae/globals/imports/finescss/_fine_functions.scss +88 -0
  108. data/app/assets/stylesheets/fae/globals/imports/finescss/_fine_mixins.scss +280 -0
  109. data/app/assets/stylesheets/fae/globals/imports/finescss/_fine_variables.scss +30 -0
  110. data/app/assets/stylesheets/fae/globals/layout/_base.scss +48 -0
  111. data/app/assets/stylesheets/fae/globals/layout/_breadcrumbs.scss +45 -0
  112. data/app/assets/stylesheets/fae/globals/layout/_content-header.scss +99 -0
  113. data/app/assets/stylesheets/fae/globals/legacy/_pre-1.3.scss +659 -0
  114. data/app/assets/stylesheets/fae/globals/navigation/_base.scss +22 -0
  115. data/app/assets/stylesheets/fae/globals/navigation/_footer.scss +50 -0
  116. data/app/assets/stylesheets/fae/globals/navigation/_header.scss +149 -0
  117. data/app/assets/stylesheets/fae/globals/navigation/_mobilenav.scss +149 -0
  118. data/app/assets/stylesheets/fae/globals/navigation/_search.scss +76 -0
  119. data/app/assets/stylesheets/fae/globals/navigation/_sidenav.scss +142 -0
  120. data/app/assets/stylesheets/fae/globals/navigation/_utility.scss +95 -0
  121. data/app/assets/stylesheets/fae/modules/_alerts.scss +50 -0
  122. data/app/assets/stylesheets/fae/modules/_buttons.scss +62 -0
  123. data/app/assets/stylesheets/fae/modules/_modal.scss +78 -0
  124. data/app/assets/stylesheets/fae/modules/_toggles.scss +48 -0
  125. data/app/assets/stylesheets/fae/modules/forms/_asset-actions.scss +83 -0
  126. data/app/assets/stylesheets/fae/modules/forms/_base.scss +100 -0
  127. data/app/assets/stylesheets/fae/modules/forms/_checkbox.scss +87 -0
  128. data/app/assets/stylesheets/fae/modules/forms/_colorpicker.scss +57 -0
  129. data/app/assets/stylesheets/fae/modules/forms/_date.scss +335 -0
  130. data/app/assets/stylesheets/fae/modules/forms/_hints.scss +40 -0
  131. data/app/assets/stylesheets/fae/modules/forms/_label.scss +57 -0
  132. data/app/assets/stylesheets/fae/modules/forms/_radio.scss +69 -0
  133. data/app/assets/stylesheets/fae/modules/forms/_select.scss +317 -0
  134. data/app/assets/stylesheets/fae/modules/forms/_simple-mde.scss +29 -0
  135. data/app/assets/stylesheets/fae/modules/forms/_text.scss +62 -0
  136. data/app/assets/stylesheets/fae/modules/forms/_textarea.scss +16 -0
  137. data/app/assets/stylesheets/fae/modules/forms/_validation.scss +63 -0
  138. data/app/assets/stylesheets/fae/modules/tables/_actions.scss +41 -0
  139. data/app/assets/stylesheets/fae/modules/tables/_base.scss +63 -0
  140. data/app/assets/stylesheets/fae/modules/tables/_collapsible.scss +76 -0
  141. data/app/assets/stylesheets/fae/modules/tables/_filters.scss +61 -0
  142. data/app/assets/stylesheets/fae/modules/tables/_image.scss +21 -0
  143. data/app/assets/stylesheets/fae/modules/tables/_pagination.scss +34 -0
  144. data/app/assets/stylesheets/fae/modules/tables/_sorting.scss +58 -0
  145. data/app/assets/stylesheets/fae/modules/tables/_sticky.scss +9 -0
  146. data/app/assets/stylesheets/fae/modules/tables/_tooltips.scss +24 -0
  147. data/app/assets/stylesheets/fae/pages/_error.scss +35 -0
  148. data/app/assets/stylesheets/fae/pages/_help.scss +28 -0
  149. data/app/assets/stylesheets/fae/pages/_home.scss +18 -0
  150. data/app/assets/stylesheets/fae/pages/_login.scss +137 -0
  151. data/app/assets/stylesheets/fae/vendor/chosen.css +377 -0
  152. data/app/assets/stylesheets/fae/vendor/daterangepicker.css +227 -0
  153. data/app/assets/stylesheets/fae/vendor/reset.css +48 -0
  154. data/app/assets/stylesheets/fae/vendor/simplemde.min.css +7 -0
  155. data/app/assets/stylesheets/fae/vendor/trumbowyg.css +584 -0
  156. data/app/controllers/concerns/fae/application_controller_concern.rb +1 -0
  157. data/app/controllers/concerns/fae/asset_cloner.rb +46 -0
  158. data/app/controllers/concerns/fae/cloneable.rb +136 -0
  159. data/app/controllers/fae/application_controller.rb +123 -0
  160. data/app/controllers/fae/base_controller.rb +117 -0
  161. data/app/controllers/fae/files_controller.rb +26 -0
  162. data/app/controllers/fae/images_controller.rb +37 -0
  163. data/app/controllers/fae/nested_base_controller.rb +100 -0
  164. data/app/controllers/fae/options_controller.rb +29 -0
  165. data/app/controllers/fae/pages_controller.rb +44 -0
  166. data/app/controllers/fae/setup_controller.rb +54 -0
  167. data/app/controllers/fae/static_pages_controller.rb +54 -0
  168. data/app/controllers/fae/users_controller.rb +71 -0
  169. data/app/controllers/fae/utilities_controller.rb +61 -0
  170. data/app/helpers/fae/application_helper.rb +114 -0
  171. data/app/helpers/fae/fae_helper.rb +6 -0
  172. data/app/helpers/fae/form_helper.rb +240 -0
  173. data/app/helpers/fae/nested_form_helper.rb +39 -0
  174. data/app/helpers/fae/view_helper.rb +175 -0
  175. data/app/inputs/date_range_input.rb +17 -0
  176. data/app/inputs/radio_collection_input.rb +17 -0
  177. data/app/inputs/symbol_input.rb +5 -0
  178. data/app/models/concerns/fae/assets_validatable.rb +12 -0
  179. data/app/models/concerns/fae/authorization_concern.rb +12 -0
  180. data/app/models/concerns/fae/base_model_concern.rb +105 -0
  181. data/app/models/concerns/fae/change_concern.rb +1 -0
  182. data/app/models/concerns/fae/file_concern.rb +1 -0
  183. data/app/models/concerns/fae/image_concern.rb +1 -0
  184. data/app/models/concerns/fae/navigation_concern.rb +10 -0
  185. data/app/models/concerns/fae/option_concern.rb +1 -0
  186. data/app/models/concerns/fae/page_validatable.rb +26 -0
  187. data/app/models/concerns/fae/paper_trailer.rb +8 -0
  188. data/app/models/concerns/fae/role_concern.rb +1 -0
  189. data/app/models/concerns/fae/sortable.rb +51 -0
  190. data/app/models/concerns/fae/static_page_concern.rb +1 -0
  191. data/app/models/concerns/fae/text_area_concern.rb +1 -0
  192. data/app/models/concerns/fae/text_field_concern.rb +1 -0
  193. data/app/models/concerns/fae/trackable.rb +124 -0
  194. data/app/models/concerns/fae/user_concern.rb +7 -0
  195. data/app/models/fae/authorization.rb +8 -0
  196. data/app/models/fae/change.rb +53 -0
  197. data/app/models/fae/file.rb +24 -0
  198. data/app/models/fae/image.rb +33 -0
  199. data/app/models/fae/navigation.rb +132 -0
  200. data/app/models/fae/option.rb +38 -0
  201. data/app/models/fae/role.rb +18 -0
  202. data/app/models/fae/static_page.rb +109 -0
  203. data/app/models/fae/text_area.rb +14 -0
  204. data/app/models/fae/text_field.rb +14 -0
  205. data/app/models/fae/user.rb +67 -0
  206. data/app/uploaders/fae/file_uploader.rb +26 -0
  207. data/app/uploaders/fae/image_uploader.rb +28 -0
  208. data/app/validators/fae/cross_model_uniqueness_validator.rb +14 -0
  209. data/app/views/devise/confirmations/new.html.slim +13 -0
  210. data/app/views/devise/mailer/confirmation_instructions.html.slim +3 -0
  211. data/app/views/devise/mailer/reset_password_instructions.html.slim +5 -0
  212. data/app/views/devise/mailer/unlock_instructions.html.slim +4 -0
  213. data/app/views/devise/passwords/edit.html.slim +10 -0
  214. data/app/views/devise/passwords/new.html.slim +10 -0
  215. data/app/views/devise/registrations/edit.html.slim +22 -0
  216. data/app/views/devise/registrations/new.html.slim +15 -0
  217. data/app/views/devise/sessions/new.html.slim +7 -0
  218. data/app/views/devise/shared/_links.slim +25 -0
  219. data/app/views/devise/unlocks/new.html.slim +13 -0
  220. data/app/views/fae/application/_breadcrumb.html.slim +19 -0
  221. data/app/views/fae/application/_content_form.html.slim +55 -0
  222. data/app/views/fae/application/_credit.slim +6 -0
  223. data/app/views/fae/application/_file_uploader.html.slim +36 -0
  224. data/app/views/fae/application/_flash_messages.slim +2 -0
  225. data/app/views/fae/application/_global_search_results.html.slim +37 -0
  226. data/app/views/fae/application/_header.slim +50 -0
  227. data/app/views/fae/application/_markdown_helper.slim +41 -0
  228. data/app/views/fae/application/_mobilenav.slim +66 -0
  229. data/app/views/fae/application/_sidenav.slim +23 -0
  230. data/app/views/fae/application/_user_log.html.slim +36 -0
  231. data/app/views/fae/images/_image_uploader.html.slim +66 -0
  232. data/app/views/fae/options/_form.html.slim +16 -0
  233. data/app/views/fae/options/edit.html.slim +1 -0
  234. data/app/views/fae/pages/activity_log.html.slim +32 -0
  235. data/app/views/fae/pages/disabled_environment.html.slim +4 -0
  236. data/app/views/fae/pages/error404.html.slim +7 -0
  237. data/app/views/fae/pages/help.html.slim +35 -0
  238. data/app/views/fae/pages/home.html.slim +36 -0
  239. data/app/views/fae/setup/first_user.html.slim +11 -0
  240. data/app/views/fae/shared/_errors.slim +4 -0
  241. data/app/views/fae/shared/_form_header.html.slim +40 -0
  242. data/app/views/fae/shared/_index_header.html.slim +26 -0
  243. data/app/views/fae/shared/_nested_table.html.slim +49 -0
  244. data/app/views/fae/shared/_recent_changes.html.slim +22 -0
  245. data/app/views/fae/shared/_shared_nested_table.html.slim +46 -0
  246. data/app/views/fae/static_pages/index.html.slim +13 -0
  247. data/app/views/fae/users/_form.html.slim +19 -0
  248. data/app/views/fae/users/edit.html.slim +1 -0
  249. data/app/views/fae/users/index.html.slim +23 -0
  250. data/app/views/fae/users/new.html.slim +1 -0
  251. data/app/views/fae/users/settings.html.slim +1 -0
  252. data/app/views/kaminari/fae/_gap.html.slim +8 -0
  253. data/app/views/kaminari/fae/_next_page.html.slim +9 -0
  254. data/app/views/kaminari/fae/_page.html.slim +15 -0
  255. data/app/views/kaminari/fae/_paginator.html.slim +15 -0
  256. data/app/views/kaminari/fae/_prev_page.html.slim +9 -0
  257. data/app/views/layouts/devise.html.slim +29 -0
  258. data/app/views/layouts/fae/application.html.slim +23 -0
  259. data/app/views/layouts/fae/error.html.slim +11 -0
  260. data/config/deploy.rb +73 -0
  261. data/config/deploy/dev.rb +19 -0
  262. data/config/deploy/prod.rb +19 -0
  263. data/config/deploy/stage.rb +19 -0
  264. data/config/initializers/assets.rb +1 -0
  265. data/config/initializers/carrierwave.rb +3 -0
  266. data/config/initializers/devise.rb +258 -0
  267. data/config/initializers/devise_monkeypatch.rb +11 -0
  268. data/config/initializers/fae_judge.rb +3 -0
  269. data/config/initializers/inflections.rb +16 -0
  270. data/config/initializers/kaminari_config.rb +10 -0
  271. data/config/initializers/simple_form.rb +147 -0
  272. data/config/initializers/time_formats.rb +3 -0
  273. data/config/locales/devise.en.yml +59 -0
  274. data/config/locales/devise.zh-CN.yml +59 -0
  275. data/config/locales/fae.en.yml +10 -0
  276. data/config/locales/fae.zh-CN.yml +10 -0
  277. data/config/locales/simple_form.en.yml +26 -0
  278. data/config/locales/simple_form.zh-CN.yml +26 -0
  279. data/config/routes.rb +46 -0
  280. data/db/migrate/20140809222030_add_user_table.rb +49 -0
  281. data/db/migrate/20140822224029_create_fae_roles.rb +10 -0
  282. data/db/migrate/20141008180718_create_fae_images_table.rb +19 -0
  283. data/db/migrate/20141017194616_create_fae_options.rb +16 -0
  284. data/db/migrate/20141021181327_create_fae_files.rb +17 -0
  285. data/db/migrate/20141021183047_create_fae_text_areas.rb +16 -0
  286. data/db/migrate/20141021184311_create_fae_pages.rb +13 -0
  287. data/db/migrate/20141105214814_create_fae_text_fields.rb +15 -0
  288. data/db/migrate/20150930224821_create_fae_changes.rb +17 -0
  289. data/lib/fae-rails.rb +6 -0
  290. data/lib/fae/concerns/models/base.rb +8 -0
  291. data/lib/fae/engine.rb +37 -0
  292. data/lib/fae/options.rb +35 -0
  293. data/lib/fae/validation_helper_collection.rb +76 -0
  294. data/lib/fae/version.rb +3 -0
  295. data/lib/file_size_validator.rb +71 -0
  296. data/lib/generators/fae/base_generator.rb +156 -0
  297. data/lib/generators/fae/controller_generator.rb +13 -0
  298. data/lib/generators/fae/install_generator.rb +61 -0
  299. data/lib/generators/fae/model_generator.rb +11 -0
  300. data/lib/generators/fae/nested_index_scaffold_generator.rb +36 -0
  301. data/lib/generators/fae/nested_scaffold_generator.rb +51 -0
  302. data/lib/generators/fae/page_generator.rb +65 -0
  303. data/lib/generators/fae/scaffold_generator.rb +15 -0
  304. data/lib/generators/fae/templates/assets/fae.js +6 -0
  305. data/lib/generators/fae/templates/assets/fae.scss +2 -0
  306. data/lib/generators/fae/templates/controllers/nested_index_scaffold_controller.rb +81 -0
  307. data/lib/generators/fae/templates/controllers/nested_scaffold_controller.rb +13 -0
  308. data/lib/generators/fae/templates/controllers/scaffold_controller.rb +13 -0
  309. data/lib/generators/fae/templates/controllers/static_pages_controller.rb +10 -0
  310. data/lib/generators/fae/templates/initializers/fae.rb +63 -0
  311. data/lib/generators/fae/templates/initializers/fae_fine.rb +51 -0
  312. data/lib/generators/fae/templates/initializers/judge.rb +6 -0
  313. data/lib/generators/fae/templates/models/concerns/authorization_concern.rb +27 -0
  314. data/lib/generators/fae/templates/models/concerns/navigation_concern.rb +33 -0
  315. data/lib/generators/fae/templates/models/pages_model.rb +14 -0
  316. data/lib/generators/fae/templates/tasks/fae_tasks.rake +19 -0
  317. data/lib/generators/fae/templates/views/_form.html.slim +18 -0
  318. data/lib/generators/fae/templates/views/_form_index_nested.html.slim +13 -0
  319. data/lib/generators/fae/templates/views/_form_nested.html.slim +17 -0
  320. data/lib/generators/fae/templates/views/edit.html.slim +1 -0
  321. data/lib/generators/fae/templates/views/edit_nested.html.slim +3 -0
  322. data/lib/generators/fae/templates/views/index.html.slim +35 -0
  323. data/lib/generators/fae/templates/views/index_nested.html.slim +8 -0
  324. data/lib/generators/fae/templates/views/new.html.slim +1 -0
  325. data/lib/generators/fae/templates/views/new_nested.html.slim +3 -0
  326. data/lib/generators/fae/templates/views/static_page_form.html.slim +15 -0
  327. data/lib/generators/fae/templates/views/table_nested.html.slim +4 -0
  328. metadata +692 -0
@@ -0,0 +1,60 @@
1
+ /* global Fae */
2
+
3
+ /**
4
+ * Fae form
5
+ * @namespace form
6
+ * @memberof Fae
7
+ */
8
+ Fae.form = {
9
+ ready: function() {
10
+ // Mutate DOM to support two column labels for all standard inputs
11
+ this.makeTwoColumnLabels();
12
+
13
+ this.dates.init();
14
+ this.color.init();
15
+ this.text.init();
16
+ this.select.init();
17
+ this.checkbox.init();
18
+ this.validator.init();
19
+ this.cancel.init();
20
+ this.ajax.init();
21
+ this.filtering.init();
22
+ this.slugger.init();
23
+
24
+ // input type=file customization
25
+ // This doesn't work in IE. It's not worth figuring out why by this point. IE9 gets plain file uploader.
26
+ if (!FCH.IE9) {
27
+ $('.input.file').fileinputer();
28
+ }
29
+
30
+ // make all the hint areas
31
+ $('.hint').hinter();
32
+ },
33
+
34
+ makeTwoColumnLabels: function() {
35
+ $('.input label').each(function() {
36
+ var $element = $(this);
37
+
38
+ // Bail if we cannot find any helper_text
39
+ if (!$element.find('.helper_text').length) {
40
+ $element.addClass('has_no_helper_text');
41
+ }
42
+
43
+ // If present, get all DOM nodes w/ contents(), but ignore the .helper_text
44
+ var label_inner = $element.contents().filter(function() {
45
+ return !$(this).hasClass('helper_text');
46
+ });
47
+ var helper_text = $element.find('.helper_text');
48
+
49
+ // Replace existing label w/ newly wrapped elements, sans .helper_text
50
+ label_inner = $('<div class="label_inner" />').html(label_inner);
51
+ $element.html(label_inner);
52
+
53
+ // But then add .helper_text as a sibling
54
+ $element.append(helper_text);
55
+
56
+ // Ensure that we mark this input as having two column label support
57
+ $element.addClass('label--two_col');
58
+ });
59
+ }
60
+ };
@@ -0,0 +1,100 @@
1
+ /* global Fae */
2
+
3
+ 'use strict';
4
+
5
+ /**
6
+ * Fae form
7
+ * @namespace form
8
+ * @memberof Fae
9
+ */
10
+ Fae.form.slugger = {
11
+ init: function() {
12
+ this.addListener();
13
+ },
14
+
15
+ /**
16
+ * Attach listeners to inputs and update slug fields with original safe values from the original inputs
17
+ */
18
+ addListener: function() {
19
+ var _this = this;
20
+
21
+ $('.slug').each(function() {
22
+ var $form = $(this).closest('form');
23
+ var $sluggers = $form.find('.slugger');
24
+ var $slug = $form.find('.slug');
25
+ var $select_slugger = $('.select.slugger');
26
+
27
+ if ($slug.val() !== '') {
28
+ $sluggers.removeClass('slugger');
29
+
30
+ } else {
31
+ // If it's a text field, listen for type input
32
+ $sluggers.keyup(function(){
33
+ var text = _this._digestSlug( $sluggers );
34
+ $slug.val( text );
35
+ });
36
+
37
+ // If it's a select field, listen for the change
38
+ if ($select_slugger.length) {
39
+ $select_slugger.change(function(){
40
+ var text = _this._digestSlug( $sluggers );
41
+ $slug.val( text );
42
+ });
43
+
44
+ };
45
+ }
46
+ });
47
+ },
48
+
49
+ /**
50
+ * Convert a group of selects or text fields into one slug string
51
+ * @access protected
52
+ * @param {jQuery} $sluggers - Input or inputs that should be converted into a URL-safe string
53
+ * @return {String}
54
+ */
55
+ _digestSlug: function($sluggers) {
56
+ var slug_text = []
57
+
58
+ $sluggers.each(function() {
59
+ var $this = $(this);
60
+
61
+ if ($this.val().length) {
62
+
63
+ if ($this.is('input')) {
64
+ slug_text.push( $this.val() );
65
+
66
+ } else {
67
+ slug_text.push( $this.find('option:selected').text() );
68
+
69
+ }
70
+ }
71
+ });
72
+
73
+ // Combine all active slug fields for the query
74
+ slug_text = slug_text.join(' ');
75
+
76
+ // Strip accented characters
77
+ var from = 'àáâãäæåçèéêëęēėìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ';
78
+ var to = 'aaaaaaaceeeeeeeiiiinooooouuuuyyAAAAACEEEEIIIINOOOOOUUUUY';
79
+
80
+ // Loop through all accented characters and replace with non-accents
81
+ for (var i = 0; i < from.length; i++) {
82
+ slug_text = slug_text.replace( new RegExp(from.charAt(i), 'g'), to.charAt(i) );
83
+ }
84
+
85
+ // Remove leading and trailing spaces
86
+ // Make them lowercase
87
+ // Remove slashes, quotes or periods
88
+ // Replace white spaces with a Fae.slug_separator
89
+ // Remove leading and trailing dashes
90
+ slug_text = slug_text
91
+ .trim()
92
+ .toLowerCase()
93
+ .replace(/[^<%= Fae.slug_separator %>\w\s]/g, '')
94
+ .replace(/[<%= Fae.slug_separator %>\s]+/g, '<%= Fae.slug_separator %>')
95
+ .replace(/(^<%= Fae.slug_separator %>)|(<%= Fae.slug_separator %>$)/g, '');
96
+
97
+ return slug_text;
98
+ }
99
+
100
+ };
@@ -0,0 +1,459 @@
1
+ /* global Fae, judge, FCH */
2
+
3
+ /**
4
+ * Fae form validator
5
+ * @namespace form.validator
6
+ * @memberof form
7
+ */
8
+ Fae.form.validator = {
9
+
10
+ is_valid: '',
11
+ validations_called: 0,
12
+ validations_returned: 0,
13
+ validation_test_count: 0,
14
+
15
+ init: function () {
16
+ // validate all forms except the login form
17
+ if ($('form').not('#login_form').length) {
18
+ this.password_confirmation_validation.init();
19
+ this.passwordPresenceConditional();
20
+ this.bindValidationEvents();
21
+ this.formValidate();
22
+ this.length_counter.init();
23
+ }
24
+ },
25
+
26
+ /**
27
+ * Validate the entire form on submit and stop it if the form is invalid
28
+ */
29
+ formValidate: function () {
30
+ var _this = this;
31
+
32
+ FCH.$document.on('submit', 'form:not([data-remote=true])', function (e) {
33
+ var $this = $(this);
34
+
35
+ if ($this.data('passed_validation') !== 'true') {
36
+
37
+ // pause form submission
38
+ e.preventDefault();
39
+
40
+ // set defaults
41
+ _this.is_valid = true;
42
+ _this.validations_called = 0;
43
+ _this.validations_returned = 0;
44
+ _this.validation_test_count = 0;
45
+
46
+ // Scope the data-validation only to the form submitted
47
+ $('[data-validate]', $this).each(function () {
48
+ if ($(this).data('validate').length) {
49
+ _this.validations_called++;
50
+ _this._judgeIt($(this));
51
+ }
52
+ });
53
+
54
+ // Catch visible errors for image/file inputs hitting the fae config file size limiter
55
+ $('.input.file', $this).each(function () {
56
+ if ($(this).hasClass('field_with_errors')) {
57
+ _this.is_valid = false;
58
+ }
59
+ });
60
+
61
+ _this.testValidation($this);
62
+
63
+ }
64
+
65
+ });
66
+ },
67
+
68
+ /**
69
+ * Tests a forms validation after all validation checks have responded
70
+ * Polls validations responses every 50ms to allow uniqueness AJAX calls to complete
71
+ */
72
+ testValidation: function($this) {
73
+ var _this = this;
74
+ _this.validation_test_count++;
75
+
76
+ setTimeout(function(){
77
+
78
+ // if all the validation checks have returned a response
79
+ if (_this.validations_called === _this.validations_returned) {
80
+
81
+ if (_this.is_valid) {
82
+ // if form is valid, submit it
83
+ $this.data('passed_validation', 'true');
84
+
85
+ $this.submit();
86
+ } else {
87
+ // otherwise scroll to the top to display alerts
88
+ Fae.navigation.language.checkForHiddenErrors();
89
+ FCH.smoothScroll($('#js-main-header'), 500, 100, 0);
90
+
91
+ if ($(".field_with_errors").length) {
92
+ $('.alert').slideDown('fast').delay(3000).slideUp('fast');
93
+ }
94
+ }
95
+
96
+ } else {
97
+ // check again if it hasn't run more than 50 times
98
+ // (to prevent against infinite loop)
99
+ if (_this.validation_test_count < 50) {
100
+ _this.testValidation($this);
101
+ }
102
+ }
103
+
104
+ }, 50);
105
+
106
+ },
107
+
108
+ /**
109
+ * Bind validation events based on input type
110
+ */
111
+ bindValidationEvents: function ($scope) {
112
+ var _this = this;
113
+
114
+ if (typeof($scope) === 'undefined'){
115
+ $scope = $('body');
116
+ }
117
+
118
+ $scope.find('[data-validate]').each(function () {
119
+ var $this = $(this);
120
+
121
+ if ($this.data('validate').length) {
122
+ if ($this.is('input:not(.hasDatepicker), textarea')) {
123
+ // normal inputs validate on blur
124
+ $this.blur(function () {
125
+ _this._judgeIt($this);
126
+ });
127
+
128
+ } else if ($this.hasClass('hasDatepicker')) {
129
+ // date pickers need a little delay
130
+ $this.blur(function () {
131
+ setTimeout(function(){ _this._judgeIt($this); }, 500);
132
+ });
133
+
134
+ } else if ($this.is('select')) {
135
+ // selects validate on change
136
+ $this.change(function () {
137
+ _this._judgeIt($this);
138
+ });
139
+ }
140
+ }
141
+ });
142
+ },
143
+
144
+
145
+ /**
146
+ * Initialize Judge on a field
147
+ * @protected
148
+ * @param {jQuery} $input - field to be validated
149
+ */
150
+ _judgeIt: function ($input) {
151
+ var _this = this;
152
+
153
+ judge.validate($input[0], {
154
+ valid: function () {
155
+ _this.validations_returned++;
156
+ _this._createSuccessClass($input);
157
+ },
158
+ invalid: function (input, messages) {
159
+ _this.validations_returned++;
160
+ messages = _this._removeIgnoredErrors(messages);
161
+ if (messages.length) {
162
+ _this.is_valid = false;
163
+ _this._createOrReplaceError($input, messages);
164
+ }
165
+ }
166
+ });
167
+ },
168
+
169
+ /**
170
+ * Strips out ignored error messages
171
+ * @protected
172
+ * @param messages - array of error messages from Judge
173
+ */
174
+ _removeIgnoredErrors: function (messages) {
175
+ // Ignored error messages from Judge:
176
+ // 'Judge validation for Release#name not allowed'
177
+ // 'Slug Request error: 0'
178
+ var ignored_error_substrings = ['Judge validation', 'Request error'];
179
+
180
+ // loop through messages
181
+ for (var i = 0; i < messages.length; i++) {
182
+ // loop through ignored errors
183
+ for (var j = 0; j < ignored_error_substrings.length; j++) {
184
+ // if the substring exists in the error message
185
+ if (messages[i].indexOf(ignored_error_substrings[j]) > -1) {
186
+ // log it in the console and remove message
187
+ window.console && console.log('Ignoring error: ', messages[i]);
188
+ messages.splice(i, 1);
189
+ break;
190
+ }
191
+ }
192
+ }
193
+
194
+ return messages;
195
+ },
196
+
197
+ /**
198
+ * Adds and removes the appropriate classes to display the success styles
199
+ * @protected
200
+ * @param {jQuery} $input - Input field (can be a chosen object)
201
+ */
202
+ _createSuccessClass: function ($input) {
203
+ var $styled_input = this._setTargetInput($input);
204
+ $styled_input.addClass('valid').removeClass('invalid');
205
+
206
+ $input.parent().removeClass('field_with_errors').children('.error').remove();
207
+ },
208
+
209
+ /**
210
+ * Adds and removes the appropriate classes to display the error styles
211
+ * @protected
212
+ * @param {jQuery} $input - Input field
213
+ * @param {Array} messages - Error messages to display
214
+ */
215
+ _createOrReplaceError: function ($input, messages) {
216
+ var $styled_input = this._setTargetInput($input);
217
+ $styled_input.addClass('invalid').removeClass('valid');
218
+
219
+ var $wrapper = $input.closest('.input');
220
+ if ($wrapper.children('.error').length) {
221
+ $wrapper.children('.error').text(messages.join(', '));
222
+ } else {
223
+ $wrapper.addClass('field_with_errors').append("<span class='error'>" + messages.join(', ') + "</span>");
224
+ }
225
+ },
226
+
227
+ /**
228
+ * A DRY method for setting the element that should take the .valid or .invalid style
229
+ * @protected
230
+ * @param {jQuery} $input - Input field for a chosen object
231
+ * @return {jQuery} The chosen container
232
+ */
233
+ _setTargetInput: function ($input) {
234
+ var $styled_input = $input;
235
+
236
+ // If field is a chosen input
237
+ if ( $input.next('.chosen-container').length ) {
238
+ if ($input.next('.chosen-container').find('.chosen-single').length) {
239
+ $styled_input = $input.next('.chosen-container').find('.chosen-single');
240
+
241
+ } else if ($input.next('.chosen-container').find('.chosen-choices').length) {
242
+ $styled_input = $input.next('.chosen-container').find('.chosen-choices');
243
+
244
+ }
245
+ } else if ($input.hasClass('mde-enabled')) {
246
+ $styled_input = $input.siblings('.editor-toolbar, .CodeMirror-wrap');
247
+
248
+ }
249
+
250
+ return $styled_input;
251
+ },
252
+
253
+ /**
254
+ * Removes a field's Judge validation
255
+ * @param {jQuery} $field - Input fields
256
+ * @param {String} kind - Type of validation (e.g. 'presence' or 'confirmation')
257
+ */
258
+ stripValidation: function($field, kind) {
259
+ var validations = $field.data('validate');
260
+
261
+ for (var i = 0; i < validations.length; i++) {
262
+ // validation items can be strings or JSON objects
263
+ // let's convert the strings to JSON so we're dealing with consistent types
264
+ if (typeof validations[i] == 'string' || validations[i] instanceof String) {
265
+ validations[i] = JSON.parse(validations[i]);
266
+ }
267
+
268
+ // if the kind matches, remove it from the array
269
+ if (validations[i]['kind'] === kind) {
270
+ validations.splice(i, 1);
271
+ }
272
+
273
+ // convert JSON back to a string
274
+ validations[i] = JSON.stringify(validations[i]);
275
+ }
276
+ $field.attr('data-validate', '[' + validations + ']');
277
+ },
278
+
279
+ /**
280
+ * Password Confirmation Validation
281
+ * @description Judge validates confirmation on the original field. This is a hack to remove Judge's validation and add it to the confirmation field
282
+ * @namespace
283
+ * @memberof! validator
284
+ */
285
+ password_confirmation_validation: {
286
+ init: function() {
287
+ var _this = this;
288
+
289
+ _this.$password_field = $('#user_password');
290
+ _this.$password_confirmation_field = $('#user_password_confirmation');
291
+
292
+ if (_this.$password_confirmation_field.length) {
293
+ Fae.form.validator.stripValidation(_this.$password_field, 'confirmation');
294
+ _this.addCustomValidation();
295
+ }
296
+ },
297
+
298
+ /**
299
+ * Validate password on blur and form submit; halt form execution if invalid
300
+ */
301
+ addCustomValidation: function() {
302
+ var _this = this;
303
+
304
+ /**
305
+ * Displays success or error depending on password validation
306
+ * @private
307
+ * @param {Object} self - The password_confirmation_validation object
308
+ * @see {@link validator.password_confirmation_validation.addCustomValidation addCustomValidation}
309
+ */
310
+ function validateConfirmation() {
311
+ var validator = Fae.form.validator;
312
+
313
+ if (_this.$password_field.val() === _this.$password_confirmation_field.val()) {
314
+ validator._createSuccessClass(_this.$password_confirmation_field);
315
+ } else {
316
+ var message = ['must match Password'];
317
+ validator.is_valid = false;
318
+ validator._createOrReplaceError(_this.$password_confirmation_field, message);
319
+ }
320
+ }
321
+
322
+ this.$password_confirmation_field.on('blur', validateConfirmation);
323
+
324
+ $('form').on('submit', function(ev) {
325
+ _this.is_valid = true;
326
+ validateConfirmation();
327
+
328
+ if (!_this.is_valid) {
329
+ ev.preventDefault();
330
+ }
331
+ });
332
+ }
333
+ },
334
+
335
+ /**
336
+ * Judge always read the `on: :create` validations, so we need to strip the password presence validation on the user edit form
337
+ */
338
+ passwordPresenceConditional: function() {
339
+ var $edit_user_password = $('.edit_user #user_password');
340
+ if ($edit_user_password.length) {
341
+ this.stripValidation($edit_user_password, 'presence');
342
+ }
343
+ },
344
+
345
+ /**
346
+ * Length Counter
347
+ * @namespace
348
+ * @memberof! validator
349
+ */
350
+ length_counter: {
351
+
352
+ init: function(){
353
+ this.findLengthValidations();
354
+ },
355
+
356
+ /**
357
+ * Add counter text to fields that validate based on character counts
358
+ */
359
+ findLengthValidations: function() {
360
+ var _this = this;
361
+
362
+ $('[data-validate]').each(function () {
363
+ var $this = $(this);
364
+
365
+ if ($this.data('validate').length ) {
366
+ var validations = $this.data('validate');
367
+
368
+ $.grep(validations, function(item){
369
+ if (item.kind === 'length'){
370
+ $this.data('length-max', item.options.maximum);
371
+ _this._setupCounter($this);
372
+ }
373
+ });
374
+ }
375
+ });
376
+ },
377
+
378
+ /**
379
+ * Sets up the counter
380
+ * @access protected
381
+ * @param {jQuery} $elem - Input field being counted
382
+ */
383
+ _setupCounter: function($elem) {
384
+ var _this = this;
385
+
386
+ _this._createCounterDiv($elem);
387
+ _this.updateCounter($elem);
388
+
389
+ $elem
390
+ .keyup(function() {
391
+ _this.updateCounter($elem);
392
+ })
393
+ .keypress(function(e) {
394
+ if (_this._charactersLeft($elem) <= 0) {
395
+ if (e.keyCode !== 8 && e.keyCode !== 46) {
396
+ e.preventDefault();
397
+ }
398
+ }
399
+ });
400
+ },
401
+
402
+ /**
403
+ * Creates counter HTML
404
+ * @protected
405
+ * @param {jQuery} $elem - Input field to evaluate
406
+ */
407
+ _createCounterDiv: function($elem) {
408
+ if ($elem.siblings('.counter').length === 0) {
409
+ var text = "Maximum Characters: " + $elem.data('length-max');
410
+ text += " / <span class='characters-left'></span>";
411
+
412
+ var $counter_div = $('<div />', {
413
+ class: 'counter',
414
+ html: '<p>' + text + '</p>'
415
+ });
416
+
417
+ $elem.parent().append( $counter_div );
418
+ }
419
+ },
420
+
421
+ /**
422
+ * Updates the counter count and class
423
+ * @param {jQuery} $elem - Input field to evaluate
424
+ */
425
+ updateCounter: function($elem) {
426
+ var $count_span = $elem.siblings('.counter').find('.characters-left');
427
+ if ($count_span.length) {
428
+ var current = this._charactersLeft($elem);
429
+ var text;
430
+
431
+ if (current >= 0) {
432
+ text = 'Characters Left: ';
433
+ $count_span.removeClass('overCount');
434
+ } else {
435
+ text = 'Characters Over: ';
436
+ $count_span.addClass('overCount');
437
+ }
438
+
439
+ $count_span.text(text + Math.abs(current));
440
+ }
441
+ },
442
+
443
+ /**
444
+ * Calculate character's left
445
+ * @protected
446
+ * @param {jQuery} $elem - Input field being counted
447
+ * @return {integer} The number of characters left
448
+ */
449
+ _charactersLeft: function($elem) {
450
+ var input_value = $elem.val();
451
+ var current = $elem.data('length-max') - input_value.length;
452
+ // Rails counts a newline as two characters, so let's make up for it here
453
+ current -= (input_value.match(/\n/g) || []).length;
454
+
455
+ return current;
456
+ }
457
+ }
458
+
459
+ };