alchemy_cms 4.6.2 → 5.0.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (378) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +33 -1
  3. data/.github/workflows/stale.yml +1 -1
  4. data/.gitignore +20 -2
  5. data/.hound.yml +2 -1
  6. data/.prettierrc +6 -0
  7. data/.rubocop.yml +31 -10
  8. data/CHANGELOG.md +89 -3
  9. data/Gemfile +24 -22
  10. data/README.md +31 -19
  11. data/Rakefile +10 -8
  12. data/alchemy_cms.gemspec +5 -4
  13. data/app/assets/javascripts/alchemy/admin.js +1 -5
  14. data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +2 -1
  15. data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +0 -2
  16. data/app/assets/javascripts/alchemy/alchemy.page_sorter.js +17 -17
  17. data/app/assets/javascripts/alchemy/node_select.js +39 -0
  18. data/app/assets/javascripts/alchemy/templates/index.js +1 -0
  19. data/app/assets/javascripts/alchemy/templates/node.hbs +16 -0
  20. data/app/assets/stylesheets/alchemy/admin.scss +3 -2
  21. data/app/assets/stylesheets/alchemy/base.scss +0 -1
  22. data/app/assets/stylesheets/alchemy/elements.scss +1 -1
  23. data/app/assets/stylesheets/alchemy/forms.scss +5 -0
  24. data/app/assets/stylesheets/alchemy/node-select.scss +43 -0
  25. data/app/assets/stylesheets/alchemy/nodes.scss +1 -1
  26. data/app/assets/stylesheets/alchemy/sitemap.scss +5 -1
  27. data/app/assets/stylesheets/alchemy/tables.scss +1 -24
  28. data/app/controllers/alchemy/admin/attachments_controller.rb +8 -7
  29. data/app/controllers/alchemy/admin/base_controller.rb +13 -33
  30. data/app/controllers/alchemy/admin/clipboard_controller.rb +5 -4
  31. data/app/controllers/alchemy/admin/contents_controller.rb +1 -2
  32. data/app/controllers/alchemy/admin/dashboard_controller.rb +10 -9
  33. data/app/controllers/alchemy/admin/elements_controller.rb +20 -20
  34. data/app/controllers/alchemy/admin/essence_pictures_controller.rb +12 -14
  35. data/app/controllers/alchemy/admin/languages_controller.rb +35 -2
  36. data/app/controllers/alchemy/admin/layoutpages_controller.rb +5 -2
  37. data/app/controllers/alchemy/admin/nodes_controller.rb +5 -4
  38. data/app/controllers/alchemy/admin/pages_controller.rb +50 -62
  39. data/app/controllers/alchemy/admin/pictures_controller.rb +16 -16
  40. data/app/controllers/alchemy/admin/resources_controller.rb +21 -13
  41. data/app/controllers/alchemy/admin/sites_controller.rb +18 -0
  42. data/app/controllers/alchemy/admin/styleguide_controller.rb +1 -0
  43. data/app/controllers/alchemy/admin/tags_controller.rb +5 -3
  44. data/app/controllers/alchemy/admin/trash_controller.rb +6 -6
  45. data/app/controllers/alchemy/api/base_controller.rb +2 -2
  46. data/app/controllers/alchemy/api/contents_controller.rb +4 -4
  47. data/app/controllers/alchemy/api/elements_controller.rb +8 -8
  48. data/app/controllers/alchemy/api/nodes_controller.rb +37 -1
  49. data/app/controllers/alchemy/api/pages_controller.rb +14 -23
  50. data/app/controllers/alchemy/attachments_controller.rb +5 -5
  51. data/app/controllers/alchemy/base_controller.rb +10 -9
  52. data/app/controllers/alchemy/messages_controller.rb +16 -23
  53. data/app/controllers/alchemy/pages_controller.rb +13 -11
  54. data/app/controllers/concerns/alchemy/admin/archive_overlay.rb +3 -2
  55. data/app/controllers/concerns/alchemy/admin/current_language.rb +23 -0
  56. data/app/controllers/concerns/alchemy/admin/uploader_responses.rb +5 -5
  57. data/app/controllers/concerns/alchemy/legacy_page_redirects.rb +4 -4
  58. data/app/controllers/concerns/alchemy/page_redirects.rb +2 -9
  59. data/app/controllers/concerns/alchemy/site_redirects.rb +2 -2
  60. data/app/decorators/alchemy/element_editor.rb +39 -0
  61. data/app/helpers/alchemy/admin/attachments_helper.rb +6 -6
  62. data/app/helpers/alchemy/admin/base_helper.rb +36 -35
  63. data/app/helpers/alchemy/admin/contents_helper.rb +3 -3
  64. data/app/helpers/alchemy/admin/elements_helper.rb +3 -88
  65. data/app/helpers/alchemy/admin/essences_helper.rb +8 -117
  66. data/app/helpers/alchemy/admin/form_helper.rb +1 -1
  67. data/app/helpers/alchemy/admin/navigation_helper.rb +24 -23
  68. data/app/helpers/alchemy/admin/pages_helper.rb +4 -4
  69. data/app/helpers/alchemy/admin/pictures_helper.rb +3 -3
  70. data/app/helpers/alchemy/admin/tags_helper.rb +8 -7
  71. data/app/helpers/alchemy/base_helper.rb +13 -8
  72. data/app/helpers/alchemy/elements_block_helper.rb +2 -31
  73. data/app/helpers/alchemy/elements_helper.rb +12 -58
  74. data/app/helpers/alchemy/pages_helper.rb +24 -174
  75. data/app/helpers/alchemy/url_helper.rb +2 -1
  76. data/app/mailers/alchemy/base_mailer.rb +1 -1
  77. data/app/mailers/alchemy/messages_mailer.rb +1 -1
  78. data/app/models/alchemy/attachment.rb +20 -18
  79. data/app/models/alchemy/base_record.rb +2 -5
  80. data/app/models/alchemy/content.rb +33 -38
  81. data/app/models/alchemy/content/factory.rb +24 -31
  82. data/app/models/alchemy/element.rb +45 -53
  83. data/app/models/alchemy/element/definitions.rb +4 -4
  84. data/app/models/alchemy/element/element_contents.rb +9 -6
  85. data/app/models/alchemy/element/element_essences.rb +4 -3
  86. data/app/models/alchemy/element/presenters.rb +3 -2
  87. data/app/models/alchemy/element_to_page.rb +1 -1
  88. data/app/models/alchemy/essence_boolean.rb +1 -3
  89. data/app/models/alchemy/essence_date.rb +2 -3
  90. data/app/models/alchemy/essence_file.rb +4 -4
  91. data/app/models/alchemy/essence_html.rb +1 -3
  92. data/app/models/alchemy/essence_link.rb +1 -3
  93. data/app/models/alchemy/essence_node.rb +18 -0
  94. data/app/models/alchemy/essence_page.rb +3 -16
  95. data/app/models/alchemy/essence_picture.rb +17 -16
  96. data/app/models/alchemy/essence_picture_view.rb +7 -6
  97. data/app/models/alchemy/essence_richtext.rb +1 -3
  98. data/app/models/alchemy/essence_select.rb +1 -3
  99. data/app/models/alchemy/essence_text.rb +0 -2
  100. data/app/models/alchemy/folded_page.rb +1 -0
  101. data/app/models/alchemy/language.rb +21 -35
  102. data/app/models/alchemy/language/code.rb +4 -4
  103. data/app/models/alchemy/legacy_page_url.rb +1 -1
  104. data/app/models/alchemy/message.rb +3 -3
  105. data/app/models/alchemy/node.rb +27 -4
  106. data/app/models/alchemy/page.rb +46 -127
  107. data/app/models/alchemy/page/fixed_attributes.rb +3 -2
  108. data/app/models/alchemy/page/page_elements.rb +35 -44
  109. data/app/models/alchemy/page/page_naming.rb +20 -70
  110. data/app/models/alchemy/page/page_natures.rb +7 -34
  111. data/app/models/alchemy/page/page_scopes.rb +23 -29
  112. data/app/models/alchemy/page/url_path.rb +0 -2
  113. data/app/models/alchemy/picture.rb +18 -27
  114. data/app/models/alchemy/picture/transformations.rb +9 -7
  115. data/app/models/alchemy/picture/url.rb +5 -5
  116. data/app/models/alchemy/site.rb +6 -36
  117. data/app/models/alchemy/site/layout.rb +2 -2
  118. data/app/models/concerns/alchemy/touch_elements.rb +24 -0
  119. data/app/serializers/alchemy/content_serializer.rb +0 -3
  120. data/app/serializers/alchemy/essence_boolean_serializer.rb +3 -3
  121. data/app/serializers/alchemy/essence_date_serializer.rb +3 -3
  122. data/app/serializers/alchemy/essence_file_serializer.rb +4 -2
  123. data/app/serializers/alchemy/essence_html_serializer.rb +3 -3
  124. data/app/serializers/alchemy/essence_link_serializer.rb +3 -3
  125. data/app/serializers/alchemy/essence_picture_serializer.rb +5 -4
  126. data/app/serializers/alchemy/essence_richtext_serializer.rb +3 -3
  127. data/app/serializers/alchemy/essence_select_serializer.rb +3 -3
  128. data/app/serializers/alchemy/essence_text_serializer.rb +5 -4
  129. data/app/serializers/alchemy/node_serializer.rb +2 -0
  130. data/app/serializers/alchemy/page_tree_serializer.rb +9 -13
  131. data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +1 -2
  132. data/app/views/alchemy/admin/attachments/_file_to_assign.html.erb +1 -2
  133. data/app/views/alchemy/admin/attachments/_files_list.html.erb +4 -4
  134. data/app/views/alchemy/admin/contents/create.js.erb +1 -3
  135. data/app/views/alchemy/admin/elements/_element.html.erb +9 -18
  136. data/app/views/alchemy/admin/elements/create.js.erb +1 -1
  137. data/app/views/alchemy/admin/elements/fold.js.erb +1 -1
  138. data/app/views/alchemy/admin/elements/index.html.erb +3 -3
  139. data/app/views/alchemy/admin/essence_files/assign.js.erb +1 -6
  140. data/app/views/alchemy/admin/essence_files/edit.html.erb +1 -1
  141. data/app/views/alchemy/admin/essence_pictures/assign.js.erb +1 -7
  142. data/app/views/alchemy/admin/essence_pictures/crop.html.erb +1 -1
  143. data/app/views/alchemy/admin/essence_pictures/edit.html.erb +7 -7
  144. data/app/views/alchemy/admin/essence_pictures/update.js.erb +1 -1
  145. data/app/views/alchemy/admin/languages/_form.html.erb +5 -5
  146. data/app/views/alchemy/admin/languages/_table.html.erb +3 -3
  147. data/app/views/alchemy/admin/languages/edit.html.erb +1 -0
  148. data/app/views/alchemy/admin/languages/index.html.erb +23 -4
  149. data/app/views/alchemy/admin/languages/new.html.erb +1 -0
  150. data/app/views/alchemy/admin/layoutpages/index.html.erb +3 -3
  151. data/app/views/alchemy/admin/nodes/_form.html.erb +18 -15
  152. data/app/views/alchemy/admin/nodes/_node.html.erb +1 -5
  153. data/app/views/alchemy/admin/nodes/index.html.erb +3 -4
  154. data/app/views/alchemy/admin/pages/_create_language_form.html.erb +0 -8
  155. data/app/views/alchemy/admin/pages/_form.html.erb +0 -1
  156. data/app/views/alchemy/admin/pages/_new_page_form.html.erb +1 -0
  157. data/app/views/alchemy/admin/pages/_page.html.erb +11 -19
  158. data/app/views/alchemy/admin/pages/_page_infos.html.erb +0 -4
  159. data/app/views/alchemy/admin/pages/edit.html.erb +1 -1
  160. data/app/views/alchemy/admin/pages/info.html.erb +0 -9
  161. data/app/views/alchemy/admin/pages/unlock.js.erb +13 -6
  162. data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +0 -2
  163. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +1 -5
  164. data/app/views/alchemy/admin/pictures/_overlay_picture_list.html.erb +1 -1
  165. data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +1 -2
  166. data/app/views/alchemy/admin/resources/_resource.html.erb +1 -1
  167. data/app/views/alchemy/admin/resources/_table.html.erb +2 -2
  168. data/app/views/alchemy/admin/sites/_form.html.erb +8 -0
  169. data/app/views/alchemy/admin/sites/edit.html.erb +1 -0
  170. data/app/views/alchemy/admin/sites/index.html.erb +21 -9
  171. data/app/views/alchemy/admin/sites/new.html.erb +1 -0
  172. data/app/views/alchemy/admin/tags/index.html.erb +2 -2
  173. data/app/views/alchemy/essences/_essence_boolean_editor.html.erb +10 -12
  174. data/app/views/alchemy/essences/_essence_date_editor.html.erb +11 -8
  175. data/app/views/alchemy/essences/_essence_file_editor.html.erb +16 -17
  176. data/app/views/alchemy/essences/_essence_html_editor.html.erb +8 -5
  177. data/app/views/alchemy/essences/_essence_link_editor.html.erb +18 -15
  178. data/app/views/alchemy/essences/_essence_node_editor.html.erb +27 -0
  179. data/app/views/alchemy/essences/_essence_node_view.html.erb +1 -0
  180. data/app/views/alchemy/essences/_essence_page_editor.html.erb +14 -11
  181. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +22 -20
  182. data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +10 -7
  183. data/app/views/alchemy/essences/_essence_select_editor.html.erb +12 -16
  184. data/app/views/alchemy/essences/_essence_text_editor.html.erb +18 -17
  185. data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +6 -11
  186. data/app/views/alchemy/pages/show.rss.builder +3 -2
  187. data/app/views/layouts/alchemy/admin.html.erb +1 -0
  188. data/babel.config.js +12 -0
  189. data/bin/rails +5 -4
  190. data/config/alchemy/config.yml +15 -18
  191. data/config/brakeman.ignore +1 -1
  192. data/config/initializers/assets.rb +2 -1
  193. data/config/initializers/dragonfly.rb +2 -1
  194. data/config/initializers/mime_types.rb +1 -0
  195. data/config/initializers/mini_profiler.rb +3 -2
  196. data/config/initializers/simple_form.rb +6 -6
  197. data/config/locales/alchemy.en.yml +23 -8
  198. data/config/routes.rb +25 -24
  199. data/config/spring.rb +3 -2
  200. data/db/migrate/20200226213334_alchemy_four_point_four.rb +313 -0
  201. data/db/migrate/20200423073425_create_alchemy_essence_nodes.rb +11 -0
  202. data/db/migrate/20200504210159_remove_site_id_from_nodes.rb +28 -0
  203. data/db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb +8 -0
  204. data/db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb +27 -0
  205. data/db/migrate/20200514091507_make_page_layoutpage_null_false.rb +6 -0
  206. data/db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb +24 -0
  207. data/lib/alchemy/admin/locale.rb +3 -1
  208. data/lib/alchemy/admin/preview_url.rb +64 -0
  209. data/lib/alchemy/auth_accessors.rb +8 -7
  210. data/lib/alchemy/cache_digests/template_tracker.rb +5 -4
  211. data/lib/alchemy/config.rb +1 -5
  212. data/lib/alchemy/configuration_methods.rb +3 -1
  213. data/lib/alchemy/controller_actions.rb +6 -5
  214. data/lib/alchemy/deprecation.rb +2 -1
  215. data/lib/alchemy/elements_finder.rb +5 -5
  216. data/lib/alchemy/engine.rb +23 -8
  217. data/lib/alchemy/errors.rb +0 -7
  218. data/lib/alchemy/essence.rb +17 -16
  219. data/lib/alchemy/filetypes.rb +5 -5
  220. data/lib/alchemy/forms/builder.rb +4 -4
  221. data/lib/alchemy/hints.rb +1 -1
  222. data/lib/alchemy/i18n.rb +2 -1
  223. data/lib/alchemy/modules.rb +12 -12
  224. data/lib/alchemy/name_conversions.rb +5 -5
  225. data/lib/alchemy/on_page_layout/callbacks_runner.rb +1 -0
  226. data/lib/alchemy/page_layout.rb +15 -12
  227. data/lib/alchemy/paths.rb +1 -1
  228. data/lib/alchemy/permissions.rb +7 -6
  229. data/lib/alchemy/resource.rb +23 -13
  230. data/lib/alchemy/resources_helper.rb +12 -18
  231. data/lib/alchemy/routing_constraints.rb +1 -1
  232. data/lib/alchemy/seeder.rb +42 -14
  233. data/lib/alchemy/shell.rb +13 -10
  234. data/lib/alchemy/taggable.rb +1 -0
  235. data/lib/alchemy/tasks/tidy.rb +4 -3
  236. data/lib/alchemy/test_support/config_stubbing.rb +1 -0
  237. data/lib/alchemy/test_support/essence_shared_examples.rb +72 -72
  238. data/lib/alchemy/test_support/factories.rb +1 -1
  239. data/lib/alchemy/test_support/factories/attachment_factory.rb +5 -5
  240. data/lib/alchemy/test_support/factories/content_factory.rb +6 -6
  241. data/lib/alchemy/test_support/factories/dummy_user_factory.rb +7 -7
  242. data/lib/alchemy/test_support/factories/element_factory.rb +9 -9
  243. data/lib/alchemy/test_support/factories/essence_file_factory.rb +3 -3
  244. data/lib/alchemy/test_support/factories/essence_page_factory.rb +3 -3
  245. data/lib/alchemy/test_support/factories/essence_picture_factory.rb +4 -4
  246. data/lib/alchemy/test_support/factories/essence_text_factory.rb +3 -3
  247. data/lib/alchemy/test_support/factories/language_factory.rb +16 -14
  248. data/lib/alchemy/test_support/factories/node_factory.rb +8 -8
  249. data/lib/alchemy/test_support/factories/page_factory.rb +15 -27
  250. data/lib/alchemy/test_support/factories/picture_factory.rb +5 -5
  251. data/lib/alchemy/test_support/factories/site_factory.rb +7 -6
  252. data/lib/alchemy/test_support/integration_helpers.rb +1 -0
  253. data/lib/alchemy/test_support/shared_contexts.rb +5 -4
  254. data/lib/alchemy/test_support/shared_uploader_examples.rb +4 -3
  255. data/lib/alchemy/tinymce.rb +15 -13
  256. data/lib/alchemy/upgrader.rb +8 -7
  257. data/lib/alchemy/upgrader/five_point_zero.rb +41 -0
  258. data/lib/alchemy/upgrader/tasks/element_views_updater.rb +4 -4
  259. data/lib/alchemy/upgrader/tasks/harden_gutentag_migrations.rb +29 -0
  260. data/lib/alchemy/version.rb +1 -1
  261. data/lib/alchemy_cms.rb +52 -50
  262. data/lib/{rails/generators → generators}/alchemy/base.rb +5 -4
  263. data/lib/{rails/generators → generators}/alchemy/elements/elements_generator.rb +13 -9
  264. data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.erb +0 -0
  265. data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.haml +0 -0
  266. data/lib/{rails/generators → generators}/alchemy/elements/templates/view.html.slim +0 -0
  267. data/lib/{rails/generators → generators}/alchemy/essence/essence_generator.rb +15 -13
  268. data/lib/generators/alchemy/essence/templates/editor.html.erb +17 -0
  269. data/lib/{rails/generators → generators}/alchemy/essence/templates/view.html.erb +0 -0
  270. data/lib/{rails/generators → generators}/alchemy/install/files/_article.html.erb +0 -0
  271. data/lib/{rails/generators → generators}/alchemy/install/files/_standard.html.erb +0 -0
  272. data/lib/{rails/generators → generators}/alchemy/install/files/alchemy.en.yml +0 -0
  273. data/lib/generators/alchemy/install/files/alchemy_admin.js +1 -0
  274. data/lib/{rails/generators → generators}/alchemy/install/files/all.css +0 -0
  275. data/lib/{rails/generators → generators}/alchemy/install/files/all.js +0 -0
  276. data/lib/{rails/generators → generators}/alchemy/install/files/application.html.erb +0 -0
  277. data/lib/{rails/generators → generators}/alchemy/install/files/article.scss +0 -0
  278. data/lib/generators/alchemy/install/install_generator.rb +110 -0
  279. data/lib/{rails/generators → generators}/alchemy/install/templates/dragonfly.rb.tt +0 -0
  280. data/lib/{rails/generators → generators}/alchemy/install/templates/elements.yml.tt +0 -0
  281. data/lib/{rails/generators → generators}/alchemy/install/templates/menus.yml.tt +0 -0
  282. data/lib/{rails/generators → generators}/alchemy/install/templates/page_layouts.yml.tt +0 -0
  283. data/lib/{rails/generators → generators}/alchemy/menus/menus_generator.rb +2 -2
  284. data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.erb +1 -4
  285. data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.haml +1 -4
  286. data/lib/{rails/generators → generators}/alchemy/menus/templates/node.html.slim +1 -4
  287. data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.erb +1 -1
  288. data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.haml +1 -1
  289. data/lib/{rails/generators → generators}/alchemy/menus/templates/wrapper.html.slim +1 -1
  290. data/lib/{rails/generators → generators}/alchemy/module/module_generator.rb +3 -2
  291. data/lib/{rails/generators → generators}/alchemy/module/templates/ability.rb.tt +0 -0
  292. data/lib/{rails/generators → generators}/alchemy/module/templates/controller.rb.tt +0 -0
  293. data/lib/{rails/generators → generators}/alchemy/module/templates/module_config.rb.tt +0 -0
  294. data/lib/{rails/generators → generators}/alchemy/page_layouts/page_layouts_generator.rb +5 -4
  295. data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.erb +0 -0
  296. data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.haml +0 -0
  297. data/lib/{rails/generators → generators}/alchemy/page_layouts/templates/layout.html.slim +0 -0
  298. data/lib/{rails/generators → generators}/alchemy/site_layouts/site_layouts_generator.rb +4 -2
  299. data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.erb +0 -0
  300. data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.haml +0 -0
  301. data/lib/{rails/generators → generators}/alchemy/site_layouts/templates/layout.html.slim +0 -0
  302. data/lib/{rails/generators → generators}/alchemy/views/views_generator.rb +7 -6
  303. data/lib/kaminari/scoped_pagination_url_helper.rb +1 -0
  304. data/lib/tasks/alchemy/db.rake +3 -19
  305. data/lib/tasks/alchemy/install.rake +3 -2
  306. data/lib/tasks/alchemy/tidy.rake +9 -8
  307. data/lib/tasks/alchemy/upgrade.rake +18 -116
  308. data/package.json +45 -0
  309. data/package/admin.js +14 -0
  310. data/package/src/__tests__/i18n.spec.js +70 -0
  311. data/package/src/i18n.js +48 -0
  312. data/package/src/node_tree.js +72 -0
  313. data/package/src/translations.js +32 -0
  314. data/package/src/utils/__tests__/ajax.spec.js +124 -0
  315. data/package/src/utils/__tests__/events.spec.js +38 -0
  316. data/package/src/utils/ajax.js +48 -0
  317. data/package/src/utils/events.js +16 -0
  318. data/vendor/assets/fonts/fa-regular-400.eot +0 -0
  319. data/vendor/assets/fonts/fa-regular-400.svg +798 -358
  320. data/vendor/assets/fonts/fa-regular-400.ttf +0 -0
  321. data/vendor/assets/fonts/fa-regular-400.woff +0 -0
  322. data/vendor/assets/fonts/fa-regular-400.woff2 +0 -0
  323. data/vendor/assets/fonts/fa-solid-900.eot +0 -0
  324. data/vendor/assets/fonts/fa-solid-900.svg +4933 -1408
  325. data/vendor/assets/fonts/fa-solid-900.ttf +0 -0
  326. data/vendor/assets/fonts/fa-solid-900.woff +0 -0
  327. data/vendor/assets/fonts/fa-solid-900.woff2 +0 -0
  328. data/vendor/assets/javascripts/jquery_plugins/jquery.ui.nestedSortable.js +1 -2
  329. data/vendor/assets/stylesheets/fontawesome/_core.scss +5 -0
  330. data/vendor/assets/stylesheets/fontawesome/_fixed-width.scss +1 -1
  331. data/vendor/assets/stylesheets/fontawesome/_icons.scss +651 -2
  332. data/vendor/assets/stylesheets/fontawesome/_mixins.scss +0 -1
  333. data/vendor/assets/stylesheets/fontawesome/_rotated-flipped.scss +3 -2
  334. data/vendor/assets/stylesheets/fontawesome/_stacked.scss +1 -1
  335. data/vendor/assets/stylesheets/fontawesome/_variables.scss +662 -9
  336. data/vendor/assets/stylesheets/fontawesome/fontawesome.scss +2 -2
  337. data/vendor/assets/stylesheets/fontawesome/regular.scss +23 -0
  338. data/vendor/assets/stylesheets/fontawesome/solid.scss +24 -0
  339. metadata +110 -88
  340. data/app/assets/javascripts/alchemy/alchemy.i18n.js.coffee +0 -32
  341. data/app/assets/javascripts/alchemy/alchemy.node_tree.js +0 -66
  342. data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +0 -29
  343. data/app/assets/javascripts/alchemy/alchemy.utils.js +0 -45
  344. data/app/helpers/alchemy/essences_helper.rb +0 -119
  345. data/app/models/concerns/alchemy/content_touching.rb +0 -23
  346. data/app/serializers/alchemy/legacy_element_serializer.rb +0 -15
  347. data/app/views/alchemy/admin/contents/_missing.html.erb +0 -17
  348. data/app/views/alchemy/admin/pages/_menu_fields.html.erb +0 -37
  349. data/app/views/alchemy/admin/pages/configure_external.html.erb +0 -32
  350. data/app/views/alchemy/elements/_editor_not_found.html.erb +0 -4
  351. data/app/views/alchemy/navigation/_image_link.html.erb +0 -14
  352. data/app/views/alchemy/navigation/_link.html.erb +0 -19
  353. data/app/views/alchemy/navigation/_renderer.html.erb +0 -29
  354. data/db/migrate/20180226123013_alchemy_four_point_zero.rb +0 -363
  355. data/db/migrate/20180227224537_migrate_tags_to_gutentag.rb +0 -41
  356. data/db/migrate/20180519204655_add_fixed_to_alchemy_elements.rb +0 -6
  357. data/db/migrate/20191016073858_create_alchemy_essence_pages.rb +0 -8
  358. data/db/migrate/20191029212236_create_alchemy_nodes.rb +0 -24
  359. data/db/migrate/20200226081535_add_site_id_to_alchemy_nodes.rb +0 -15
  360. data/lib/alchemy/ssl_protection.rb +0 -34
  361. data/lib/alchemy/tasks/helpers.rb +0 -81
  362. data/lib/alchemy/test_support/controller_requests.rb +0 -93
  363. data/lib/alchemy/upgrader/four_point_four.rb +0 -52
  364. data/lib/alchemy/upgrader/four_point_one.rb +0 -42
  365. data/lib/alchemy/upgrader/four_point_six.rb +0 -50
  366. data/lib/alchemy/upgrader/four_point_two.rb +0 -85
  367. data/lib/alchemy/upgrader/tasks/cells_migration.rb +0 -43
  368. data/lib/alchemy/upgrader/tasks/cells_upgrader.rb +0 -148
  369. data/lib/alchemy/upgrader/tasks/element_partial_name_variable_updater.rb +0 -28
  370. data/lib/alchemy/upgrader/tasks/harden_acts_as_taggable_on_migrations.rb +0 -27
  371. data/lib/alchemy/upgrader/tasks/picture_gallery_migration.rb +0 -65
  372. data/lib/alchemy/upgrader/tasks/picture_gallery_upgrader.rb +0 -210
  373. data/lib/rails/generators/alchemy/essence/templates/editor.html.erb +0 -15
  374. data/lib/rails/generators/alchemy/install/install_generator.rb +0 -60
  375. data/lib/tasks/alchemy/convert.rake +0 -97
  376. data/vendor/assets/javascripts/sortable/Sortable.min.js +0 -2
  377. data/vendor/assets/stylesheets/fontawesome/fa-regular.scss +0 -22
  378. data/vendor/assets/stylesheets/fontawesome/fa-solid.scss +0 -23
@@ -21,20 +21,17 @@ module Alchemy
21
21
 
22
22
  # All pages locked by given user
23
23
  #
24
- scope :locked_by, ->(user) {
25
- if user.class.respond_to? :primary_key
26
- locked.where(locked_by: user.send(user.class.primary_key))
27
- end
28
- }
24
+ scope :locked_by,
25
+ ->(user) {
26
+ if user.class.respond_to? :primary_key
27
+ locked.where(locked_by: user.send(user.class.primary_key))
28
+ end
29
+ }
29
30
 
30
31
  # All not locked pages
31
32
  #
32
33
  scope :not_locked, -> { where(locked_at: nil, locked_by: nil) }
33
34
 
34
- # All visible pages
35
- #
36
- scope :visible, -> { where(visible: true) }
37
-
38
35
  # All not restricted pages
39
36
  #
40
37
  scope :not_restricted, -> { where(restricted: false) }
@@ -45,29 +42,27 @@ module Alchemy
45
42
 
46
43
  # All pages that are a published language root
47
44
  #
48
- scope :public_language_roots, -> {
49
- published.language_roots.where(
50
- language_code: Language.published.pluck(:language_code)
51
- )
52
- }
45
+ scope :public_language_roots,
46
+ -> {
47
+ published.language_roots.where(
48
+ language_code: Language.published.pluck(:language_code),
49
+ )
50
+ }
53
51
 
54
52
  # Last 5 pages that where recently edited by given user
55
53
  #
56
- scope :all_last_edited_from, ->(user) {
57
- where(updater_id: user.id).order('updated_at DESC').limit(5)
58
- }
54
+ scope :all_last_edited_from,
55
+ ->(user) {
56
+ where(updater_id: user.id).order("updated_at DESC").limit(5)
57
+ }
59
58
 
60
59
  # Returns all pages that have the given +language_id+
61
60
  #
62
- scope :with_language, ->(language_id) {
63
- where(language_id: language_id)
64
- }
61
+ scope :with_language, ->(language_id) { where(language_id: language_id) }
65
62
 
66
63
  # Returns all content pages.
67
64
  #
68
- scope :contentpages, -> {
69
- where(layoutpage: [false, nil]).where.not(parent_id: nil)
70
- }
65
+ scope :contentpages, -> { where(layoutpage: [false, nil]) }
71
66
 
72
67
  # Returns all public contentpages that are not locked.
73
68
  #
@@ -79,9 +74,7 @@ module Alchemy
79
74
  #
80
75
  # Used for flushing all pages caches at once.
81
76
  #
82
- scope :flushable_layoutpages, -> {
83
- not_locked.layoutpages.where.not(parent_id: Page.unscoped.root.id)
84
- }
77
+ scope :flushable_layoutpages, -> { not_locked.layoutpages }
85
78
 
86
79
  # All searchable pages
87
80
  #
@@ -89,9 +82,10 @@ module Alchemy
89
82
 
90
83
  # All pages from +Alchemy::Site.current+
91
84
  #
92
- scope :from_current_site, -> {
93
- where(Language.table_name => {site_id: Site.current || Site.default}).joins(:language)
94
- }
85
+ scope :from_current_site,
86
+ -> {
87
+ where(Language.table_name => { site_id: Site.current || Site.default }).joins(:language)
88
+ }
95
89
 
96
90
  # All pages for xml sitemap
97
91
  #
@@ -29,8 +29,6 @@ module Alchemy
29
29
  end
30
30
 
31
31
  def call
32
- return @page.urlname if @page.definition["redirects_to_external"]
33
-
34
32
  if @page.language_root?
35
33
  language_root_path
36
34
  elsif @site.languages.select(&:public?).length > 1
@@ -26,13 +26,13 @@ module Alchemy
26
26
 
27
27
  include Alchemy::NameConversions
28
28
  include Alchemy::Taggable
29
- include Alchemy::ContentTouching
29
+ include Alchemy::TouchElements
30
30
  include Alchemy::Picture::Transformations
31
31
  include Alchemy::Picture::Url
32
32
 
33
33
  has_many :essence_pictures,
34
- class_name: 'Alchemy::EssencePicture',
35
- foreign_key: 'picture_id',
34
+ class_name: "Alchemy::EssencePicture",
35
+ foreign_key: "picture_id",
36
36
  inverse_of: :ingredient_association
37
37
 
38
38
  has_many :contents, through: :essence_pictures
@@ -62,12 +62,12 @@ module Alchemy
62
62
  # We need to define this method here to have it available in the validations below.
63
63
  class << self
64
64
  def allowed_filetypes
65
- Config.get(:uploader).fetch('allowed_filetypes', {}).fetch('alchemy/pictures', [])
65
+ Config.get(:uploader).fetch("allowed_filetypes", {}).fetch("alchemy/pictures", [])
66
66
  end
67
67
  end
68
68
 
69
69
  validates_presence_of :image_file
70
- validates_size_of :image_file, maximum: Config.get(:uploader)['file_size_limit'].megabytes
70
+ validates_size_of :image_file, maximum: Config.get(:uploader)["file_size_limit"].megabytes
71
71
  validates_property :format,
72
72
  of: :image_file,
73
73
  in: allowed_filetypes,
@@ -76,21 +76,10 @@ module Alchemy
76
76
 
77
77
  stampable stamper_class_name: Alchemy.user_class_name
78
78
 
79
- scope :named, ->(name) {
80
- where("#{table_name}.name LIKE ?", "%#{name}%")
81
- }
82
-
83
- scope :recent, -> {
84
- where("#{table_name}.created_at > ?", Time.current - 24.hours).order(:created_at)
85
- }
86
-
87
- scope :deletable, -> {
88
- where("#{table_name}.id NOT IN (SELECT picture_id FROM #{EssencePicture.table_name})")
89
- }
90
-
91
- scope :without_tag, -> {
92
- left_outer_joins(:taggings).where(gutentag_taggings: {id: nil})
93
- }
79
+ scope :named, ->(name) { where("#{table_name}.name LIKE ?", "%#{name}%") }
80
+ scope :recent, -> { where("#{table_name}.created_at > ?", Time.current - 24.hours).order(:created_at) }
81
+ scope :deletable, -> { where("#{table_name}.id NOT IN (SELECT picture_id FROM #{EssencePicture.table_name})") }
82
+ scope :without_tag, -> { left_outer_joins(:taggings).where(gutentag_taggings: { id: nil }) }
94
83
 
95
84
  # Class methods
96
85
 
@@ -102,6 +91,7 @@ module Alchemy
102
91
  def last_upload
103
92
  last_picture = Picture.last
104
93
  return Picture.all unless last_picture
94
+
105
95
  Picture.where(upload_hash: last_picture.upload_hash)
106
96
  end
107
97
 
@@ -123,11 +113,11 @@ module Alchemy
123
113
  pictures.order(:name)
124
114
  end
125
115
 
126
- def filtered_by(filter = '')
116
+ def filtered_by(filter = "")
127
117
  case filter
128
- when 'recent' then recent
129
- when 'last_upload' then last_upload
130
- when 'without_tag' then without_tag
118
+ when "recent" then recent
119
+ when "last_upload" then last_upload
120
+ when "without_tag" then without_tag
131
121
  else
132
122
  all
133
123
  end
@@ -166,7 +156,7 @@ module Alchemy
166
156
  {
167
157
  name: image_file_name,
168
158
  size: image_file_size,
169
- error: errors[:image_file].join
159
+ error: errors[:image_file].join,
170
160
  }
171
161
  end
172
162
 
@@ -176,7 +166,7 @@ module Alchemy
176
166
  if name.blank?
177
167
  "image_#{id}"
178
168
  else
179
- ::CGI.escape(name.gsub(/\.(gif|png|jpe?g|tiff?)/i, '').tr('.', ' '))
169
+ ::CGI.escape(name.gsub(/\.(gif|png|jpe?g|tiff?)/i, "").tr(".", " "))
180
170
  end
181
171
  end
182
172
 
@@ -190,6 +180,7 @@ module Alchemy
190
180
  #
191
181
  def humanized_name
192
182
  return "" if image_file_name.blank?
183
+
193
184
  convert_to_humanized_name(image_file_name, suffix)
194
185
  end
195
186
 
@@ -213,7 +204,7 @@ module Alchemy
213
204
  #
214
205
  def convertible?
215
206
  Config.get(:image_output_format) &&
216
- Config.get(:image_output_format) != 'original' &&
207
+ Config.get(:image_output_format) != "original" &&
217
208
  has_convertible_format?
218
209
  end
219
210
 
@@ -49,6 +49,7 @@ module Alchemy
49
49
  #
50
50
  def crop(size, crop_from = nil, crop_size = nil, upsample = false)
51
51
  raise "No size given!" if size.empty?
52
+
52
53
  render_to = sizes_from_string(size)
53
54
  if crop_from && crop_size
54
55
  top_left = point_from_string(crop_from)
@@ -79,7 +80,7 @@ module Alchemy
79
80
  height = 0 if height.nil?
80
81
  {
81
82
  width: width,
82
- height: height
83
+ height: height,
83
84
  }
84
85
  end
85
86
 
@@ -109,7 +110,7 @@ module Alchemy
109
110
  def image_size
110
111
  {
111
112
  width: image_file_width,
112
- height: image_file_height
113
+ height: image_file_height,
113
114
  }
114
115
  end
115
116
 
@@ -118,6 +119,7 @@ module Alchemy
118
119
  #
119
120
  def can_be_cropped_to(string, upsample = false)
120
121
  return true if upsample
122
+
121
123
  is_bigger_than sizes_from_string(string)
122
124
  end
123
125
 
@@ -147,7 +149,7 @@ module Alchemy
147
149
  y = 0 if y.nil?
148
150
  {
149
151
  x: x,
150
- y: y
152
+ y: y,
151
153
  }
152
154
  end
153
155
 
@@ -158,7 +160,7 @@ module Alchemy
158
160
  def get_top_left_crop_corner(dimensions)
159
161
  {
160
162
  x: (image_file_width - dimensions[:width]) / 2,
161
- y: (image_file_height - dimensions[:height]) / 2
163
+ y: (image_file_height - dimensions[:height]) / 2,
162
164
  }
163
165
  end
164
166
 
@@ -182,7 +184,7 @@ module Alchemy
182
184
  def size_when_fitting(target, dimensions = get_base_dimensions)
183
185
  zoom = [
184
186
  dimensions[:width].to_f / target[:width],
185
- dimensions[:height].to_f / target[:height]
187
+ dimensions[:height].to_f / target[:height],
186
188
  ].max
187
189
 
188
190
  if zoom == 0.0
@@ -205,7 +207,7 @@ module Alchemy
205
207
  x1: point[:x],
206
208
  y1: point[:y],
207
209
  x2: point[:x] + mask[:width],
208
- y2: point[:y] + mask[:height]
210
+ y2: point[:y] + mask[:height],
209
211
  }
210
212
  end
211
213
 
@@ -252,7 +254,7 @@ module Alchemy
252
254
  def reduce_to_image(dimensions)
253
255
  {
254
256
  width: [dimensions[:width], image_file_width].min,
255
- height: [dimensions[:height], image_file_height].min
257
+ height: [dimensions[:height], image_file_height].min,
256
258
  }
257
259
  end
258
260
  end
@@ -12,7 +12,7 @@ module Alchemy
12
12
  :format,
13
13
  :quality,
14
14
  :size,
15
- :upsample
15
+ :upsample,
16
16
  ]
17
17
 
18
18
  # Returns a path to picture for use inside a image_tag helper.
@@ -66,8 +66,8 @@ module Alchemy
66
66
  end
67
67
 
68
68
  options = {
69
- flatten: target_format != 'gif' && image_file_format == 'gif'
70
- }.merge(options)
69
+ flatten: target_format != "gif" && image_file_format == "gif",
70
+ }.with_indifferent_access.merge(options)
71
71
 
72
72
  encoding_options = []
73
73
 
@@ -77,13 +77,13 @@ module Alchemy
77
77
  end
78
78
 
79
79
  if options[:flatten]
80
- encoding_options << '-flatten'
80
+ encoding_options << "-flatten"
81
81
  end
82
82
 
83
83
  convertion_needed = target_format != image_file_format || encoding_options.present?
84
84
 
85
85
  if has_convertible_format? && convertion_needed
86
- image = image.encode(target_format, encoding_options.join(' '))
86
+ image = image.encode(target_format, encoding_options.join(" "))
87
87
  end
88
88
 
89
89
  image
@@ -23,10 +23,12 @@ module Alchemy
23
23
  # associations
24
24
  has_many :languages
25
25
 
26
- scope :published, -> { where(public: true) }
26
+ before_destroy if: -> { languages.any? } do
27
+ errors.add(:languages, :still_present)
28
+ throw(:abort)
29
+ end
27
30
 
28
- # Callbacks
29
- before_create :create_default_language!, unless: -> { languages.any? }
31
+ scope :published, -> { where(public: true) }
30
32
 
31
33
  # concerns
32
34
  include Alchemy::Site::Layout
@@ -64,7 +66,7 @@ module Alchemy
64
66
  end
65
67
 
66
68
  def default
67
- Site.first || create_default_site!
69
+ Site.first
68
70
  end
69
71
 
70
72
  def find_for_host(host)
@@ -81,38 +83,6 @@ module Alchemy
81
83
  site.aliases.split.include?(host) if site.aliases.present?
82
84
  end
83
85
  end
84
-
85
- private
86
-
87
- def create_default_site!
88
- default_site = Alchemy::Config.get(:default_site)
89
- if default_site
90
- create!(name: default_site['name'], host: default_site['host'])
91
- else
92
- raise DefaultSiteNotFoundError
93
- end
94
- end
95
- end
96
-
97
- private
98
-
99
- # If no languages are present, create a default language based
100
- # on the host app's Alchemy configuration.
101
- def create_default_language!
102
- default_language = Alchemy::Config.get(:default_language)
103
- if default_language
104
- languages.build(
105
- name: default_language['name'],
106
- language_code: default_language['code'],
107
- locale: default_language['code'],
108
- frontpage_name: default_language['frontpage_name'],
109
- page_layout: default_language['page_layout'],
110
- public: true,
111
- default: true
112
- )
113
- else
114
- raise DefaultLanguageNotFoundError
115
- end
116
86
  end
117
87
  end
118
88
  end
@@ -3,7 +3,7 @@
3
3
  module Alchemy
4
4
  module Site::Layout
5
5
  extend ActiveSupport::Concern
6
- SITE_DEFINITIONS_FILE = Rails.root.join('config/alchemy/site_layouts.yml')
6
+ SITE_DEFINITIONS_FILE = Rails.root.join("config/alchemy/site_layouts.yml")
7
7
 
8
8
  module ClassMethods
9
9
  # Returns the site layouts definition defined in +site_layouts.yml+ file
@@ -28,7 +28,7 @@ module Alchemy
28
28
  # Returns site's layout definition
29
29
  #
30
30
  def definition
31
- self.class.definitions.detect { |l| l['name'] == partial_name }
31
+ self.class.definitions.detect { |l| l["name"] == partial_name }
32
32
  end
33
33
 
34
34
  # Returns the name for the layout partial
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alchemy
4
+ # If the model has a +elements+ association,
5
+ # it updates all their timestamps after save.
6
+ #
7
+ # Should only be used on bottom to top relations,
8
+ # e.g. +Alchemy::Picture+ or +Alchemy::Attachment+
9
+ # not on top to bottom ones like +Alchemy::Page+.
10
+ #
11
+ module TouchElements
12
+ def self.included(base)
13
+ base.after_save(:touch_elements)
14
+ end
15
+
16
+ private
17
+
18
+ def touch_elements
19
+ return unless respond_to?(:elements)
20
+
21
+ elements.map(&:touch)
22
+ end
23
+ end
24
+ end
@@ -6,9 +6,6 @@ module Alchemy
6
6
  :name,
7
7
  :ingredient,
8
8
  :element_id,
9
- :position,
10
- :created_at,
11
- :updated_at,
12
9
  :settings
13
10
 
14
11
  has_one :essence, polymorphic: true
@@ -2,9 +2,9 @@
2
2
 
3
3
  module Alchemy
4
4
  class EssenceBooleanSerializer < ActiveModel::Serializer
5
- attributes :id,
5
+ attributes(
6
+ :id,
6
7
  :value,
7
- :created_at,
8
- :updated_at
8
+ )
9
9
  end
10
10
  end