alchemy_cms 5.2.4 → 6.0.0.b1

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 (269) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +6 -14
  3. data/.gitignore +0 -1
  4. data/.hound.yml +1 -1
  5. data/.rubocop.yml +46 -4
  6. data/CHANGELOG.md +80 -25
  7. data/Gemfile +4 -2
  8. data/README.md +5 -2
  9. data/alchemy_cms.gemspec +78 -65
  10. data/app/assets/javascripts/alchemy/admin.js +0 -2
  11. data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +0 -27
  12. data/app/assets/javascripts/alchemy/alchemy.confirm_dialog.js.coffee +2 -1
  13. data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +1 -1
  14. data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee +0 -25
  15. data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +1 -1
  16. data/app/assets/javascripts/alchemy/alchemy.elements_window.js.coffee +2 -0
  17. data/app/assets/javascripts/alchemy/alchemy.fixed_elements.js +1 -1
  18. data/app/assets/javascripts/alchemy/alchemy.gui.js.coffee +3 -1
  19. data/app/assets/javascripts/alchemy/alchemy.image_overlay.coffee +1 -1
  20. data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +40 -27
  21. data/app/assets/javascripts/alchemy/templates/node_folder.hbs +1 -1
  22. data/app/assets/stylesheets/alchemy/admin.scss +1 -1
  23. data/app/assets/stylesheets/alchemy/archive.scss +4 -4
  24. data/app/assets/stylesheets/alchemy/buttons.scss +0 -4
  25. data/app/assets/stylesheets/alchemy/elements.scss +73 -61
  26. data/app/assets/stylesheets/alchemy/images.scss +8 -0
  27. data/app/assets/stylesheets/alchemy/node-select.scss +4 -3
  28. data/app/assets/stylesheets/alchemy/page-select.scss +1 -0
  29. data/app/assets/stylesheets/tinymce/skins/alchemy/skin.min.css.scss +6 -6
  30. data/app/controllers/alchemy/admin/attachments_controller.rb +6 -2
  31. data/app/controllers/alchemy/admin/base_controller.rb +5 -7
  32. data/app/controllers/alchemy/admin/elements_controller.rb +58 -34
  33. data/app/controllers/alchemy/admin/essence_audios_controller.rb +30 -0
  34. data/app/controllers/alchemy/admin/essence_files_controller.rb +0 -14
  35. data/app/controllers/alchemy/admin/essence_pictures_controller.rb +8 -79
  36. data/app/controllers/alchemy/admin/essence_videos_controller.rb +33 -0
  37. data/app/controllers/alchemy/admin/ingredients_controller.rb +30 -0
  38. data/app/controllers/alchemy/admin/layoutpages_controller.rb +0 -1
  39. data/app/controllers/alchemy/admin/pages_controller.rb +6 -13
  40. data/app/controllers/alchemy/admin/pictures_controller.rb +35 -9
  41. data/app/controllers/alchemy/api/elements_controller.rb +10 -5
  42. data/app/controllers/alchemy/api/pages_controller.rb +2 -4
  43. data/app/controllers/concerns/alchemy/admin/archive_overlay.rb +13 -3
  44. data/app/controllers/concerns/alchemy/admin/crop_action.rb +26 -0
  45. data/app/decorators/alchemy/element_editor.rb +23 -1
  46. data/app/decorators/alchemy/ingredient_editor.rb +154 -0
  47. data/app/helpers/alchemy/admin/elements_helper.rb +1 -0
  48. data/app/helpers/alchemy/admin/essences_helper.rb +1 -1
  49. data/app/helpers/alchemy/admin/ingredients_helper.rb +42 -0
  50. data/app/helpers/alchemy/elements_block_helper.rb +22 -7
  51. data/app/helpers/alchemy/elements_helper.rb +12 -5
  52. data/app/helpers/alchemy/pages_helper.rb +3 -11
  53. data/app/jobs/alchemy/base_job.rb +11 -0
  54. data/app/jobs/alchemy/publish_page_job.rb +11 -0
  55. data/app/models/alchemy/attachment.rb +1 -1
  56. data/app/models/alchemy/content/factory.rb +23 -27
  57. data/app/models/alchemy/content.rb +1 -6
  58. data/app/models/alchemy/element/definitions.rb +29 -27
  59. data/app/models/alchemy/element/element_contents.rb +131 -122
  60. data/app/models/alchemy/element/element_essences.rb +100 -98
  61. data/app/models/alchemy/element/element_ingredients.rb +176 -0
  62. data/app/models/alchemy/element/presenters.rb +89 -87
  63. data/app/models/alchemy/element.rb +40 -73
  64. data/app/models/alchemy/elements_repository.rb +126 -0
  65. data/app/models/alchemy/essence_audio.rb +12 -0
  66. data/app/models/alchemy/essence_headline.rb +40 -0
  67. data/app/models/alchemy/essence_picture.rb +4 -116
  68. data/app/models/alchemy/essence_richtext.rb +12 -0
  69. data/app/models/alchemy/essence_video.rb +12 -0
  70. data/app/models/alchemy/image_cropper_settings.rb +87 -0
  71. data/app/models/alchemy/ingredient.rb +219 -0
  72. data/app/models/alchemy/ingredient_validator.rb +97 -0
  73. data/app/models/alchemy/ingredients/audio.rb +29 -0
  74. data/app/models/alchemy/ingredients/boolean.rb +21 -0
  75. data/app/models/alchemy/ingredients/datetime.rb +20 -0
  76. data/app/models/alchemy/ingredients/file.rb +30 -0
  77. data/app/models/alchemy/ingredients/headline.rb +42 -0
  78. data/app/models/alchemy/ingredients/html.rb +19 -0
  79. data/app/models/alchemy/ingredients/link.rb +16 -0
  80. data/app/models/alchemy/ingredients/node.rb +23 -0
  81. data/app/models/alchemy/ingredients/page.rb +23 -0
  82. data/app/models/alchemy/ingredients/picture.rb +41 -0
  83. data/app/models/alchemy/ingredients/richtext.rb +57 -0
  84. data/app/models/alchemy/ingredients/select.rb +10 -0
  85. data/app/models/alchemy/ingredients/text.rb +17 -0
  86. data/app/models/alchemy/ingredients/video.rb +33 -0
  87. data/app/models/alchemy/language.rb +0 -11
  88. data/app/models/alchemy/node.rb +1 -1
  89. data/app/models/alchemy/page/fixed_attributes.rb +53 -51
  90. data/app/models/alchemy/page/page_elements.rb +186 -205
  91. data/app/models/alchemy/page/page_naming.rb +66 -64
  92. data/app/models/alchemy/page/page_natures.rb +139 -142
  93. data/app/models/alchemy/page/page_scopes.rb +113 -102
  94. data/app/models/alchemy/page/publisher.rb +50 -0
  95. data/app/models/alchemy/page/url_path.rb +1 -1
  96. data/app/models/alchemy/page.rb +67 -33
  97. data/app/models/alchemy/page_version.rb +58 -0
  98. data/app/models/alchemy/picture/calculations.rb +2 -8
  99. data/app/models/alchemy/picture/preprocessor.rb +2 -0
  100. data/app/models/alchemy/picture/transformations.rb +24 -96
  101. data/app/models/alchemy/picture.rb +4 -2
  102. data/app/models/concerns/alchemy/picture_thumbnails.rb +181 -0
  103. data/app/models/concerns/alchemy/touch_elements.rb +2 -2
  104. data/app/presenters/alchemy/picture_view.rb +88 -0
  105. data/app/serializers/alchemy/element_serializer.rb +5 -0
  106. data/app/serializers/alchemy/page_tree_serializer.rb +3 -2
  107. data/app/services/alchemy/delete_elements.rb +44 -0
  108. data/app/services/alchemy/duplicate_element.rb +56 -0
  109. data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +1 -2
  110. data/app/views/alchemy/admin/attachments/_file_to_assign.html.erb +3 -3
  111. data/app/views/alchemy/admin/attachments/assign.js.erb +11 -0
  112. data/app/views/alchemy/admin/crop.html.erb +36 -0
  113. data/app/views/alchemy/admin/elements/_element.html.erb +14 -10
  114. data/app/views/alchemy/admin/elements/{_element_footer.html.erb → _footer.html.erb} +0 -0
  115. data/app/views/alchemy/admin/elements/{_new_element_form.html.erb → _form.html.erb} +1 -1
  116. data/app/views/alchemy/admin/elements/{_element_header.html.erb → _header.html.erb} +1 -1
  117. data/app/views/alchemy/admin/elements/{_element_toolbar.html.erb → _toolbar.html.erb} +5 -6
  118. data/app/views/alchemy/admin/elements/{trash.js.erb → destroy.js.erb} +1 -3
  119. data/app/views/alchemy/admin/elements/new.html.erb +3 -3
  120. data/app/views/alchemy/admin/elements/order.js.erb +0 -17
  121. data/app/views/alchemy/admin/elements/update.js.erb +3 -2
  122. data/app/views/alchemy/admin/essence_audios/edit.html.erb +7 -0
  123. data/app/views/alchemy/admin/essence_pictures/update.js.erb +0 -1
  124. data/app/views/alchemy/admin/essence_videos/edit.html.erb +11 -0
  125. data/app/views/alchemy/admin/ingredients/_audio_fields.html.erb +4 -0
  126. data/app/views/alchemy/admin/ingredients/_file_fields.html.erb +18 -0
  127. data/app/views/alchemy/admin/ingredients/_picture_fields.html.erb +25 -0
  128. data/app/views/alchemy/admin/ingredients/_video_fields.html.erb +8 -0
  129. data/app/views/alchemy/admin/ingredients/edit.html.erb +4 -0
  130. data/app/views/alchemy/admin/layoutpages/edit.html.erb +0 -5
  131. data/app/views/alchemy/admin/nodes/_node.html.erb +2 -2
  132. data/app/views/alchemy/admin/pages/_anchor_link.html.erb +1 -1
  133. data/app/views/alchemy/admin/pages/_external_link.html.erb +1 -1
  134. data/app/views/alchemy/admin/pages/_file_link.html.erb +1 -1
  135. data/app/views/alchemy/admin/pages/_form.html.erb +0 -6
  136. data/app/views/alchemy/admin/pages/_internal_link.html.erb +1 -1
  137. data/app/views/alchemy/admin/pages/_tinymce_custom_config.html.erb +5 -2
  138. data/app/views/alchemy/admin/pages/edit.html.erb +36 -24
  139. data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +2 -4
  140. data/app/views/alchemy/admin/partials/_routes.html.erb +7 -11
  141. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +4 -8
  142. data/app/views/alchemy/admin/pictures/_infos.html.erb +0 -1
  143. data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +4 -4
  144. data/app/views/alchemy/admin/pictures/assign.js.erb +10 -0
  145. data/app/views/alchemy/admin/resources/_form.html.erb +1 -0
  146. data/app/views/alchemy/essences/_essence_audio_editor.html.erb +4 -0
  147. data/app/views/alchemy/essences/_essence_audio_view.html.erb +15 -0
  148. data/app/views/alchemy/essences/_essence_file_editor.html.erb +15 -6
  149. data/app/views/alchemy/essences/_essence_headline_editor.html.erb +36 -0
  150. data/app/views/alchemy/essences/_essence_headline_view.html.erb +10 -0
  151. data/app/views/alchemy/essences/_essence_link_editor.html.erb +8 -4
  152. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +27 -12
  153. data/app/views/alchemy/essences/_essence_text_editor.html.erb +12 -4
  154. data/app/views/alchemy/essences/_essence_video_editor.html.erb +4 -0
  155. data/app/views/alchemy/essences/_essence_video_view.html.erb +18 -0
  156. data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +21 -16
  157. data/app/views/alchemy/essences/shared/_linkable_essence_tools.html.erb +2 -2
  158. data/app/views/alchemy/ingredients/_audio_editor.html.erb +5 -0
  159. data/app/views/alchemy/ingredients/_audio_view.html.erb +14 -0
  160. data/app/views/alchemy/ingredients/_boolean_editor.html.erb +11 -0
  161. data/app/views/alchemy/ingredients/_boolean_view.html.erb +1 -0
  162. data/app/views/alchemy/ingredients/_datetime_editor.html.erb +17 -0
  163. data/app/views/alchemy/ingredients/_datetime_view.html.erb +9 -0
  164. data/app/views/alchemy/ingredients/_file_editor.html.erb +50 -0
  165. data/app/views/alchemy/ingredients/_file_view.html.erb +17 -0
  166. data/app/views/alchemy/ingredients/_headline_editor.html.erb +30 -0
  167. data/app/views/alchemy/ingredients/_headline_view.html.erb +9 -0
  168. data/app/views/alchemy/ingredients/_html_editor.html.erb +8 -0
  169. data/app/views/alchemy/ingredients/_html_view.html.erb +1 -0
  170. data/app/views/alchemy/ingredients/_link_editor.html.erb +24 -0
  171. data/app/views/alchemy/ingredients/_link_view.html.erb +9 -0
  172. data/app/views/alchemy/ingredients/_node_editor.html.erb +25 -0
  173. data/app/views/alchemy/ingredients/_node_view.html.erb +1 -0
  174. data/app/views/alchemy/ingredients/_page_editor.html.erb +24 -0
  175. data/app/views/alchemy/ingredients/_page_view.html.erb +4 -0
  176. data/app/views/alchemy/ingredients/_picture_editor.html.erb +59 -0
  177. data/app/views/alchemy/ingredients/_picture_view.html.erb +5 -0
  178. data/app/views/alchemy/ingredients/_richtext_editor.html.erb +12 -0
  179. data/app/views/alchemy/ingredients/_richtext_view.html.erb +3 -0
  180. data/app/views/alchemy/ingredients/_select_editor.html.erb +29 -0
  181. data/app/views/alchemy/ingredients/_select_view.html.erb +1 -0
  182. data/app/views/alchemy/ingredients/_text_editor.html.erb +19 -0
  183. data/app/views/alchemy/ingredients/_text_view.html.erb +16 -0
  184. data/app/views/alchemy/ingredients/_video_editor.html.erb +5 -0
  185. data/app/views/alchemy/ingredients/_video_view.html.erb +17 -0
  186. data/app/views/alchemy/ingredients/shared/_link_tools.html.erb +20 -0
  187. data/app/views/alchemy/ingredients/shared/_picture_tools.html.erb +57 -0
  188. data/config/brakeman.ignore +66 -159
  189. data/config/initializers/dragonfly.rb +10 -0
  190. data/config/locales/alchemy.en.yml +23 -15
  191. data/config/routes.rb +17 -22
  192. data/db/migrate/20201207131309_create_page_versions.rb +19 -0
  193. data/db/migrate/20201207135820_add_page_version_id_to_alchemy_elements.rb +76 -0
  194. data/db/migrate/20210205143548_rename_public_on_and_public_until_on_alchemy_pages.rb +10 -0
  195. data/db/migrate/20210326105046_add_sanitized_body_to_alchemy_essence_richtexts.rb +7 -0
  196. data/db/migrate/20210406093436_add_alchemy_essence_headlines.rb +12 -0
  197. data/db/migrate/20210506135919_create_essence_audios.rb +19 -0
  198. data/db/migrate/20210506140258_create_essence_videos.rb +23 -0
  199. data/db/migrate/20210508091432_create_alchemy_ingredients.rb +22 -0
  200. data/lib/alchemy/admin/preview_url.rb +2 -0
  201. data/lib/alchemy/deprecation.rb +1 -1
  202. data/lib/alchemy/dragonfly/processors/auto_orient.rb +18 -0
  203. data/lib/alchemy/dragonfly/processors/crop_resize.rb +35 -0
  204. data/lib/alchemy/elements_finder.rb +14 -60
  205. data/lib/alchemy/engine.rb +1 -1
  206. data/lib/alchemy/essence.rb +1 -2
  207. data/lib/alchemy/hints.rb +8 -4
  208. data/lib/alchemy/page_layout.rb +0 -13
  209. data/lib/alchemy/permissions.rb +30 -29
  210. data/lib/alchemy/resource.rb +13 -3
  211. data/lib/alchemy/tasks/tidy.rb +29 -0
  212. data/lib/alchemy/test_support/essence_shared_examples.rb +0 -1
  213. data/lib/alchemy/test_support/factories/element_factory.rb +8 -8
  214. data/lib/alchemy/test_support/factories/essence_audio_factory.rb +7 -0
  215. data/lib/alchemy/test_support/factories/essence_video_factory.rb +7 -0
  216. data/lib/alchemy/test_support/factories/ingredient_factory.rb +25 -0
  217. data/lib/alchemy/test_support/factories/page_factory.rb +20 -1
  218. data/lib/alchemy/test_support/factories/page_version_factory.rb +23 -0
  219. data/lib/alchemy/test_support/having_crop_action_examples.rb +170 -0
  220. data/lib/alchemy/test_support/having_picture_thumbnails_examples.rb +646 -0
  221. data/lib/alchemy/test_support/shared_ingredient_editor_examples.rb +21 -0
  222. data/lib/alchemy/test_support/shared_ingredient_examples.rb +57 -0
  223. data/lib/alchemy/test_support.rb +2 -11
  224. data/lib/alchemy/tinymce.rb +17 -0
  225. data/lib/alchemy/upgrader/five_point_zero.rb +0 -32
  226. data/lib/alchemy/upgrader/six_point_zero.rb +21 -0
  227. data/lib/alchemy/upgrader/tasks/add_page_versions.rb +33 -0
  228. data/lib/alchemy/upgrader/tasks/ingredients_migrator.rb +51 -0
  229. data/lib/alchemy/version.rb +1 -1
  230. data/lib/generators/alchemy/elements/elements_generator.rb +1 -0
  231. data/lib/generators/alchemy/elements/templates/view.html.erb +9 -0
  232. data/lib/generators/alchemy/elements/templates/view.html.haml +9 -0
  233. data/lib/generators/alchemy/elements/templates/view.html.slim +9 -0
  234. data/lib/generators/alchemy/ingredient/ingredient_generator.rb +38 -0
  235. data/lib/generators/alchemy/ingredient/templates/editor.html.erb +14 -0
  236. data/lib/generators/alchemy/ingredient/templates/model.rb.tt +13 -0
  237. data/lib/generators/alchemy/ingredient/templates/view.html.erb +1 -0
  238. data/lib/generators/alchemy/install/install_generator.rb +1 -2
  239. data/lib/generators/alchemy/install/templates/dragonfly.rb.tt +1 -1
  240. data/lib/generators/alchemy/menus/templates/node.html.erb +1 -1
  241. data/lib/generators/alchemy/menus/templates/node.html.haml +1 -1
  242. data/lib/generators/alchemy/menus/templates/node.html.slim +1 -1
  243. data/lib/generators/alchemy/menus/templates/wrapper.html.erb +1 -1
  244. data/lib/generators/alchemy/menus/templates/wrapper.html.haml +1 -1
  245. data/lib/generators/alchemy/menus/templates/wrapper.html.slim +1 -1
  246. data/lib/tasks/alchemy/tidy.rake +12 -0
  247. data/lib/tasks/alchemy/upgrade.rake +21 -15
  248. data/package/admin.js +9 -1
  249. data/package/src/file_editors.js +28 -0
  250. data/package/src/image_cropper.js +103 -0
  251. data/package/src/image_loader.js +58 -0
  252. data/package/src/node_tree.js +5 -5
  253. data/package/src/picture_editors.js +169 -0
  254. data/package/src/utils/__tests__/ajax.spec.js +20 -12
  255. data/package/src/utils/ajax.js +8 -3
  256. data/package.json +3 -2
  257. data/vendor/assets/javascripts/jquery_plugins/jquery.Jcrop.min.js +3 -18
  258. data/vendor/assets/stylesheets/jquery.Jcrop.min.scss +2 -28
  259. metadata +285 -56
  260. data/app/assets/javascripts/alchemy/alchemy.image_cropper.js.coffee +0 -44
  261. data/app/assets/javascripts/alchemy/alchemy.trash_window.js.coffee +0 -30
  262. data/app/assets/stylesheets/alchemy/trash.scss +0 -8
  263. data/app/controllers/alchemy/admin/trash_controller.rb +0 -44
  264. data/app/views/alchemy/admin/essence_files/assign.js.erb +0 -3
  265. data/app/views/alchemy/admin/essence_pictures/assign.js.erb +0 -4
  266. data/app/views/alchemy/admin/essence_pictures/crop.html.erb +0 -48
  267. data/app/views/alchemy/admin/trash/clear.js.erb +0 -4
  268. data/app/views/alchemy/admin/trash/index.html.erb +0 -31
  269. data/lib/alchemy/test_support/factories.rb +0 -20
@@ -22,4 +22,6 @@ Alchemy.GUI =
22
22
  initElement: ($el) ->
23
23
  Alchemy.ElementDirtyObserver($el)
24
24
  Alchemy.GUI.init($el)
25
- Alchemy.ImageLoader($el)
25
+ Alchemy.ImageLoader($el[0])
26
+ Alchemy.fileEditors($el.find(".essence_file, .essence_video, .essence_audio, .ingredient-editor.file, .ingredient-editor.audio, .ingredient-editor.video").selector)
27
+ Alchemy.pictureEditors($el.find(".essence_picture, .ingredient-editor.picture").selector)
@@ -7,7 +7,7 @@ class window.Alchemy.ImageOverlay extends Alchemy.Dialog
7
7
  return
8
8
 
9
9
  init: ->
10
- Alchemy.ImageLoader(@dialog_body)
10
+ Alchemy.ImageLoader(@dialog_body[0])
11
11
  $('.zoomed-picture-background').click (e) =>
12
12
  e.stopPropagation()
13
13
  return if e.target.nodeName == 'IMG'
@@ -4,6 +4,12 @@
4
4
  class window.Alchemy.LinkDialog extends Alchemy.Dialog
5
5
 
6
6
  constructor: (@link_object) ->
7
+ parent_selector = @link_object.dataset.parentSelector
8
+ parent = document.querySelector(parent_selector)
9
+ @link_value_field = parent.querySelector("[data-link-value]")
10
+ @link_title_field = parent.querySelector("[data-link-title]")
11
+ @link_target_field = parent.querySelector("[data-link-target]")
12
+ @link_class_field = parent.querySelector("[data-link-class]")
7
13
  @url = Alchemy.routes.link_admin_pages_path
8
14
  @$link_object = $(@link_object)
9
15
  @options =
@@ -136,7 +142,7 @@ class window.Alchemy.LinkDialog extends Alchemy.Dialog
136
142
  if @link_object.editor
137
143
  @setTinyMCELink(url, title, target)
138
144
  else
139
- @setEssenceLink(url, title, target)
145
+ @setLinkFields(url, title, target)
140
146
 
141
147
  # Sets a link in TinyMCE editor.
142
148
  setTinyMCELink: (url, title, target) ->
@@ -151,14 +157,16 @@ class window.Alchemy.LinkDialog extends Alchemy.Dialog
151
157
  true
152
158
 
153
159
  # Sets a link on an Essence (e.g. EssencePicture).
154
- setEssenceLink: (url, title, target) ->
155
- content_id = @$link_object.data('content-id')
156
- $("#contents_#{content_id}_link").val(url).change()
157
- $("#contents_#{content_id}_link_title").val(title)
158
- $("#contents_#{content_id}_link_class_name").val(@link_type)
159
- $("#contents_#{content_id}_link_target").val(target)
160
- @$link_object.addClass('linked')
161
- @$link_object.next().addClass('linked').removeClass('disabled').removeAttr('tabindex')
160
+ setLinkFields: (url, title, target) ->
161
+ @link_value_field.value = url
162
+ @link_value_field.dispatchEvent(new Event("change"))
163
+ @link_title_field.value = title
164
+ @link_class_field.value = @link_type
165
+ @link_target_field.value = target
166
+ @link_object.classList.add("linked")
167
+ @link_object.nextElementSibling.classList.replace("disabled", "linked")
168
+ @link_object.nextElementSibling.removeAttribute("tabindex")
169
+ return
162
170
 
163
171
  # Selects the correct tab for link type and fills all fields.
164
172
  selectTab: ->
@@ -205,12 +213,11 @@ class window.Alchemy.LinkDialog extends Alchemy.Dialog
205
213
  # Creates a temporay $('a') object that holds all values on it.
206
214
  createTempLink: ->
207
215
  @$tmp_link = $('<a/>')
208
- content_id = @$link_object.data('content-id')
209
- @$tmp_link.attr 'href', $("#contents_#{content_id}_link").val()
210
- @$tmp_link.attr 'title', $("#contents_#{content_id}_link_title").val()
211
- @$tmp_link.attr 'data-link-target', $("#contents_#{content_id}_link_target").val()
212
- @$tmp_link.attr 'target', if $("#contents_#{content_id}_link_target").val() == 'blank' then '_blank' else null
213
- @$tmp_link.addClass $("#contents_#{content_id}_link_class_name").val()
216
+ @$tmp_link.attr('href', @link_value_field.value)
217
+ @$tmp_link.attr('title', @link_title_field.value)
218
+ @$tmp_link.attr('data-link-target', @link_target_field.value)
219
+ @$tmp_link.attr('target', if @link_target_field.value == 'blank' then '_blank' else null)
220
+ @$tmp_link.addClass(@link_class_field.value)
214
221
  @$tmp_link
215
222
 
216
223
  # Validates url for beginning with an protocol.
@@ -228,7 +235,7 @@ class window.Alchemy.LinkDialog extends Alchemy.Dialog
228
235
  # Populates the internal anchors select
229
236
  initAnchorLinks: ->
230
237
  frame = document.getElementById('alchemy_preview_window')
231
- elements = frame.contentDocument.getElementsByTagName('*')
238
+ elements = frame.contentDocument?.getElementsByTagName('*') || []
232
239
  if elements.length > 0
233
240
  for element in elements
234
241
  if element.id
@@ -240,15 +247,21 @@ class window.Alchemy.LinkDialog extends Alchemy.Dialog
240
247
  # Public class methods
241
248
 
242
249
  # Removes link from Essence.
243
- @removeLink = (link, content_id) ->
244
- $link = $(link)
245
- $("#contents_#{content_id}_link").val('').change()
246
- $("#contents_#{content_id}_link_title").val('')
247
- $("#contents_#{content_id}_link_class_name").val('')
248
- $("#contents_#{content_id}_link_target").val('')
249
- if $link.hasClass('linked')
250
- Alchemy.setElementDirty $(link).closest('.element-editor')
251
- $link.removeClass('linked').addClass('disabled').attr('tabindex', '-1')
252
- $link.blur()
253
- $('#edit_link_' + content_id).removeClass('linked')
250
+ @removeLink = (link, parent_selector) ->
251
+ parent = document.querySelector(parent_selector)
252
+ link_value_field = parent.querySelector("[data-link-value]")
253
+ link_title_field = parent.querySelector("[data-link-title]")
254
+ link_target_field = parent.querySelector("[data-link-target]")
255
+ link_class_field = parent.querySelector("[data-link-class]")
256
+ link_value_field.value = ""
257
+ link_value_field.dispatchEvent(new Event("change"))
258
+ link_title_field.value = ""
259
+ link_class_field.value = ""
260
+ link_target_field.value = ""
261
+ if link.classList.contains('linked')
262
+ Alchemy.setElementDirty link.closest('.element-editor')
263
+ link.classList.replace('linked', 'disabled')
264
+ link.setAttribute('tabindex', '-1')
265
+ link.blur()
266
+ link.previousElementSibling.classList.remove("linked")
254
267
  false
@@ -1,3 +1,3 @@
1
- <a class="node_folder" data-node-id="{{ node.id }}">
1
+ <a class="node_folder" data-record-id="{{ node.id }}" data-record-type="{{ node.type }}">
2
2
  <i class="far fa-{{#if node.folded }}plus{{else}}minus{{/if}}-square fa-fw"></i>
3
3
  </a>
@@ -27,6 +27,7 @@
27
27
  @import "alchemy/frame";
28
28
  @import "alchemy/hints";
29
29
  @import "alchemy/icons";
30
+ @import "alchemy/images";
30
31
  @import "alchemy/image_library";
31
32
  @import "alchemy/labels";
32
33
  @import "alchemy/nodes";
@@ -42,7 +43,6 @@
42
43
  @import "alchemy/spinner";
43
44
  @import "alchemy/tables";
44
45
  @import "alchemy/tags";
45
- @import "alchemy/trash";
46
46
  @import "alchemy/typography";
47
47
  @import "alchemy/lists";
48
48
  @import "alchemy/upload";
@@ -43,10 +43,9 @@ div#image_assign_filter_and_image_sizing {
43
43
  width: 160px;
44
44
 
45
45
  img {
46
- width: auto;
47
- height: auto;
48
- max-width: 100%;
49
- max-height: 100%;
46
+ width: 100%;
47
+ height: 100%;
48
+ object-fit: contain;
50
49
  }
51
50
 
52
51
  .picture_name {
@@ -141,6 +140,7 @@ div.assign_image_list_image {
141
140
  }
142
141
 
143
142
  &.delete {
143
+ cursor: pointer;
144
144
  right: $default-padding;
145
145
  }
146
146
 
@@ -40,10 +40,6 @@ input.button {
40
40
 
41
41
  &[disabled] {
42
42
  cursor: not-allowed;
43
-
44
- & + label {
45
- display: none;
46
- }
47
43
  }
48
44
  }
49
45
 
@@ -45,13 +45,13 @@
45
45
  }
46
46
 
47
47
  > .message {
48
- margin: 2*$default-margin
48
+ margin: 2 * $default-margin;
49
49
  }
50
50
  }
51
51
 
52
52
  #main-content-elements,
53
53
  .element-editor.is-fixed .nestable-elements {
54
- padding: 2*$default-padding $default-padding 2px;
54
+ padding: 2 * $default-padding $default-padding 2px;
55
55
  }
56
56
 
57
57
  .element-title {
@@ -124,7 +124,7 @@
124
124
  border: 1px solid $default-border-color;
125
125
  border-radius: $default-border-radius;
126
126
  background-color: $light-gray;
127
- margin-bottom: 2*$default-margin;
127
+ margin-bottom: 2 * $default-margin;
128
128
  transition: box-shadow $transition-duration;
129
129
 
130
130
  &.hidden {
@@ -165,7 +165,7 @@
165
165
  &.dirty {
166
166
  border-color: #d0c83d;
167
167
 
168
- >.element-header {
168
+ > .element-header {
169
169
  background-color: #fff8df;
170
170
  }
171
171
  }
@@ -189,7 +189,8 @@
189
189
  }
190
190
  }
191
191
 
192
- &.selected:not(.is-fixed), &:hover {
192
+ &.selected:not(.is-fixed),
193
+ &:hover {
193
194
  &:not(.hidden) {
194
195
  box-shadow: 0 2px 8px rgba(#9b9b9b, 0.75);
195
196
  }
@@ -203,7 +204,6 @@
203
204
  }
204
205
 
205
206
  &.folded {
206
-
207
207
  .nested-elements {
208
208
  display: none;
209
209
  }
@@ -248,7 +248,7 @@
248
248
  transition: all $transition-duration;
249
249
  }
250
250
 
251
- .element-header:hover+.element-toolbar,
251
+ .element-header:hover + .element-toolbar,
252
252
  .element-toolbar:hover {
253
253
  visibility: visible;
254
254
  opacity: 1;
@@ -280,6 +280,7 @@
280
280
  }
281
281
 
282
282
  .content_editor,
283
+ .ingredient-editor,
283
284
  .picture_thumbnail {
284
285
  width: 100%;
285
286
  }
@@ -303,7 +304,7 @@
303
304
  }
304
305
 
305
306
  .element-content {
306
- margin: 2*$default-padding;
307
+ margin: 2 * $default-padding;
307
308
  }
308
309
 
309
310
  .validation_notice {
@@ -315,7 +316,7 @@
315
316
  }
316
317
 
317
318
  .message {
318
- margin: 2*$default-margin;
319
+ margin: 2 * $default-margin;
319
320
  }
320
321
 
321
322
  .foot_note {
@@ -343,7 +344,7 @@
343
344
  hr {
344
345
  height: 0;
345
346
  width: 100%;
346
- margin: 0 0 4*$default-margin 0;
347
+ margin: 0 0 4 * $default-margin 0;
347
348
  border: 0 none;
348
349
  border-top: 1px solid $medium-gray;
349
350
  opacity: 1;
@@ -352,7 +353,7 @@
352
353
 
353
354
  .element-header {
354
355
  position: relative;
355
- padding: 2*$default-padding;
356
+ padding: 2 * $default-padding;
356
357
  background-color: $element-header-bg-color;
357
358
  @extend .disable-user-select;
358
359
  cursor: pointer;
@@ -369,7 +370,7 @@
369
370
  transition: color $transition-duration;
370
371
  }
371
372
 
372
- >.hint-with-icon {
373
+ > .hint-with-icon {
373
374
  position: absolute;
374
375
  right: 32px;
375
376
  top: 10px;
@@ -405,7 +406,7 @@
405
406
 
406
407
  .element-footer {
407
408
  border-top: 1px solid $medium-gray;
408
- padding: 2*$default-padding;
409
+ padding: 2 * $default-padding;
409
410
  text-align: right;
410
411
 
411
412
  .button {
@@ -413,7 +414,8 @@
413
414
  }
414
415
  }
415
416
 
416
- .element-content-editors {
417
+ .element-content-editors,
418
+ .element-ingredient-editors {
417
419
  display: flex;
418
420
  flex-wrap: wrap;
419
421
  }
@@ -437,7 +439,8 @@
437
439
  right: 0;
438
440
 
439
441
  .icon_button {
440
- @include button-defaults($background-color: $medium-gray,
442
+ @include button-defaults(
443
+ $background-color: $medium-gray,
441
444
  $hover-color: darken($medium-gray, 5%),
442
445
  $border: 1px solid #c0c0c0,
443
446
  $box-shadow: none,
@@ -447,7 +450,8 @@
447
450
  $margin: 0,
448
451
  $border-radius: 0,
449
452
  $focus-border-color: $focus-color,
450
- $focus-box-shadow: 0 0 0 2px $focus-color);
453
+ $focus-box-shadow: 0 0 0 2px $focus-color
454
+ );
451
455
  width: 29px;
452
456
  height: $form-field-height;
453
457
 
@@ -457,9 +461,11 @@
457
461
  }
458
462
 
459
463
  &.linked.link-essence {
460
- @include linked-button($border-radius: 0,
464
+ @include linked-button(
465
+ $border-radius: 0,
461
466
  $line-height: 30px,
462
- $padding: 0);
467
+ $padding: 0
468
+ );
463
469
 
464
470
  &:focus {
465
471
  border-radius: 0;
@@ -467,9 +473,11 @@
467
473
  }
468
474
 
469
475
  &.linked.unlink-essence {
470
- @include linked-button($border-radius: 0 $default-border-radius $default-border-radius 0,
476
+ @include linked-button(
477
+ $border-radius: 0 $default-border-radius $default-border-radius 0,
471
478
  $line-height: 30px,
472
- $padding: 0);
479
+ $padding: 0
480
+ );
473
481
 
474
482
  &:focus {
475
483
  border-radius: 0 $default-border-radius $default-border-radius 0;
@@ -487,7 +495,7 @@
487
495
  height: 36px;
488
496
  border: 1px dotted $button-border-color;
489
497
  background-color: $medium-gray;
490
- margin-bottom: 2*$default-margin;
498
+ margin-bottom: 2 * $default-margin;
491
499
  border-radius: $default-border-radius;
492
500
  }
493
501
 
@@ -518,21 +526,10 @@
518
526
  }
519
527
  }
520
528
 
521
- .essence_picture {
529
+ .essence_picture,
530
+ .ingredient-editor.picture {
522
531
  position: relative;
523
532
 
524
- .picture_tool_delete {
525
- position: absolute;
526
- right: $default-margin;
527
- top: $default-margin;
528
- padding: 2px 2px 0;
529
- z-index: 2;
530
- }
531
-
532
- .picture_thumbnail:hover .picture_tool_delete {
533
- display: block;
534
- }
535
-
536
533
  .picture_thumbnail {
537
534
  display: inline-block;
538
535
  width: 160px;
@@ -541,7 +538,7 @@
541
538
  }
542
539
 
543
540
  &.validation_failed .picture_thumbnail {
544
- border-color: $error_border_color
541
+ border-color: $error_border_color;
545
542
  }
546
543
 
547
544
  .thumbnail_background .icon {
@@ -565,9 +562,15 @@
565
562
  }
566
563
  }
567
564
 
568
- .content_editor.essence_file {
569
-
565
+ .content_editor.essence_audio,
566
+ .content_editor.essence_file,
567
+ .content_editor.essence_video,
568
+ .ingredient-editor.audio,
569
+ .ingredient-editor.file,
570
+ .ingredient-editor.video {
570
571
  .file {
572
+ display: flex;
573
+ align-items: center;
571
574
  margin: 6px 0 $default-margin;
572
575
  border: $default-border;
573
576
  background-color: $white;
@@ -581,35 +584,39 @@
581
584
  }
582
585
 
583
586
  .file_icon {
584
- display: inline-block;
585
587
  text-align: center;
586
- float: left;
587
588
  width: 24px;
588
- padding: 6px 4px;
589
+ padding: $default-padding;
589
590
  }
590
591
 
591
592
  .file_name {
592
593
  white-space: nowrap;
593
594
  overflow: hidden;
594
- float: left;
595
595
  max-width: 80%;
596
- line-height: 28px;
597
596
  font-size: $small-font-size;
598
597
  text-overflow: ellipsis;
598
+ padding: $default-padding;
599
+ }
600
+
601
+ .remove_file_link {
602
+ width: 24px;
603
+ padding: $default-padding;
599
604
  }
600
605
  }
601
606
 
607
+ .file_tools,
602
608
  .essence_file_tools {
603
- height: 27px;
604
- float: right;
609
+ display: flex;
610
+ align-items: center;
611
+ margin-left: auto;
605
612
  background-color: white;
606
613
  width: 48px;
607
614
  border-radius: 0 $default-border-radius $default-border-radius 0;
608
615
 
609
616
  a {
617
+ text-align: center;
610
618
  text-decoration: none;
611
- padding: 6px $default-margin;
612
- float: left;
619
+ padding: $default-padding;
613
620
  }
614
621
  }
615
622
 
@@ -633,7 +640,8 @@ select.long {
633
640
  padding: 0;
634
641
  }
635
642
 
636
- .content_editor {
643
+ .content_editor,
644
+ .ingredient-editor {
637
645
  width: 100%;
638
646
  padding: $default-padding 0;
639
647
  position: relative;
@@ -644,7 +652,6 @@ select.long {
644
652
  }
645
653
 
646
654
  &.missing {
647
-
648
655
  .message {
649
656
  margin: 0;
650
657
  @include clearfix;
@@ -675,13 +682,12 @@ select.long {
675
682
  }
676
683
 
677
684
  &.validation_failed {
678
-
679
- label {
680
- color: $error_text_color
685
+ > label {
686
+ color: $error_text_color;
681
687
  }
682
688
 
683
689
  input {
684
- @extend %field-with-error
690
+ @extend %field-with-error;
685
691
  }
686
692
 
687
693
  .tinymce_container {
@@ -727,10 +733,10 @@ select.long {
727
733
  }
728
734
  }
729
735
 
730
- &.essence_select {
731
-
736
+ &.essence_select,
737
+ &.select {
732
738
  label {
733
- margin-bottom: 2*$default-margin
739
+ margin-bottom: 2 * $default-margin;
734
740
  }
735
741
 
736
742
  .select2-container {
@@ -742,6 +748,7 @@ select.long {
742
748
  }
743
749
  }
744
750
 
751
+ select.ingredient-editor-select,
745
752
  select.essence_editor_select {
746
753
  border-radius: $default-border-radius;
747
754
  background: white;
@@ -769,12 +776,14 @@ select.long {
769
776
  }
770
777
  }
771
778
 
772
- &.essence_picture {
779
+ &.essence_picture,
780
+ &.picture {
773
781
  width: 50%;
774
782
  padding-left: 1px; // Compensate the box shadow
775
783
  padding-right: $default-padding;
776
784
 
777
- +.essence_picture {
785
+ + .essence_picture,
786
+ + .picture {
778
787
  padding-left: $default-padding;
779
788
  padding-right: 1px; // Compensate the box shadow
780
789
  }
@@ -812,7 +821,7 @@ textarea.has_tinymce {
812
821
  margin-top: 8px;
813
822
  margin-bottom: 8px;
814
823
  background-color: $error_background_color;
815
- padding: 2*$default-padding;
824
+ padding: 2 * $default-padding;
816
825
  list-style-type: none;
817
826
  border-radius: $default-border-radius;
818
827
  color: $error_text_color;
@@ -826,10 +835,12 @@ textarea.has_tinymce {
826
835
 
827
836
  .content_editor .hint-with-icon,
828
837
  .content_editor .with-hint,
838
+ .ingredient-editor .hint-with-icon,
839
+ .ingredient-editor .with-hint,
829
840
  .element-handle .hint-with-icon {
830
841
  margin: 0;
831
842
 
832
- >.hint-bubble {
843
+ > .hint-bubble {
833
844
  left: -7px;
834
845
  transform: none;
835
846
 
@@ -841,13 +852,13 @@ textarea.has_tinymce {
841
852
 
842
853
  .is-fixed {
843
854
  &.with-contents {
844
- >.element-footer {
855
+ > .element-footer {
845
856
  border-top: 0;
846
857
  border-bottom: 1px solid $medium-gray;
847
858
  }
848
859
  }
849
860
 
850
- >.nestable-elements .add-nestable-element-button {
861
+ > .nestable-elements .add-nestable-element-button {
851
862
  width: 100%;
852
863
  text-align: center;
853
864
  }
@@ -885,6 +896,7 @@ textarea.has_tinymce {
885
896
  }
886
897
  }
887
898
 
899
+ .ingredient-date--label,
888
900
  .essence_date--label {
889
901
  position: absolute;
890
902
  right: 7px;
@@ -0,0 +1,8 @@
1
+ img {
2
+ opacity: 1;
3
+ transition: opacity $transition-duration;
4
+
5
+ &.loading {
6
+ opacity: 0;
7
+ }
8
+ }
@@ -8,12 +8,13 @@
8
8
  .node-select--node {
9
9
  display: flex;
10
10
  align-items: center;
11
+ height: 21px;
11
12
 
12
13
  .icon {
13
14
  margin: 0 8px 0 4px;
14
15
 
15
16
  .select2-highlighted & {
16
- color: $white
17
+ color: $white;
17
18
  }
18
19
  }
19
20
  }
@@ -24,12 +25,12 @@
24
25
 
25
26
  .node-select--node-url {
26
27
  margin-left: auto;
27
- padding: $default-padding 2*$default-padding;
28
+ padding: $default-padding 2 * $default-padding;
28
29
  color: $dark-gray;
29
30
  font-size: $small-font-size;
30
31
 
31
32
  .select2-highlighted & {
32
- color: $white
33
+ color: $white;
33
34
  }
34
35
  }
35
36
 
@@ -1,4 +1,5 @@
1
1
  .page-select--page,
2
+ .page-select--page-name,
2
3
  .page-select--page-urlname {
3
4
  text-overflow: ellipsis;
4
5
  overflow: hidden;
@@ -1566,18 +1566,18 @@ i.mce-i-resize {
1566
1566
 
1567
1567
  @font-face {
1568
1568
  font-family: 'tinymce';
1569
- src: url('./fonts/tinymce.woff') format('woff'),
1570
- url('./fonts/tinymce.ttf') format('truetype'),
1571
- url('./fonts/tinymce.svg#tinymce') format('svg');
1569
+ src: url('fonts/tinymce.woff') format('woff'),
1570
+ url('fonts/tinymce.ttf') format('truetype'),
1571
+ url('fonts/tinymce.svg#tinymce') format('svg');
1572
1572
  font-weight: normal;
1573
1573
  font-style: normal;
1574
1574
  }
1575
1575
 
1576
1576
  @font-face {
1577
1577
  font-family: 'tinymce-small';
1578
- src: url('./fonts/tinymce-small.woff') format('woff'),
1579
- url('./fonts/tinymce-small.ttf') format('truetype'),
1580
- url('./fonts/tinymce-small.svg#tinymce') format('svg');
1578
+ src: url('fonts/tinymce-small.woff') format('woff'),
1579
+ url('fonts/tinymce-small.ttf') format('truetype'),
1580
+ url('fonts/tinymce-small.svg#tinymce') format('svg');
1581
1581
  font-weight: normal;
1582
1582
  font-style: normal;
1583
1583
  }
@@ -8,6 +8,10 @@ module Alchemy
8
8
 
9
9
  helper "alchemy/admin/tags"
10
10
 
11
+ before_action(only: :assign) do
12
+ @attachment = Attachment.find(params[:id])
13
+ end
14
+
11
15
  def index
12
16
  @query = Attachment.ransack(search_filter_params[:q])
13
17
  @query.sorts = "name asc" if @query.sorts.empty?
@@ -74,8 +78,8 @@ module Alchemy
74
78
  @_search_filter_params ||= params.except(*COMMON_SEARCH_FILTER_EXCLUDES + [:attachment]).permit(
75
79
  *common_search_filter_includes + [
76
80
  :file_type,
77
- :content_id,
78
- ],
81
+ :form_field_id,
82
+ ]
79
83
  )
80
84
  end
81
85