lato_core 1.1.5 → 2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (307) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +29 -0
  4. data/Rakefile +1 -22
  5. data/app/assets/config/lato_core_manifest.js +2 -0
  6. data/app/assets/fonts/lato_core/fontawesome-webfont.eot +0 -0
  7. data/app/assets/fonts/lato_core/fontawesome-webfont.svg +2671 -0
  8. data/app/assets/fonts/lato_core/fontawesome-webfont.ttf +0 -0
  9. data/app/assets/fonts/lato_core/fontawesome-webfont.woff +0 -0
  10. data/app/assets/fonts/lato_core/fontawesome-webfont.woff2 +0 -0
  11. data/app/assets/fonts/lato_core/lato-bold-webfont.eot +0 -0
  12. data/app/assets/fonts/lato_core/lato-bold-webfont.svg +4551 -0
  13. data/app/assets/fonts/lato_core/lato-bold-webfont.ttf +0 -0
  14. data/app/assets/fonts/lato_core/lato-bold-webfont.woff +0 -0
  15. data/app/assets/fonts/lato_core/lato-bold-webfont.woff2 +0 -0
  16. data/app/assets/fonts/lato_core/lato-regular-webfont.eot +0 -0
  17. data/app/assets/fonts/lato_core/lato-regular-webfont.svg +4241 -0
  18. data/app/assets/fonts/lato_core/lato-regular-webfont.ttf +0 -0
  19. data/app/assets/fonts/lato_core/lato-regular-webfont.woff +0 -0
  20. data/app/assets/fonts/lato_core/lato-regular-webfont.woff2 +0 -0
  21. data/app/assets/images/lato_core/editor-icons.svg +1 -0
  22. data/app/assets/images/lato_core/logo-negative.svg +13 -0
  23. data/app/assets/images/lato_core/logo.svg +1 -0
  24. data/app/assets/images/lato_core/user.png +0 -0
  25. data/app/assets/javascripts/lato_core/application.js +28 -0
  26. data/app/assets/javascripts/lato_core/initializers/Charts.js +36 -0
  27. data/app/assets/javascripts/lato_core/initializers/Elements.js +67 -0
  28. data/app/assets/javascripts/lato_core/initializers/Inputs.js +201 -0
  29. data/app/assets/javascripts/lato_core/initializers/Layout.js +37 -0
  30. data/app/assets/javascripts/lato_core/initializers/SortableManager.js +66 -0
  31. data/app/assets/javascripts/lato_core/interfaces/Modal.js +28 -0
  32. data/app/assets/javascripts/lato_core/vendors/Sortable.min.js +2 -0
  33. data/app/assets/javascripts/lato_core/vendors/chart.bundle.js +17220 -0
  34. data/app/assets/javascripts/lato_core/vendors/dropzone.js +1767 -0
  35. data/app/assets/javascripts/lato_core/vendors/jquery.datetimepicker.full.js +3243 -0
  36. data/app/assets/javascripts/lato_core/vendors/jquery.floatThead.js +1106 -0
  37. data/app/assets/javascripts/lato_core/vendors/jquery.selectize.js +3829 -0
  38. data/app/assets/javascripts/lato_core/vendors/jquery.trumbowyg.js +1603 -0
  39. data/app/assets/stylesheets/lato_core/application.scss +23 -0
  40. data/app/assets/stylesheets/lato_core/base/_base.scss +35 -0
  41. data/app/assets/stylesheets/lato_core/base/_button.scss +23 -0
  42. data/app/assets/stylesheets/lato_core/base/_grid.scss +258 -0
  43. data/app/assets/stylesheets/lato_core/base/_helpers.scss +29 -0
  44. data/app/assets/stylesheets/lato_core/base/_mixin.scss +37 -0
  45. data/app/assets/stylesheets/lato_core/base/_normalize.scss +424 -0
  46. data/app/assets/stylesheets/lato_core/base/_table.scss +47 -0
  47. data/app/assets/stylesheets/lato_core/base/_typography.scss +23 -0
  48. data/app/assets/stylesheets/lato_core/cells/_cells.scss +4 -0
  49. data/app/assets/stylesheets/lato_core/cells/charts/_bar.scss +3 -0
  50. data/app/assets/stylesheets/lato_core/cells/charts/_charts.scss +2 -0
  51. data/app/assets/stylesheets/lato_core/cells/charts/_general.scss +7 -0
  52. data/app/assets/stylesheets/lato_core/cells/elements/_block.scss +12 -0
  53. data/app/assets/stylesheets/lato_core/cells/elements/_button.scss +132 -0
  54. data/app/assets/stylesheets/lato_core/cells/elements/_buttongroup.scss +25 -0
  55. data/app/assets/stylesheets/lato_core/cells/elements/_code.scss +8 -0
  56. data/app/assets/stylesheets/lato_core/cells/elements/_elements.scss +10 -0
  57. data/app/assets/stylesheets/lato_core/cells/elements/_flash.scss +74 -0
  58. data/app/assets/stylesheets/lato_core/cells/elements/_modal.scss +76 -0
  59. data/app/assets/stylesheets/lato_core/cells/elements/_pagination.scss +64 -0
  60. data/app/assets/stylesheets/lato_core/cells/elements/_row.scss +3 -0
  61. data/app/assets/stylesheets/lato_core/cells/elements/_table.scss +57 -0
  62. data/app/assets/stylesheets/lato_core/cells/elements/_title.scss +32 -0
  63. data/app/assets/stylesheets/lato_core/cells/inputs/_checkbox.scss +42 -0
  64. data/app/assets/stylesheets/lato_core/cells/inputs/_datetime.scss +23 -0
  65. data/app/assets/stylesheets/lato_core/cells/inputs/_dropzone.scss +12 -0
  66. data/app/assets/stylesheets/lato_core/cells/inputs/_editor.scss +3 -0
  67. data/app/assets/stylesheets/lato_core/cells/inputs/_email.scss +3 -0
  68. data/app/assets/stylesheets/lato_core/cells/inputs/_form.scss +3 -0
  69. data/app/assets/stylesheets/lato_core/cells/inputs/_general.scss +51 -0
  70. data/app/assets/stylesheets/lato_core/cells/inputs/_geolocalization.scss +12 -0
  71. data/app/assets/stylesheets/lato_core/cells/inputs/_inputs.scss +14 -0
  72. data/app/assets/stylesheets/lato_core/cells/inputs/_number.scss +3 -0
  73. data/app/assets/stylesheets/lato_core/cells/inputs/_password.scss +3 -0
  74. data/app/assets/stylesheets/lato_core/cells/inputs/_select.scss +47 -0
  75. data/app/assets/stylesheets/lato_core/cells/inputs/_sortableblock.scss +51 -0
  76. data/app/assets/stylesheets/lato_core/cells/inputs/_text.scss +3 -0
  77. data/app/assets/stylesheets/lato_core/cells/inputs/_textarea.scss +25 -0
  78. data/app/assets/stylesheets/lato_core/cells/widgets/_index.scss +74 -0
  79. data/app/assets/stylesheets/lato_core/cells/widgets/_widgets.scss +1 -0
  80. data/app/assets/stylesheets/lato_core/layouts/_admin.scss +352 -0
  81. data/app/assets/stylesheets/lato_core/layouts/_authentication.scss +10 -0
  82. data/app/assets/stylesheets/lato_core/layouts/_layouts.scss +2 -0
  83. data/app/assets/stylesheets/lato_core/pages/_dashboard.scss +35 -0
  84. data/app/assets/stylesheets/lato_core/pages/_login.scss +7 -0
  85. data/app/assets/stylesheets/lato_core/pages/_pages.scss +2 -0
  86. data/app/assets/stylesheets/lato_core/partials/_dynamic_data_to_js.scss +3 -0
  87. data/app/assets/stylesheets/lato_core/partials/_partials.scss +1 -0
  88. data/app/assets/stylesheets/lato_core/theme.scss.erb +127 -0
  89. data/app/assets/stylesheets/lato_core/vendors/_datetimepicker.css +568 -0
  90. data/app/assets/stylesheets/lato_core/vendors/_dropzone.css +388 -0
  91. data/app/assets/stylesheets/lato_core/vendors/_fontawesome.css +2341 -0
  92. data/app/assets/stylesheets/lato_core/vendors/_scrollbar.css +904 -0
  93. data/app/assets/stylesheets/lato_core/vendors/_selectize.css +324 -0
  94. data/app/assets/stylesheets/lato_core/vendors/_trumbowyg.css +584 -0
  95. data/app/assets/stylesheets/lato_core/vendors/_vendors.scss +6 -0
  96. data/app/assets/stylesheets/lato_core/widgets/_systeminfo.scss +21 -0
  97. data/app/assets/stylesheets/lato_core/widgets/_widgets.scss +1 -0
  98. data/app/cells/lato_core/charts/bar/vertical/cell.rb +57 -0
  99. data/app/cells/lato_core/charts/bar/vertical/views/show.html.erb +7 -0
  100. data/app/cells/lato_core/elements/block/cell.rb +39 -0
  101. data/app/cells/lato_core/elements/block/views/close.html.erb +1 -0
  102. data/app/cells/lato_core/elements/block/views/open.html.erb +4 -0
  103. data/app/cells/lato_core/elements/button/cell.rb +59 -0
  104. data/app/cells/lato_core/elements/button/views/button.html.erb +27 -0
  105. data/app/cells/lato_core/elements/button/views/link.html.erb +65 -0
  106. data/app/cells/lato_core/elements/buttongroup/cell.rb +33 -0
  107. data/app/cells/lato_core/elements/buttongroup/views/show.html.erb +7 -0
  108. data/app/cells/lato_core/elements/code/cell.rb +36 -0
  109. data/app/cells/lato_core/elements/code/views/close.html.erb +2 -0
  110. data/app/cells/lato_core/elements/code/views/open.html.erb +2 -0
  111. data/app/cells/lato_core/elements/flash/cell.rb +35 -0
  112. data/app/cells/lato_core/elements/flash/views/show.html.erb +11 -0
  113. data/app/cells/lato_core/elements/icon/cell.rb +31 -0
  114. data/app/cells/lato_core/elements/icon/views/show.html.erb +1 -0
  115. data/app/cells/lato_core/elements/modal/cell.rb +31 -0
  116. data/app/cells/lato_core/elements/modal/views/show.html.erb +21 -0
  117. data/app/cells/lato_core/elements/pagination/cell.rb +68 -0
  118. data/app/cells/lato_core/elements/pagination/views/show.html.erb +59 -0
  119. data/app/cells/lato_core/elements/row/cell.rb +37 -0
  120. data/app/cells/lato_core/elements/row/views/close.html.erb +1 -0
  121. data/app/cells/lato_core/elements/row/views/open.html.erb +3 -0
  122. data/app/cells/lato_core/elements/table/body/cell.rb +37 -0
  123. data/app/cells/lato_core/elements/table/body/views/close.html.erb +1 -0
  124. data/app/cells/lato_core/elements/table/body/views/open.html.erb +3 -0
  125. data/app/cells/lato_core/elements/table/container/cell.rb +41 -0
  126. data/app/cells/lato_core/elements/table/container/views/close.html.erb +2 -0
  127. data/app/cells/lato_core/elements/table/container/views/open.html.erb +7 -0
  128. data/app/cells/lato_core/elements/table/head/cell.rb +33 -0
  129. data/app/cells/lato_core/elements/table/head/views/show.html.erb +7 -0
  130. data/app/cells/lato_core/elements/table/row/cell.rb +49 -0
  131. data/app/cells/lato_core/elements/table/row/views/show.html.erb +35 -0
  132. data/app/cells/lato_core/elements/title/cell.rb +52 -0
  133. data/app/cells/lato_core/elements/title/views/show.html.erb +4 -0
  134. data/app/cells/lato_core/inputs/checkbox/cell.rb +38 -0
  135. data/app/cells/lato_core/inputs/checkbox/views/show.html.erb +20 -0
  136. data/app/cells/lato_core/inputs/datetime/cell.rb +53 -0
  137. data/app/cells/lato_core/inputs/datetime/views/show.html.erb +19 -0
  138. data/app/cells/lato_core/inputs/dropzone/cell.rb +37 -0
  139. data/app/cells/lato_core/inputs/dropzone/views/show.html.erb +24 -0
  140. data/app/cells/lato_core/inputs/editor/cell.rb +37 -0
  141. data/app/cells/lato_core/inputs/editor/views/show.html.erb +12 -0
  142. data/app/cells/lato_core/inputs/email/cell.rb +40 -0
  143. data/app/cells/lato_core/inputs/email/views/show.html.erb +19 -0
  144. data/app/cells/lato_core/inputs/form/cell.rb +39 -0
  145. data/app/cells/lato_core/inputs/form/views/close.html.erb +1 -0
  146. data/app/cells/lato_core/inputs/form/views/open.html.erb +12 -0
  147. data/app/cells/lato_core/inputs/geolocalization/cell.rb +51 -0
  148. data/app/cells/lato_core/inputs/geolocalization/views/show.html.erb +26 -0
  149. data/app/cells/lato_core/inputs/number/cell.rb +44 -0
  150. data/app/cells/lato_core/inputs/number/views/show.html.erb +25 -0
  151. data/app/cells/lato_core/inputs/password/cell.rb +42 -0
  152. data/app/cells/lato_core/inputs/password/views/show.html.erb +21 -0
  153. data/app/cells/lato_core/inputs/select/cell.rb +56 -0
  154. data/app/cells/lato_core/inputs/select/views/show.html.erb +25 -0
  155. data/app/cells/lato_core/inputs/shared/help.html.erb +7 -0
  156. data/app/cells/lato_core/inputs/shared/label.html.erb +11 -0
  157. data/app/cells/lato_core/inputs/sortableblock/cell.rb +39 -0
  158. data/app/cells/lato_core/inputs/sortableblock/views/show.html.erb +40 -0
  159. data/app/cells/lato_core/inputs/text/cell.rb +42 -0
  160. data/app/cells/lato_core/inputs/text/views/show.html.erb +21 -0
  161. data/app/cells/lato_core/inputs/textarea/cell.rb +41 -0
  162. data/app/cells/lato_core/inputs/textarea/views/show.html.erb +16 -0
  163. data/app/cells/lato_core/widgets/index/cell.rb +215 -0
  164. data/app/cells/lato_core/widgets/index/views/partials/new.html.erb +3 -0
  165. data/app/cells/lato_core/widgets/index/views/partials/pagination.html.erb +3 -0
  166. data/app/cells/lato_core/widgets/index/views/partials/search.html.erb +17 -0
  167. data/app/cells/lato_core/widgets/index/views/show.html.erb +45 -0
  168. data/app/controllers/lato_core/api/api_controller.rb +5 -0
  169. data/app/controllers/lato_core/application_controller.rb +9 -1
  170. data/app/controllers/lato_core/back/authentication_controller.rb +33 -99
  171. data/app/controllers/lato_core/back/back_controller.rb +5 -14
  172. data/app/controllers/lato_core/back/dashboard_controller.rb +13 -0
  173. data/app/controllers/lato_core/back/superusers_controller.rb +97 -113
  174. data/app/controllers/lato_core/doc/cells_charts_controller.rb +7 -0
  175. data/app/controllers/lato_core/doc/cells_elements_controller.rb +31 -0
  176. data/app/controllers/lato_core/doc/cells_inputs_controller.rb +33 -0
  177. data/app/controllers/lato_core/doc/cells_widgets_controller.rb +10 -0
  178. data/app/controllers/lato_core/doc/doc_controller.rb +17 -0
  179. data/app/controllers/lato_core/doc/general_controller.rb +13 -0
  180. data/app/helpers/lato_core/application_helper.rb +4 -0
  181. data/app/jobs/lato_core/application_job.rb +4 -0
  182. data/app/mailers/lato_core/application_mailer.rb +2 -5
  183. data/app/models/lato_core/application_record.rb +5 -0
  184. data/app/models/lato_core/superuser.rb +11 -16
  185. data/app/models/lato_core/superuser/entity_helpers.rb +29 -0
  186. data/app/views/lato_core/back/authentication/index.html.erb +25 -0
  187. data/app/views/lato_core/back/dashboard/index.html.erb +29 -0
  188. data/app/views/lato_core/back/superusers/edit.html.erb +10 -15
  189. data/app/views/lato_core/back/superusers/index.html.erb +16 -27
  190. data/app/views/lato_core/back/superusers/new.html.erb +8 -13
  191. data/app/views/lato_core/back/superusers/shared/_form.html.erb +47 -55
  192. data/app/views/lato_core/back/superusers/show.html.erb +65 -1
  193. data/app/views/lato_core/doc/cells_charts/bar_vertical.erb +64 -0
  194. data/app/views/lato_core/doc/cells_elements/block.html.erb +172 -0
  195. data/app/views/lato_core/doc/cells_elements/button.html.erb +375 -0
  196. data/app/views/lato_core/doc/cells_elements/buttongroup.html.erb +101 -0
  197. data/app/views/lato_core/doc/cells_elements/flash_messages.html.erb +123 -0
  198. data/app/views/lato_core/doc/cells_elements/icon.html.erb +58 -0
  199. data/app/views/lato_core/doc/cells_elements/modal.html.erb +89 -0
  200. data/app/views/lato_core/doc/cells_elements/pagination.html.erb +149 -0
  201. data/app/views/lato_core/doc/cells_elements/row.html.erb +62 -0
  202. data/app/views/lato_core/doc/cells_elements/table.html.erb +272 -0
  203. data/app/views/lato_core/doc/cells_elements/table_body.html.erb +118 -0
  204. data/app/views/lato_core/doc/cells_elements/table_head.html.erb +110 -0
  205. data/app/views/lato_core/doc/cells_elements/table_row.html.erb +212 -0
  206. data/app/views/lato_core/doc/cells_elements/title.html.erb +70 -0
  207. data/app/views/lato_core/doc/cells_inputs/checkbox.html.erb +101 -0
  208. data/app/views/lato_core/doc/cells_inputs/datetime.html.erb +178 -0
  209. data/app/views/lato_core/doc/cells_inputs/dropzone.html.erb +114 -0
  210. data/app/views/lato_core/doc/cells_inputs/editor.html.erb +59 -0
  211. data/app/views/lato_core/doc/cells_inputs/email.html.erb +79 -0
  212. data/app/views/lato_core/doc/cells_inputs/form.html.erb +242 -0
  213. data/app/views/lato_core/doc/cells_inputs/geolocalization.html.erb +157 -0
  214. data/app/views/lato_core/doc/cells_inputs/number.html.erb +100 -0
  215. data/app/views/lato_core/doc/cells_inputs/password.html.erb +79 -0
  216. data/app/views/lato_core/doc/cells_inputs/select.html.erb +124 -0
  217. data/app/views/lato_core/doc/cells_inputs/sortableblock.html.erb +72 -0
  218. data/app/views/lato_core/doc/cells_inputs/text.html.erb +204 -0
  219. data/app/views/lato_core/doc/cells_inputs/textarea.html.erb +104 -0
  220. data/app/views/lato_core/doc/cells_widgets/index.html.erb +163 -0
  221. data/app/views/lato_core/doc/doc/index.html.erb +95 -0
  222. data/app/views/lato_core/doc/general/generators.html.erb +60 -0
  223. data/app/views/lato_core/doc/general/installation.html.erb +49 -0
  224. data/app/views/lato_core/doc/general/languages.html.erb +67 -0
  225. data/app/views/lato_core/doc/general/personalization.html.erb +177 -0
  226. data/app/views/lato_core/doc/shared/_modal_content.html.erb +4 -0
  227. data/app/views/lato_core/doc/shared/_sortableblock_partial.html.erb +1 -0
  228. data/app/views/lato_core/partials/_dynamic_data_to_js.html.erb +3 -0
  229. data/app/views/lato_core/partials/_gmaps.html.erb +5 -0
  230. data/app/views/lato_core/widgets/_systeminfo.html.erb +15 -0
  231. data/app/views/layouts/lato_core/admin.html.erb +44 -0
  232. data/app/views/layouts/lato_core/authentication.html.erb +22 -0
  233. data/app/views/layouts/lato_core/partials/_back.html.erb +5 -0
  234. data/app/views/layouts/lato_core/partials/_load_javascript.html.erb +4 -0
  235. data/app/views/layouts/lato_core/partials/_load_partials.html.erb +5 -0
  236. data/app/views/layouts/lato_core/partials/_load_stylesheet.html.erb +4 -0
  237. data/app/views/layouts/lato_core/partials/_logo.html.erb +9 -0
  238. data/app/views/layouts/lato_core/partials/_menu.html.erb +67 -0
  239. data/app/views/layouts/lato_core/partials/_profile.html.erb +19 -0
  240. data/app/views/layouts/lato_core/partials/_title.html.erb +3 -0
  241. data/app/views/layouts/lato_core/partials/_widgets.html.erb +13 -0
  242. data/config/configs.yml +102 -0
  243. data/config/initializers/assets.rb +9 -0
  244. data/config/initializers/init_system.rb +39 -0
  245. data/config/languages/default.yml +63 -0
  246. data/config/languages/it.yml +63 -0
  247. data/config/routes.rb +10 -13
  248. data/config/routes/api.rb +3 -0
  249. data/config/routes/back.rb +10 -0
  250. data/config/routes/doc.rb +48 -0
  251. data/db/migrate/20160224181217_create_lato_core_superusers.rb +8 -2
  252. data/lib/generators/lato_core/crud_generator.rb +26 -0
  253. data/lib/generators/lato_core/initializer_generator.rb +46 -0
  254. data/lib/generators/lato_core/templates/assets/images/logo.svg +13 -0
  255. data/{config/initializers/lists.rb → lib/generators/lato_core/templates/assets/javascripts/application.js} +0 -0
  256. data/lib/generators/lato_core/templates/assets/stylesheets/application.scss +2 -0
  257. data/lib/generators/lato_core/templates/assets/stylesheets/theme.scss.erb +13 -0
  258. data/lib/generators/lato_core/templates/controllers/application_controller.rb +13 -0
  259. data/lib/generators/lato_core/templates/controllers/crud_controller.rb +87 -0
  260. data/lib/generators/lato_core/templates/views/application/index.html.erb +16 -0
  261. data/lib/generators/lato_core/templates/views/crud/edit.html.erb +18 -0
  262. data/lib/generators/lato_core/templates/views/crud/index.html.erb +29 -0
  263. data/lib/generators/lato_core/templates/views/crud/new.html.erb +18 -0
  264. data/lib/generators/lato_core/templates/views/crud/shared/_form.html.erb +25 -0
  265. data/lib/generators/lato_core/templates/views/crud/show.html.erb +16 -0
  266. data/lib/lato_core.rb +6 -5
  267. data/lib/lato_core/cell.rb +28 -0
  268. data/lib/lato_core/engine.rb +16 -13
  269. data/lib/lato_core/helper.rb +11 -0
  270. data/lib/lato_core/helpers/cells.rb +20 -0
  271. data/lib/lato_core/helpers/general.rb +16 -0
  272. data/lib/lato_core/interface.rb +17 -14
  273. data/lib/lato_core/interfaces/apihelpers.rb +39 -0
  274. data/lib/lato_core/interfaces/application.rb +65 -0
  275. data/lib/lato_core/interfaces/authentication.rb +41 -0
  276. data/lib/lato_core/interfaces/cells.rb +41 -0
  277. data/lib/lato_core/interfaces/general.rb +39 -0
  278. data/lib/lato_core/interfaces/layout.rb +213 -0
  279. data/lib/lato_core/interfaces/modules.rb +110 -0
  280. data/lib/lato_core/interfaces/token.rb +25 -0
  281. data/lib/lato_core/version.rb +3 -0
  282. data/lib/tasks/lato_core_tasks.rake +4 -8
  283. data/lib/tasks/lato_tasks.rake +83 -0
  284. metadata +407 -33
  285. data/app/controllers/lato_core/api/v1/api_controller.rb +0 -8
  286. data/app/mailers/lato_core/superusers_mailer.rb +0 -27
  287. data/app/views/lato_core/back/authentication/login.html.erb +0 -45
  288. data/app/views/lato_core/back/authentication/password_edit.html.erb +0 -45
  289. data/app/views/lato_core/back/authentication/password_forget.html.erb +0 -36
  290. data/app/views/lato_core/back/back/home.html.erb +0 -20
  291. data/app/views/lato_core/mailers/layouts/mailer.html.erb +0 -9
  292. data/app/views/lato_core/mailers/layouts/mailer.text.erb +0 -1
  293. data/app/views/lato_core/mailers/superusers/notify.html.erb +0 -2
  294. data/app/views/lato_core/mailers/superusers/recover_password.html.erb +0 -4
  295. data/config/config.yml +0 -8
  296. data/config/example.yml +0 -66
  297. data/config/initializers/init.rb +0 -15
  298. data/config/initializers/ram.rb +0 -14
  299. data/lang/default.yml +0 -61
  300. data/lang/en.yml +0 -61
  301. data/lib/lato_core/interface/authentication.rb +0 -26
  302. data/lib/lato_core/interface/cache.rb +0 -23
  303. data/lib/lato_core/interface/communication.rb +0 -87
  304. data/lib/lato_core/interface/languages.rb +0 -51
  305. data/lib/lato_core/interface/navigation.rb +0 -95
  306. data/lib/lato_core/interface/session.rb +0 -57
  307. data/lib/lato_core/interface/superusers.rb +0 -134
@@ -0,0 +1,1106 @@
1
+ /** @preserve jQuery.floatThead 2.0.3 - http://mkoryak.github.io/floatThead/ - Copyright (c) 2012 - 2017 Misha Koryak **/
2
+ // @license MIT
3
+
4
+ /* @author Misha Koryak
5
+ * @projectDescription lock a table header in place while scrolling - without breaking styles or events bound to the header
6
+ *
7
+ * Dependencies:
8
+ * jquery 1.9.0 + [required] OR jquery 1.7.0 + jquery UI core
9
+ *
10
+ * http://mkoryak.github.io/floatThead/
11
+ *
12
+ * Tested on FF13+, Chrome 21+, IE8, IE9, IE10, IE11
13
+ *
14
+ */
15
+ (function( $ ) {
16
+ /**
17
+ * provides a default config object. You can modify this after including this script if you want to change the init defaults
18
+ * @type {Object}
19
+ */
20
+ $.floatThead = $.floatThead || {};
21
+ $.floatThead.defaults = {
22
+ headerCellSelector: 'tr:visible:first>*:visible', //thead cells are this.
23
+ zIndex: 1001, //zindex of the floating thead (actually a container div)
24
+ position: 'auto', // 'fixed', 'absolute', 'auto'. auto picks the best for your table scrolling type.
25
+ top: 0, //String or function($table) - offset from top of window where the header should not pass above
26
+ bottom: 0, //String or function($table) - offset from the bottom of the table where the header should stop scrolling
27
+ scrollContainer: function($table) { // or boolean 'true' (use offsetParent) | function -> if the table has horizontal scroll bars then this is the container that has overflow:auto and causes those scroll bars
28
+ return $([]);
29
+ },
30
+ responsiveContainer: function($table) { // only valid if scrollContainer is not used (ie window scrolling). this is the container which will control y scrolling at some mobile breakpoints
31
+ return $([]);
32
+ },
33
+ getSizingRow: function($table, $cols, $fthCells){ // this is only called when using IE,
34
+ // override it if the first row of the table is going to contain colgroups (any cell spans greater than one col)
35
+ // it should return a jquery object containing a wrapped set of table cells comprising a row that contains no col spans and is visible
36
+ return $table.find('tbody tr:visible:first>*:visible');
37
+ },
38
+ floatTableClass: 'floatThead-table',
39
+ floatWrapperClass: 'floatThead-wrapper',
40
+ floatContainerClass: 'floatThead-container',
41
+ copyTableClass: true, //copy 'class' attribute from table into the floated table so that the styles match.
42
+ autoReflow: false, //(undocumented) - use MutationObserver api to reflow automatically when internal table DOM changes
43
+ debug: false, //print possible issues (that don't prevent script loading) to console, if console exists.
44
+ support: { //should we bind events that expect these frameworks to be present and/or check for them?
45
+ bootstrap: true,
46
+ datatables: true,
47
+ jqueryUI: true,
48
+ perfectScrollbar: true
49
+ }
50
+ };
51
+
52
+ var util = window._ || (function underscoreShim(){
53
+ var that = {};
54
+ var hasOwnProperty = Object.prototype.hasOwnProperty, isThings = ['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'];
55
+ that.has = function(obj, key) {
56
+ return hasOwnProperty.call(obj, key);
57
+ };
58
+ that.keys = Object.keys || function(obj) {
59
+ if (obj !== Object(obj)) throw new TypeError('Invalid object');
60
+ var keys = [];
61
+ for (var key in obj) if (that.has(obj, key)) keys.push(key);
62
+ return keys;
63
+ };
64
+ var idCounter = 0;
65
+ that.uniqueId = function(prefix) {
66
+ var id = ++idCounter + '';
67
+ return prefix ? prefix + id : id;
68
+ };
69
+ $.each(isThings, function(){
70
+ var name = this;
71
+ that['is' + name] = function(obj) {
72
+ return Object.prototype.toString.call(obj) == '[object ' + name + ']';
73
+ };
74
+ });
75
+ that.debounce = function(func, wait, immediate) {
76
+ var timeout, args, context, timestamp, result;
77
+ return function() {
78
+ context = this;
79
+ args = arguments;
80
+ timestamp = new Date();
81
+ var later = function() {
82
+ var last = (new Date()) - timestamp;
83
+ if (last < wait) {
84
+ timeout = setTimeout(later, wait - last);
85
+ } else {
86
+ timeout = null;
87
+ if (!immediate) result = func.apply(context, args);
88
+ }
89
+ };
90
+ var callNow = immediate && !timeout;
91
+ if (!timeout) {
92
+ timeout = setTimeout(later, wait);
93
+ }
94
+ if (callNow) result = func.apply(context, args);
95
+ return result;
96
+ };
97
+ };
98
+ return that;
99
+ })();
100
+
101
+ var canObserveMutations = typeof MutationObserver !== 'undefined';
102
+
103
+
104
+ //browser stuff
105
+ var ieVersion = function(){for(var a=3,b=document.createElement("b"),c=b.all||[];a = 1+a,b.innerHTML="<!--[if gt IE "+ a +"]><i><![endif]-->",c[0];);return 4<a?a:document.documentMode}();
106
+ var isFF = /Gecko\//.test(navigator.userAgent);
107
+ var isWebkit = /WebKit\//.test(navigator.userAgent);
108
+
109
+ if(!(ieVersion || isFF || isWebkit)){
110
+ ieVersion = 11; //yey a hack!
111
+ }
112
+
113
+ //safari 7 (and perhaps others) reports table width to be parent container's width if max-width is set on table. see: https://github.com/mkoryak/floatThead/issues/108
114
+ var isTableWidthBug = function(){
115
+ if(isWebkit) {
116
+ var $test = $('<div>').css('width', 0).append(
117
+ $('<table>').css('max-width', '100%').append(
118
+ $('<tr>').append(
119
+ $('<th>').append(
120
+ $('<div>').css('min-width', 100).text('X')
121
+ )
122
+ )
123
+ )
124
+ );
125
+ $("body").append($test);
126
+ var ret = ($test.find("table").width() == 0);
127
+ $test.remove();
128
+ return ret;
129
+ }
130
+ return false;
131
+ };
132
+
133
+ var createElements = !isFF && !ieVersion; //FF can read width from <col> elements, but webkit cannot
134
+
135
+ var $window = $(window);
136
+
137
+ if(!window.matchMedia) {
138
+ var _beforePrint = window.onbeforeprint;
139
+ var _afterPrint = window.onafterprint;
140
+ window.onbeforeprint = function () {
141
+ _beforePrint && _beforePrint();
142
+ $window.triggerHandler("beforeprint");
143
+ };
144
+ window.onafterprint = function () {
145
+ _afterPrint && _afterPrint();
146
+ $window.triggerHandler("afterprint");
147
+ };
148
+ }
149
+
150
+ /**
151
+ * @param debounceMs
152
+ * @param cb
153
+ */
154
+ function windowResize(eventName, cb){
155
+ if(ieVersion == 8){ //ie8 is crap: https://github.com/mkoryak/floatThead/issues/65
156
+ var winWidth = $window.width();
157
+ var debouncedCb = util.debounce(function(){
158
+ var winWidthNew = $window.width();
159
+ if(winWidth != winWidthNew){
160
+ winWidth = winWidthNew;
161
+ cb();
162
+ }
163
+ }, 1);
164
+ $window.on(eventName, debouncedCb);
165
+ } else {
166
+ $window.on(eventName, util.debounce(cb, 1));
167
+ }
168
+ }
169
+
170
+ function getClosestScrollContainer($elem) {
171
+ var elem = $elem[0];
172
+ var parent = elem.parentElement;
173
+
174
+ do {
175
+ var pos = window
176
+ .getComputedStyle(parent)
177
+ .getPropertyValue('overflow');
178
+
179
+ if (pos != 'visible') break;
180
+
181
+ } while (parent = parent.parentElement);
182
+
183
+ if(parent == document.body){
184
+ return $([]);
185
+ }
186
+ return $(parent);
187
+ }
188
+
189
+
190
+ function debug(str){
191
+ window && window.console && window.console.error && window.console.error("jQuery.floatThead: " + str);
192
+ }
193
+
194
+ //returns fractional pixel widths
195
+ function getOffsetWidth(el) {
196
+ var rect = el.getBoundingClientRect();
197
+ return rect.width || rect.right - rect.left;
198
+ }
199
+
200
+ /**
201
+ * try to calculate the scrollbar width for your browser/os
202
+ * @return {Number}
203
+ */
204
+ function scrollbarWidth() {
205
+ var d = document.createElement("scrolltester");
206
+ d.style.cssText = 'width:100px;height:100px;overflow:scroll!important;position:absolute;top:-9999px;display:block';
207
+ document.body.appendChild(d);
208
+ var result = d.offsetWidth - d.clientWidth;
209
+ document.body.removeChild(d);
210
+ return result;
211
+ }
212
+
213
+ /**
214
+ * Check if a given table has been datatableized (http://datatables.net)
215
+ * @param $table
216
+ * @return {Boolean}
217
+ */
218
+ function isDatatable($table){
219
+ if($table.dataTableSettings){
220
+ for(var i = 0; i < $table.dataTableSettings.length; i++){
221
+ var table = $table.dataTableSettings[i].nTable;
222
+ if($table[0] == table){
223
+ return true;
224
+ }
225
+ }
226
+ }
227
+ return false;
228
+ }
229
+
230
+ function tableWidth($table, $fthCells, isOuter){
231
+ // see: https://github.com/mkoryak/floatThead/issues/108
232
+ var fn = isOuter ? "outerWidth": "width";
233
+ if(isTableWidthBug && $table.css("max-width")){
234
+ var w = 0;
235
+ if(isOuter) {
236
+ w += parseInt($table.css("borderLeft"), 10);
237
+ w += parseInt($table.css("borderRight"), 10);
238
+ }
239
+ for(var i=0; i < $fthCells.length; i++){
240
+ w += $fthCells.get(i).offsetWidth;
241
+ }
242
+ return w;
243
+ } else {
244
+ return $table[fn]();
245
+ }
246
+ }
247
+ $.fn.floatThead = function(map){
248
+ map = map || {};
249
+
250
+ if(ieVersion < 8){
251
+ return this; //no more crappy browser support.
252
+ }
253
+
254
+ var mObs = null; //mutation observer lives in here if we can use it / make it
255
+
256
+ if(util.isFunction(isTableWidthBug)) {
257
+ isTableWidthBug = isTableWidthBug();
258
+ }
259
+
260
+ if(util.isString(map)){
261
+ var command = map;
262
+ var args = Array.prototype.slice.call(arguments, 1);
263
+ var ret = this;
264
+ this.filter('table').each(function(){
265
+ var $this = $(this);
266
+ var opts = $this.data('floatThead-lazy');
267
+ if(opts){
268
+ $this.floatThead(opts);
269
+ }
270
+ var obj = $this.data('floatThead-attached');
271
+ if(obj && util.isFunction(obj[command])){
272
+ var r = obj[command].apply(this, args);
273
+ if(r !== undefined){
274
+ ret = r;
275
+ }
276
+ }
277
+ });
278
+ return ret;
279
+ }
280
+ var opts = $.extend({}, $.floatThead.defaults || {}, map);
281
+
282
+ $.each(map, function(key, val){
283
+ if((!(key in $.floatThead.defaults)) && opts.debug){
284
+ debug("Used ["+key+"] key to init plugin, but that param is not an option for the plugin. Valid options are: "+ (util.keys($.floatThead.defaults)).join(', '));
285
+ }
286
+ });
287
+ if(opts.debug){
288
+ var v = $.fn.jquery.split(".");
289
+ if(parseInt(v[0], 10) == 1 && parseInt(v[1], 10) <= 7){
290
+ debug("jQuery version "+$.fn.jquery+" detected! This plugin supports 1.8 or better, or 1.7.x with jQuery UI 1.8.24 -> http://jqueryui.com/resources/download/jquery-ui-1.8.24.zip")
291
+ }
292
+ }
293
+
294
+ this.filter(':not(.'+opts.floatTableClass+')').each(function(){
295
+ var floatTheadId = util.uniqueId();
296
+ var $table = $(this);
297
+ if($table.data('floatThead-attached')){
298
+ return true; //continue the each loop
299
+ }
300
+ if(!$table.is('table')){
301
+ throw new Error('jQuery.floatThead must be run on a table element. ex: $("table").floatThead();');
302
+ }
303
+ canObserveMutations = opts.autoReflow && canObserveMutations; //option defaults to false!
304
+ var $header = $table.children('thead:first');
305
+ var $tbody = $table.children('tbody:first');
306
+ if($header.length == 0 || $tbody.length == 0){
307
+ if(opts.debug) {
308
+ if($header.length == 0){
309
+ debug('The thead element is missing.');
310
+ } else{
311
+ debug('The tbody element is missing.');
312
+ }
313
+ }
314
+ $table.data('floatThead-lazy', opts);
315
+ $table.unbind("reflow").one('reflow', function(){
316
+ $table.floatThead(opts);
317
+ });
318
+ return;
319
+ }
320
+ if($table.data('floatThead-lazy')){
321
+ $table.unbind("reflow");
322
+ }
323
+ $table.data('floatThead-lazy', false);
324
+
325
+ var headerFloated = true;
326
+ var scrollingTop, scrollingBottom;
327
+ var scrollbarOffset = {vertical: 0, horizontal: 0};
328
+ var scWidth = scrollbarWidth();
329
+ var lastColumnCount = 0; //used by columnNum()
330
+
331
+ if(opts.scrollContainer === true){
332
+ opts.scrollContainer = getClosestScrollContainer;
333
+ }
334
+
335
+ var $scrollContainer = opts.scrollContainer($table) || $([]); //guard against returned nulls
336
+ var locked = $scrollContainer.length > 0;
337
+ var $responsiveContainer = locked ? $([]) : opts.responsiveContainer($table) || $([]);
338
+ var responsive = isResponsiveContainerActive();
339
+
340
+ var useAbsolutePositioning = null;
341
+
342
+
343
+
344
+ if (opts.position == 'auto') {
345
+ useAbsolutePositioning = null;
346
+ } else if (opts.position == 'fixed') {
347
+ useAbsolutePositioning = false;
348
+ } else if (opts.position == 'absolute'){
349
+ useAbsolutePositioning = true;
350
+ } else if (opts.debug) {
351
+ debug('Invalid value given to "position" option, valid is "fixed", "absolute" and "auto". You passed: ', opts.position);
352
+ }
353
+
354
+ if(useAbsolutePositioning == null){ //defaults: locked=true, !locked=false
355
+ useAbsolutePositioning = locked;
356
+ }
357
+ var $caption = $table.find("caption");
358
+ var haveCaption = $caption.length == 1;
359
+ if(haveCaption){
360
+ var captionAlignTop = ($caption.css("caption-side") || $caption.attr("align") || "top") === "top";
361
+ }
362
+
363
+ var $fthGrp = $('<fthfoot>').css({
364
+ 'display': 'table-footer-group',
365
+ 'border-spacing': 0,
366
+ 'height': 0,
367
+ 'border-collapse': 'collapse',
368
+ 'visibility': 'hidden'
369
+ });
370
+
371
+ var wrappedContainer = false; //used with absolute positioning enabled. did we need to wrap the scrollContainer/table with a relative div?
372
+ var $wrapper = $([]); //used when absolute positioning enabled - wraps the table and the float container
373
+ var absoluteToFixedOnScroll = ieVersion <= 9 && !locked && useAbsolutePositioning; //on IE using absolute positioning doesn't look good with window scrolling, so we change position to fixed on scroll, and then change it back to absolute when done.
374
+ var $floatTable = $("<table/>");
375
+ var $floatColGroup = $("<colgroup/>");
376
+ var $tableColGroup = $table.children('colgroup:first');
377
+ var existingColGroup = true;
378
+ if($tableColGroup.length == 0){
379
+ $tableColGroup = $("<colgroup/>");
380
+ existingColGroup = false;
381
+ }
382
+ var $fthRow = $('<fthtr>').css({ //created unstyled elements (used for sizing the table because chrome can't read <col> width)
383
+ 'display': 'table-row',
384
+ 'border-spacing': 0,
385
+ 'height': 0,
386
+ 'border-collapse': 'collapse'
387
+ });
388
+ var $floatContainer = $('<div>').css('overflow', 'hidden').attr('aria-hidden', 'true');
389
+ var floatTableHidden = false; //this happens when the table is hidden and we do magic when making it visible
390
+ var $newHeader = $("<thead/>");
391
+ var $sizerRow = $('<tr class="size-row" aria-hidden="true"/>');
392
+ var $sizerCells = $([]);
393
+ var $tableCells = $([]); //used for sizing - either $sizerCells or $tableColGroup cols. $tableColGroup cols are only created in chrome for borderCollapse:collapse because of a chrome bug.
394
+ var $headerCells = $([]);
395
+ var $fthCells = $([]); //created elements
396
+
397
+ $newHeader.append($sizerRow);
398
+ $table.prepend($tableColGroup);
399
+ if(createElements){
400
+ $fthGrp.append($fthRow);
401
+ $table.append($fthGrp);
402
+ }
403
+
404
+ $floatTable.append($floatColGroup);
405
+ $floatContainer.append($floatTable);
406
+ if(opts.copyTableClass){
407
+ $floatTable.attr('class', $table.attr('class'));
408
+ }
409
+ $floatTable.attr({ //copy over some deprecated table attributes that people still like to use. Good thing people don't use colgroups...
410
+ 'cellpadding': $table.attr('cellpadding'),
411
+ 'cellspacing': $table.attr('cellspacing'),
412
+ 'border': $table.attr('border')
413
+ });
414
+ var tableDisplayCss = $table.css('display');
415
+ $floatTable.css({
416
+ 'borderCollapse': $table.css('borderCollapse'),
417
+ 'border': $table.css('border'),
418
+ 'display': tableDisplayCss
419
+ });
420
+ if(!locked){
421
+ $floatTable.css('width', 'auto');
422
+ }
423
+ if(tableDisplayCss == 'none'){
424
+ floatTableHidden = true;
425
+ }
426
+
427
+ $floatTable.addClass(opts.floatTableClass).css({'margin': 0, 'border-bottom-width': 0}); //must have no margins or you won't be able to click on things under floating table
428
+
429
+ if(useAbsolutePositioning){
430
+ var makeRelative = function($container, alwaysWrap){
431
+ var positionCss = $container.css('position');
432
+ var relativeToScrollContainer = (positionCss == "relative" || positionCss == "absolute");
433
+ var $containerWrap = $container;
434
+ if(!relativeToScrollContainer || alwaysWrap){
435
+ var css = {"paddingLeft": $container.css('paddingLeft'), "paddingRight": $container.css('paddingRight')};
436
+ $floatContainer.css(css);
437
+ $containerWrap = $container.data('floatThead-containerWrap') || $container.wrap(
438
+ $('<div>').addClass(opts.floatWrapperClass).css({
439
+ 'position': 'relative',
440
+ 'clear': 'both'
441
+ })
442
+ ).parent();
443
+ $container.data('floatThead-containerWrap', $containerWrap); //multiple tables inside one scrolling container - #242
444
+ wrappedContainer = true;
445
+ }
446
+ return $containerWrap;
447
+ };
448
+ if(locked){
449
+ $wrapper = makeRelative($scrollContainer, true);
450
+ $wrapper.prepend($floatContainer);
451
+ } else {
452
+ $wrapper = makeRelative($table);
453
+ $table.before($floatContainer);
454
+ }
455
+ } else {
456
+ $table.before($floatContainer);
457
+ }
458
+
459
+
460
+ $floatContainer.css({
461
+ position: useAbsolutePositioning ? 'absolute' : 'fixed',
462
+ marginTop: 0,
463
+ top: useAbsolutePositioning ? 0 : 'auto',
464
+ zIndex: opts.zIndex,
465
+ willChange: 'transform'
466
+ });
467
+ $floatContainer.addClass(opts.floatContainerClass);
468
+ updateScrollingOffsets();
469
+
470
+ var layoutFixed = {'table-layout': 'fixed'};
471
+ var layoutAuto = {'table-layout': $table.css('tableLayout') || 'auto'};
472
+ var originalTableWidth = $table[0].style.width || ""; //setting this to auto is bad: #70
473
+ var originalTableMinWidth = $table.css('minWidth') || "";
474
+
475
+ function eventName(name){
476
+ return name+'.fth-'+floatTheadId+'.floatTHead'
477
+ }
478
+
479
+ function setHeaderHeight(){
480
+ var headerHeight = 0;
481
+ $header.children("tr:visible").each(function(){
482
+ headerHeight += $(this).outerHeight(true);
483
+ });
484
+ if($table.css('border-collapse') == 'collapse') {
485
+ var tableBorderTopHeight = parseInt($table.css('border-top-width'), 10);
486
+ var cellBorderTopHeight = parseInt($table.find("thead tr:first").find(">*:first").css('border-top-width'), 10);
487
+ if(tableBorderTopHeight > cellBorderTopHeight) {
488
+ headerHeight -= (tableBorderTopHeight / 2); //id love to see some docs where this magic recipe is found..
489
+ }
490
+ }
491
+ $sizerRow.outerHeight(headerHeight);
492
+ $sizerCells.outerHeight(headerHeight);
493
+ }
494
+
495
+
496
+ function setFloatWidth(){
497
+ var tw = tableWidth($table, $fthCells, true);
498
+ var $container = responsive ? $responsiveContainer : $scrollContainer;
499
+ var width = $container.width() || tw;
500
+ var floatContainerWidth = $container.css("overflow-y") != 'hidden' ? width - scrollbarOffset.vertical : width;
501
+ $floatContainer.width(floatContainerWidth);
502
+ if(locked){
503
+ var percent = 100 * tw / (floatContainerWidth);
504
+ $floatTable.css('width', percent+'%');
505
+ } else {
506
+ $floatTable.outerWidth(tw);
507
+ }
508
+ }
509
+
510
+ function updateScrollingOffsets(){
511
+ scrollingTop = (util.isFunction(opts.top) ? opts.top($table) : opts.top) || 0;
512
+ scrollingBottom = (util.isFunction(opts.bottom) ? opts.bottom($table) : opts.bottom) || 0;
513
+ }
514
+
515
+ /**
516
+ * get the number of columns and also rebuild resizer rows if the count is different than the last count
517
+ */
518
+ function columnNum(){
519
+ var count;
520
+ var $headerColumns = $header.find(opts.headerCellSelector);
521
+ if(existingColGroup){
522
+ count = $tableColGroup.find('col').length;
523
+ } else {
524
+ count = 0;
525
+ $headerColumns.each(function () {
526
+ count += parseInt(($(this).attr('colspan') || 1), 10);
527
+ });
528
+ }
529
+ if(count != lastColumnCount){
530
+ lastColumnCount = count;
531
+ var cells = [], cols = [], psuedo = [], content;
532
+ for(var x = 0; x < count; x++){
533
+ content = $headerColumns.eq(x).text();
534
+ cells.push('<th class="floatThead-col" aria-label="'+content+'"/>');
535
+ cols.push('<col/>');
536
+ psuedo.push(
537
+ $('<fthtd>').css({
538
+ 'display': 'table-cell',
539
+ 'height': 0,
540
+ 'width': 'auto'
541
+ })
542
+ );
543
+ }
544
+
545
+ cols = cols.join('');
546
+ cells = cells.join('');
547
+
548
+ if(createElements){
549
+ $fthRow.empty();
550
+ $fthRow.append(psuedo);
551
+ $fthCells = $fthRow.find('fthtd');
552
+ }
553
+
554
+ $sizerRow.html(cells);
555
+ $sizerCells = $sizerRow.find("th");
556
+ if(!existingColGroup){
557
+ $tableColGroup.html(cols);
558
+ }
559
+ $tableCells = $tableColGroup.find('col');
560
+ $floatColGroup.html(cols);
561
+ $headerCells = $floatColGroup.find("col");
562
+
563
+ }
564
+ return count;
565
+ }
566
+
567
+ function refloat(){ //make the thing float
568
+ if(!headerFloated){
569
+ headerFloated = true;
570
+ if(useAbsolutePositioning){ //#53, #56
571
+ var tw = tableWidth($table, $fthCells, true);
572
+ var wrapperWidth = $wrapper.width();
573
+ if(tw > wrapperWidth){
574
+ $table.css('minWidth', tw);
575
+ }
576
+ }
577
+ $table.css(layoutFixed);
578
+ $floatTable.css(layoutFixed);
579
+ $floatTable.append($header); //append because colgroup must go first in chrome
580
+ $tbody.before($newHeader);
581
+ setHeaderHeight();
582
+ }
583
+ }
584
+ function unfloat(){ //put the header back into the table
585
+ if(headerFloated){
586
+ headerFloated = false;
587
+ if(useAbsolutePositioning){ //#53, #56
588
+ $table.width(originalTableWidth);
589
+ }
590
+ $newHeader.detach();
591
+ $table.prepend($header);
592
+ $table.css(layoutAuto);
593
+ $floatTable.css(layoutAuto);
594
+ $table.css('minWidth', originalTableMinWidth); //this looks weird, but it's not a bug. Think about it!!
595
+ $table.css('minWidth', tableWidth($table, $fthCells)); //#121
596
+ }
597
+ }
598
+ var isHeaderFloatingLogical = false; //for the purpose of this event, the header is/isnt floating, even though the element
599
+ //might be in some other state. this is what the header looks like to the user
600
+ function triggerFloatEvent(isFloating){
601
+ if(isHeaderFloatingLogical != isFloating){
602
+ isHeaderFloatingLogical = isFloating;
603
+ $table.triggerHandler("floatThead", [isFloating, $floatContainer])
604
+ }
605
+ }
606
+ function changePositioning(isAbsolute){
607
+ if(useAbsolutePositioning != isAbsolute){
608
+ useAbsolutePositioning = isAbsolute;
609
+ $floatContainer.css({
610
+ position: useAbsolutePositioning ? 'absolute' : 'fixed'
611
+ });
612
+ }
613
+ }
614
+ function getSizingRow($table, $cols, $fthCells, ieVersion){
615
+ if(createElements){
616
+ return $fthCells;
617
+ } else if(ieVersion) {
618
+ return opts.getSizingRow($table, $cols, $fthCells);
619
+ } else {
620
+ return $cols;
621
+ }
622
+ }
623
+
624
+ /**
625
+ * returns a function that updates the floating header's cell widths.
626
+ * @return {Function}
627
+ */
628
+ function reflow(){
629
+ var i;
630
+ var numCols = columnNum(); //if the tables columns changed dynamically since last time (datatables), rebuild the sizer rows and get a new count
631
+
632
+ return function(){
633
+ //Cache the current scrollLeft value so that it can be reset post reflow
634
+ var scrollLeft = $floatContainer.scrollLeft();
635
+ $tableCells = $tableColGroup.find('col');
636
+ var $rowCells = getSizingRow($table, $tableCells, $fthCells, ieVersion);
637
+
638
+ if($rowCells.length == numCols && numCols > 0){
639
+ if(!existingColGroup){
640
+ for(i=0; i < numCols; i++){
641
+ $tableCells.eq(i).css('width', '');
642
+ }
643
+ }
644
+ unfloat();
645
+ var widths = [];
646
+ for(i=0; i < numCols; i++){
647
+ widths[i] = getOffsetWidth($rowCells.get(i));
648
+ }
649
+ for(i=0; i < numCols; i++){
650
+ $headerCells.eq(i).width(widths[i]);
651
+ $tableCells.eq(i).width(widths[i]);
652
+ }
653
+ refloat();
654
+ } else {
655
+ $floatTable.append($header);
656
+ $table.css(layoutAuto);
657
+ $floatTable.css(layoutAuto);
658
+ setHeaderHeight();
659
+ }
660
+ //Set back the current scrollLeft value on floatContainer
661
+ $floatContainer.scrollLeft(scrollLeft);
662
+ $table.triggerHandler("reflowed", [$floatContainer]);
663
+ };
664
+ }
665
+
666
+ function floatContainerBorderWidth(side){
667
+ var border = $scrollContainer.css("border-"+side+"-width");
668
+ var w = 0;
669
+ if (border && ~border.indexOf('px')) {
670
+ w = parseInt(border, 10);
671
+ }
672
+ return w;
673
+ }
674
+
675
+ function isResponsiveContainerActive(){
676
+ return $responsiveContainer.css("overflow-x") == 'auto';
677
+ }
678
+ /**
679
+ * first performs initial calculations that we expect to not change when the table, window, or scrolling container are scrolled.
680
+ * returns a function that calculates the floating container's top and left coords. takes into account if we are using page scrolling or inner scrolling
681
+ * @return {Function}
682
+ */
683
+ function calculateFloatContainerPosFn(){
684
+ var scrollingContainerTop = $scrollContainer.scrollTop();
685
+
686
+ //this floatEnd calc was moved out of the returned function because we assume the table height doesn't change (otherwise we must reinit by calling calculateFloatContainerPosFn)
687
+ var floatEnd;
688
+ var tableContainerGap = 0;
689
+ var captionHeight = haveCaption ? $caption.outerHeight(true) : 0;
690
+ var captionScrollOffset = captionAlignTop ? captionHeight : -captionHeight;
691
+
692
+ var floatContainerHeight = $floatContainer.height();
693
+ var tableOffset = $table.offset();
694
+ var tableLeftGap = 0; //can be caused by border on container (only in locked mode)
695
+ var tableTopGap = 0;
696
+ if(locked){
697
+ var containerOffset = $scrollContainer.offset();
698
+ tableContainerGap = tableOffset.top - containerOffset.top + scrollingContainerTop;
699
+ if(haveCaption && captionAlignTop){
700
+ tableContainerGap += captionHeight;
701
+ }
702
+ tableLeftGap = floatContainerBorderWidth('left');
703
+ tableTopGap = floatContainerBorderWidth('top');
704
+ tableContainerGap -= tableTopGap;
705
+ } else {
706
+ floatEnd = tableOffset.top - scrollingTop - floatContainerHeight + scrollingBottom + scrollbarOffset.horizontal;
707
+ }
708
+ var windowTop = $window.scrollTop();
709
+ var windowLeft = $window.scrollLeft();
710
+ var getScrollContainerLeft = function(){
711
+ return (isResponsiveContainerActive() ? $responsiveContainer : $scrollContainer).scrollLeft() || 0;
712
+ };
713
+ var scrollContainerLeft = getScrollContainerLeft();
714
+
715
+ return function(eventType){
716
+ responsive = isResponsiveContainerActive();
717
+
718
+ var isTableHidden = $table[0].offsetWidth <= 0 && $table[0].offsetHeight <= 0;
719
+ if(!isTableHidden && floatTableHidden) {
720
+ floatTableHidden = false;
721
+ setTimeout(function(){
722
+ $table.triggerHandler("reflow");
723
+ }, 1);
724
+ return null;
725
+ }
726
+ if(isTableHidden){ //it's hidden
727
+ floatTableHidden = true;
728
+ if(!useAbsolutePositioning){
729
+ return null;
730
+ }
731
+ }
732
+
733
+ if(eventType == 'windowScroll'){
734
+ windowTop = $window.scrollTop();
735
+ windowLeft = $window.scrollLeft();
736
+ } else if(eventType == 'containerScroll'){
737
+ if($responsiveContainer.length){
738
+ if(!responsive){
739
+ return; //we dont care about the event if we arent responsive right now
740
+ }
741
+ scrollContainerLeft = $responsiveContainer.scrollLeft();
742
+ } else {
743
+ scrollingContainerTop = $scrollContainer.scrollTop();
744
+ scrollContainerLeft = $scrollContainer.scrollLeft();
745
+ }
746
+ } else if(eventType != 'init') {
747
+ windowTop = $window.scrollTop();
748
+ windowLeft = $window.scrollLeft();
749
+ scrollingContainerTop = $scrollContainer.scrollTop();
750
+ scrollContainerLeft = getScrollContainerLeft();
751
+ }
752
+ if(isWebkit && (windowTop < 0 || windowLeft < 0)){ //chrome overscroll effect at the top of the page - breaks fixed positioned floated headers
753
+ return;
754
+ }
755
+
756
+ if(absoluteToFixedOnScroll){
757
+ if(eventType == 'windowScrollDone'){
758
+ changePositioning(true); //change to absolute
759
+ } else {
760
+ changePositioning(false); //change to fixed
761
+ }
762
+ } else if(eventType == 'windowScrollDone'){
763
+ return null; //event is fired when they stop scrolling. ignore it if not 'absoluteToFixedOnScroll'
764
+ }
765
+
766
+ tableOffset = $table.offset();
767
+ if(haveCaption && captionAlignTop){
768
+ tableOffset.top += captionHeight;
769
+ }
770
+ var top, left;
771
+ var tableHeight = $table.outerHeight();
772
+
773
+ if(locked && useAbsolutePositioning){ //inner scrolling, absolute positioning
774
+ if (tableContainerGap >= scrollingContainerTop) {
775
+ var gap = tableContainerGap - scrollingContainerTop + tableTopGap;
776
+ top = gap > 0 ? gap : 0;
777
+ triggerFloatEvent(false);
778
+ } else {
779
+ top = wrappedContainer ? tableTopGap : scrollingContainerTop;
780
+ //headers stop at the top of the viewport
781
+ triggerFloatEvent(true);
782
+ }
783
+ left = tableLeftGap;
784
+ } else if(!locked && useAbsolutePositioning) { //window scrolling, absolute positioning
785
+ if(windowTop > floatEnd + tableHeight + captionScrollOffset){
786
+ top = tableHeight - floatContainerHeight + captionScrollOffset; //scrolled past table
787
+ } else if (tableOffset.top >= windowTop + scrollingTop) {
788
+ top = 0; //scrolling to table
789
+ unfloat();
790
+ triggerFloatEvent(false);
791
+ } else {
792
+ top = scrollingTop + windowTop - tableOffset.top + tableContainerGap + (captionAlignTop ? captionHeight : 0);
793
+ refloat(); //scrolling within table. header floated
794
+ triggerFloatEvent(true);
795
+ }
796
+ left = scrollContainerLeft;
797
+ } else if(locked && !useAbsolutePositioning){ //inner scrolling, fixed positioning
798
+ if (tableContainerGap > scrollingContainerTop || scrollingContainerTop - tableContainerGap > tableHeight) {
799
+ top = tableOffset.top - windowTop;
800
+ unfloat();
801
+ triggerFloatEvent(false);
802
+ } else {
803
+ top = tableOffset.top + scrollingContainerTop - windowTop - tableContainerGap;
804
+ refloat();
805
+ triggerFloatEvent(true);
806
+ //headers stop at the top of the viewport
807
+ }
808
+ left = tableOffset.left + scrollContainerLeft - windowLeft;
809
+ } else if(!locked && !useAbsolutePositioning) { //window scrolling, fixed positioning
810
+ if(windowTop > floatEnd + tableHeight + captionScrollOffset){
811
+ top = tableHeight + scrollingTop - windowTop + floatEnd + captionScrollOffset;
812
+ //scrolled past the bottom of the table
813
+ } else if (tableOffset.top > windowTop + scrollingTop) {
814
+ top = tableOffset.top - windowTop;
815
+ refloat();
816
+ triggerFloatEvent(false); //this is a weird case, the header never gets unfloated and i have no no way to know
817
+ //scrolled past the top of the table
818
+ } else {
819
+ //scrolling within the table
820
+ top = scrollingTop;
821
+ triggerFloatEvent(true);
822
+ }
823
+ left = tableOffset.left + scrollContainerLeft - windowLeft;
824
+ }
825
+ return {top: Math.round(top), left: Math.round(left)};
826
+ };
827
+ }
828
+ /**
829
+ * returns a function that caches old floating container position and only updates css when the position changes
830
+ * @return {Function}
831
+ */
832
+ function repositionFloatContainerFn(){
833
+ var oldTop = null;
834
+ var oldLeft = null;
835
+ var oldScrollLeft = null;
836
+ return function(pos, setWidth, setHeight){
837
+ if(pos != null && (oldTop != pos.top || oldLeft != pos.left)){
838
+ if(ieVersion === 8){
839
+ $floatContainer.css({
840
+ top: pos.top,
841
+ left: pos.left
842
+ });
843
+ } else {
844
+ var transform = 'translateX(' + pos.left + 'px) translateY(' + pos.top + 'px)';
845
+ $floatContainer.css({
846
+ '-webkit-transform' : transform,
847
+ '-moz-transform' : transform,
848
+ '-ms-transform' : transform,
849
+ '-o-transform' : transform,
850
+ 'transform' : transform,
851
+ 'top': 0,
852
+ 'left': 0
853
+ });
854
+ }
855
+ oldTop = pos.top;
856
+ oldLeft = pos.left;
857
+ }
858
+ if(setWidth){
859
+ setFloatWidth();
860
+ }
861
+ if(setHeight){
862
+ setHeaderHeight();
863
+ }
864
+ var scrollLeft = (responsive ? $responsiveContainer : $scrollContainer).scrollLeft();
865
+ if(!useAbsolutePositioning || oldScrollLeft != scrollLeft){
866
+ $floatContainer.scrollLeft(scrollLeft);
867
+ oldScrollLeft = scrollLeft;
868
+ }
869
+ }
870
+ }
871
+
872
+ /**
873
+ * checks if THIS table has scrollbars, and finds their widths
874
+ */
875
+ function calculateScrollBarSize(){ //this should happen after the floating table has been positioned
876
+ if($scrollContainer.length){
877
+ if(opts.support && opts.support.perfectScrollbar && $scrollContainer.data().perfectScrollbar){
878
+ scrollbarOffset = {horizontal:0, vertical:0};
879
+ } else {
880
+ if($scrollContainer.css('overflow-x') == 'scroll'){
881
+ scrollbarOffset.horizontal = scWidth;
882
+ } else {
883
+ var sw = $scrollContainer.width(), tw = tableWidth($table, $fthCells);
884
+ var offsetv = sh < th ? scWidth : 0;
885
+ scrollbarOffset.horizontal = sw - offsetv < tw ? scWidth : 0;
886
+ }
887
+ if($scrollContainer.css('overflow-y') == 'scroll'){
888
+ scrollbarOffset.vertical = scWidth;
889
+ } else {
890
+ var sh = $scrollContainer.height(), th = $table.height();
891
+ var offseth = sw < tw ? scWidth : 0;
892
+ scrollbarOffset.vertical = sh - offseth < th ? scWidth : 0;
893
+ }
894
+ }
895
+ }
896
+ }
897
+ //finish up. create all calculation functions and bind them to events
898
+ calculateScrollBarSize();
899
+
900
+ var flow;
901
+
902
+ var ensureReflow = function(){
903
+ flow = reflow();
904
+ flow();
905
+ };
906
+
907
+ ensureReflow();
908
+
909
+ var calculateFloatContainerPos = calculateFloatContainerPosFn();
910
+ var repositionFloatContainer = repositionFloatContainerFn();
911
+
912
+ repositionFloatContainer(calculateFloatContainerPos('init'), true); //this must come after reflow because reflow changes scrollLeft back to 0 when it rips out the thead
913
+
914
+ var windowScrollDoneEvent = util.debounce(function(){
915
+ repositionFloatContainer(calculateFloatContainerPos('windowScrollDone'), false);
916
+ }, 1);
917
+
918
+ var windowScrollEvent = function(){
919
+ repositionFloatContainer(calculateFloatContainerPos('windowScroll'), false);
920
+ if(absoluteToFixedOnScroll){
921
+ windowScrollDoneEvent();
922
+ }
923
+ };
924
+ var containerScrollEvent = function(){
925
+ repositionFloatContainer(calculateFloatContainerPos('containerScroll'), false);
926
+ };
927
+
928
+
929
+ var windowResizeEvent = function(){
930
+ if($table.is(":hidden")){
931
+ return;
932
+ }
933
+ updateScrollingOffsets();
934
+ calculateScrollBarSize();
935
+ ensureReflow();
936
+ calculateFloatContainerPos = calculateFloatContainerPosFn();
937
+ repositionFloatContainer = repositionFloatContainerFn();
938
+ repositionFloatContainer(calculateFloatContainerPos('resize'), true, true);
939
+ };
940
+ var reflowEvent = util.debounce(function(){
941
+ if($table.is(":hidden")){
942
+ return;
943
+ }
944
+ calculateScrollBarSize();
945
+ updateScrollingOffsets();
946
+ ensureReflow();
947
+ calculateFloatContainerPos = calculateFloatContainerPosFn();
948
+ repositionFloatContainer(calculateFloatContainerPos('reflow'), true);
949
+ }, 1);
950
+
951
+ /////// printing stuff
952
+ var beforePrint = function(){
953
+ unfloat();
954
+ };
955
+ var afterPrint = function(){
956
+ refloat();
957
+ };
958
+ var printEvent = function(mql){
959
+ //make printing the table work properly on IE10+
960
+ if(mql.matches) {
961
+ beforePrint();
962
+ } else {
963
+ afterPrint();
964
+ }
965
+ };
966
+
967
+ var matchMediaPrint;
968
+ if(window.matchMedia && window.matchMedia('print').addListener){
969
+ matchMediaPrint = window.matchMedia("print");
970
+ matchMediaPrint.addListener(printEvent);
971
+ } else {
972
+ $window.on('beforeprint', beforePrint);
973
+ $window.on('afterprint', afterPrint);
974
+ }
975
+ ////// end printing stuff
976
+
977
+
978
+ if(locked){ //internal scrolling
979
+ if(useAbsolutePositioning){
980
+ $scrollContainer.on(eventName('scroll'), containerScrollEvent);
981
+ } else {
982
+ $scrollContainer.on(eventName('scroll'), containerScrollEvent);
983
+ $window.on(eventName('scroll'), windowScrollEvent);
984
+ }
985
+ } else { //window scrolling
986
+ $responsiveContainer.on(eventName('scroll'), containerScrollEvent);
987
+ $window.on(eventName('scroll'), windowScrollEvent);
988
+ }
989
+
990
+ $window.on(eventName('load'), reflowEvent); //for tables with images
991
+
992
+ windowResize(eventName('resize'), windowResizeEvent);
993
+ $table.on('reflow', reflowEvent);
994
+ if(opts.support && opts.support.datatables && isDatatable($table)){
995
+ $table
996
+ .on('filter', reflowEvent)
997
+ .on('sort', reflowEvent)
998
+ .on('page', reflowEvent);
999
+ }
1000
+
1001
+ if(opts.support && opts.support.bootstrap) {
1002
+ $window.on(eventName('shown.bs.tab'), reflowEvent); // people cant seem to figure out how to use this plugin with bs3 tabs... so this :P
1003
+ }
1004
+ if(opts.support && opts.support.jqueryUI) {
1005
+ $window.on(eventName('tabsactivate'), reflowEvent); // same thing for jqueryui
1006
+ }
1007
+
1008
+
1009
+ if (canObserveMutations) {
1010
+ var mutationElement = null;
1011
+ if(util.isFunction(opts.autoReflow)){
1012
+ mutationElement = opts.autoReflow($table, $scrollContainer)
1013
+ }
1014
+ if(!mutationElement) {
1015
+ mutationElement = $scrollContainer.length ? $scrollContainer[0] : $table[0]
1016
+ }
1017
+ mObs = new MutationObserver(function(e){
1018
+ var wasTableRelated = function(nodes){
1019
+ return nodes && nodes[0] && (nodes[0].nodeName == "THEAD" || nodes[0].nodeName == "TD"|| nodes[0].nodeName == "TH");
1020
+ };
1021
+ for(var i=0; i < e.length; i++){
1022
+ if(!(wasTableRelated(e[i].addedNodes) || wasTableRelated(e[i].removedNodes))){
1023
+ reflowEvent();
1024
+ break;
1025
+ }
1026
+ }
1027
+ });
1028
+ mObs.observe(mutationElement, {
1029
+ childList: true,
1030
+ subtree: true
1031
+ });
1032
+ }
1033
+
1034
+ //attach some useful functions to the table.
1035
+ $table.data('floatThead-attached', {
1036
+ destroy: function(){
1037
+ var ns = '.fth-'+floatTheadId;
1038
+ unfloat();
1039
+ $table.css(layoutAuto);
1040
+ $tableColGroup.remove();
1041
+ createElements && $fthGrp.remove();
1042
+ if($newHeader.parent().length){ //only if it's in the DOM
1043
+ $newHeader.replaceWith($header);
1044
+ }
1045
+ triggerFloatEvent(false);
1046
+ if(canObserveMutations){
1047
+ mObs.disconnect();
1048
+ mObs = null;
1049
+ }
1050
+ $table.off('reflow reflowed');
1051
+ $scrollContainer.off(ns);
1052
+ $responsiveContainer.off(ns);
1053
+ if (wrappedContainer) {
1054
+ if ($scrollContainer.length) {
1055
+ $scrollContainer.unwrap();
1056
+ }
1057
+ else {
1058
+ $table.unwrap();
1059
+ }
1060
+ }
1061
+ if(locked){
1062
+ $scrollContainer.data('floatThead-containerWrap', false);
1063
+ } else {
1064
+ $table.data('floatThead-containerWrap', false);
1065
+ }
1066
+ $table.css('minWidth', originalTableMinWidth);
1067
+ $floatContainer.remove();
1068
+ $table.data('floatThead-attached', false);
1069
+ $window.off(ns);
1070
+ if (matchMediaPrint) {
1071
+ matchMediaPrint.removeListener(printEvent);
1072
+ }
1073
+ beforePrint = afterPrint = function(){};
1074
+
1075
+ return function reinit(){
1076
+ return $table.floatThead(opts);
1077
+ }
1078
+ },
1079
+ reflow: function(){
1080
+ reflowEvent();
1081
+ },
1082
+ setHeaderHeight: function(){
1083
+ setHeaderHeight();
1084
+ },
1085
+ getFloatContainer: function(){
1086
+ return $floatContainer;
1087
+ },
1088
+ getRowGroups: function(){
1089
+ if(headerFloated){
1090
+ return $floatContainer.find('>table>thead').add($table.children("tbody,tfoot"));
1091
+ } else {
1092
+ return $table.children("thead,tbody,tfoot");
1093
+ }
1094
+ }
1095
+ });
1096
+ });
1097
+ return this;
1098
+ };
1099
+ })((function(){
1100
+ var $ = window.jQuery;
1101
+ if(typeof module !== 'undefined' && module.exports && !$) {
1102
+ // only use cjs if they dont have a jquery for me to use, and we have commonjs
1103
+ $ = require('jquery');
1104
+ }
1105
+ return $;
1106
+ })());